diff options
Diffstat (limited to 'src/ast.c')
| -rw-r--r-- | src/ast.c | 375 |
1 files changed, 223 insertions, 152 deletions
@@ -7,43 +7,66 @@ #include "stdlib/tables.h" #include "stdlib/text.h" -static Text_t quoted_text(const char *text) { - return Text$quoted(Text$from_str(text), false, Text("\"")); -} +static Text_t quoted_text(const char *text) { return Text$quoted(Text$from_str(text), false, Text("\"")); } CONSTFUNC const char *binop_method_name(ast_e tag) { switch (tag) { - case Power: case PowerUpdate: return "power"; - case Multiply: case MultiplyUpdate: return "times"; - case Divide: case DivideUpdate: return "divided_by"; - case Mod: case ModUpdate: return "modulo"; - case Mod1: case Mod1Update: return "modulo1"; - case Plus: case PlusUpdate: return "plus"; - case Minus: case MinusUpdate: return "minus"; - case Concat: case ConcatUpdate: return "concatenated_with"; - case LeftShift: case LeftShiftUpdate: return "left_shifted"; - case RightShift: case RightShiftUpdate: return "right_shifted"; - case UnsignedLeftShift: case UnsignedLeftShiftUpdate: return "unsigned_left_shifted"; - case UnsignedRightShift: case UnsignedRightShiftUpdate: return "unsigned_right_shifted"; - case And: case AndUpdate: return "bit_and"; - case Or: case OrUpdate: return "bit_or"; - case Xor: case XorUpdate: return "bit_xor"; + case Power: + case PowerUpdate: return "power"; + case Multiply: + case MultiplyUpdate: return "times"; + case Divide: + case DivideUpdate: return "divided_by"; + case Mod: + case ModUpdate: return "modulo"; + case Mod1: + case Mod1Update: return "modulo1"; + case Plus: + case PlusUpdate: return "plus"; + case Minus: + case MinusUpdate: return "minus"; + case Concat: + case ConcatUpdate: return "concatenated_with"; + case LeftShift: + case LeftShiftUpdate: return "left_shifted"; + case RightShift: + case RightShiftUpdate: return "right_shifted"; + case UnsignedLeftShift: + case UnsignedLeftShiftUpdate: return "unsigned_left_shifted"; + case UnsignedRightShift: + case UnsignedRightShiftUpdate: return "unsigned_right_shifted"; + case And: + case AndUpdate: return "bit_and"; + case Or: + case OrUpdate: return "bit_or"; + case Xor: + case XorUpdate: return "bit_xor"; default: return NULL; } }; CONSTFUNC const char *binop_operator(ast_e tag) { switch (tag) { - case Multiply: case MultiplyUpdate: return "*"; - case Divide: case DivideUpdate: return "/"; - case Mod: case ModUpdate: return "%"; - case Plus: case PlusUpdate: return "+"; - case Minus: case MinusUpdate: return "-"; - case LeftShift: case LeftShiftUpdate: return "<<"; - case RightShift: case RightShiftUpdate: return ">>"; - case And: case AndUpdate: return "&"; - case Or: case OrUpdate: return "|"; - case Xor: case XorUpdate: return "^"; + case Multiply: + case MultiplyUpdate: return "*"; + case Divide: + case DivideUpdate: return "/"; + case Mod: + case ModUpdate: return "%"; + case Plus: + case PlusUpdate: return "+"; + case Minus: + case MinusUpdate: return "-"; + case LeftShift: + case LeftShiftUpdate: return "<<"; + case RightShift: + case RightShiftUpdate: return ">>"; + case And: + case AndUpdate: return "&"; + case Or: + case OrUpdate: return "|"; + case Xor: + case XorUpdate: return "^"; case Equals: return "=="; case NotEquals: return "!="; case LessThan: return "<"; @@ -62,8 +85,7 @@ static Text_t tags_to_sexp(tag_ast_t *tags); static Text_t optional_sexp(const char *tag, ast_t *ast); static Text_t optional_type_sexp(const char *tag, type_ast_t *ast); -Text_t ast_list_to_sexp(ast_list_t *asts) -{ +Text_t ast_list_to_sexp(ast_list_t *asts) { Text_t c = EMPTY_TEXT; for (; asts; asts = asts->next) { c = Texts(c, " ", ast_to_sexp(asts->ast)); @@ -74,8 +96,8 @@ Text_t ast_list_to_sexp(ast_list_t *asts) Text_t arg_defs_to_sexp(arg_ast_t *args) { Text_t c = Text("(args"); for (arg_ast_t *arg = args; arg; arg = arg->next) { - c = Texts(c, " (arg ", arg->name ? quoted_text(arg->name) : Text("nil"), - " ", type_ast_to_sexp(arg->type), " ", ast_to_sexp(arg->value), ")"); + c = Texts(c, " (arg ", arg->name ? quoted_text(arg->name) : Text("nil"), " ", type_ast_to_sexp(arg->type), " ", + ast_to_sexp(arg->value), ")"); } return Texts(c, ")"); } @@ -84,8 +106,7 @@ Text_t arg_list_to_sexp(arg_ast_t *args) { Text_t c = EMPTY_TEXT; for (arg_ast_t *arg = args; arg; arg = arg->next) { assert(arg->value && !arg->type); - if (arg->name) - c = Texts(c, " :", arg->name); + if (arg->name) c = Texts(c, " :", arg->name); c = Texts(c, " ", ast_to_sexp(arg->value)); } return c; @@ -107,118 +128,163 @@ Text_t tags_to_sexp(tag_ast_t *tags) { return c; } -Text_t type_ast_to_sexp(type_ast_t *t) -{ +Text_t type_ast_to_sexp(type_ast_t *t) { if (!t) return Text("nil"); switch (t->tag) { -#define T(type, ...) case type: { __typeof(t->__data.type) data = t->__data.type; (void)data; return Texts(__VA_ARGS__); } - T(UnknownTypeAST, "(UnknownType)") - T(VarTypeAST, "(VarType \"", data.name, "\")") - T(PointerTypeAST, "(PointerType \"", data.is_stack ? "stack" : "heap", "\" ", type_ast_to_sexp(data.pointed), ")") - T(ListTypeAST, "(ListType ", type_ast_to_sexp(data.item), ")") - T(SetTypeAST, "(SetType ", type_ast_to_sexp(data.item), ")") - T(TableTypeAST, "(TableType ", type_ast_to_sexp(data.key), " ", type_ast_to_sexp(data.value), ")") - T(FunctionTypeAST, "(FunctionType ", arg_defs_to_sexp(data.args), " ", type_ast_to_sexp(data.ret), ")") - T(OptionalTypeAST, "(OptionalType ", type_ast_to_sexp(data.type), ")") +#define T(type, ...) \ + case type: { \ + __typeof(t->__data.type) data = t->__data.type; \ + (void)data; \ + return Texts(__VA_ARGS__); \ + } + T(UnknownTypeAST, "(UnknownType)"); + T(VarTypeAST, "(VarType \"", data.name, "\")"); + T(PointerTypeAST, "(PointerType \"", data.is_stack ? "stack" : "heap", "\" ", type_ast_to_sexp(data.pointed), + ")"); + T(ListTypeAST, "(ListType ", type_ast_to_sexp(data.item), ")"); + T(SetTypeAST, "(SetType ", type_ast_to_sexp(data.item), ")"); + T(TableTypeAST, "(TableType ", type_ast_to_sexp(data.key), " ", type_ast_to_sexp(data.value), ")"); + T(FunctionTypeAST, "(FunctionType ", arg_defs_to_sexp(data.args), " ", type_ast_to_sexp(data.ret), ")"); + T(OptionalTypeAST, "(OptionalType ", type_ast_to_sexp(data.type), ")"); #undef T default: return EMPTY_TEXT; } } -Text_t optional_sexp(const char *name, ast_t *ast) -{ +Text_t optional_sexp(const char *name, ast_t *ast) { return ast ? Texts(" :", name, " ", ast_to_sexp(ast)) : EMPTY_TEXT; } -Text_t optional_type_sexp(const char *name, type_ast_t *ast) -{ +Text_t optional_type_sexp(const char *name, type_ast_t *ast) { return ast ? Texts(" :", name, " ", type_ast_to_sexp(ast)) : EMPTY_TEXT; } -Text_t ast_to_sexp(ast_t *ast) -{ +Text_t ast_to_sexp(ast_t *ast) { if (!ast) return Text("nil"); switch (ast->tag) { -#define T(type, ...) case type: { __typeof(ast->__data.type) data = ast->__data.type; (void)data; return Texts(__VA_ARGS__); } - T(Unknown, "(Unknown)") - T(None, "(None)") - T(Bool, "(Bool ", data.b ? "yes" : "no", ")") - T(Var, "(Var ", quoted_text(data.name), ")") - T(Int, "(Int ", quoted_text(ast_source(ast)), ")") - T(Num, "(Num ", quoted_text(ast_source(ast)), ")") - T(TextLiteral, Text$quoted(data.text, false, Text("\""))) - T(TextJoin, "(Text", data.lang ? Texts(" :lang ", quoted_text(data.lang)) : EMPTY_TEXT, ast_list_to_sexp(data.children), ")") - T(Path, "(Path ", quoted_text(data.path), ")") - T(Declare, "(Declare ", ast_to_sexp(data.var), " ", type_ast_to_sexp(data.type), " ", ast_to_sexp(data.value), ")") - T(Assign, "(Assign (targets ", ast_list_to_sexp(data.targets), ") (values ", ast_list_to_sexp(data.values), "))") +#define T(type, ...) \ + case type: { \ + __typeof(ast->__data.type) data = ast->__data.type; \ + (void)data; \ + return Texts(__VA_ARGS__); \ + } + T(Unknown, "(Unknown)"); + T(None, "(None)"); + T(Bool, "(Bool ", data.b ? "yes" : "no", ")"); + T(Var, "(Var ", quoted_text(data.name), ")"); + T(Int, "(Int ", quoted_text(ast_source(ast)), ")"); + T(Num, "(Num ", quoted_text(ast_source(ast)), ")"); + T(TextLiteral, Text$quoted(data.text, false, Text("\""))); + T(TextJoin, "(Text", data.lang ? Texts(" :lang ", quoted_text(data.lang)) : EMPTY_TEXT, + ast_list_to_sexp(data.children), ")"); + T(Path, "(Path ", quoted_text(data.path), ")"); + T(Declare, "(Declare ", ast_to_sexp(data.var), " ", type_ast_to_sexp(data.type), " ", ast_to_sexp(data.value), + ")"); + T(Assign, "(Assign (targets ", ast_list_to_sexp(data.targets), ") (values ", ast_list_to_sexp(data.values), + "))"); #define BINOP(name) T(name, "(" #name " ", ast_to_sexp(data.lhs), " ", ast_to_sexp(data.rhs), ")") - BINOP(Power) BINOP(PowerUpdate) BINOP(Multiply) BINOP(MultiplyUpdate) BINOP(Divide) BINOP(DivideUpdate) BINOP(Mod) BINOP(ModUpdate) - BINOP(Mod1) BINOP(Mod1Update) BINOP(Plus) BINOP(PlusUpdate) BINOP(Minus) BINOP(MinusUpdate) BINOP(Concat) BINOP(ConcatUpdate) - BINOP(LeftShift) BINOP(LeftShiftUpdate) BINOP(RightShift) BINOP(RightShiftUpdate) BINOP(UnsignedLeftShift) BINOP(UnsignedLeftShiftUpdate) - BINOP(UnsignedRightShift) BINOP(UnsignedRightShiftUpdate) BINOP(And) BINOP(AndUpdate) BINOP(Or) BINOP(OrUpdate) - BINOP(Xor) BINOP(XorUpdate) BINOP(Compare) - BINOP(Equals) BINOP(NotEquals) BINOP(LessThan) BINOP(LessThanOrEquals) BINOP(GreaterThan) BINOP(GreaterThanOrEquals) + BINOP(Power); + BINOP(PowerUpdate); + BINOP(Multiply); + BINOP(MultiplyUpdate); + BINOP(Divide); + BINOP(DivideUpdate); + BINOP(Mod); + BINOP(ModUpdate); + BINOP(Mod1); + BINOP(Mod1Update); + BINOP(Plus); + BINOP(PlusUpdate); + BINOP(Minus); + BINOP(MinusUpdate); + BINOP(Concat); + BINOP(ConcatUpdate); + BINOP(LeftShift); + BINOP(LeftShiftUpdate); + BINOP(RightShift); + BINOP(RightShiftUpdate); + BINOP(UnsignedLeftShift); + BINOP(UnsignedLeftShiftUpdate); + BINOP(UnsignedRightShift); + BINOP(UnsignedRightShiftUpdate); + BINOP(And); + BINOP(AndUpdate); + BINOP(Or); + BINOP(OrUpdate); + BINOP(Xor); + BINOP(XorUpdate); + BINOP(Compare); + BINOP(Equals); + BINOP(NotEquals); + BINOP(LessThan); + BINOP(LessThanOrEquals); + BINOP(GreaterThan); + BINOP(GreaterThanOrEquals); #undef BINOP - T(Negative, "(Negative ", ast_to_sexp(data.value), ")") - T(Not, "(Not ", ast_to_sexp(data.value), ")") - T(HeapAllocate, "(HeapAllocate ", ast_to_sexp(data.value), ")") - T(StackReference, "(StackReference ", ast_to_sexp(data.value), ")") - T(Min, "(Min ", ast_to_sexp(data.lhs), " ", ast_to_sexp(data.rhs), optional_sexp("key", data.key), ")") - T(Max, "(Max ", ast_to_sexp(data.lhs), " ", ast_to_sexp(data.rhs), optional_sexp("key", data.key), ")") - T(List, "(List", ast_list_to_sexp(data.items), ")") - T(Set, "(Set", ast_list_to_sexp(data.items), ")") - T(Table, "(Table", optional_sexp("default", data.default_value), optional_sexp("fallback", data.fallback), - ast_list_to_sexp(data.entries), ")") - T(TableEntry, "(TableEntry ", ast_to_sexp(data.key), " ", ast_to_sexp(data.value), ")") - T(Comprehension, "(Comprehension ", ast_to_sexp(data.expr), " (vars", ast_list_to_sexp(data.vars), ") ", - ast_to_sexp(data.iter), " ", optional_sexp("filter", data.filter), ")") - T(FunctionDef, "(FunctionDef ", ast_to_sexp(data.name), " ", arg_defs_to_sexp(data.args), - optional_type_sexp("return", data.ret_type), " ", ast_to_sexp(data.body), ")") - T(ConvertDef, "(ConvertDef ", arg_defs_to_sexp(data.args), " ", type_ast_to_sexp(data.ret_type), " ", ast_to_sexp(data.body), ")") - T(Lambda, "(Lambda ", arg_defs_to_sexp(data.args), optional_type_sexp("return", data.ret_type), " ", ast_to_sexp(data.body), ")") - T(FunctionCall, "(FunctionCall ", ast_to_sexp(data.fn), arg_list_to_sexp(data.args), ")") - T(MethodCall, "(MethodCall ", ast_to_sexp(data.self), " ", quoted_text(data.name), arg_list_to_sexp(data.args), ")") - T(Block, "(Block", ast_list_to_sexp(data.statements), ")") - T(For, "(For (vars", ast_list_to_sexp(data.vars), ") ", ast_to_sexp(data.iter), " ", ast_to_sexp(data.body), - " ", ast_to_sexp(data.empty), ")") - T(While, "(While ", ast_to_sexp(data.condition), " ", ast_to_sexp(data.body), ")") - T(Repeat, "(Repeat ", ast_to_sexp(data.body), ")") - T(If, "(If ", ast_to_sexp(data.condition), " ", ast_to_sexp(data.body), optional_sexp("else", data.else_body), ")") - T(When, "(When ", ast_to_sexp(data.subject), when_clauses_to_sexp(data.clauses), optional_sexp("else", data.else_body), ")") - T(Reduction, "(Reduction ", quoted_text(binop_method_name(data.op)), " ", ast_to_sexp(data.key), " ", ast_to_sexp(data.iter), ")") - T(Skip, "(Skip ", quoted_text(data.target), ")") - T(Stop, "(Stop ", quoted_text(data.target), ")") - T(Pass, "(Pass)") - T(Defer, "(Defer ", ast_to_sexp(data.body), ")") - T(Return, "(Return ", ast_to_sexp(data.value), ")") - T(Extern, "(Extern \"", data.name, "\" ", type_ast_to_sexp(data.type), ")") - T(StructDef, "(StructDef \"", data.name, "\" ", arg_defs_to_sexp(data.fields), " ", ast_to_sexp(data.namespace), ")") - T(EnumDef, "(EnumDef \"", data.name, "\" (tags ", tags_to_sexp(data.tags), ") ", ast_to_sexp(data.namespace), ")") - T(LangDef, "(LangDef \"", data.name, "\" ", ast_to_sexp(data.namespace), ")") - T(Index, "(Index ", ast_to_sexp(data.indexed), " ", ast_to_sexp(data.index), ")") - T(FieldAccess, "(FieldAccess ", ast_to_sexp(data.fielded), " \"", data.field, "\")") - T(Optional, "(Optional ", ast_to_sexp(data.value), ")") - T(NonOptional, "(NonOptional ", ast_to_sexp(data.value), ")") - T(DocTest, "(DocTest ", ast_to_sexp(data.expr), optional_sexp("expected", data.expected), ")") - T(Assert, "(Assert ", ast_to_sexp(data.expr), " ", optional_sexp("message", data.message), ")") - T(Use, "(Use ", optional_sexp("var", data.var), " ", quoted_text(data.path), ")") - T(InlineCCode, "(InlineCCode ", ast_list_to_sexp(data.chunks), optional_type_sexp("type", data.type_ast), ")") - T(Deserialize, "(Deserialize ", type_ast_to_sexp(data.type), " ", ast_to_sexp(data.value), ")") - T(Extend, "(Extend \"", data.name, "\" ", ast_to_sexp(data.body), ")") - default: errx(1, "S-expressions are not implemented for this AST"); + T(Negative, "(Negative ", ast_to_sexp(data.value), ")"); + T(Not, "(Not ", ast_to_sexp(data.value), ")"); + T(HeapAllocate, "(HeapAllocate ", ast_to_sexp(data.value), ")"); + T(StackReference, "(StackReference ", ast_to_sexp(data.value), ")"); + T(Min, "(Min ", ast_to_sexp(data.lhs), " ", ast_to_sexp(data.rhs), optional_sexp("key", data.key), ")"); + T(Max, "(Max ", ast_to_sexp(data.lhs), " ", ast_to_sexp(data.rhs), optional_sexp("key", data.key), ")"); + T(List, "(List", ast_list_to_sexp(data.items), ")"); + T(Set, "(Set", ast_list_to_sexp(data.items), ")"); + T(Table, "(Table", optional_sexp("default", data.default_value), optional_sexp("fallback", data.fallback), + ast_list_to_sexp(data.entries), ")"); + T(TableEntry, "(TableEntry ", ast_to_sexp(data.key), " ", ast_to_sexp(data.value), ")"); + T(Comprehension, "(Comprehension ", ast_to_sexp(data.expr), " (vars", ast_list_to_sexp(data.vars), ") ", + ast_to_sexp(data.iter), " ", optional_sexp("filter", data.filter), ")"); + T(FunctionDef, "(FunctionDef ", ast_to_sexp(data.name), " ", arg_defs_to_sexp(data.args), + optional_type_sexp("return", data.ret_type), " ", ast_to_sexp(data.body), ")"); + T(ConvertDef, "(ConvertDef ", arg_defs_to_sexp(data.args), " ", type_ast_to_sexp(data.ret_type), " ", + ast_to_sexp(data.body), ")"); + T(Lambda, "(Lambda ", arg_defs_to_sexp(data.args), optional_type_sexp("return", data.ret_type), " ", + ast_to_sexp(data.body), ")"); + T(FunctionCall, "(FunctionCall ", ast_to_sexp(data.fn), arg_list_to_sexp(data.args), ")"); + T(MethodCall, "(MethodCall ", ast_to_sexp(data.self), " ", quoted_text(data.name), arg_list_to_sexp(data.args), + ")") + T(Block, "(Block", ast_list_to_sexp(data.statements), ")"); + T(For, "(For (vars", ast_list_to_sexp(data.vars), ") ", ast_to_sexp(data.iter), " ", ast_to_sexp(data.body), + " ", ast_to_sexp(data.empty), ")"); + T(While, "(While ", ast_to_sexp(data.condition), " ", ast_to_sexp(data.body), ")"); + T(Repeat, "(Repeat ", ast_to_sexp(data.body), ")"); + T(If, "(If ", ast_to_sexp(data.condition), " ", ast_to_sexp(data.body), optional_sexp("else", data.else_body), + ")"); + T(When, "(When ", ast_to_sexp(data.subject), when_clauses_to_sexp(data.clauses), + optional_sexp("else", data.else_body), ")"); + T(Reduction, "(Reduction ", quoted_text(binop_method_name(data.op)), " ", ast_to_sexp(data.key), " ", + ast_to_sexp(data.iter), ")"); + T(Skip, "(Skip ", quoted_text(data.target), ")"); + T(Stop, "(Stop ", quoted_text(data.target), ")"); + T(Pass, "(Pass)"); + T(Defer, "(Defer ", ast_to_sexp(data.body), ")"); + T(Return, "(Return ", ast_to_sexp(data.value), ")"); + T(Extern, "(Extern \"", data.name, "\" ", type_ast_to_sexp(data.type), ")"); + T(StructDef, "(StructDef \"", data.name, "\" ", arg_defs_to_sexp(data.fields), " ", ast_to_sexp(data.namespace), + ")"); + T(EnumDef, "(EnumDef \"", data.name, "\" (tags ", tags_to_sexp(data.tags), ") ", ast_to_sexp(data.namespace), + ")"); + T(LangDef, "(LangDef \"", data.name, "\" ", ast_to_sexp(data.namespace), ")"); + T(Index, "(Index ", ast_to_sexp(data.indexed), " ", ast_to_sexp(data.index), ")"); + T(FieldAccess, "(FieldAccess ", ast_to_sexp(data.fielded), " \"", data.field, "\")"); + T(Optional, "(Optional ", ast_to_sexp(data.value), ")"); + T(NonOptional, "(NonOptional ", ast_to_sexp(data.value), ")"); + T(DocTest, "(DocTest ", ast_to_sexp(data.expr), optional_sexp("expected", data.expected), ")"); + T(Assert, "(Assert ", ast_to_sexp(data.expr), " ", optional_sexp("message", data.message), ")"); + T(Use, "(Use ", optional_sexp("var", data.var), " ", quoted_text(data.path), ")"); + T(InlineCCode, "(InlineCCode ", ast_list_to_sexp(data.chunks), optional_type_sexp("type", data.type_ast), ")"); + T(Deserialize, "(Deserialize ", type_ast_to_sexp(data.type), " ", ast_to_sexp(data.value), ")"); + T(Extend, "(Extend \"", data.name, "\" ", ast_to_sexp(data.body), ")"); + default: errx(1, "S-expressions are not implemented for this AST"); #undef T } } -const char *ast_to_sexp_str(ast_t *ast) -{ - return Text$as_c_string(ast_to_sexp(ast)); -} +const char *ast_to_sexp_str(ast_t *ast) { return Text$as_c_string(ast_to_sexp(ast)); } -const char *ast_source(ast_t *ast) -{ +const char *ast_source(ast_t *ast) { if (!ast) return NULL; size_t len = (size_t)(ast->end - ast->start); char *source = GC_MALLOC_ATOMIC(len + 1); @@ -227,10 +293,14 @@ const char *ast_source(ast_t *ast) return source; } -PUREFUNC bool is_idempotent(ast_t *ast) -{ +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 Int: + case Bool: + case Num: + case Var: + case None: + case TextLiteral: return true; case Index: { DeclareMatch(index, ast, Index); return is_idempotent(index->indexed) && index->index != NULL && is_idempotent(index->index); @@ -243,15 +313,13 @@ PUREFUNC bool is_idempotent(ast_t *ast) } } -void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Closure_t fn) -{ - void (*visit)(void*, ast_t*) = (void*)fn.fn; +void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Closure_t fn) { + void (*visit)(void *, ast_t *) = (void *)fn.fn; if (ast->tag == StructDef) { DeclareMatch(def, ast, StructDef); - if (Table$str_get(*visited, def->name)) - return; + if (Table$str_get(*visited, def->name)) return; - Table$str_set(visited, def->name, (void*)_visit_topologically); + Table$str_set(visited, def->name, (void *)_visit_topologically); for (arg_ast_t *field = def->fields; field; field = field->next) { if (field->type && field->type->tag == VarTypeAST) { const char *field_type_name = Match(field->type, VarTypeAST)->name; @@ -260,15 +328,13 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo _visit_topologically(dependency, definitions, visited, fn); } } - } visit(fn.userdata, ast); } else if (ast->tag == EnumDef) { DeclareMatch(def, ast, EnumDef); - if (Table$str_get(*visited, def->name)) - return; + if (Table$str_get(*visited, def->name)) return; - Table$str_set(visited, def->name, (void*)_visit_topologically); + Table$str_set(visited, def->name, (void *)_visit_topologically); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { for (arg_ast_t *field = tag->fields; field; field = field->next) { if (field->type && field->type->tag == VarTypeAST) { @@ -283,16 +349,14 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo visit(fn.userdata, ast); } else if (ast->tag == LangDef) { DeclareMatch(def, ast, LangDef); - if (Table$str_get(*visited, def->name)) - return; + if (Table$str_get(*visited, def->name)) return; visit(fn.userdata, ast); } else { visit(fn.userdata, ast); } } -void visit_topologically(ast_list_t *asts, Closure_t fn) -{ +void visit_topologically(ast_list_t *asts, Closure_t fn) { // Visit each top-level statement in topological order: // - 'use' statements first // - then typedefs @@ -313,12 +377,11 @@ void visit_topologically(ast_list_t *asts, Closure_t fn) } } - void (*visit)(void*, ast_t*) = (void*)fn.fn; + void (*visit)(void *, ast_t *) = (void *)fn.fn; Table_t visited = {}; // First: 'use' statements in order: for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { - if (stmt->ast->tag == Use) - visit(fn.userdata, stmt->ast); + if (stmt->ast->tag == Use) visit(fn.userdata, stmt->ast); } // Then typedefs in topological order: for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { @@ -334,27 +397,35 @@ void visit_topologically(ast_list_t *asts, Closure_t fn) } } -CONSTFUNC bool is_binary_operation(ast_t *ast) -{ +CONSTFUNC bool is_binary_operation(ast_t *ast) { switch (ast->tag) { case BINOP_CASES: return true; default: return false; } } -CONSTFUNC bool is_update_assignment(ast_t *ast) -{ +CONSTFUNC bool is_update_assignment(ast_t *ast) { switch (ast->tag) { - case PowerUpdate: case MultiplyUpdate: case DivideUpdate: case ModUpdate: case Mod1Update: - case PlusUpdate: case MinusUpdate: case ConcatUpdate: case LeftShiftUpdate: case UnsignedLeftShiftUpdate: - case RightShiftUpdate: case UnsignedRightShiftUpdate: case AndUpdate: case OrUpdate: case XorUpdate: - return true; + case PowerUpdate: + case MultiplyUpdate: + case DivideUpdate: + case ModUpdate: + case Mod1Update: + case PlusUpdate: + case MinusUpdate: + case ConcatUpdate: + case LeftShiftUpdate: + case UnsignedLeftShiftUpdate: + case RightShiftUpdate: + case UnsignedRightShiftUpdate: + case AndUpdate: + case OrUpdate: + case XorUpdate: return true; default: return false; } } -CONSTFUNC ast_e binop_tag(ast_e tag) -{ +CONSTFUNC ast_e binop_tag(ast_e tag) { switch (tag) { case PowerUpdate: return Power; case MultiplyUpdate: return Multiply; |
