aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-18 11:49:51 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-18 11:49:51 -0400
commit752ab8212c7556ed714d1272582e57180b50c5a6 (patch)
tree50d05d8e7512494fbbe16a27ed89d6a14b401ea5
parent8b94c2c7f198babe64a2636538913cf67165709c (diff)
Split BigIntType out of IntType and switch to using enums for the size
of ints/nums
-rw-r--r--ast.c4
-rw-r--r--ast.h4
-rw-r--r--compile.c125
-rw-r--r--environment.c14
-rw-r--r--parse.c19
-rw-r--r--repl.c49
-rw-r--r--structs.c31
-rw-r--r--typecheck.c37
-rw-r--r--types.c57
-rw-r--r--types.h10
10 files changed, 176 insertions, 174 deletions
diff --git a/ast.c b/ast.c
index 69991e4c..02cf51fa 100644
--- a/ast.c
+++ b/ast.c
@@ -99,8 +99,8 @@ CORD ast_to_xml(ast_t *ast)
T(Nil, "<Nil>%r</Nil>", type_ast_to_xml(data.type))
T(Bool, "<Bool value=\"%s\" />", data.b ? "yes" : "no")
T(Var, "<Var>%s</Var>", data.name)
- T(Int, "<Int bits=\"%ld\">%s</Int>", data.bits, data.str)
- T(Num, "<Num bits=\"%ld\">%g</Num>", data.bits, data.n)
+ T(Int, "<Int bits=\"%d\">%s</Int>", data.bits, data.str)
+ T(Num, "<Num bits=\"%d\">%g</Num>", data.bits, data.n)
T(TextLiteral, "%r", xml_escape(data.cord))
T(TextJoin, "<Text%r>%r</Text>", data.lang ? CORD_all(" lang=\"", data.lang, "\"") : CORD_EMPTY, ast_list_to_xml(data.children))
T(Declare, "<Declare var=\"%r\">%r</Declare>", ast_to_xml(data.var), ast_to_xml(data.value))
diff --git a/ast.h b/ast.h
index fc4a505b..d824c181 100644
--- a/ast.h
+++ b/ast.h
@@ -144,11 +144,11 @@ struct ast_s {
} Var;
struct {
const char *str;
- int64_t bits;
+ enum { IBITS_UNSPECIFIED=0, IBITS8=8, IBITS16=16, IBITS32=32, IBITS64=64 } bits;
} Int;
struct {
double n;
- int64_t bits;
+ enum { NBITS_UNSPECIFIED=0, NBITS32=32, NBITS64=64 } bits;
} Num;
struct {
CORD cord;
diff --git a/compile.c b/compile.c
index cda7da6d..88902cfb 100644
--- a/compile.c
+++ b/compile.c
@@ -32,7 +32,7 @@ static bool promote(env_t *env, CORD *code, type_t *actual, type_t *needed)
if (!can_promote(actual, needed))
return false;
- if (actual->tag == IntType && needed->tag == IntType && Match(needed, IntType)->bits == 0) {
+ if (actual->tag == IntType && needed->tag == BigIntType) {
*code = CORD_all("I(", *code, ")");
return true;
}
@@ -156,8 +156,9 @@ CORD compile_type(type_t *t)
case MemoryType: return "void";
case BoolType: return "Bool_t";
case CStringType: return "char*";
- case IntType: return Match(t, IntType)->bits == 0 ? "Int_t" : CORD_asprintf("Int%ld_t", Match(t, IntType)->bits);
- case NumType: return Match(t, NumType)->bits == 64 ? "Num_t" : CORD_asprintf("Num%ld_t", Match(t, NumType)->bits);
+ case BigIntType: return "Int_t";
+ case IntType: return CORD_asprintf("Int%ld_t", Match(t, IntType)->bits);
+ case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? "Num_t" : CORD_asprintf("Num%ld_t", Match(t, NumType)->bits);
case TextType: {
auto text = Match(t, TextType);
return text->lang ? CORD_all(namespace_prefix(text->env->libname, text->env->namespace->parent), text->lang, "_t") : "Text_t";
@@ -540,7 +541,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
case BINOP_POWER: {
if (lhs_t->tag != NumType)
code_err(ast, "'^=' is only supported for Num types");
- if (lhs_t->tag == NumType && Match(lhs_t, NumType)->bits == 32)
+ if (lhs_t->tag == NumType && Match(lhs_t, NumType)->bits == TYPE_NBITS32)
return CORD_all(lhs, " = powf(", lhs, ", ", rhs, ");");
else
return CORD_all(lhs, " = pow(", lhs, ", ", rhs, ");");
@@ -1248,26 +1249,28 @@ env_t *with_enum_scope(env_t *env, type_t *t)
CORD compile_int_to_type(env_t *env, ast_t *ast, type_t *target)
{
- int64_t target_bits = Match(target, IntType)->bits;
+ if (target->tag == BigIntType)
+ return compile(env, ast);
+
+ int64_t target_bits = (int64_t)Match(target, IntType)->bits;
Int_t int_val = Int$from_text(Match(ast, Int)->str);
mpz_t i;
mpz_init_set_int(i, int_val);
switch (target_bits) {
- case 0: return compile(env, ast);
- case 64:
+ case TYPE_IBITS64:
if (mpz_cmp_si(i, INT64_MAX) <= 0 && mpz_cmp_si(i, INT64_MIN) >= 0)
return CORD_asprintf("I64(%s)", Match(ast, Int)->str);
break;
- case 32:
+ case TYPE_IBITS32:
if (mpz_cmp_si(i, INT32_MAX) <= 0 && mpz_cmp_si(i, INT32_MIN) >= 0)
return CORD_asprintf("I32(%s)", Match(ast, Int)->str);
break;
- case 16:
+ case TYPE_IBITS16:
if (mpz_cmp_si(i, INT16_MAX) <= 0 && mpz_cmp_si(i, INT16_MIN) >= 0)
return CORD_asprintf("I16(%s)", Match(ast, Int)->str);
break;
- case 8:
+ case TYPE_IBITS8:
if (mpz_cmp_si(i, INT8_MAX) <= 0 && mpz_cmp_si(i, INT8_MIN) >= 0)
return CORD_asprintf("I8(%s)", Match(ast, Int)->str);
break;
@@ -1292,7 +1295,7 @@ CORD compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_t
} else if (spec_arg->type->tag == NumType && call_arg->value->tag == Int) {
Int_t int_val = Int$from_text(Match(call_arg->value, Int)->str);
double n = Int_to_Num(int_val);
- value = CORD_asprintf(Match(spec_arg->type, NumType)->bits == 64
+ value = CORD_asprintf(Match(spec_arg->type, NumType)->bits == TYPE_NBITS64
? "N64(%.9g)" : "N32(%.9g)", n);
} else {
env_t *arg_env = with_enum_scope(env, spec_arg->type);
@@ -1320,7 +1323,7 @@ CORD compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_t
} else if (spec_arg->type->tag == NumType && call_arg->value->tag == Int) {
Int_t int_val = Int$from_text(Match(call_arg->value, Int)->str);
double n = Int_to_Num(int_val);
- value = CORD_asprintf(Match(spec_arg->type, NumType)->bits == 64
+ value = CORD_asprintf(Match(spec_arg->type, NumType)->bits == TYPE_NBITS64
? "N64(%.9g)" : "N32(%.9g)", n);
} else {
env_t *arg_env = with_enum_scope(env, spec_arg->type);
@@ -1454,7 +1457,7 @@ CORD compile(env_t *env, ast_t *ast)
mpz_init_set_int(i, int_val);
switch (Match(ast, Int)->bits) {
- case 0:
+ case IBITS_UNSPECIFIED:
if (mpz_cmpabs_ui(i, BIGGEST_SMALL_INT) <= 0) {
return CORD_asprintf("I_small(%s)", str);
} else if (mpz_cmp_si(i, INT64_MAX) <= 0 && mpz_cmp_si(i, INT64_MIN) >= 0) {
@@ -1462,19 +1465,19 @@ CORD compile(env_t *env, ast_t *ast)
} else {
return CORD_asprintf("Int$from_text(\"%s\")", str);
}
- case 64:
+ case IBITS64:
if ((mpz_cmp_si(i, INT64_MAX) < 0) && (mpz_cmp_si(i, INT64_MIN) > 0))
return CORD_asprintf("I64(%s)", str);
code_err(ast, "This value cannot fit in a 64-bit integer");
- case 32:
+ case IBITS32:
if ((mpz_cmp_si(i, INT32_MAX) < 0) && (mpz_cmp_si(i, INT32_MIN) > 0))
return CORD_asprintf("I32(%s)", str);
code_err(ast, "This value cannot fit in a 32-bit integer");
- case 16:
+ case IBITS16:
if ((mpz_cmp_si(i, INT16_MAX) < 0) && (mpz_cmp_si(i, INT16_MIN) > 0))
return CORD_asprintf("I16(%s)", str);
code_err(ast, "This value cannot fit in a 16-bit integer");
- case 8:
+ case IBITS8:
if ((mpz_cmp_si(i, INT8_MAX) < 0) && (mpz_cmp_si(i, INT8_MIN) > 0))
return CORD_asprintf("I8(%s)", str);
code_err(ast, "This value cannot fit in a 8-bit integer");
@@ -1482,7 +1485,13 @@ CORD compile(env_t *env, ast_t *ast)
}
}
case Num: {
- return CORD_asprintf(Match(ast, Num)->bits == 64 ? "N64(%.9g)" : "N32(%.9g)", Match(ast, Num)->n);
+ switch (Match(ast, Num)->bits) {
+ case NBITS_UNSPECIFIED: case NBITS64:
+ return CORD_asprintf("N64(%.9g)", Match(ast, Num)->n);
+ case NBITS32:
+ return CORD_asprintf("N32(%.9g)", Match(ast, Num)->n);
+ default: code_err(ast, "This is not a valid number bit width");
+ }
}
case Length: {
ast_t *expr = Match(ast, Length)->value;
@@ -1588,7 +1597,7 @@ CORD compile(env_t *env, ast_t *ast)
case BINOP_POWER: {
if (operand_t->tag != NumType)
code_err(ast, "Exponentiation is only supported for Num types");
- if (operand_t->tag == NumType && Match(operand_t, NumType)->bits == 32)
+ if (operand_t->tag == NumType && Match(operand_t, NumType)->bits == TYPE_NBITS32)
return CORD_all("powf(", lhs, ", ", rhs, ")");
else
return CORD_all("pow(", lhs, ", ", rhs, ")");
@@ -1635,11 +1644,9 @@ CORD compile(env_t *env, ast_t *ast)
}
case BINOP_EQ: {
switch (operand_t->tag) {
- case IntType:
- if (Match(operand_t, IntType)->bits == 0)
- return CORD_all("Int$equal_value(", lhs, ", ", rhs, ")");
- return CORD_all("(", lhs, " == ", rhs, ")");
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BigIntType:
+ return CORD_all("Int$equal_value(", lhs, ", ", rhs, ")");
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
return CORD_all("(", lhs, " == ", rhs, ")");
default:
return CORD_asprintf("generic_equal(stack(%r), stack(%r), %r)", lhs, rhs, compile_type_info(env, operand_t));
@@ -1647,11 +1654,9 @@ CORD compile(env_t *env, ast_t *ast)
}
case BINOP_NE: {
switch (operand_t->tag) {
- case IntType:
- if (Match(operand_t, IntType)->bits == 0)
- return CORD_all("!Int$equal_value(", lhs, ", ", rhs, ")");
- return CORD_all("(", lhs, " != ", rhs, ")");
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BigIntType:
+ return CORD_all("!Int$equal_value(", lhs, ", ", rhs, ")");
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
return CORD_all("(", lhs, " != ", rhs, ")");
default:
return CORD_asprintf("!generic_equal(stack(%r), stack(%r), %r)", lhs, rhs, compile_type_info(env, operand_t));
@@ -1659,11 +1664,9 @@ CORD compile(env_t *env, ast_t *ast)
}
case BINOP_LT: {
switch (operand_t->tag) {
- case IntType:
- if (Match(operand_t, IntType)->bits == 0)
- return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") < 0)");
- return CORD_all("(", lhs, " != ", rhs, ")");
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BigIntType:
+ return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") < 0)");
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
return CORD_all("(", lhs, " < ", rhs, ")");
default:
return CORD_asprintf("(generic_compare(stack(%r), stack(%r), %r) < 0)", lhs, rhs, compile_type_info(env, operand_t));
@@ -1671,11 +1674,9 @@ CORD compile(env_t *env, ast_t *ast)
}
case BINOP_LE: {
switch (operand_t->tag) {
- case IntType:
- if (Match(operand_t, IntType)->bits == 0)
- return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") <= 0)");
- return CORD_all("(", lhs, " != ", rhs, ")");
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BigIntType:
+ return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") <= 0)");
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
return CORD_all("(", lhs, " <= ", rhs, ")");
default:
return CORD_asprintf("(generic_compare(stack(%r), stack(%r), %r) <= 0)", lhs, rhs, compile_type_info(env, operand_t));
@@ -1683,11 +1684,9 @@ CORD compile(env_t *env, ast_t *ast)
}
case BINOP_GT: {
switch (operand_t->tag) {
- case IntType:
- if (Match(operand_t, IntType)->bits == 0)
- return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") > 0)");
- return CORD_all("(", lhs, " != ", rhs, ")");
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BigIntType:
+ return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") > 0)");
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
return CORD_all("(", lhs, " > ", rhs, ")");
default:
return CORD_asprintf("(generic_compare(stack(%r), stack(%r), %r) > 0)", lhs, rhs, compile_type_info(env, operand_t));
@@ -1695,11 +1694,9 @@ CORD compile(env_t *env, ast_t *ast)
}
case BINOP_GE: {
switch (operand_t->tag) {
- case IntType:
- if (Match(operand_t, IntType)->bits == 0)
- return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") >= 0)");
- return CORD_all("(", lhs, " != ", rhs, ")");
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BigIntType:
+ return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") >= 0)");
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
return CORD_all("(", lhs, " >= ", rhs, ")");
default:
return CORD_asprintf("(generic_compare(stack(%r), stack(%r), %r) >= 0)", lhs, rhs, compile_type_info(env, operand_t));
@@ -1865,7 +1862,7 @@ CORD compile(env_t *env, ast_t *ast)
type_t *key_t = get_type(expr_env, key);
CORD comparison;
- if (key_t->tag == IntType && Match(key_t, IntType)->bits == 0)
+ if (key_t->tag == BigIntType)
comparison = CORD_all("(Int$compare_value(", lhs_key, ", ", rhs_key, ")", (ast->tag == Min ? "<=" : ">="), "0)");
else if (key_t->tag == IntType || key_t->tag == NumType || key_t->tag == BoolType || key_t->tag == PointerType)
comparison = CORD_all("((", lhs_key, ")", (ast->tag == Min ? "<=" : ">="), "(", rhs_key, "))");
@@ -2161,25 +2158,25 @@ CORD compile(env_t *env, ast_t *ast)
if (streq(call->name, "insert")) {
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
arg_t *arg_spec = new(arg_t, .name="item", .type=item_t,
- .next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0", .bits=0)));
+ .next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0")));
return CORD_all("Array$insert_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
} else if (streq(call->name, "insert_all")) {
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
arg_t *arg_spec = new(arg_t, .name="items", .type=self_value_t,
- .next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0", .bits=0)));
+ .next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0")));
return CORD_all("Array$insert_all(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
} else if (streq(call->name, "remove_at")) {
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
- arg_t *arg_spec = new(arg_t, .name="index", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1", .bits=0),
- .next=new(arg_t, .name="count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="1", .bits=0)));
+ arg_t *arg_spec = new(arg_t, .name="index", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1"),
+ .next=new(arg_t, .name="count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="1")));
return CORD_all("Array$remove_at(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
} else if (streq(call->name, "remove_item")) {
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
arg_t *arg_spec = new(arg_t, .name="item", .type=item_t,
- .next=new(arg_t, .name="max_count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1", .bits=0)));
+ .next=new(arg_t, .name="max_count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1")));
return CORD_all("Array$remove_item_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
compile_type_info(env, self_value_t), ")");
} else if (streq(call->name, "random")) {
@@ -2194,7 +2191,7 @@ CORD compile(env_t *env, ast_t *ast)
} else if (streq(call->name, "sample")) {
CORD self = compile_to_pointer_depth(env, call->self, 0, false);
arg_t *arg_spec = new(arg_t, .name="count", .type=INT_TYPE,
- .next=new(arg_t, .name="weights", .type=Type(ArrayType, .item_type=Type(NumType, .bits=64)),
+ .next=new(arg_t, .name="weights", .type=Type(ArrayType, .item_type=Type(NumType)),
.default_val=FakeAST(Array, .item_type=new(type_ast_t, .tag=VarTypeAST, .__data.VarTypeAST.name="Num"))));
return CORD_all("Array$sample(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
padded_item_size, ")");
@@ -2212,7 +2209,7 @@ CORD compile(env_t *env, ast_t *ast)
if (call->args) {
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true, .is_readonly=true);
type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=32));
+ .ret=Type(IntType, .bits=TYPE_IBITS32));
arg_t *arg_spec = new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t));
comparison = compile_arguments(env, ast, arg_spec, call->args);
} else {
@@ -2225,7 +2222,7 @@ CORD compile(env_t *env, ast_t *ast)
if (call->args) {
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=32));
+ .ret=Type(IntType, .bits=TYPE_IBITS32));
arg_t *arg_spec = new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t));
comparison = compile_arguments(env, ast, arg_spec, call->args);
} else {
@@ -2236,7 +2233,7 @@ CORD compile(env_t *env, ast_t *ast)
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=32));
+ .ret=Type(IntType, .bits=TYPE_IBITS32));
ast_t *default_cmp = FakeAST(InlineCCode,
.code=CORD_all("((closure_t){.fn=generic_compare, .userdata=(void*)",
compile_type_info(env, item_t), "})"),
@@ -2249,7 +2246,7 @@ CORD compile(env_t *env, ast_t *ast)
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=32));
+ .ret=Type(IntType, .bits=TYPE_IBITS32));
ast_t *default_cmp = FakeAST(InlineCCode,
.code=CORD_all("((closure_t){.fn=generic_compare, .userdata=(void*)",
compile_type_info(env, item_t), "})"),
@@ -2261,7 +2258,7 @@ CORD compile(env_t *env, ast_t *ast)
CORD self = compile_to_pointer_depth(env, call->self, 0, false);
type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true);
type_t *fn_t = Type(FunctionType, .args=new(arg_t, .name="x", .type=item_ptr, .next=new(arg_t, .name="y", .type=item_ptr)),
- .ret=Type(IntType, .bits=32));
+ .ret=Type(IntType, .bits=TYPE_IBITS32));
ast_t *default_cmp = FakeAST(InlineCCode,
.code=CORD_all("((closure_t){.fn=generic_compare, .userdata=(void*)",
compile_type_info(env, item_t), "})"),
@@ -2436,8 +2433,8 @@ CORD compile(env_t *env, ast_t *ast)
if (!(table->value_type->tag == IntType || table->value_type->tag == NumType))
code_err(ast, "bump() is only supported for tables with numeric value types, not %T", self_value_t);
ast_t *one = table->value_type->tag == IntType
- ? FakeAST(Int, .str="1", .bits=Match(table->value_type, IntType)->bits)
- : FakeAST(Num, .n=1, .bits=Match(table->value_type, NumType)->bits);
+ ? FakeAST(Int, .str="1")
+ : FakeAST(Num, .n=1);
arg_t *arg_spec = new(arg_t, .name="key", .type=table->key_type,
.next=new(arg_t, .name="amount", .type=table->value_type, .default_val=one));
return CORD_all("Table$bump(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ",
@@ -2479,7 +2476,7 @@ CORD compile(env_t *env, ast_t *ast)
// Struct constructor:
fn_t = Type(FunctionType, .args=Match(t, StructType)->fields, .ret=t);
return CORD_all("((", compile_type(t), "){", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, call->args), "})");
- } else if (t->tag == NumType || (t->tag == IntType && Match(t, IntType)->bits == 0)) {
+ } else if (t->tag == NumType || t->tag == BigIntType) {
type_t *actual = get_type(env, call->args->value);
arg_t *args = new(arg_t, .name="i", .type=actual); // No truncation argument
CORD arg_code = compile_arguments(env, ast, args, call->args);
diff --git a/environment.c b/environment.c
index becf1291..411074ef 100644
--- a/environment.c
+++ b/environment.c
@@ -87,7 +87,7 @@ env_t *new_compilation_unit(CORD *libname)
{"from_text", "Bool$from_text", "func(text:Text, success=!&Bool)->Bool"},
{"random", "Bool$random", "func(p=0.5)->Bool"},
)},
- {"Int", Type(IntType, .bits=0), "Int_t", "$Int", TypedArray(ns_entry_t,
+ {"Int", Type(BigIntType), "Int_t", "$Int", TypedArray(ns_entry_t,
{"format", "Int$format", "func(i:Int, digits=0)->Text"},
{"hex", "Int$hex", "func(i:Int, digits=0, uppercase=yes, prefix=yes)->Text"},
{"octal", "Int$octal", "func(i:Int, digits=0, prefix=yes)->Text"},
@@ -111,7 +111,7 @@ env_t *new_compilation_unit(CORD *libname)
{"sqrt", "Int$sqrt", "func(x:Int)->Int"},
{"power", "Int$power", "func(base:Int,exponent:Int)->Int"},
)},
- {"Int64", Type(IntType, .bits=64), "Int64_t", "$Int64", TypedArray(ns_entry_t,
+ {"Int64", Type(IntType, .bits=TYPE_IBITS64), "Int64_t", "$Int64", TypedArray(ns_entry_t,
{"format", "Int64$format", "func(i:Int64, digits=0)->Text"},
{"hex", "Int64$hex", "func(i:Int64, digits=0, uppercase=yes, prefix=yes)->Text"},
{"octal", "Int64$octal", "func(i:Int64, digits=0, prefix=yes)->Text"},
@@ -126,7 +126,7 @@ env_t *new_compilation_unit(CORD *libname)
{"modulo", "Int64$modulo", "func(x:Int64,y:Int64)->Int64"},
{"modulo1", "Int64$modulo1", "func(x:Int64,y:Int64)->Int64"},
)},
- {"Int32", Type(IntType, .bits=32), "Int32_t", "$Int32", TypedArray(ns_entry_t,
+ {"Int32", Type(IntType, .bits=TYPE_IBITS32), "Int32_t", "$Int32", TypedArray(ns_entry_t,
{"format", "Int32$format", "func(i:Int32, digits=0)->Text"},
{"hex", "Int32$hex", "func(i:Int32, digits=0, uppercase=yes, prefix=yes)->Text"},
{"octal", "Int32$octal", "func(i:Int32, digits=0, prefix=yes)->Text"},
@@ -141,7 +141,7 @@ env_t *new_compilation_unit(CORD *libname)
{"modulo", "Int32$modulo", "func(x:Int32,y:Int32)->Int32"},
{"modulo1", "Int32$modulo1", "func(x:Int32,y:Int32)->Int32"},
)},
- {"Int16", Type(IntType, .bits=16), "Int16_t", "$Int16", TypedArray(ns_entry_t,
+ {"Int16", Type(IntType, .bits=TYPE_IBITS16), "Int16_t", "$Int16", TypedArray(ns_entry_t,
{"format", "Int16$format", "func(i:Int16, digits=0)->Text"},
{"hex", "Int16$hex", "func(i:Int16, digits=0, uppercase=yes, prefix=yes)->Text"},
{"octal", "Int16$octal", "func(i:Int16, digits=0, prefix=yes)->Text"},
@@ -156,7 +156,7 @@ env_t *new_compilation_unit(CORD *libname)
{"modulo", "Int16$modulo", "func(x:Int16,y:Int16)->Int16"},
{"modulo1", "Int16$modulo1", "func(x:Int16,y:Int16)->Int16"},
)},
- {"Int8", Type(IntType, .bits=8), "Int8_t", "$Int8", TypedArray(ns_entry_t,
+ {"Int8", Type(IntType, .bits=TYPE_IBITS8), "Int8_t", "$Int8", TypedArray(ns_entry_t,
{"format", "Int8$format", "func(i:Int8, digits=0)->Text"},
{"hex", "Int8$hex", "func(i:Int8, digits=0, uppercase=yes, prefix=yes)->Text"},
{"octal", "Int8$octal", "func(i:Int8, digits=0, prefix=yes)->Text"},
@@ -174,7 +174,7 @@ env_t *new_compilation_unit(CORD *libname)
#define C(name) {#name, "M_"#name, "Num"}
#define F(name) {#name, #name, "func(n:Num)->Num"}
#define F2(name) {#name, #name, "func(x:Num, y:Num)->Num"}
- {"Num", Type(NumType, .bits=64), "Num_t", "$Num", TypedArray(ns_entry_t,
+ {"Num", Type(NumType, .bits=TYPE_NBITS64), "Num_t", "$Num", TypedArray(ns_entry_t,
{"near", "Num$near", "func(x:Num, y:Num, ratio=1e-9, min_epsilon=1e-9)->Bool"},
{"format", "Num$format", "func(n:Num, precision=0)->Text"},
{"scientific", "Num$scientific", "func(n:Num, precision=0)->Text"},
@@ -202,7 +202,7 @@ env_t *new_compilation_unit(CORD *libname)
#define C(name) {#name, "(Num32_t)(M_"#name")", "Num32"}
#define F(name) {#name, #name"f", "func(n:Num32)->Num32"}
#define F2(name) {#name, #name"f", "func(x:Num32, y:Num32)->Num32"}
- {"Num32", Type(NumType, .bits=32), "Num32_t", "$Num32", TypedArray(ns_entry_t,
+ {"Num32", Type(NumType, .bits=TYPE_NBITS32), "Num32_t", "$Num32", TypedArray(ns_entry_t,
{"near", "Num32$near", "func(x:Num32, y:Num32, ratio=1e-9f32, min_epsilon=1e-9f32)->Bool"},
{"format", "Num32$format", "func(n:Num32, precision=0)->Text"},
{"scientific", "Num32$scientific", "func(n:Num32, precision=0)->Text"},
diff --git a/parse.c b/parse.c
index 59e41ec6..f8f1a512 100644
--- a/parse.c
+++ b/parse.c
@@ -468,11 +468,11 @@ PARSER(parse_int) {
}
match(&pos, "_");
- int64_t bits = 0;
- if (match(&pos, "i64")) bits = 64;
- else if (match(&pos, "i32")) bits = 32;
- else if (match(&pos, "i16")) bits = 16;
- else if (match(&pos, "i8")) bits = 8;
+ auto bits = IBITS_UNSPECIFIED;
+ if (match(&pos, "i64")) bits = IBITS64;
+ else if (match(&pos, "i32")) bits = IBITS32;
+ else if (match(&pos, "i16")) bits = IBITS16;
+ else if (match(&pos, "i8")) bits = IBITS8;
// else if (match(&pos, ".") || match(&pos, "e")) return NULL; // looks like a float
@@ -624,14 +624,13 @@ PARSER(parse_num) {
if (negative) d *= -1;
- int64_t bits = 64;
+ auto bits = NBITS_UNSPECIFIED;
match(&pos, "_");
- if (match(&pos, "f64")) bits = 64;
- else if (match(&pos, "f32")) bits = 32;
+ if (match(&pos, "f64")) bits = NBITS64;
+ else if (match(&pos, "f32")) bits = NBITS32;
- if (match(&pos, "%")) {
+ if (match(&pos, "%"))
d /= 100.;
- }
return NewAST(ctx->file, start, pos, Num, .n=d, .bits=bits);
}
diff --git a/repl.c b/repl.c
index 289914e7..111aff1d 100644
--- a/repl.c
+++ b/repl.c
@@ -103,18 +103,19 @@ const TypeInfo *type_to_type_info(type_t *t)
case VoidType: return &$Void;
case MemoryType: return &$Memory;
case BoolType: return &$Bool;
+ case BigIntType: return &$Int;
case IntType:
switch (Match(t, IntType)->bits) {
- case 0: case 64: return &$Int;
- case 32: return &$Int32;
- case 16: return &$Int16;
- case 8: return &$Int8;
+ case TYPE_IBITS64: return &$Int64;
+ case TYPE_IBITS32: return &$Int32;
+ case TYPE_IBITS16: return &$Int16;
+ case TYPE_IBITS8: return &$Int8;
default: errx(1, "Invalid bits");
}
case NumType:
switch (Match(t, NumType)->bits) {
- case 0: case 64: return &$Num;
- case 32: return &$Num32;
+ case TYPE_NBITS64: return &$Num;
+ case TYPE_NBITS32: return &$Num32;
default: errx(1, "Invalid bits");
}
case TextType: return &$Text;
@@ -161,15 +162,19 @@ static Int_t ast_to_int(env_t *env, ast_t *ast)
{
type_t *t = get_type(env, ast);
switch (t->tag) {
+ case BigIntType: {
+ number_t num;
+ eval(env, ast, &num);
+ return num.integer;
+ }
case IntType: {
number_t num;
eval(env, ast, &num);
switch (Match(t, IntType)->bits) {
- case 0: return num.integer;
- case 64: return Int64_to_Int((int64_t)num.i64);
- case 32: return Int32_to_Int(num.i32);
- case 16: return Int16_to_Int(num.i16);
- case 8: return Int8_to_Int(num.i8);
+ case TYPE_IBITS64: return Int64_to_Int((int64_t)num.i64);
+ case TYPE_IBITS32: return Int32_to_Int(num.i32);
+ case TYPE_IBITS16: return Int16_to_Int(num.i16);
+ case TYPE_IBITS8: return Int8_to_Int(num.i8);
default: errx(1, "Invalid int bits");
}
}
@@ -181,22 +186,23 @@ static double ast_to_num(env_t *env, ast_t *ast)
{
type_t *t = get_type(env, ast);
switch (t->tag) {
- case IntType: {
+ case BigIntType: case IntType: {
number_t num;
eval(env, ast, &num);
+ if (t->tag == BigIntType)
+ return Int_to_Num(num.integer);
switch (Match(t, IntType)->bits) {
- case 0: return Int_to_Num(num.integer);
- case 64: return (double)num.i64;
- case 32: return (double)num.i32;
- case 16: return (double)num.i16;
- case 8: return (double)num.i8;
+ case TYPE_IBITS64: return (double)num.i64;
+ case TYPE_IBITS32: return (double)num.i32;
+ case TYPE_IBITS16: return (double)num.i16;
+ case TYPE_IBITS8: return (double)num.i8;
default: errx(1, "Invalid int bits");
}
}
case NumType: {
number_t num;
eval(env, ast, &num);
- return Match(t, NumType)->bits == 32 ? (double)num.n32 : (double)num.n64;
+ return Match(t, NumType)->bits == TYPE_NBITS32 ? (double)num.n32 : (double)num.n64;
}
default: repl_err(NULL, "Cannot convert to number");
}
@@ -388,13 +394,16 @@ void eval(env_t *env, ast_t *ast, void *dest)
}
case BinaryOp: {
auto binop = Match(ast, BinaryOp);
- if (t->tag == IntType) {
+ if (t->tag == IntType || t->tag == BigIntType) {
#define CASE_OP(OP_NAME, method_name) case BINOP_##OP_NAME: {\
Int_t lhs = ast_to_int(env, binop->lhs); \
Int_t rhs = ast_to_int(env, binop->rhs); \
Int_t result = Int$ ## method_name (lhs, rhs); \
+ if (t->tag == BigIntType) {\
+ *(Int_t*)dest = result; \
+ return; \
+ } \
switch (Match(t, IntType)->bits) { \
- case 0: *(Int_t*)dest = result; return; \
case 64: *(int64_t*)dest = Int_to_Int64(result, false); return; \
case 32: *(int32_t*)dest = Int_to_Int32(result, false); return; \
case 16: *(int16_t*)dest = Int_to_Int16(result, false); return; \
diff --git a/structs.c b/structs.c
index fb22eef6..8099012e 100644
--- a/structs.c
+++ b/structs.c
@@ -47,13 +47,10 @@ static CORD compile_compare_method(env_t *env, ast_t *ast)
for (arg_ast_t *field = def->fields; field; field = field->next) {
type_t *field_type = get_arg_ast_type(env, field);
switch (field_type->tag) {
- case IntType:
- if (Match(field_type, IntType)->bits == 0)
- cmp_func = CORD_all(cmp_func, "diff = Int$compare_value(x->$", field->name, ", y->$", field->name, ");");
- else
- cmp_func = CORD_all(cmp_func, "diff = (x->$", field->name, " > y->$", field->name, ") - (x->$", field->name, " < y->$", field->name, ");");
+ case BigIntType:
+ cmp_func = CORD_all(cmp_func, "diff = Int$compare_value(x->$", field->name, ", y->$", field->name, ");");
break;
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
cmp_func = CORD_all(cmp_func, "diff = (x->$", field->name, " > y->$", field->name, ") - (x->$", field->name, " < y->$", field->name, ");");
break;
case TextType:
@@ -83,13 +80,10 @@ static CORD compile_equals_method(env_t *env, ast_t *ast)
condition = CORD_all(condition, " && ");
type_t *field_type = get_arg_ast_type(env, field);
switch (field_type->tag) {
- case IntType:
- if (Match(field_type, IntType)->bits == 0)
- condition = CORD_all(condition, "Int$equal_value(x->$", field->name, ", y->$", field->name, ")");
- else
- condition = CORD_all(condition, "(x->$", field->name, " == y->$", field->name, ")");
+ case BigIntType:
+ condition = CORD_all(condition, "Int$equal_value(x->$", field->name, ", y->$", field->name, ")");
break;
- case BoolType: case NumType: case PointerType: case FunctionType:
+ case BoolType: case IntType: case NumType: case PointerType: case FunctionType:
condition = CORD_all(condition, "(x->$", field->name, " == y->$", field->name, ")");
break;
case TextType:
@@ -144,24 +138,15 @@ void compile_struct_def(env_t *env, ast_t *ast)
if (struct_->fields && !struct_->fields->next) { // Single member, can just use its methods
type_t *member_t = struct_->fields->type;
switch (member_t->tag) {
- case NumType:
+ case IntType: case NumType:
typeinfo = CORD_all(typeinfo, ".compare=(void*)", type_to_cord(member_t), "$compare, "
".equal=(void*)", type_to_cord(member_t), "$equal, ");
goto got_methods;
- case TextType:
+ case BigIntType: case TextType:
typeinfo = CORD_all(typeinfo, ".hash=(void*)", type_to_cord(member_t), "$hash", ", ",
".compare=(void*)", type_to_cord(member_t), "$compare, "
".equal=(void*)", type_to_cord(member_t), "$equal, ");
goto got_methods;
- case IntType:
- if (Match(member_t, IntType)->bits == 0)
- typeinfo = CORD_all(typeinfo, ".hash=(void*)Int$hash", ", ",
- ".compare=(void*)Int$compare, "
- ".equal=(void*)Int$equal, ");
- else
- typeinfo = CORD_all(typeinfo, ".compare=(void*)", type_to_cord(member_t), "$compare, "
- ".equal=(void*)", type_to_cord(member_t), "$equal, ");
- goto got_methods;
case BoolType: goto got_methods;
default: break;
}
diff --git a/typecheck.c b/typecheck.c
index 332f68e1..129a71da 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -116,15 +116,11 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast)
type_t *get_math_type(env_t *env, ast_t *ast, type_t *lhs_t, type_t *rhs_t)
{
(void)env;
- if (lhs_t->tag == IntType && rhs_t->tag == IntType)
- return Match(lhs_t, IntType)->bits >= Match(rhs_t, IntType)->bits ? lhs_t : rhs_t;
- else if (lhs_t->tag == NumType && rhs_t->tag == NumType)
- return Match(lhs_t, NumType)->bits >= Match(rhs_t, NumType)->bits ? lhs_t : rhs_t;
- else if (lhs_t->tag == NumType && rhs_t->tag == IntType)
- return lhs_t;
- else if (rhs_t->tag == NumType && lhs_t->tag == IntType)
- return rhs_t;
-
+ switch (compare_precision(lhs_t, rhs_t)) {
+ case NUM_PRECISION_EQUAL: case NUM_PRECISION_MORE: return lhs_t;
+ case NUM_PRECISION_LESS: return rhs_t;
+ default: return NULL;
+ }
code_err(ast, "Math operations between %T and %T are not supported", lhs_t, rhs_t);
}
@@ -456,11 +452,24 @@ type_t *get_type(env_t *env, ast_t *ast)
}
case Int: {
auto i = Match(ast, Int);
- return Type(IntType, .bits=i->bits);
+ switch (i->bits) {
+ case IBITS_UNSPECIFIED: return Type(BigIntType);
+ case IBITS8: return Type(IntType, .bits=TYPE_IBITS8);
+ case IBITS16: return Type(IntType, .bits=TYPE_IBITS16);
+ case IBITS32: return Type(IntType, .bits=TYPE_IBITS32);
+ case IBITS64: return Type(IntType, .bits=TYPE_IBITS64);
+ default: errx(1, "Invalid integer bits");
+ }
}
case Num: {
auto n = Match(ast, Num);
- return Type(NumType, .bits=n->bits);
+ switch (n->bits) {
+ case NBITS_UNSPECIFIED: case NBITS64:
+ return Type(NumType, .bits=TYPE_NBITS64);
+ case NBITS32:
+ return Type(NumType, .bits=TYPE_NBITS32);
+ default: errx(1, "Invalid num bits");
+ }
}
case HeapAllocate: {
type_t *pointed = get_type(env, Match(ast, HeapAllocate)->value);
@@ -987,12 +996,12 @@ type_t *get_type(env_t *env, ast_t *ast)
return Type(BoolType);
}
case BINOP_CMP:
- return Type(IntType, .bits=32);
+ return Type(IntType, .bits=TYPE_IBITS32);
case BINOP_POWER: {
type_t *result = get_math_type(env, ast, lhs_t, rhs_t);
if (result->tag == NumType)
return result;
- return Type(NumType, .bits=64);
+ return Type(NumType, .bits=TYPE_NBITS64);
}
default: {
return get_math_type(env, ast, lhs_t, rhs_t);
@@ -1351,7 +1360,7 @@ bool is_constant(env_t *env, ast_t *ast)
case Bool: case Num: case Nil: case TextLiteral: return true;
case Int: {
auto info = Match(ast, Int);
- if (info->bits == 0) {
+ if (info->bits == IBITS_UNSPECIFIED) {
Int_t int_val = Int$from_text(info->str);
mpz_t i;
mpz_init_set_int(i, int_val);
diff --git a/types.c b/types.c
index 8e234948..d71da0e3 100644
--- a/types.c
+++ b/types.c
@@ -19,8 +19,9 @@ CORD type_to_cord(type_t *t) {
case BoolType: return "Bool";
case CStringType: return "CString";
case TextType: return Match(t, TextType)->lang ? Match(t, TextType)->lang : "Text";
- case IntType: return Match(t, IntType)->bits == 0 ? "Int" : CORD_asprintf("Int%ld", Match(t, IntType)->bits);
- case NumType: return Match(t, NumType)->bits == 64 ? "Num" : CORD_asprintf("Num%ld", Match(t, NumType)->bits);
+ case BigIntType: return "Int";
+ case IntType: return CORD_asprintf("Int%d", Match(t, IntType)->bits);
+ case NumType: return Match(t, NumType)->bits == TYPE_NBITS32 ? "Num32" : "Num";
case ArrayType: {
auto array = Match(t, ArrayType);
return CORD_asprintf("[%r]", type_to_cord(array->item_type));
@@ -154,14 +155,14 @@ static inline double type_min_magnitude(type_t *t)
{
switch (t->tag) {
case BoolType: return (double)false;
+ case BigIntType: return -1./0.;
case IntType: {
switch (Match(t, IntType)->bits) {
- case 0: return -1./0.;
- case 8: return (double)INT8_MIN;
- case 16: return (double)INT16_MIN;
- case 32: return (double)INT32_MIN;
- case 64: return (double)INT64_MIN;
- default: return NAN;
+ case TYPE_IBITS8: return (double)INT8_MIN;
+ case TYPE_IBITS16: return (double)INT16_MIN;
+ case TYPE_IBITS32: return (double)INT32_MIN;
+ case TYPE_IBITS64: return (double)INT64_MIN;
+ default: errx(1, "Invalid integer bit size");
}
}
case NumType: return -1./0.;
@@ -173,14 +174,14 @@ static inline double type_max_magnitude(type_t *t)
{
switch (t->tag) {
case BoolType: return (double)true;
+ case BigIntType: return 1./0.;
case IntType: {
switch (Match(t, IntType)->bits) {
- case 0: return 1./0.;
- case 8: return (double)INT8_MAX;
- case 16: return (double)INT16_MAX;
- case 32: return (double)INT32_MAX;
- case 64: return (double)INT64_MAX;
- default: return NAN;
+ case TYPE_IBITS8: return (double)INT8_MAX;
+ case TYPE_IBITS16: return (double)INT16_MAX;
+ case TYPE_IBITS32: return (double)INT32_MAX;
+ case TYPE_IBITS64: return (double)INT64_MAX;
+ default: errx(1, "Invalid integer bit size");
}
}
case NumType: return 1./0.;
@@ -211,7 +212,7 @@ bool has_heap_memory(type_t *t)
case TableType: return true;
case SetType: return true;
case PointerType: return true;
- case IntType: return (Match(t, IntType)->bits == 0);
+ case BigIntType: return true;
case StructType: {
for (arg_t *field = Match(t, StructType)->fields; field; field = field->next) {
if (has_heap_memory(field->type))
@@ -452,17 +453,17 @@ size_t type_size(type_t *t)
case MemoryType: errx(1, "Memory has undefined type size");
case BoolType: return sizeof(bool);
case CStringType: return sizeof(char*);
+ case BigIntType: return sizeof(Int_t);
case IntType: {
switch (Match(t, IntType)->bits) {
- case 0: return sizeof(Int_t);
- case 64: return sizeof(int64_t);
- case 32: return sizeof(int32_t);
- case 16: return sizeof(int16_t);
- case 8: return sizeof(int8_t);
- default: return 0;
+ case TYPE_IBITS64: return sizeof(int64_t);
+ case TYPE_IBITS32: return sizeof(int32_t);
+ case TYPE_IBITS16: return sizeof(int16_t);
+ case TYPE_IBITS8: return sizeof(int8_t);
+ default: errx(1, "Invalid integer bit size");
}
}
- case NumType: return Match(t, NumType)->bits/8;
+ case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? sizeof(double) : sizeof(float);
case TextType: return sizeof(CORD);
case ArrayType: return sizeof(array_t);
case SetType: return sizeof(table_t);
@@ -515,17 +516,17 @@ size_t type_align(type_t *t)
case MemoryType: errx(1, "Memory has undefined type alignment");
case BoolType: return __alignof__(bool);
case CStringType: return __alignof__(char*);
+ case BigIntType: return __alignof__(Int_t);
case IntType: {
switch (Match(t, IntType)->bits) {
- case 0: return __alignof__(Int_t);
- case 64: return __alignof__(int64_t);
- case 32: return __alignof__(int32_t);
- case 16: return __alignof__(int16_t);
- case 8: return __alignof__(int8_t);
+ case TYPE_IBITS64: return __alignof__(int64_t);
+ case TYPE_IBITS32: return __alignof__(int32_t);
+ case TYPE_IBITS16: return __alignof__(int16_t);
+ case TYPE_IBITS8: return __alignof__(int8_t);
default: return 0;
}
}
- case NumType: return Match(t, NumType)->bits/8;
+ case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? __alignof__(double) : __alignof__(float);
case TextType: return __alignof__(CORD);
case SetType: return __alignof__(table_t);
case ArrayType: return __alignof__(array_t);
diff --git a/types.h b/types.h
index 0791dade..8c3abb75 100644
--- a/types.h
+++ b/types.h
@@ -43,6 +43,7 @@ struct type_s {
VoidType,
MemoryType,
BoolType,
+ BigIntType,
IntType,
NumType,
CStringType,
@@ -66,11 +67,12 @@ struct type_s {
struct {
type_t *ret;
} ReturnType;
+ struct {} BigIntType;
struct {
- int64_t bits;
+ enum { TYPE_IBITS8=8, TYPE_IBITS16=16, TYPE_IBITS32=32, TYPE_IBITS64=64 } bits;
} IntType;
struct {
- int64_t bits;
+ enum { TYPE_NBITS32=32, TYPE_NBITS64=64 } bits;
} NumType;
struct {} CStringType;
struct {
@@ -121,8 +123,8 @@ struct type_s {
};
#define Type(typetag, ...) new(type_t, .tag=typetag, .__data.typetag={__VA_ARGS__})
-#define INT_TYPE Type(IntType, .bits=0)
-#define NUM_TYPE Type(NumType, .bits=64)
+#define INT_TYPE Type(BigIntType)
+#define NUM_TYPE Type(NumType, .bits=TYPE_NBITS64)
int printf_pointer_size(const struct printf_info *info, size_t n, int argtypes[n], int size[n]);
int printf_type(FILE *stream, const struct printf_info *info, const void *const args[]);