aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-15 19:36:23 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-15 19:36:23 -0400
commitc3615dc92c667899af7a11b2b25201dad5502ee6 (patch)
treebdc5db2b7c1cda415ef58eabd6c6dd23237d0ad6 /src
parent9c1a7c473d96b80561a845bf15ecfd42cd980135 (diff)
Deprecate `auto`
Diffstat (limited to 'src')
-rw-r--r--src/ast.c20
-rw-r--r--src/ast.h3
-rw-r--r--src/compile.c214
-rw-r--r--src/enums.c6
-rw-r--r--src/environment.c20
-rw-r--r--src/parse.c4
-rw-r--r--src/repl.c28
-rw-r--r--src/stdlib/lists.c4
-rw-r--r--src/stdlib/pointers.c2
-rw-r--r--src/stdlib/tables.c6
-rw-r--r--src/stdlib/types.h22
-rw-r--r--src/stdlib/util.h4
-rw-r--r--src/structs.c2
-rw-r--r--src/tomo.c12
-rw-r--r--src/typecheck.c112
-rw-r--r--src/types.c52
16 files changed, 258 insertions, 253 deletions
diff --git a/src/ast.c b/src/ast.c
index 2d564d98..3380d927 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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);
}
}
diff --git a/src/ast.h b/src/ast.h
index 44698628..2e1a035a 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -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; })
diff --git a/src/repl.c b/src/repl.c
index aae80b2c..6ac07936 100644
--- a/src/repl.c
+++ b/src/repl.c
@@ -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");
diff --git a/src/tomo.c b/src/tomo.c
index 347efc98..f4ab6b76 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -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);