diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-04-15 19:36:23 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-04-15 19:36:23 -0400 |
| commit | c3615dc92c667899af7a11b2b25201dad5502ee6 (patch) | |
| tree | bdc5db2b7c1cda415ef58eabd6c6dd23237d0ad6 /src | |
| parent | 9c1a7c473d96b80561a845bf15ecfd42cd980135 (diff) | |
Deprecate `auto`
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.c | 20 | ||||
| -rw-r--r-- | src/ast.h | 3 | ||||
| -rw-r--r-- | src/compile.c | 214 | ||||
| -rw-r--r-- | src/enums.c | 6 | ||||
| -rw-r--r-- | src/environment.c | 20 | ||||
| -rw-r--r-- | src/parse.c | 4 | ||||
| -rw-r--r-- | src/repl.c | 28 | ||||
| -rw-r--r-- | src/stdlib/lists.c | 4 | ||||
| -rw-r--r-- | src/stdlib/pointers.c | 2 | ||||
| -rw-r--r-- | src/stdlib/tables.c | 6 | ||||
| -rw-r--r-- | src/stdlib/types.h | 22 | ||||
| -rw-r--r-- | src/stdlib/util.h | 4 | ||||
| -rw-r--r-- | src/structs.c | 2 | ||||
| -rw-r--r-- | src/tomo.c | 12 | ||||
| -rw-r--r-- | src/typecheck.c | 112 | ||||
| -rw-r--r-- | src/types.c | 52 |
16 files changed, 258 insertions, 253 deletions
@@ -123,7 +123,7 @@ CORD ast_to_xml(ast_t *ast) if (!ast) return CORD_EMPTY; switch (ast->tag) { -#define T(type, ...) case type: { auto data = ast->__data.type; (void)data; return CORD_asprintf(__VA_ARGS__); } +#define T(type, ...) case type: { __typeof(ast->__data.type) data = ast->__data.type; (void)data; return CORD_asprintf(__VA_ARGS__); } T(Unknown, "<Unknown>") T(None, "<None/>") T(Bool, "<Bool value=\"%s\" />", data.b ? "yes" : "no") @@ -219,7 +219,7 @@ CORD type_ast_to_xml(type_ast_t *t) if (!t) return "NULL"; switch (t->tag) { -#define T(type, ...) case type: { auto data = t->__data.type; (void)data; return CORD_asprintf(__VA_ARGS__); } +#define T(type, ...) case type: { __typeof(t->__data.type) data = t->__data.type; (void)data; return CORD_asprintf(__VA_ARGS__); } T(UnknownTypeAST, "<UnknownType/>") T(VarTypeAST, "%s", data.name) T(PointerTypeAST, "<PointerType is_stack=\"%s\">%r</PointerType>", @@ -239,11 +239,11 @@ PUREFUNC bool is_idempotent(ast_t *ast) switch (ast->tag) { case Int: case Bool: case Num: case Var: case None: case TextLiteral: return true; case Index: { - auto index = Match(ast, Index); + DeclareMatch(index, ast, Index); return is_idempotent(index->indexed) && index->index != NULL && is_idempotent(index->index); } case FieldAccess: { - auto access = Match(ast, FieldAccess); + DeclareMatch(access, ast, FieldAccess); return is_idempotent(access->fielded); } default: return false; @@ -254,7 +254,7 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo { void (*visit)(void*, ast_t*) = (void*)fn.fn; if (ast->tag == StructDef) { - auto def = Match(ast, StructDef); + DeclareMatch(def, ast, StructDef); if (Table$str_get(*visited, def->name)) return; @@ -271,7 +271,7 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo } visit(fn.userdata, ast); } else if (ast->tag == EnumDef) { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); if (Table$str_get(*visited, def->name)) return; @@ -289,7 +289,7 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo } visit(fn.userdata, ast); } else if (ast->tag == LangDef) { - auto def = Match(ast, LangDef); + DeclareMatch(def, ast, LangDef); if (Table$str_get(*visited, def->name)) return; visit(fn.userdata, ast); @@ -309,13 +309,13 @@ void visit_topologically(ast_list_t *asts, Closure_t fn) Table_t definitions = {}; for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { if (stmt->ast->tag == StructDef) { - auto def = Match(stmt->ast, StructDef); + DeclareMatch(def, stmt->ast, StructDef); Table$str_set(&definitions, def->name, stmt->ast); } else if (stmt->ast->tag == EnumDef) { - auto def = Match(stmt->ast, EnumDef); + DeclareMatch(def, stmt->ast, EnumDef); Table$str_set(&definitions, def->name, stmt->ast); } else if (stmt->ast->tag == LangDef) { - auto def = Match(stmt->ast, LangDef); + DeclareMatch(def, stmt->ast, LangDef); Table$str_set(&definitions, def->name, stmt->ast); } } @@ -21,12 +21,13 @@ #define TextAST(ast, _str) WrapAST(ast, TextLiteral, .str=GC_strdup(_str)) #define LiteralCode(code, ...) new(ast_t, .tag=InlineCCode, .__data.InlineCCode={.chunks=new(ast_list_t, .ast=FakeAST(TextLiteral, code)), __VA_ARGS__}) #define Match(x, _tag) ((x)->tag == _tag ? &(x)->__data._tag : (errx(1, __FILE__ ":%d This was supposed to be a " # _tag "\n", __LINE__), &(x)->__data._tag)) +#define DeclareMatch(var, x, _tag) __typeof((x)->__data._tag) *var = Match(x, _tag) #define BINARY_OPERANDS(ast) ({ if (!is_binary_operation(ast)) errx(1, __FILE__ ":%d This is not a binary operation!", __LINE__); (ast)->__data.Plus; }) #define REVERSE_LIST(list) do { \ __typeof(list) _prev = NULL; \ __typeof(list) _next = NULL; \ - auto _current = list; \ + __typeof(list) _current = list; \ while (_current != NULL) { \ _next = _current->next; \ _current->next = _prev; \ diff --git a/src/compile.c b/src/compile.c index 766da09d..2c644747 100644 --- a/src/compile.c +++ b/src/compile.c @@ -126,7 +126,7 @@ static bool promote(env_t *env, ast_t *ast, CORD *code, type_t *actual, type_t * arg_ast_t *args = new(arg_ast_t, .value=LiteralCode(*code, .type=actual)); binding_t *constructor = get_constructor(env, needed, args); if (constructor) { - auto fn = Match(constructor->type, FunctionType); + DeclareMatch(fn, constructor->type, FunctionType); if (fn->args->next == NULL) { *code = CORD_all(constructor->code, "(", compile_arguments(env, ast, fn->args, args), ")"); return true; @@ -276,7 +276,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t break; } case Comprehension: { - auto comp = Match(ast, Comprehension); + DeclareMatch(comp, ast, Comprehension); if (comp->expr->tag == Comprehension) { // Nested comprehension ast_t *body = comp->filter ? WrapAST(ast, If, .condition=comp->filter, .body=comp->expr) : comp->expr; ast_t *loop = WrapAST(ast, For, .vars=comp->vars, .iter=comp->iter, .body=body); @@ -292,7 +292,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t break; } case Lambda: { - auto lambda = Match(ast, Lambda); + DeclareMatch(lambda, ast, Lambda); env_t *lambda_scope = fresh_scope(env); for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) set_binding(lambda_scope, arg->name, get_arg_ast_type(env, arg), CORD_all("_$", arg->name)); @@ -325,14 +325,14 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t break; } case While: { - auto while_ = Match(ast, While); + DeclareMatch(while_, ast, While); add_closed_vars(closed_vars, enclosing_scope, env, while_->condition); env_t *scope = fresh_scope(env); add_closed_vars(closed_vars, enclosing_scope, scope, while_->body); break; } case If: { - auto if_ = Match(ast, If); + DeclareMatch(if_, ast, If); ast_t *condition = if_->condition; if (condition->tag == Declare) { env_t *truthy_scope = fresh_scope(env); @@ -363,7 +363,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t break; } case When: { - auto when = Match(ast, When); + DeclareMatch(when, ast, When); add_closed_vars(closed_vars, enclosing_scope, env, when->subject); type_t *subject_t = get_type(env, when->subject); @@ -378,7 +378,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t return; } - auto enum_t = Match(subject_t, EnumType); + DeclareMatch(enum_t, subject_t, EnumType); for (when_clause_t *clause = when->clauses; clause; clause = clause->next) { const char *clause_tag_name; if (clause->pattern->tag == Var) @@ -408,7 +408,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t break; } case Reduction: { - auto reduction = Match(ast, Reduction); + DeclareMatch(reduction, ast, Reduction); static int64_t next_id = 1; ast_t *item = FakeAST(Var, String("$it", next_id++)); ast_t *loop = FakeAST(For, .vars=new(ast_list_t, .ast=item), .iter=reduction->iter, .body=FakeAST(Pass)); @@ -478,7 +478,7 @@ static Table_t get_closed_vars(env_t *env, arg_ast_t *args, ast_t *block) CORD compile_declaration(type_t *t, CORD name) { if (t->tag == FunctionType) { - auto fn = Match(t, FunctionType); + DeclareMatch(fn, t, FunctionType); CORD code = CORD_all(compile_type(fn->ret), " (*", name, ")("); for (arg_t *arg = fn->args; arg; arg = arg->next) { code = CORD_all(code, compile_type(arg->type)); @@ -576,14 +576,14 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) binding_t *b = get_metamethod_binding(env, ast->tag, binop.lhs, binop.rhs, overall_t); if (b) { arg_ast_t *args = new(arg_ast_t, .value=binop.lhs, .next=new(arg_ast_t, .value=binop.rhs)); - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); return CORD_all(b->code, "(", compile_arguments(env, ast, fn->args, args), ")"); } if (ast->tag == Multiply && is_numeric_type(lhs_t)) { b = get_namespace_binding(env, binop.rhs, "scaled_by"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, rhs_t)) { arg_ast_t *args = new(arg_ast_t, .value=binop.rhs, .next=new(arg_ast_t, .value=binop.lhs)); if (is_valid_call(env, fn->args, args, true)) @@ -593,7 +593,7 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) } else if (ast->tag == Multiply && is_numeric_type(rhs_t)) { b = get_namespace_binding(env, binop.lhs, "scaled_by"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, lhs_t)) { arg_ast_t *args = new(arg_ast_t, .value=binop.lhs, .next=new(arg_ast_t, .value=binop.rhs)); if (is_valid_call(env, fn->args, args, true)) @@ -603,7 +603,7 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) } else if (ast->tag == Divide && is_numeric_type(rhs_t)) { b = get_namespace_binding(env, binop.lhs, "divided_by"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, lhs_t)) { arg_ast_t *args = new(arg_ast_t, .value=binop.lhs, .next=new(arg_ast_t, .value=binop.rhs)); if (is_valid_call(env, fn->args, args, true)) @@ -613,7 +613,7 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) } else if ((ast->tag == Divide || ast->tag == Mod || ast->tag == Mod1) && is_numeric_type(rhs_t)) { b = get_namespace_binding(env, binop.lhs, binop_method_name(ast->tag)); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, lhs_t)) { arg_ast_t *args = new(arg_ast_t, .value=binop.lhs, .next=new(arg_ast_t, .value=binop.rhs)); if (is_valid_call(env, fn->args, args, true)) @@ -787,7 +787,7 @@ CORD compile_type(type_t *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); + DeclareMatch(text, t, TextType); if (!text->lang || streq(text->lang, "Text")) return "Text_t"; else @@ -797,7 +797,7 @@ CORD compile_type(type_t *t) case SetType: return "Table_t"; case TableType: return "Table_t"; case FunctionType: { - auto fn = Match(t, FunctionType); + DeclareMatch(fn, t, FunctionType); CORD code = CORD_all(compile_type(fn->ret), " (*)("); for (arg_t *arg = fn->args; arg; arg = arg->next) { code = CORD_all(code, compile_type(arg->type)); @@ -810,12 +810,12 @@ CORD compile_type(type_t *t) case ClosureType: return "Closure_t"; case PointerType: return CORD_cat(compile_type(Match(t, PointerType)->pointed), "*"); case StructType: { - auto s = Match(t, StructType); + DeclareMatch(s, t, StructType); if (s->external) return s->name; return CORD_all("struct ", namespace_prefix(s->env, s->env->namespace->parent), s->name, "$$struct"); } case EnumType: { - auto e = Match(t, EnumType); + DeclareMatch(e, t, EnumType); return CORD_all(namespace_prefix(e->env, e->env->namespace->parent), e->name, "$$type"); } case OptionalType: { @@ -834,7 +834,7 @@ CORD compile_type(type_t *t) return "OptionalPath_t"; if (nonnull == PATH_TYPE_TYPE) return "OptionalPathType_t"; - auto s = Match(nonnull, StructType); + DeclareMatch(s, nonnull, StructType); return CORD_all(namespace_prefix(s->env, s->env->namespace->parent), "$Optional", s->name, "$$type"); } default: @@ -862,7 +862,7 @@ CORD compile_lvalue(env_t *env, ast_t *ast) } if (ast->tag == Index) { - auto index = Match(ast, Index); + DeclareMatch(index, ast, Index); type_t *container_t = get_type(env, index->indexed); if (container_t->tag == OptionalType) code_err(index->indexed, "This value might be null, so it can't be safely used as an assignment target"); @@ -889,7 +889,7 @@ CORD compile_lvalue(env_t *env, ast_t *ast) ", ", String((int)(ast->end - ast->file->text)), ")"); } } else if (container_t->tag == TableType) { - auto table_type = Match(container_t, TableType); + DeclareMatch(table_type, container_t, TableType); if (table_type->default_value) { type_t *value_type = get_type(env, table_type->default_value); return CORD_all("*Table$get_or_setdefault(", @@ -1017,7 +1017,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) type_t *result_t = get_type(env, ast); (void)result_t; - auto when = Match(ast, When); + DeclareMatch(when, ast, When); type_t *subject_t = get_type(env, when->subject); if (subject_t->tag != EnumType) { @@ -1043,7 +1043,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) return code; } - auto enum_t = Match(subject_t, EnumType); + DeclareMatch(enum_t, subject_t, EnumType); CORD code = CORD_all("WHEN(", compile_type(subject_t), ", ", compile(env, when->subject), ", _when_subject, {\n"); for (when_clause_t *clause = when->clauses; clause; clause = clause->next) { if (clause->pattern->tag == Var) { @@ -1070,7 +1070,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) assert(tag_type); env_t *scope = env; - auto tag_struct = Match(tag_type, StructType); + DeclareMatch(tag_struct, tag_type, StructType); arg_ast_t *args = Match(clause->pattern, FunctionCall)->args; if (args && !args->next && tag_struct->fields && tag_struct->fields->next) { if (args->value->tag != Var) @@ -1127,7 +1127,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) return code; } case DocTest: { - auto test = Match(ast, DocTest); + DeclareMatch(test, ast, DocTest); type_t *expr_t = get_type(env, test->expr); if (!expr_t) code_err(test->expr, "I couldn't figure out the type of this expression"); @@ -1135,7 +1135,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) CORD setup = CORD_EMPTY; CORD test_code; if (test->expr->tag == Declare) { - auto decl = Match(test->expr, Declare); + DeclareMatch(decl, test->expr, Declare); type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); if (t->tag == FunctionType) t = Type(ClosureType, t); CORD var = CORD_all("_$", Match(decl->var, Var)->name); @@ -1144,7 +1144,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) test_code = CORD_all("(", var, " = ", val_code, ")"); expr_t = t; } else if (test->expr->tag == Assign) { - auto assign = Match(test->expr, Assign); + DeclareMatch(assign, test->expr, Assign); if (!assign->targets->next && assign->targets->ast->tag == Var && is_idempotent(assign->targets->ast)) { // Common case: assigning to one variable: type_t *lhs_t = get_type(env, assign->targets->ast); @@ -1230,7 +1230,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) } } case Declare: { - auto decl = Match(ast, Declare); + DeclareMatch(decl, ast, Declare); const char *name = Match(decl->var, Var)->name; if (streq(name, "_")) { // Explicit discard if (decl->value) @@ -1248,7 +1248,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) } } case Assign: { - auto assign = Match(ast, Assign); + DeclareMatch(assign, ast, Assign); // Single assignment, no temp vars needed: if (assign->targets && !assign->targets->next) { type_t *lhs_t = get_type(env, assign->targets->ast); @@ -1282,35 +1282,35 @@ static CORD _compile_statement(env_t *env, ast_t *ast) return CORD_cat(code, "\n}"); } case PlusUpdate: { - auto update = Match(ast, PlusUpdate); + DeclareMatch(update, ast, PlusUpdate); type_t *lhs_t = get_type(env, update->lhs); if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) return CORD_all(compile_lvalue(env, update->lhs), " += ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } case MinusUpdate: { - auto update = Match(ast, MinusUpdate); + DeclareMatch(update, ast, MinusUpdate); type_t *lhs_t = get_type(env, update->lhs); if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) return CORD_all(compile_lvalue(env, update->lhs), " -= ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } case MultiplyUpdate: { - auto update = Match(ast, MultiplyUpdate); + DeclareMatch(update, ast, MultiplyUpdate); type_t *lhs_t = get_type(env, update->lhs); if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) return CORD_all(compile_lvalue(env, update->lhs), " *= ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } case DivideUpdate: { - auto update = Match(ast, DivideUpdate); + DeclareMatch(update, ast, DivideUpdate); type_t *lhs_t = get_type(env, update->lhs); if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) return CORD_all(compile_lvalue(env, update->lhs), " /= ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } case ModUpdate: { - auto update = Match(ast, ModUpdate); + DeclareMatch(update, ast, ModUpdate); type_t *lhs_t = get_type(env, update->lhs); if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) return CORD_all(compile_lvalue(env, update->lhs), " %= ", compile_to_type(env, update->rhs, lhs_t), ";"); @@ -1407,7 +1407,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) } case Return: { if (!env->fn_ret) code_err(ast, "This return statement is not inside any function"); - auto ret = Match(ast, Return)->value; + ast_t *ret = Match(ast, Return)->value; CORD code = CORD_EMPTY; for (deferral_t *deferred = env->deferred; deferred; deferred = deferred->next) { @@ -1433,7 +1433,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) } } case While: { - auto while_ = Match(ast, While); + DeclareMatch(while_, ast, While); env_t *scope = fresh_scope(env); loop_ctx_t loop_ctx = (loop_ctx_t){ .loop_name="while", @@ -1467,14 +1467,14 @@ static CORD _compile_statement(env_t *env, ast_t *ast) return loop; } case For: { - auto for_ = Match(ast, For); + DeclareMatch(for_, ast, For); // If we're iterating over a comprehension, that's actually just doing // one loop, we don't need to compile the comprehension as a list // comprehension. This is a common case for reducers like `(+: i*2 for i in 5)` // or `(and) x.is_good() for x in xs` if (for_->iter->tag == Comprehension) { - auto comp = Match(for_->iter, Comprehension); + DeclareMatch(comp, for_->iter, Comprehension); ast_t *body = for_->body; if (for_->vars) { if (for_->vars->next) @@ -1759,7 +1759,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) next_fn = "next"; } - auto fn = iter_value_t->tag == ClosureType ? Match(Match(iter_value_t, ClosureType)->fn, FunctionType) : Match(iter_value_t, FunctionType); + __typeof(iter_value_t->__data.FunctionType) *fn = iter_value_t->tag == ClosureType ? Match(Match(iter_value_t, ClosureType)->fn, FunctionType) : Match(iter_value_t, FunctionType); CORD get_next; if (iter_value_t->tag == ClosureType) { @@ -1811,7 +1811,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) } } case If: { - auto if_ = Match(ast, If); + DeclareMatch(if_, ast, If); ast_t *condition = if_->condition; if (condition->tag == Declare) { if (Match(condition, Declare)->value == NULL) @@ -1853,7 +1853,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) case Comprehension: { if (!env->comprehension_action) code_err(ast, "I don't know what to do with this comprehension!"); - auto comp = Match(ast, Comprehension); + DeclareMatch(comp, ast, Comprehension); if (comp->expr->tag == Comprehension) { // Nested comprehension ast_t *body = comp->filter ? WrapAST(ast, If, .condition=comp->filter, .body=comp->expr) : comp->expr; ast_t *loop = WrapAST(ast, For, .vars=comp->vars, .iter=comp->iter, .body=body); @@ -1870,7 +1870,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) } case Extern: return CORD_EMPTY; case InlineCCode: { - auto inline_code = Match(ast, InlineCCode); + DeclareMatch(inline_code, ast, InlineCCode); CORD code = CORD_EMPTY; for (ast_list_t *chunk = inline_code->chunks; chunk; chunk = chunk->next) { if (chunk->ast->tag == TextLiteral) { @@ -1882,7 +1882,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) return code; } case Use: { - auto use = Match(ast, Use); + DeclareMatch(use, ast, Use); if (use->what == USE_LOCAL) { CORD name = file_base_id(Match(ast, Use)->path); return with_source_info(env, ast, CORD_all("_$", name, "$$initialize();\n")); @@ -1978,7 +1978,7 @@ CORD compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bool t = Type(PointerType, .pointed=t, .is_stack=true); ++depth; } else { - auto ptr = Match(t, PointerType); + DeclareMatch(ptr, t, PointerType); val = CORD_all("*(", val, ")"); t = ptr->pointed; --depth; @@ -1986,7 +1986,7 @@ CORD compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bool } while (t->tag == PointerType) { - auto ptr = Match(t, PointerType); + DeclareMatch(ptr, t, PointerType); t = ptr->pointed; } @@ -2037,7 +2037,7 @@ CORD compile_to_type(env_t *env, ast_t *ast, type_t *t) // Here, we know that `[none]` is `[Int?]`, but we need to thread that // information through the compiler using an `ExplicitlyTyped` node. if (ast->tag == MethodCall) { - auto methodcall = Match(ast, MethodCall); + DeclareMatch(methodcall, ast, MethodCall); type_t *self_type = get_type(env, methodcall->self); // Currently, this is only implemented for cases where you have the return type // and the self type equal to each other, because that's the main case I care @@ -2065,7 +2065,7 @@ CORD compile_to_type(env_t *env, ast_t *ast, type_t *t) CORD compile_typed_list(env_t *env, ast_t *ast, type_t *list_type) { - auto list = Match(ast, List); + DeclareMatch(list, ast, List); if (!list->items) return "(List_t){.length=0}"; @@ -2113,7 +2113,7 @@ CORD compile_typed_list(env_t *env, ast_t *ast, type_t *list_type) CORD compile_typed_set(env_t *env, ast_t *ast, type_t *set_type) { - auto set = Match(ast, Set); + DeclareMatch(set, ast, Set); if (!set->items) return "((Table_t){})"; @@ -2161,7 +2161,7 @@ CORD compile_typed_set(env_t *env, ast_t *ast, type_t *set_type) CORD compile_typed_table(env_t *env, ast_t *ast, type_t *table_type) { - auto table = Match(ast, Table); + DeclareMatch(table, ast, Table); if (!table->entries) { CORD code = "((Table_t){"; if (table->fallback) @@ -2199,7 +2199,7 @@ CORD compile_typed_table(env_t *env, ast_t *ast, type_t *table_type) CORD_appendf(&code, ", %zu", n); for (ast_list_t *entry = table->entries; entry; entry = entry->next) { - auto e = Match(entry->ast, TableEntry); + DeclareMatch(e, entry->ast, TableEntry); code = CORD_all(code, ",\n\t{", compile_to_type(key_scope, e->key, key_t), ", ", compile_to_type(value_scope, e->value, value_t), "}"); } @@ -2536,7 +2536,7 @@ CORD compile_empty(type_t *t) case TextType: return "Text(\"\")"; case CStringType: return "\"\""; case PointerType: { - auto ptr = Match(t, PointerType); + DeclareMatch(ptr, t, PointerType); CORD empty_pointed = compile_empty(ptr->pointed); return empty_pointed == CORD_EMPTY ? CORD_EMPTY : CORD_all(ptr->is_stack ? "stack(" : "heap(", empty_pointed, ")"); } @@ -2544,7 +2544,7 @@ CORD compile_empty(type_t *t) return Match(t, NumType)->bits == TYPE_NBITS32 ? "N32(0.0f)" : "N64(0.0)" ; } case StructType: { - auto struct_ = Match(t, StructType); + DeclareMatch(struct_, t, StructType); CORD code = CORD_all("((", compile_type(t), "){"); for (arg_t *field = struct_->fields; field; field = field->next) { CORD empty_field = field->default_val @@ -2560,7 +2560,7 @@ CORD compile_empty(type_t *t) return CORD_all(code, "})"); } case EnumType: { - auto enum_ = Match(t, EnumType); + DeclareMatch(enum_, t, EnumType); tag_t *tag = enum_->tags; assert(tag); assert(tag->type); @@ -2575,7 +2575,7 @@ CORD compile_empty(type_t *t) static CORD compile_declared_value(env_t *env, ast_t *declare_ast) { - auto decl = Match(declare_ast, Declare); + DeclareMatch(decl, declare_ast, Declare); type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); if (t->tag == AbortType || t->tag == VoidType || t->tag == ReturnType) @@ -2598,7 +2598,7 @@ static CORD compile_declared_value(env_t *env, ast_t *declare_ast) ast_t *add_to_table_comprehension(ast_t *entry, ast_t *subject) { - auto e = Match(entry, TableEntry); + DeclareMatch(e, entry, TableEntry); return WrapAST(entry, MethodCall, .name="set", .self=subject, .args=new(arg_ast_t, .value=e->key, .next=new(arg_ast_t, .value=e->value))); } @@ -2651,7 +2651,7 @@ CORD compile(env_t *env, ast_t *ast) binding_t *b = get_namespace_binding(env, value, "negated"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (fn->args && can_promote(t, get_arg_type(env, fn->args))) return CORD_all(b->code, "(", compile_arguments(env, ast, fn->args, new(arg_ast_t, .value=value)), ")"); } @@ -2676,7 +2676,7 @@ CORD compile(env_t *env, ast_t *ast) type_t *t = get_type(env, value); binding_t *b = get_namespace_binding(env, value, "negative"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (fn->args && can_promote(t, get_arg_type(env, fn->args))) return CORD_all(b->code, "(", compile_arguments(env, ast, fn->args, new(arg_ast_t, .value=value)), ")"); } @@ -2912,7 +2912,7 @@ CORD compile(env_t *env, ast_t *ast) "})"); } case List: { - auto list = Match(ast, List); + DeclareMatch(list, ast, List); if (!list->items) return "(List_t){.length=0}"; @@ -2920,7 +2920,7 @@ CORD compile(env_t *env, ast_t *ast) return compile_typed_list(env, ast, list_type); } case Table: { - auto table = Match(ast, Table); + DeclareMatch(table, ast, Table); if (!table->entries) { CORD code = "((Table_t){"; if (table->fallback) @@ -2932,7 +2932,7 @@ CORD compile(env_t *env, ast_t *ast) return compile_typed_table(env, ast, table_type); } case Set: { - auto set = Match(ast, Set); + DeclareMatch(set, ast, Set); if (!set->items) return "((Table_t){})"; @@ -2949,7 +2949,7 @@ CORD compile(env_t *env, ast_t *ast) return compile(env, WrapAST(ast, List, .items=new(ast_list_t, .ast=ast))); } case Lambda: { - auto lambda = Match(ast, Lambda); + DeclareMatch(lambda, ast, Lambda); CORD name = CORD_asprintf("%rlambda$%ld", namespace_prefix(env, env->namespace), lambda->id); env->code->function_naming = CORD_all( @@ -3042,7 +3042,7 @@ CORD compile(env_t *env, ast_t *ast) return CORD_all("((Closure_t){", name, ", ", userdata, "})"); } case MethodCall: { - auto call = Match(ast, MethodCall); + DeclareMatch(call, ast, MethodCall); type_t *self_t = get_type(env, call->self); if (streq(call->name, "serialized")) { @@ -3243,7 +3243,7 @@ CORD compile(env_t *env, ast_t *ast) } else code_err(ast, "There is no '", call->name, "' method for lists"); } case SetType: { - auto set = Match(self_value_t, SetType); + DeclareMatch(set, self_value_t, SetType); if (streq(call->name, "has")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="key", .type=set->item_type); @@ -3309,7 +3309,7 @@ CORD compile(env_t *env, ast_t *ast) } else code_err(ast, "There is no '", call->name, "' method for tables"); } case TableType: { - auto table = Match(self_value_t, TableType); + DeclareMatch(table, self_value_t, TableType); if (streq(call->name, "get")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="key", .type=table->key_type); @@ -3354,7 +3354,7 @@ CORD compile(env_t *env, ast_t *ast) } else code_err(ast, "There is no '", call->name, "' method for tables"); } default: { - auto methodcall = Match(ast, MethodCall); + DeclareMatch(methodcall, ast, MethodCall); type_t *fn_t = get_method_type(env, methodcall->self, methodcall->name); arg_ast_t *args = new(arg_ast_t, .value=methodcall->self, .next=methodcall->args); binding_t *b = get_namespace_binding(env, methodcall->self, methodcall->name); @@ -3365,7 +3365,7 @@ CORD compile(env_t *env, ast_t *ast) #undef EXPECT_POINTER } case FunctionCall: { - auto call = Match(ast, FunctionCall); + DeclareMatch(call, ast, FunctionCall); type_t *fn_t = get_type(env, call->fn); if (fn_t->tag == FunctionType) { CORD fn = compile(env, call->fn); @@ -3408,7 +3408,7 @@ CORD compile(env_t *env, ast_t *ast) return compile_string_literal(Match(Match(call->args->value, TextJoin)->children->ast, TextLiteral)->cord); return CORD_all("Text$as_c_string(", expr_as_text(compile(env, call->args->value), actual, "no"), ")"); } else if (t->tag == StructType) { - auto struct_ = Match(t, StructType); + DeclareMatch(struct_, t, StructType); if (!struct_->opaque && is_valid_call(env, struct_->fields, call->args, true)) { return CORD_all("((", compile_type(t), "){", compile_arguments(env, ast, struct_->fields, call->args), "})"); @@ -3453,7 +3453,7 @@ CORD compile(env_t *env, ast_t *ast) return compile_to_type(env, Match(ast, ExplicitlyTyped)->ast, get_type(env, ast)); } case When: { - auto original = Match(ast, When); + DeclareMatch(original, ast, When); ast_t *when_var = WrapAST(ast, Var, .name="when"); when_clause_t *new_clauses = NULL; type_t *subject_t = get_type(env, original->subject); @@ -3488,14 +3488,14 @@ CORD compile(env_t *env, ast_t *ast) "when; })"); } case If: { - auto if_ = Match(ast, If); + DeclareMatch(if_, ast, If); ast_t *condition = if_->condition; CORD decl_code = CORD_EMPTY; env_t *truthy_scope = env, *falsey_scope = env; CORD condition_code; if (condition->tag == Declare) { - auto decl = Match(condition, Declare); + DeclareMatch(decl, condition, Declare); if (decl->value == NULL) code_err(condition, "This declaration must have a value"); type_t *condition_type = @@ -3544,7 +3544,7 @@ CORD compile(env_t *env, ast_t *ast) compile(truthy_scope, if_->body), " : ", compile(falsey_scope, if_->else_body), ")"); } case Reduction: { - auto reduction = Match(ast, Reduction); + DeclareMatch(reduction, ast, Reduction); ast_e op = reduction->op; type_t *iter_t = get_type(env, reduction->iter); @@ -3682,12 +3682,12 @@ CORD compile(env_t *env, ast_t *ast) } } case FieldAccess: { - auto f = Match(ast, FieldAccess); + DeclareMatch(f, ast, FieldAccess); type_t *fielded_t = get_type(env, f->fielded); type_t *value_t = value_type(fielded_t); switch (value_t->tag) { case TypeInfoType: { - auto info = Match(value_t, TypeInfoType); + DeclareMatch(info, value_t, TypeInfoType); if (f->field[0] == '_') { for (Table_t *locals = env->locals; locals; locals = locals->fallback) { if (locals == info->env->locals) @@ -3726,7 +3726,7 @@ CORD compile(env_t *env, ast_t *ast) code_err(ast, "The field '", f->field, "' is not a valid field name of ", type_to_str(value_t)); } case EnumType: { - auto e = Match(value_t, EnumType); + DeclareMatch(e, value_t, EnumType); for (tag_t *tag = e->tags; tag; tag = tag->next) { if (streq(f->field, tag->name)) { CORD prefix = namespace_prefix(e->env, e->env->namespace); @@ -3759,7 +3759,7 @@ CORD compile(env_t *env, ast_t *ast) } else if (streq(f->field, "keys")) { return CORD_all("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)"); } else if (streq(f->field, "values")) { - auto table = Match(value_t, TableType); + DeclareMatch(table, value_t, TableType); CORD offset = CORD_all("offsetof(struct { ", compile_declaration(table->key_type, "k"), "; ", compile_declaration(table->value_type, "v"), "; }, v)"); return CORD_all("({ List_t *entries = &(", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries;\n" "LIST_INCREF(*entries);\n" @@ -3781,12 +3781,12 @@ CORD compile(env_t *env, ast_t *ast) } } case Index: { - auto indexing = Match(ast, Index); + DeclareMatch(indexing, ast, Index); type_t *indexed_type = get_type(env, indexing->indexed); if (!indexing->index) { if (indexed_type->tag != PointerType) code_err(ast, "Only pointers can use the '[]' operator to dereference the entire value."); - auto ptr = Match(indexed_type, PointerType); + DeclareMatch(ptr, indexed_type, PointerType); if (ptr->pointed->tag == ListType) { return CORD_all("*({ List_t *list = ", compile(env, indexing->indexed), "; LIST_INCREF(*list); list; })"); } else if (ptr->pointed->tag == TableType || ptr->pointed->tag == SetType) { @@ -3816,7 +3816,7 @@ CORD compile(env_t *env, ast_t *ast) CORD_asprintf("%ld", (int64_t)(indexing->index->end - f->text)), ")"); } else if (container_t->tag == TableType) { - auto table_type = Match(container_t, TableType); + DeclareMatch(table_type, container_t, TableType); if (indexing->unchecked) code_err(ast, "Table indexes cannot be unchecked"); if (table_type->default_value) { @@ -3871,17 +3871,17 @@ CORD compile_type_info(type_t *t) case BoolType: case ByteType: case IntType: case BigIntType: case NumType: case CStringType: return CORD_all("&", type_to_cord(t), "$info"); case TextType: { - auto text = Match(t, TextType); + DeclareMatch(text, t, TextType); if (!text->lang || streq(text->lang, "Text")) return "&Text$info"; return CORD_all("(&", namespace_prefix(text->env, text->env->namespace->parent), text->lang, "$$info)"); } case StructType: { - auto s = Match(t, StructType); + DeclareMatch(s, t, StructType); return CORD_all("(&", namespace_prefix(s->env, s->env->namespace->parent), s->name, "$$info)"); } case EnumType: { - auto e = Match(t, EnumType); + DeclareMatch(e, t, EnumType); return CORD_all("(&", namespace_prefix(e->env, e->env->namespace->parent), e->name, "$$info)"); } case ListType: { @@ -3893,13 +3893,13 @@ CORD compile_type_info(type_t *t) return CORD_all("Set$info(", compile_type_info(item_type), ")"); } case TableType: { - auto table = Match(t, TableType); + DeclareMatch(table, t, TableType); type_t *key_type = table->key_type; type_t *value_type = table->value_type; return CORD_all("Table$info(", compile_type_info(key_type), ", ", compile_type_info(value_type), ")"); } case PointerType: { - auto ptr = Match(t, PointerType); + DeclareMatch(ptr, t, PointerType); CORD sigil = ptr->is_stack ? "&" : "@"; return CORD_asprintf("Pointer$info(%r, %r)", CORD_quoted(sigil), @@ -3943,7 +3943,7 @@ static CORD get_flag_options(type_t *t, CORD separator) CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type) { - auto fn_info = Match(fn_type, FunctionType); + DeclareMatch(fn_info, fn_type, FunctionType); env_t *main_env = fresh_scope(env); @@ -4042,7 +4042,7 @@ CORD compile_function(env_t *env, CORD name_code, ast_t *ast, CORD *staticdefs) ast_t *cache; bool is_inline; if (ast->tag == FunctionDef) { - auto fndef = Match(ast, FunctionDef); + DeclareMatch(fndef, ast, FunctionDef); function_name = Match(fndef->name, Var)->name; is_private = function_name[0] == '_'; args = fndef->args; @@ -4051,7 +4051,7 @@ CORD compile_function(env_t *env, CORD name_code, ast_t *ast, CORD *staticdefs) cache = fndef->cache; is_inline = fndef->is_inline; } else { - auto convertdef = Match(ast, ConvertDef); + DeclareMatch(convertdef, ast, ConvertDef); args = convertdef->args; ret_t = convertdef->ret_type ? parse_type_ast(env, convertdef->ret_type) : Type(VoidType); function_name = get_type_name(ret_t); @@ -4230,7 +4230,7 @@ CORD compile_top_level_code(env_t *env, ast_t *ast) switch (ast->tag) { case Use: { - auto use = Match(ast, Use); + DeclareMatch(use, ast, Use); if (use->what == USE_C_CODE) { Path_t path = Path$relative_to(Path$from_str(use->path), Path(".build")); return CORD_all("#include \"", Path$as_c_string(path), "\"\n"); @@ -4238,7 +4238,7 @@ CORD compile_top_level_code(env_t *env, ast_t *ast) return CORD_EMPTY; } case Declare: { - auto decl = Match(ast, Declare); + DeclareMatch(decl, ast, Declare); const char *decl_name = Match(decl->var, Var)->name; CORD full_name = CORD_all(namespace_prefix(env, env->namespace), decl_name); type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); @@ -4273,7 +4273,7 @@ CORD compile_top_level_code(env_t *env, ast_t *ast) return compile_function(env, name_code, ast, &env->code->staticdefs); } case StructDef: { - auto def = Match(ast, StructDef); + DeclareMatch(def, ast, StructDef); type_t *t = Table$str_get(*env->types, def->name); assert(t && t->tag == StructType); CORD code = compile_struct_typeinfo(env, t, def->name, def->fields, def->secret, def->opaque); @@ -4281,14 +4281,14 @@ CORD compile_top_level_code(env_t *env, ast_t *ast) return CORD_all(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : CORD_EMPTY); } case EnumDef: { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); CORD code = compile_enum_typeinfo(env, ast); code = CORD_all(code, compile_enum_constructors(env, ast)); env_t *ns_env = namespace_env(env, def->name); return CORD_all(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : CORD_EMPTY); } case LangDef: { - auto def = Match(ast, LangDef); + DeclareMatch(def, ast, LangDef); CORD code = CORD_asprintf("public const TypeInfo_t %r%s$$info = {%zu, %zu, .metamethods=Text$metamethods, .tag=TextInfo, .TextInfo={%r}};\n", namespace_prefix(env, env->namespace), def->name, sizeof(Text_t), __alignof__(Text_t), CORD_quoted(def->name)); @@ -4296,7 +4296,7 @@ CORD compile_top_level_code(env_t *env, ast_t *ast) return CORD_all(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : CORD_EMPTY); } case Extend: { - auto extend = Match(ast, Extend); + DeclareMatch(extend, ast, Extend); env_t *ns_env = namespace_env(env, extend->name); env_t *extended = new(env_t); *extended = *ns_env; @@ -4326,7 +4326,7 @@ static void initialize_vars_and_statics(env_t *env, ast_t *ast) CORD code = compile_statement(env, stmt->ast); env->code->staticdefs = CORD_all(env->code->staticdefs, code, "\n"); } else if (stmt->ast->tag == Declare) { - auto decl = Match(stmt->ast, Declare); + DeclareMatch(decl, stmt->ast, Declare); const char *decl_name = Match(decl->var, Var)->name; CORD full_name = CORD_all(namespace_prefix(env, env->namespace), decl_name); type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); @@ -4400,7 +4400,7 @@ CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) { switch (ast->tag) { case Use: { - auto use = Match(ast, Use); + DeclareMatch(use, ast, Use); Path_t source_path = Path$from_str(ast->file->filename); Path_t source_dir = Path$parent(source_path); Path_t build_dir = Path$resolved(Path$parent(header_path), Path$current_dir()); @@ -4432,7 +4432,7 @@ CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) return compile_enum_header(env, ast); } case LangDef: { - auto def = Match(ast, LangDef); + DeclareMatch(def, ast, LangDef); CORD full_name = CORD_cat(namespace_prefix(env, env->namespace), def->name); return CORD_all( // Constructor macro: @@ -4457,13 +4457,13 @@ CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *a ast_t *block = NULL; switch (ast->tag) { case LangDef: { - auto def = Match(ast, LangDef); + DeclareMatch(def, ast, LangDef); ns_env = namespace_env(env, def->name); block = def->namespace; break; } case Extend: { - auto extend = Match(ast, Extend); + DeclareMatch(extend, ast, Extend); ns_env = namespace_env(env, extend->name); env_t *extended = new(env_t); @@ -4477,24 +4477,24 @@ CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *a break; } case StructDef: { - auto def = Match(ast, StructDef); + DeclareMatch(def, ast, StructDef); ns_env = namespace_env(env, def->name); block = def->namespace; break; } case EnumDef: { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); ns_env = namespace_env(env, def->name); block = def->namespace; break; } case Extern: { - auto ext = Match(ast, Extern); + DeclareMatch(ext, ast, Extern); type_t *t = parse_type_ast(env, ext->type); CORD decl; if (t->tag == ClosureType) { t = Match(t, ClosureType)->fn; - auto fn = Match(t, FunctionType); + DeclareMatch(fn, t, FunctionType); decl = CORD_all(compile_type(fn->ret), " ", ext->name, "("); for (arg_t *arg = fn->args; arg; arg = arg->next) { decl = CORD_all(decl, compile_type(arg->type)); @@ -4507,7 +4507,7 @@ CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *a return CORD_all("extern ", decl, ";\n"); } case Declare: { - auto decl = Match(ast, Declare); + DeclareMatch(decl, ast, Declare); const char *decl_name = Match(decl->var, Var)->name; bool is_private = (decl_name[0] == '_'); if (is_private) @@ -4525,7 +4525,7 @@ CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *a "extern ", compile_declaration(t, CORD_cat(namespace_prefix(env, env->namespace), decl_name)), ";\n"); } case FunctionDef: { - auto fndef = Match(ast, FunctionDef); + DeclareMatch(fndef, ast, FunctionDef); const char *decl_name = Match(fndef->name, Var)->name; bool is_private = decl_name[0] == '_'; if (is_private) return CORD_EMPTY; @@ -4547,7 +4547,7 @@ CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *a return CORD_all(ret_type_code, " ", name, arg_signature, ";\n"); } case ConvertDef: { - auto def = Match(ast, ConvertDef); + DeclareMatch(def, ast, ConvertDef); CORD arg_signature = "("; for (arg_ast_t *arg = def->args; arg; arg = arg->next) { @@ -4585,12 +4585,12 @@ typedef struct { static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast) { if (ast->tag == StructDef) { - auto def = Match(ast, StructDef); + DeclareMatch(def, ast, StructDef); if (def->external) return; CORD full_name = CORD_cat(namespace_prefix(info->env, info->env->namespace), def->name); *info->header = CORD_all(*info->header, "typedef struct ", full_name, "$$struct ", full_name, "$$type;\n"); } else if (ast->tag == EnumDef) { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); CORD full_name = CORD_cat(namespace_prefix(info->env, info->env->namespace), def->name); *info->header = CORD_all(*info->header, "typedef struct ", full_name, "$$struct ", full_name, "$$type;\n"); @@ -4599,7 +4599,7 @@ static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast) *info->header = CORD_all(*info->header, "typedef struct ", full_name, "$", tag->name, "$$struct ", full_name, "$", tag->name, "$$type;\n"); } } else if (ast->tag == LangDef) { - auto def = Match(ast, LangDef); + DeclareMatch(def, ast, LangDef); *info->header = CORD_all(*info->header, "typedef Text_t ", namespace_prefix(info->env, info->env->namespace), def->name, "$$type;\n"); } } diff --git a/src/enums.c b/src/enums.c index eeeff19d..ac21bdda 100644 --- a/src/enums.c +++ b/src/enums.c @@ -15,7 +15,7 @@ CORD compile_enum_typeinfo(env_t *env, ast_t *ast) { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); CORD full_name = CORD_cat(namespace_prefix(env, env->namespace), def->name); // Compile member types and constructors: @@ -54,7 +54,7 @@ CORD compile_enum_typeinfo(env_t *env, ast_t *ast) CORD compile_enum_constructors(env_t *env, ast_t *ast) { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); CORD full_name = CORD_cat(namespace_prefix(env, env->namespace), def->name); CORD constructors = CORD_EMPTY; @@ -82,7 +82,7 @@ CORD compile_enum_constructors(env_t *env, ast_t *ast) CORD compile_enum_header(env_t *env, ast_t *ast) { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); CORD full_name = CORD_all(namespace_prefix(env, env->namespace), def->name); CORD all_defs = CORD_EMPTY; CORD enum_def = CORD_all("struct ", full_name, "$$struct {\n" diff --git a/src/environment.c b/src/environment.c index ea056bb0..70c29ce7 100644 --- a/src/environment.c +++ b/src/environment.c @@ -25,13 +25,13 @@ static type_t *declare_type(env_t *env, const char *def_str) if (statements == NULL || statements->next) errx(1, "Couldn't not parse struct def: %s", def_str); switch (statements->ast->tag) { case StructDef: { - auto def = Match(statements->ast, StructDef); + DeclareMatch(def, statements->ast, StructDef); prebind_statement(env, statements->ast); bind_statement(env, statements->ast); return Table$str_get(*env->types, def->name); } case EnumDef: { - auto def = Match(statements->ast, EnumDef); + DeclareMatch(def, statements->ast, EnumDef); prebind_statement(env, statements->ast); bind_statement(env, statements->ast); return Table$str_get(*env->types, def->name); @@ -602,7 +602,7 @@ env_t *with_enum_scope(env_t *env, type_t *t) env_t *for_scope(env_t *env, ast_t *ast) { - auto for_ = Match(ast, For); + DeclareMatch(for_, ast, For); type_t *iter_t = value_type(get_type(env, for_->iter)); env_t *scope = fresh_scope(env); @@ -663,7 +663,7 @@ env_t *for_scope(env_t *env, ast_t *ast) return scope; } case FunctionType: case ClosureType: { - auto fn = iter_t->tag == ClosureType ? Match(Match(iter_t, ClosureType)->fn, FunctionType) : Match(iter_t, FunctionType); + __typeof(iter_t->__data.FunctionType) *fn = iter_t->tag == ClosureType ? Match(Match(iter_t, ClosureType)->fn, FunctionType) : Match(iter_t, FunctionType); if (for_->vars) { if (for_->vars->next) @@ -692,15 +692,15 @@ env_t *get_namespace_by_type(env_t *env, type_t *t) } case TextType: return Match(t, TextType)->env; case StructType: { - auto struct_ = Match(t, StructType); + DeclareMatch(struct_, t, StructType); return struct_->env; } case EnumType: { - auto enum_ = Match(t, EnumType); + DeclareMatch(enum_, t, EnumType); return enum_->env; } case TypeInfoType: { - auto info = Match(t, TypeInfoType); + DeclareMatch(info, t, TypeInfoType); return info->env; } default: break; @@ -744,14 +744,14 @@ PUREFUNC binding_t *get_constructor(env_t *env, type_t *t, arg_ast_t *args) // Prioritize exact matches: for (int64_t i = constructors.length-1; i >= 0; i--) { binding_t *b = constructors.data + i*constructors.stride; - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, t) && is_valid_call(env, fn->args, args, false)) return b; } // Fall back to promotion: for (int64_t i = constructors.length-1; i >= 0; i--) { binding_t *b = constructors.data + i*constructors.stride; - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, t) && is_valid_call(env, fn->args, args, true)) return b; } @@ -764,7 +764,7 @@ PUREFUNC binding_t *get_metamethod_binding(env_t *env, ast_e tag, ast_t *lhs, as if (!method_name) return NULL; binding_t *b = get_namespace_binding(env, lhs, method_name); if (!b || b->type->tag != FunctionType) return NULL; - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (!type_eq(fn->ret, ret)) return NULL; arg_ast_t *args = new(arg_ast_t, .value=lhs, .next=new(arg_ast_t, .value=rhs)); return is_valid_call(env, fn->args, args, true) ? b : NULL; diff --git a/src/parse.c b/src/parse.c index d6ff4e5a..93a2dcdd 100644 --- a/src/parse.c +++ b/src/parse.c @@ -210,7 +210,7 @@ static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, ch #define expect(ctx, start, pos, parser, ...) ({ \ const char **_pos = pos; \ spaces(_pos); \ - auto _result = parser(ctx, *_pos); \ + __typeof(parser(ctx, *_pos)) _result = parser(ctx, *_pos); \ if (!_result) { \ if (USE_COLOR) \ fputs("\x1b[31;1;7m", stderr); \ @@ -222,7 +222,7 @@ static ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, ch #define optional(ctx, pos, parser) ({ \ const char **_pos = pos; \ spaces(_pos); \ - auto _result = parser(ctx, *_pos); \ + __typeof(parser(ctx, *_pos)) _result = parser(ctx, *_pos); \ if (_result) *_pos = _result->end; \ _result; }) @@ -140,7 +140,7 @@ const TypeInfo_t *type_to_type_info(type_t *t) return memcpy(GC_MALLOC(sizeof(TypeInfo_t)), &table_info, sizeof(TypeInfo_t)); } case PointerType: { - auto ptr = Match(t, PointerType); + DeclareMatch(ptr, t, PointerType); CORD sigil = ptr->is_stack ? "&" : "@"; const TypeInfo_t *pointed_info = type_to_type_info(ptr->pointed); const TypeInfo_t pointer_info = *Pointer$info(sigil, pointed_info); @@ -222,7 +222,7 @@ void run(env_t *env, ast_t *ast) { switch (ast->tag) { case Declare: { - auto decl = Match(ast, Declare); + DeclareMatch(decl, ast, Declare); const char *name = Match(decl->var, Var)->name; type_t *type = get_type(env, decl->value); repl_binding_t *binding = new(repl_binding_t, .type=type, .value=GC_MALLOC(type_size(type))); @@ -231,7 +231,7 @@ void run(env_t *env, ast_t *ast) break; } case Assign: { - auto assign = Match(ast, Assign); + DeclareMatch(assign, ast, Assign); for (ast_list_t *val = assign->values, *target = assign->targets; val && target; val = val->next, target = target->next) { type_t *t_target = get_type(env, target->ast); type_t *t_val = get_type(env, val->ast); @@ -255,7 +255,7 @@ void run(env_t *env, ast_t *ast) break; } // case Index: { - // auto index = Match(target->ast, Index); + // DeclareMatch(index, target->ast, Index); // type_t *obj_t = get_type(env, index->indexed); // TypeInfo_t *table_info = type_to_type_info(t); // } @@ -265,7 +265,7 @@ void run(env_t *env, ast_t *ast) break; } case DocTest: { - auto doctest = Match(ast, DocTest); + DeclareMatch(doctest, ast, DocTest); type_t *t = get_type(env, doctest->expr); size_t size = t ? type_size(t) : 0; if (size == 0) { @@ -280,7 +280,7 @@ void run(env_t *env, ast_t *ast) break; } case Block: { - auto block = Match(ast, Block); + DeclareMatch(block, ast, Block); for (ast_list_t *stmt = block->statements; stmt; stmt = stmt->next) { run(env, stmt->ast); } @@ -298,7 +298,7 @@ void run(env_t *env, ast_t *ast) // LinkerDirective, // InlineCCode, case If: { - auto if_ = Match(ast, If); + DeclareMatch(if_, ast, If); bool condition; type_t *cond_t = get_type(env, if_->condition); assert(cond_t->tag == BoolType); @@ -311,7 +311,7 @@ void run(env_t *env, ast_t *ast) break; } case While: { - auto while_ = Match(ast, While); + DeclareMatch(while_, ast, While); bool condition; type_t *cond_t = get_type(env, while_->condition); assert(cond_t->tag == BoolType); @@ -323,7 +323,7 @@ void run(env_t *env, ast_t *ast) break; } // case For: { - // auto for_ = Match(ast, For); + // DeclareMatch(for_, ast, For); // } default: { eval(env, ast, NULL); @@ -387,7 +387,7 @@ void eval(env_t *env, ast_t *ast, void *dest) break; } case Index: { - auto index = Match(ast, Index); + DeclareMatch(index, ast, Index); type_t *indexed_t = get_type(env, index->indexed); // type_t *index_t = get_type(env, index->index); switch (indexed_t->tag) { @@ -416,7 +416,7 @@ void eval(env_t *env, ast_t *ast, void *dest) break; } case PointerType: { - auto ptr = Match(indexed_t, PointerType); + DeclareMatch(ptr, indexed_t, PointerType); size_t pointed_size = type_size(ptr->pointed); void *pointer; eval(env, index->indexed, &pointer); @@ -441,7 +441,7 @@ void eval(env_t *env, ast_t *ast, void *dest) } case Table: { assert(t->tag == TableType); - auto table_ast = Match(ast, Table); + DeclareMatch(table_ast, ast, Table); Table_t table = {}; size_t key_size = type_size(Match(t, TableType)->key_type); size_t value_size = type_size(Match(t, TableType)->value_type); @@ -450,7 +450,7 @@ void eval(env_t *env, ast_t *ast, void *dest) const TypeInfo_t *table_info = type_to_type_info(t); assert(table_info->tag == TableInfo); for (ast_list_t *entry = table_ast->entries; entry; entry = entry->next) { - auto e = Match(entry->ast, TableEntry); + DeclareMatch(e, entry->ast, TableEntry); eval(env, e->key, key_buf); eval(env, e->value, value_buf); Table$set(&table, key_buf, value_buf, table_info); @@ -461,7 +461,7 @@ void eval(env_t *env, ast_t *ast, void *dest) break; } case Block: { - auto block = Match(ast, Block); + DeclareMatch(block, ast, Block); for (ast_list_t *stmt = block->statements; stmt; stmt = stmt->next) { if (stmt->next) run(env, stmt->ast); diff --git a/src/stdlib/lists.c b/src/stdlib/lists.c index 69ac7026..fb6c4fb9 100644 --- a/src/stdlib/lists.c +++ b/src/stdlib/lists.c @@ -773,7 +773,7 @@ public void List$serialize(const void *obj, FILE *out, Table_t *pointers, const List_t list = *(List_t*)obj; int64_t len = list.length; Int64$serialize(&len, out, pointers, &Int64$info); - auto item_serialize = type->ListInfo.item->metamethods.serialize; + serialize_fn_t item_serialize = type->ListInfo.item->metamethods.serialize; if (item_serialize) { for (int64_t i = 0; i < len; i++) item_serialize(list.data + i*list.stride, out, pointers, type->ListInfo.item); @@ -797,7 +797,7 @@ public void List$deserialize(FILE *in, void *obj, List_t *pointers, const TypeIn .data=GC_MALLOC((size_t)(len*padded_size)), .stride=padded_size, }; - auto item_deserialize = type->ListInfo.item->metamethods.deserialize; + deserialize_fn_t item_deserialize = type->ListInfo.item->metamethods.deserialize; if (item_deserialize) { for (int64_t i = 0; i < len; i++) item_deserialize(in, list.data + i*list.stride, pointers, type->ListInfo.item); diff --git a/src/stdlib/pointers.c b/src/stdlib/pointers.c index b674ac6f..daea2dbd 100644 --- a/src/stdlib/pointers.c +++ b/src/stdlib/pointers.c @@ -15,7 +15,7 @@ #include "util.h" public Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *type) { - auto ptr_info = type->PointerInfo; + __typeof(type->PointerInfo) ptr_info = type->PointerInfo; if (!x) { Text_t typename = generic_as_text(NULL, false, ptr_info.pointed); if (colorize) diff --git a/src/stdlib/tables.c b/src/stdlib/tables.c index 3cb2e742..780aca83 100644 --- a/src/stdlib/tables.c +++ b/src/stdlib/tables.c @@ -437,7 +437,7 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type Table_t *x = (Table_t*)vx, *y = (Table_t*)vy; assert(type->tag == TableInfo); - auto table = type->TableInfo; + __typeof(type->TableInfo) table = type->TableInfo; // Sort empty tables before non-empty tables: if (x->entries.length == 0 || y->entries.length == 0) @@ -543,7 +543,7 @@ PUREFUNC public uint64_t Table$hash(const void *obj, const TypeInfo_t *type) // Table hashes are computed as: // hash(t.length, (xor: t.keys), (xor: t.values), t.fallback) // Where fallback and default hash to zero if absent - auto table = type->TableInfo; + __typeof(type->TableInfo) table = type->TableInfo; uint64_t keys_hash = 0, values_hash = 0; size_t offset = value_offset(type); if (table.value->size > 0) { @@ -576,7 +576,7 @@ public Text_t Table$as_text(const void *obj, bool colorize, const TypeInfo_t *ty { Table_t *t = (Table_t*)obj; assert(type->tag == TableInfo); - auto table = type->TableInfo; + __typeof(type->TableInfo) table = type->TableInfo; if (!t) { if (table.value != &Void$info) diff --git a/src/stdlib/types.h b/src/stdlib/types.h index ddece7c9..7d61a524 100644 --- a/src/stdlib/types.h +++ b/src/stdlib/types.h @@ -10,14 +10,22 @@ typedef struct TypeInfo_s TypeInfo_t; +typedef void (*serialize_fn_t)(const void*, FILE*, Table_t*, const TypeInfo_t*); +typedef void (*deserialize_fn_t)(FILE*, void*, List_t*, const TypeInfo_t*); +typedef bool (*is_none_fn_t)(const void*, const TypeInfo_t*); +typedef uint64_t (*hash_fn_t)(const void*, const TypeInfo_t*); +typedef int32_t (*compare_fn_t)(const void*, const void*, const TypeInfo_t*); +typedef bool (*equal_fn_t)(const void*, const void*, const TypeInfo_t*); +typedef Text_t (*as_text_fn_t)(const void*, bool, const TypeInfo_t*); + typedef struct { - uint64_t (*hash)(const void*, const TypeInfo_t*); - int32_t (*compare)(const void*, const void*, const TypeInfo_t*); - bool (*equal)(const void*, const void*, const TypeInfo_t*); - Text_t (*as_text)(const void*, bool, const TypeInfo_t*); - bool (*is_none)(const void*, const TypeInfo_t*); - void (*serialize)(const void*, FILE*, Table_t*, const TypeInfo_t*); - void (*deserialize)(FILE*, void*, List_t*, const TypeInfo_t*); + hash_fn_t hash; + compare_fn_t compare; + equal_fn_t equal; + as_text_fn_t as_text; + is_none_fn_t is_none; + serialize_fn_t serialize; + deserialize_fn_t deserialize; } metamethods_t; typedef struct { diff --git a/src/stdlib/util.h b/src/stdlib/util.h index 4cb1b375..25cd49f9 100644 --- a/src/stdlib/util.h +++ b/src/stdlib/util.h @@ -19,10 +19,6 @@ #define IF_DECLARE(decl, expr, block) if (({ decl; expr ? ({ block; 1; }) : 0; })) {} -#ifndef auto -#define auto __auto_type -#endif - #define WHEN(type, subj, var, body) { type var = subj; switch (var.$tag) body } #ifndef public diff --git a/src/structs.c b/src/structs.c index c5f45c59..401fcb7a 100644 --- a/src/structs.c +++ b/src/structs.c @@ -45,7 +45,7 @@ CORD compile_struct_typeinfo(env_t *env, type_t *t, const char *name, arg_ast_t CORD compile_struct_header(env_t *env, ast_t *ast) { - auto def = Match(ast, StructDef); + DeclareMatch(def, ast, StructDef); CORD typeinfo_name = CORD_all(namespace_prefix(env, env->namespace), def->name, "$$info"); CORD type_code = def->external ? def->name : CORD_all("struct ", namespace_prefix(env, env->namespace), def->name, "$$struct"); @@ -343,7 +343,7 @@ typedef struct { static void _compile_statement_header_for_library(libheader_info_t *info, ast_t *ast) { if (ast->tag == Use) { - auto use = Match(ast, Use); + DeclareMatch(use, ast, Use); if (use->what == USE_LOCAL) return; @@ -362,11 +362,11 @@ static void _compile_statement_header_for_library(libheader_info_t *info, ast_t static void _make_typedefs_for_library(libheader_info_t *info, ast_t *ast) { if (ast->tag == StructDef) { - auto def = Match(ast, StructDef); + DeclareMatch(def, ast, StructDef); CORD full_name = CORD_cat(namespace_prefix(info->env, info->env->namespace), def->name); CORD_put(CORD_all("typedef struct ", full_name, "$$struct ", full_name, "$$type;\n"), info->output); } else if (ast->tag == EnumDef) { - auto def = Match(ast, EnumDef); + DeclareMatch(def, ast, EnumDef); CORD full_name = CORD_cat(namespace_prefix(info->env, info->env->namespace), def->name); CORD_put(CORD_all("typedef struct ", full_name, "$$struct ", full_name, "$$type;\n"), info->output); @@ -375,7 +375,7 @@ static void _make_typedefs_for_library(libheader_info_t *info, ast_t *ast) CORD_put(CORD_all("typedef struct ", full_name, "$", tag->name, "$$struct ", full_name, "$", tag->name, "$$type;\n"), info->output); } } else if (ast->tag == LangDef) { - auto def = Match(ast, LangDef); + DeclareMatch(def, ast, LangDef); CORD_put(CORD_all("typedef Text_t ", namespace_prefix(info->env, info->env->namespace), def->name, "$$type;\n"), info->output); } } @@ -403,7 +403,7 @@ static void _compile_file_header_for_library(env_t *env, Path_t header_path, Pat ast_t *ast = stmt->ast; if (ast->tag != Use) continue; - auto use = Match(ast, Use); + DeclareMatch(use, ast, Use); if (use->what == USE_LOCAL) { Path_t resolved = Path$resolved(Path$from_str(use->path), Path$parent(path)); _compile_file_header_for_library(env, header_path, resolved, visited_files, used_imports, output); @@ -615,7 +615,7 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { ast_t *stmt_ast = stmt->ast; if (stmt_ast->tag != Use) continue; - auto use = Match(stmt_ast, Use); + DeclareMatch(use, stmt_ast, Use); switch (use->what) { case USE_LOCAL: { diff --git a/src/typecheck.c b/src/typecheck.c index 83b715cf..3695de76 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -46,7 +46,7 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) code_err(ast, "I don't know a type with the name '", name, "'"); } case PointerTypeAST: { - auto ptr = Match(ast, PointerTypeAST); + DeclareMatch(ptr, ast, PointerTypeAST); type_t *pointed_t = parse_type_ast(env, ptr->pointed); if (pointed_t->tag == VoidType) code_err(ast, "Void pointers are not supported. You probably meant 'Memory' instead of 'Void'"); @@ -75,7 +75,7 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) return Type(SetType, .item_type=item_t); } case TableTypeAST: { - auto table_type = Match(ast, TableTypeAST); + DeclareMatch(table_type, ast, TableTypeAST); type_ast_t *key_type_ast = table_type->key; type_t *key_type = parse_type_ast(env, key_type_ast); if (!key_type) code_err(key_type_ast, "I can't figure out what type this is."); @@ -92,7 +92,7 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) return Type(TableType, .key_type=key_type, .value_type=val_type, .env=env, .default_value=table_type->default_value); } case FunctionTypeAST: { - auto fn = Match(ast, FunctionTypeAST); + DeclareMatch(fn, ast, FunctionTypeAST); type_t *ret_t = fn->ret ? parse_type_ast(env, fn->ret) : Type(VoidType); if (has_stack_memory(ret_t)) code_err(fn->ret, "Functions are not allowed to return stack references, because the reference may no longer exist on the stack."); @@ -111,7 +111,7 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) return Type(ClosureType, Type(FunctionType, .args=type_args, .ret=ret_t)); } case OptionalTypeAST: { - auto opt = Match(ast, OptionalTypeAST); + DeclareMatch(opt, ast, OptionalTypeAST); type_t *t = parse_type_ast(env, opt->type); if (t->tag == VoidType || t->tag == AbortType || t->tag == ReturnType) code_err(ast, "Optional ", type_to_str(t), " types are not supported."); @@ -161,7 +161,7 @@ PUREFUNC type_t *get_math_type(env_t *env, ast_t *ast, type_t *lhs_t, type_t *rh static env_t *load_module(env_t *env, ast_t *module_ast) { - auto use = Match(module_ast, Use); + DeclareMatch(use, module_ast, Use); switch (use->what) { case USE_LOCAL: { Path_t source_path = Path$from_str(module_ast->file->filename); @@ -222,7 +222,7 @@ void prebind_statement(env_t *env, ast_t *statement) break; } case StructDef: { - auto def = Match(statement, StructDef); + DeclareMatch(def, statement, StructDef); if (get_binding(env, def->name)) code_err(statement, "A ", type_to_str(get_binding(env, def->name)->type), " called ", quoted(def->name), " has already been defined"); @@ -236,7 +236,7 @@ void prebind_statement(env_t *env, ast_t *statement) break; } case EnumDef: { - auto def = Match(statement, EnumDef); + DeclareMatch(def, statement, EnumDef); if (get_binding(env, def->name)) code_err(statement, "A ", type_to_str(get_binding(env, def->name)->type), " called ", quoted(def->name), " has already been defined"); @@ -250,7 +250,7 @@ void prebind_statement(env_t *env, ast_t *statement) break; } case LangDef: { - auto def = Match(statement, LangDef); + DeclareMatch(def, statement, LangDef); if (get_binding(env, def->name)) code_err(statement, "A ", type_to_str(get_binding(env, def->name)->type), " called ", quoted(def->name), " has already been defined"); @@ -264,7 +264,7 @@ void prebind_statement(env_t *env, ast_t *statement) break; } case Extend: { - auto extend = Match(statement, Extend); + DeclareMatch(extend, statement, Extend); env_t *ns_env = namespace_env(env, extend->name); env_t *extended = new(env_t); *extended = *ns_env; @@ -297,7 +297,7 @@ void bind_statement(env_t *env, ast_t *statement) break; } case Declare: { - auto decl = Match(statement, Declare); + DeclareMatch(decl, statement, Declare); const char *name = Match(decl->var, Var)->name; if (streq(name, "_")) // Explicit discard return; @@ -316,7 +316,7 @@ void bind_statement(env_t *env, ast_t *statement) break; } case FunctionDef: { - auto def = Match(statement, FunctionDef); + DeclareMatch(def, statement, FunctionDef); const char *name = Match(def->name, Var)->name; type_t *type = get_function_def_type(env, statement); CORD code = CORD_all(namespace_prefix(env, env->namespace), name); @@ -338,7 +338,7 @@ void bind_statement(env_t *env, ast_t *statement) break; } case StructDef: { - auto def = Match(statement, StructDef); + DeclareMatch(def, statement, StructDef); env_t *ns_env = namespace_env(env, def->name); type_t *type = Table$str_get(*env->types, def->name); if (!type) code_err(statement, "Couldn't find type!"); @@ -380,7 +380,7 @@ void bind_statement(env_t *env, ast_t *statement) break; } case EnumDef: { - auto def = Match(statement, EnumDef); + DeclareMatch(def, statement, EnumDef); env_t *ns_env = namespace_env(env, def->name); type_t *type = Table$str_get(*env->types, def->name); assert(type); @@ -439,7 +439,7 @@ void bind_statement(env_t *env, ast_t *statement) break; } case LangDef: { - auto def = Match(statement, LangDef); + DeclareMatch(def, statement, LangDef); env_t *ns_env = namespace_env(env, def->name); type_t *type = Type(TextType, .lang=def->name, .env=ns_env); Table$str_set(env->types, def->name, type); @@ -452,7 +452,7 @@ void bind_statement(env_t *env, ast_t *statement) break; } case Extend: { - auto extend = Match(statement, Extend); + DeclareMatch(extend, statement, Extend); env_t *ns_env = namespace_env(env, extend->name); env_t *extended = new(env_t); *extended = *ns_env; @@ -507,7 +507,7 @@ void bind_statement(env_t *env, ast_t *statement) break; } case Extern: { - auto ext = Match(statement, Extern); + DeclareMatch(ext, statement, Extern); type_t *t = parse_type_ast(env, ext->type); if (t->tag == ClosureType) t = Match(t, ClosureType)->fn; @@ -553,7 +553,7 @@ env_t *when_clause_scope(env_t *env, type_t *subject_t, when_clause_t *clause) if (clause->pattern->tag != FunctionCall || Match(clause->pattern, FunctionCall)->fn->tag != Var) code_err(clause->pattern, "I only support variables and constructors for pattern matching ", type_to_str(subject_t), " types in a 'when' block"); - auto fn = Match(clause->pattern, FunctionCall); + DeclareMatch(fn, clause->pattern, FunctionCall); const char *tag_name = Match(fn->fn, Var)->name; type_t *tag_type = NULL; tag_t * const tags = Match(subject_t, EnumType)->tags; @@ -571,7 +571,7 @@ env_t *when_clause_scope(env_t *env, type_t *subject_t, when_clause_t *clause) return env; env_t *scope = fresh_scope(env); - auto tag_struct = Match(tag_type, StructType); + DeclareMatch(tag_struct, tag_type, StructType); if (fn->args && !fn->args->next && tag_struct->fields && tag_struct->fields->next) { if (fn->args->value->tag != Var) code_err(fn->args->value, "I expected a variable here"); @@ -652,7 +652,7 @@ type_t *get_type(env_t *env, ast_t *ast) if (base_type->tag == OptionalType) { code_err(base, "This value might be null, so it can't be safely dereferenced"); } else if (base_type->tag == PointerType) { - auto ptr = Match(base_type, PointerType); + DeclareMatch(ptr, base_type, PointerType); return Type(PointerType, .pointed=ref_type, .is_stack=ptr->is_stack); } else if (base->tag == Var) { return Type(PointerType, .pointed=ref_type, .is_stack=true); @@ -693,19 +693,19 @@ type_t *get_type(env_t *env, ast_t *ast) } } case Var: { - auto var = Match(ast, Var); + DeclareMatch(var, ast, Var); binding_t *b = get_binding(env, var->name); if (b) return b->type; code_err(ast, "I don't know what ", quoted(var->name), " refers to"); } case List: { - auto list = Match(ast, List); + DeclareMatch(list, ast, List); type_t *item_type = NULL; for (ast_list_t *item = list->items; item; item = item->next) { ast_t *item_ast = item->ast; env_t *scope = env; while (item_ast->tag == Comprehension) { - auto comp = Match(item_ast, Comprehension); + DeclareMatch(comp, item_ast, Comprehension); scope = for_scope( scope, FakeAST(For, .iter=comp->iter, .vars=comp->vars)); item_ast = comp->expr; @@ -725,13 +725,13 @@ type_t *get_type(env_t *env, ast_t *ast) return Type(ListType, .item_type=item_type); } case Set: { - auto set = Match(ast, Set); + DeclareMatch(set, ast, Set); type_t *item_type = NULL; for (ast_list_t *item = set->items; item; item = item->next) { ast_t *item_ast = item->ast; env_t *scope = env; while (item_ast->tag == Comprehension) { - auto comp = Match(item_ast, Comprehension); + DeclareMatch(comp, item_ast, Comprehension); scope = for_scope( scope, FakeAST(For, .iter=comp->iter, .vars=comp->vars)); item_ast = comp->expr; @@ -752,19 +752,19 @@ type_t *get_type(env_t *env, ast_t *ast) return Type(SetType, .item_type=item_type); } case Table: { - auto table = Match(ast, Table); + DeclareMatch(table, ast, Table); type_t *key_type = NULL, *value_type = NULL; for (ast_list_t *entry = table->entries; entry; entry = entry->next) { ast_t *entry_ast = entry->ast; env_t *scope = env; while (entry_ast->tag == Comprehension) { - auto comp = Match(entry_ast, Comprehension); + DeclareMatch(comp, entry_ast, Comprehension); scope = for_scope( scope, FakeAST(For, .iter=comp->iter, .vars=comp->vars)); entry_ast = comp->expr; } - auto e = Match(entry_ast, TableEntry); + DeclareMatch(e, entry_ast, TableEntry); type_t *key_t = get_type(scope, e->key); type_t *value_t = get_type(scope, e->value); @@ -792,19 +792,19 @@ type_t *get_type(env_t *env, ast_t *ast) code_err(ast, "Table entries should not be typechecked directly"); } case Comprehension: { - auto comp = Match(ast, Comprehension); + DeclareMatch(comp, ast, Comprehension); env_t *scope = for_scope(env, FakeAST(For, .iter=comp->iter, .vars=comp->vars)); if (comp->expr->tag == Comprehension) { return get_type(scope, comp->expr); } else if (comp->expr->tag == TableEntry) { - auto e = Match(comp->expr, TableEntry); + DeclareMatch(e, comp->expr, TableEntry); return Type(TableType, .key_type=get_type(scope, e->key), .value_type=get_type(scope, e->value), .env=env); } else { return Type(ListType, .item_type=get_type(scope, comp->expr)); } } case FieldAccess: { - auto access = Match(ast, FieldAccess); + DeclareMatch(access, ast, FieldAccess); type_t *fielded_t = get_type(env, access->fielded); if (fielded_t->tag == ModuleType) { const char *name = Match(fielded_t, ModuleType)->name; @@ -812,7 +812,7 @@ type_t *get_type(env_t *env, ast_t *ast) if (!module_env) code_err(access->fielded, "I couldn't find the environment for the module ", name); return get_type(module_env, WrapAST(ast, Var, access->field)); } else if (fielded_t->tag == TypeInfoType) { - auto info = Match(fielded_t, TypeInfoType); + DeclareMatch(info, fielded_t, TypeInfoType); assert(info->env); binding_t *b = get_binding(info->env, access->field); if (!b) code_err(ast, "I couldn't find the field '", access->field, "' on this type"); @@ -824,7 +824,7 @@ type_t *get_type(env_t *env, ast_t *ast) return field_t; } case Index: { - auto indexing = Match(ast, Index); + DeclareMatch(indexing, ast, Index); type_t *indexed_t = get_type(env, indexing->indexed); if (indexed_t->tag == OptionalType && !indexing->index) code_err(ast, "You're attempting to dereference a value whose type indicates it could be null"); @@ -840,7 +840,7 @@ type_t *get_type(env_t *env, ast_t *ast) return Match(value_t, ListType)->item_type; code_err(indexing->index, "I only know how to index lists using integers, not ", type_to_str(index_t)); } else if (value_t->tag == TableType) { - auto table_type = Match(value_t, TableType); + DeclareMatch(table_type, value_t, TableType); if (table_type->default_value) return table_type->value_type; return Type(OptionalType, table_type->value_type); @@ -851,7 +851,7 @@ type_t *get_type(env_t *env, ast_t *ast) } } case FunctionCall: { - auto call = Match(ast, FunctionCall); + DeclareMatch(call, ast, FunctionCall); type_t *fn_type_t = get_type(env, call->fn); if (!fn_type_t) code_err(call->fn, "I couldn't find this function"); @@ -871,11 +871,11 @@ type_t *get_type(env_t *env, ast_t *ast) fn_type_t = Match(fn_type_t, ClosureType)->fn; if (fn_type_t->tag != FunctionType) code_err(call->fn, "This isn't a function, it's a ", type_to_str(fn_type_t)); - auto fn_type = Match(fn_type_t, FunctionType); + DeclareMatch(fn_type, fn_type_t, FunctionType); return fn_type->ret; } case MethodCall: { - auto call = Match(ast, MethodCall); + DeclareMatch(call, ast, MethodCall); if (streq(call->name, "serialized")) // Data serialization return Type(ListType, Type(ByteType)); @@ -935,7 +935,7 @@ type_t *get_type(env_t *env, ast_t *ast) else code_err(ast, "There is no '", call->name, "' method for sets"); } case TableType: { - auto table = Match(self_value_t, TableType); + DeclareMatch(table, self_value_t, TableType); if (streq(call->name, "clear")) return Type(VoidType); else if (streq(call->name, "get")) return Type(OptionalType, .type=table->value_type); else if (streq(call->name, "get_or_set")) return table->value_type; @@ -956,13 +956,13 @@ type_t *get_type(env_t *env, ast_t *ast) code_err(ast, "No such method!"); if (fn_type_t->tag != FunctionType) code_err(ast, "This isn't a method, it's a ", type_to_str(fn_type_t)); - auto fn_type = Match(fn_type_t, FunctionType); + DeclareMatch(fn_type, fn_type_t, FunctionType); return fn_type->ret; } } } case Block: { - auto block = Match(ast, Block); + DeclareMatch(block, ast, Block); ast_list_t *last = block->statements; if (!last) return Type(VoidType); @@ -1028,7 +1028,7 @@ type_t *get_type(env_t *env, ast_t *ast) binding_t *b = get_namespace_binding(env, value, "negative"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (fn->args && type_eq(t, get_arg_type(env, fn->args)) && type_eq(t, fn->ret)) return t; } @@ -1045,7 +1045,7 @@ type_t *get_type(env_t *env, ast_t *ast) ast_t *value = Match(ast, Not)->value; binding_t *b = get_namespace_binding(env, value, "negated"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (fn->args && type_eq(t, get_arg_type(env, fn->args)) && type_eq(t, fn->ret)) return t; } @@ -1213,7 +1213,7 @@ type_t *get_type(env_t *env, ast_t *ast) if (ast->tag == Multiply && is_numeric_type(lhs_t)) { binding_t *b = get_namespace_binding(env, binop.rhs, "scaled_by"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, rhs_t)) { arg_ast_t *args = new(arg_ast_t, .value=binop.rhs, .next=new(arg_ast_t, .value=binop.lhs)); if (is_valid_call(env, fn->args, args, true)) @@ -1223,7 +1223,7 @@ type_t *get_type(env_t *env, ast_t *ast) } else if (ast->tag == Multiply && is_numeric_type(rhs_t)) { binding_t *b = get_namespace_binding(env, binop.lhs, "scaled_by"); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, lhs_t)) { arg_ast_t *args = new(arg_ast_t, .value=binop.lhs, .next=new(arg_ast_t, .value=binop.rhs)); if (is_valid_call(env, fn->args, args, true)) @@ -1233,7 +1233,7 @@ type_t *get_type(env_t *env, ast_t *ast) } else if ((ast->tag == Divide || ast->tag == Mod || ast->tag == Mod1) && is_numeric_type(rhs_t)) { binding_t *b = get_namespace_binding(env, binop.lhs, binop_method_name(ast->tag)); if (b && b->type->tag == FunctionType) { - auto fn = Match(b->type, FunctionType); + DeclareMatch(fn, b->type, FunctionType); if (type_eq(fn->ret, lhs_t)) { arg_ast_t *args = new(arg_ast_t, .value=binop.lhs, .next=new(arg_ast_t, .value=binop.rhs)); if (is_valid_call(env, fn->args, args, true)) @@ -1273,7 +1273,7 @@ type_t *get_type(env_t *env, ast_t *ast) } case Reduction: { - auto reduction = Match(ast, Reduction); + DeclareMatch(reduction, ast, Reduction); type_t *iter_t = get_type(env, reduction->iter); if (reduction->op == Equals || reduction->op == NotEquals || reduction->op == LessThan @@ -1304,7 +1304,7 @@ type_t *get_type(env_t *env, ast_t *ast) } case Lambda: { - auto lambda = Match(ast, Lambda); + DeclareMatch(lambda, ast, Lambda); arg_t *args = NULL; env_t *scope = fresh_scope(env); // For now, just use closed variables in scope normally for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) { @@ -1342,14 +1342,14 @@ type_t *get_type(env_t *env, ast_t *ast) } case If: { - auto if_ = Match(ast, If); + DeclareMatch(if_, ast, If); if (!if_->else_body) return Type(VoidType); env_t *truthy_scope = env; env_t *falsey_scope = env; if (if_->condition->tag == Declare) { - auto decl = Match(if_->condition, Declare); + DeclareMatch(decl, if_->condition, Declare); type_t *condition_type = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); const char *varname = Match(decl->var, Var)->name; if (streq(varname, "_")) @@ -1382,7 +1382,7 @@ type_t *get_type(env_t *env, ast_t *ast) } case When: { - auto when = Match(ast, When); + DeclareMatch(when, ast, When); type_t *subject_t = get_type(env, when->subject); if (subject_t->tag != EnumType) { type_t *t = NULL; @@ -1478,7 +1478,7 @@ type_t *get_type(env_t *env, ast_t *ast) case While: case Repeat: case For: return Type(VoidType); case InlineCCode: { - auto inline_code = Match(ast, InlineCCode); + DeclareMatch(inline_code, ast, InlineCCode); if (inline_code->type) return inline_code->type; type_ast_t *type_ast = inline_code->type_ast; @@ -1596,7 +1596,7 @@ PUREFUNC bool can_be_mutated(env_t *env, ast_t *ast) case Var: return true; case InlineCCode: return true; case FieldAccess: { - auto access = Match(ast, FieldAccess); + DeclareMatch(access, ast, FieldAccess); type_t *fielded_type = get_type(env, access->fielded); if (fielded_type->tag == PointerType) { type_t *val = value_type(fielded_type); @@ -1608,7 +1608,7 @@ PUREFUNC bool can_be_mutated(env_t *env, ast_t *ast) } } case Index: { - auto index = Match(ast, Index); + DeclareMatch(index, ast, Index); type_t *indexed_type = get_type(env, index->indexed); return (indexed_type->tag == PointerType); } @@ -1627,13 +1627,13 @@ PUREFUNC bool is_constant(env_t *env, ast_t *ast) switch (ast->tag) { case Bool: case Num: case None: return true; case Int: { - auto info = Match(ast, Int); + DeclareMatch(info, ast, Int); Int_t int_val = Int$parse(Text$from_str(info->str)); if (int_val.small == 0) return false; // Failed to parse return (Int$compare_value(int_val, I(BIGGEST_SMALL_INT)) <= 0); } case TextJoin: { - auto text = Match(ast, TextJoin); + DeclareMatch(text, ast, TextJoin); if (!text->children) return true; // Empty string, OK if (text->children->next) return false; // Concatenation, not constant return is_constant(env, text->children->ast); @@ -1701,13 +1701,13 @@ PUREFUNC bool can_compile_to_type(env_t *env, ast_t *ast, type_t *needed) for (ast_list_t *entry = Match(ast, Table)->entries; entry; entry = entry->next) { if (entry->ast->tag != TableEntry) continue; // TODO: fix this - auto e = Match(entry->ast, TableEntry); + DeclareMatch(e, entry->ast, TableEntry); if (!can_compile_to_type(env, e->key, key_type) || !can_compile_to_type(env, e->value, value_type)) return false; } return true; } else if (needed->tag == PointerType) { - auto ptr = Match(needed, PointerType); + DeclareMatch(ptr, needed, PointerType); if (ast->tag == HeapAllocate) return !ptr->is_stack && can_compile_to_type(env, Match(ast, HeapAllocate)->value, ptr->pointed); else if (ast->tag == StackReference) diff --git a/src/types.c b/src/types.c index efd83477..14f6bc8e 100644 --- a/src/types.c +++ b/src/types.c @@ -34,15 +34,15 @@ CORD type_to_cord(type_t *t) { case IntType: return CORD_asprintf("Int%d", Match(t, IntType)->bits); case NumType: return Match(t, NumType)->bits == TYPE_NBITS32 ? "Num32" : "Num"; case ListType: { - auto list = Match(t, ListType); + DeclareMatch(list, t, ListType); return CORD_asprintf("[%r]", type_to_cord(list->item_type)); } case TableType: { - auto table = Match(t, TableType); + DeclareMatch(table, t, TableType); return CORD_all("{", type_to_cord(table->key_type), "=", type_to_cord(table->value_type), "}"); } case SetType: { - auto set = Match(t, SetType); + DeclareMatch(set, t, SetType); return CORD_asprintf("{%r}", type_to_cord(set->item_type)); } case ClosureType: { @@ -50,7 +50,7 @@ CORD type_to_cord(type_t *t) { } case FunctionType: { CORD c = "func("; - auto fn = Match(t, FunctionType); + DeclareMatch(fn, t, FunctionType); for (arg_t *arg = fn->args; arg; arg = arg->next) { c = CORD_cat(c, type_to_cord(arg->type)); if (arg->next) c = CORD_cat(c, ","); @@ -61,16 +61,16 @@ CORD type_to_cord(type_t *t) { return c; } case StructType: { - auto struct_ = Match(t, StructType); + DeclareMatch(struct_, t, StructType); return struct_->name; } case PointerType: { - auto ptr = Match(t, PointerType); + DeclareMatch(ptr, t, PointerType); CORD sigil = ptr->is_stack ? "&" : "@"; return CORD_all(sigil, type_to_cord(ptr->pointed)); } case EnumType: { - auto tagged = Match(t, EnumType); + DeclareMatch(tagged, t, EnumType); return tagged->name; } case OptionalType: { @@ -123,8 +123,8 @@ bool type_is_a(type_t *t, type_t *req) if (req->tag == OptionalType && Match(req, OptionalType)->type) return type_is_a(t, Match(req, OptionalType)->type); if (t->tag == PointerType && req->tag == PointerType) { - auto t_ptr = Match(t, PointerType); - auto req_ptr = Match(req, PointerType); + DeclareMatch(t_ptr, t, PointerType); + DeclareMatch(req_ptr, req, PointerType); if (type_eq(t_ptr->pointed, req_ptr->pointed)) return (!t_ptr->is_stack && req_ptr->is_stack) || (!t_ptr->is_stack); } @@ -279,7 +279,7 @@ PUREFUNC const char *enum_single_value_tag(type_t *enum_type, type_t *t) const char *found = NULL; for (tag_t *tag = Match(enum_type, EnumType)->tags; tag; tag = tag->next) { if (tag->type->tag != StructType) continue; - auto s = Match(tag->type, StructType); + DeclareMatch(s, tag->type, StructType); if (!s->fields || s->fields->next || !s->fields->type) continue; @@ -312,7 +312,7 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) return true; if (actual->tag == IntType && needed->tag == IntType) { - auto cmp = compare_precision(actual, needed); + precision_cmp_e cmp = compare_precision(actual, needed); return cmp == NUM_PRECISION_EQUAL || cmp == NUM_PRECISION_LESS; } @@ -349,8 +349,8 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) return true; if (needed->tag == PointerType && actual->tag == PointerType) { - auto needed_ptr = Match(needed, PointerType); - auto actual_ptr = Match(actual, PointerType); + DeclareMatch(needed_ptr, needed, PointerType); + DeclareMatch(actual_ptr, actual, PointerType); if (actual_ptr->is_stack && !needed_ptr->is_stack) // Can't use &x for a function that wants a @Foo or ?Foo @@ -376,8 +376,8 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) // Cross-promotion between tables with default values and without if (needed->tag == TableType && actual->tag == TableType) { - auto actual_table = Match(actual, TableType); - auto needed_table = Match(needed, TableType); + DeclareMatch(actual_table, actual, TableType); + DeclareMatch(needed_table, needed, TableType); if (type_eq(needed_table->key_type, actual_table->key_type) && type_eq(needed_table->value_type, actual_table->value_type)) return true; @@ -661,7 +661,7 @@ type_t *get_field_type(type_t *t, const char *field_name) return NULL; } case StructType: { - auto struct_t = Match(t, StructType); + DeclareMatch(struct_t, t, StructType); for (arg_t *field = struct_t->fields; field; field = field->next) { if (streq(field->name, field_name)) return field->type; @@ -669,7 +669,7 @@ type_t *get_field_type(type_t *t, const char *field_name) return NULL; } case EnumType: { - auto e = Match(t, EnumType); + DeclareMatch(e, t, EnumType); for (tag_t *tag = e->tags; tag; tag = tag->next) { if (streq(field_name, tag->name)) return Type(BoolType); @@ -712,7 +712,7 @@ PUREFUNC type_t *get_iterated_type(type_t *t) case TableType: return NULL; case FunctionType: case ClosureType: { // Iterator function - auto fn = iter_value_t->tag == ClosureType ? + __typeof(iter_value_t->__data.FunctionType) *fn = iter_value_t->tag == ClosureType ? Match(Match(iter_value_t, ClosureType)->fn, FunctionType) : Match(iter_value_t, FunctionType); if (fn->args || fn->ret->tag != OptionalType) return NULL; @@ -731,11 +731,11 @@ CONSTFUNC bool is_incomplete_type(type_t *t) case ListType: return is_incomplete_type(Match(t, ListType)->item_type); case SetType: return is_incomplete_type(Match(t, SetType)->item_type); case TableType: { - auto table = Match(t, TableType); + DeclareMatch(table, t, TableType); return is_incomplete_type(table->key_type) || is_incomplete_type(table->value_type); } case FunctionType: { - auto fn = Match(t, FunctionType); + DeclareMatch(fn, t, FunctionType); for (arg_t *arg = fn->args; arg; arg = arg->next) { if (arg->type == NULL || is_incomplete_type(arg->type)) return true; @@ -779,16 +779,16 @@ CONSTFUNC type_t *most_complete_type(type_t *t1, type_t *t2) return item ? Type(SetType, item) : NULL; } case TableType: { - auto table1 = Match(t1, TableType); - auto table2 = Match(t2, TableType); + DeclareMatch(table1, t1, TableType); + DeclareMatch(table2, t2, TableType); ast_t *default_value = table1->default_value ? table1->default_value : table2->default_value; type_t *key = most_complete_type(table1->key_type, table2->key_type); type_t *value = most_complete_type(table1->value_type, table2->value_type); return (key && value) ? Type(TableType, key, value, table1->env, default_value) : NULL; } case FunctionType: { - auto fn1 = Match(t1, FunctionType); - auto fn2 = Match(t2, FunctionType); + DeclareMatch(fn1, t1, FunctionType); + DeclareMatch(fn2, t2, FunctionType); arg_t *args = NULL; for (arg_t *arg1 = fn1->args, *arg2 = fn2->args; arg1 || arg2; arg1 = arg1->next, arg2 = arg2->next) { if (!arg1 || !arg2) @@ -807,8 +807,8 @@ CONSTFUNC type_t *most_complete_type(type_t *t1, type_t *t2) return fn ? Type(ClosureType, fn) : NULL; } case PointerType: { - auto ptr1 = Match(t1, PointerType); - auto ptr2 = Match(t2, PointerType); + DeclareMatch(ptr1, t1, PointerType); + DeclareMatch(ptr2, t2, PointerType); if (ptr1->is_stack != ptr2->is_stack) return NULL; type_t *pointed = most_complete_type(ptr1->pointed, ptr2->pointed); |
