#include #include #include #include "ast.h" #include "module.h" #include "parser.h" #include "resolver.h" #include "symtab.h" /* String representations of value types. */ const char *type_names[] = { [TYPE_VOID] = "void", [TYPE_I8] = "i8", [TYPE_I16] = "i16", [TYPE_I32] = "i32", [TYPE_U8] = "u8", [TYPE_U16] = "u16", [TYPE_U32] = "u32", [TYPE_F32] = "f32", [TYPE_BOOL] = "bool", [TYPE_FN] = "fn", [TYPE_UNION] = "union", [TYPE_RESULT] = "result", [TYPE_RECORD] = "record", [TYPE_ARRAY] = "array", [TYPE_SLICE] = "slice", [TYPE_PTR] = "pointer", [TYPE_OPT] = "optional", [TYPE_NEVER] = "never", [TYPE_OPAQUE] = "opaque" }; /* String representations of node classes. */ const char *node_names[] = { [NODE_TYPE] = "TYPE", [NODE_NUMBER] = "NUMBER", [NODE_BOOL] = "BOOL", [NODE_CHAR] = "CHAR", [NODE_STRING] = "STRING", [NODE_UNDEF] = "UNDEFINED", [NODE_NIL] = "NIL", [NODE_IDENT] = "IDENT", [NODE_SUPER] = "SUPER", [NODE_BINOP] = "BINOP", [NODE_UNOP] = "UNOP", [NODE_BLOCK] = "BLOCK", [NODE_CALL] = "CALL", [NODE_BUILTIN] = "BUILTIN", [NODE_CALL_ARG] = "ARG", [NODE_ASSIGN] = "ASSIGN", [NODE_PTR] = "PTR", [NODE_MOD] = "MOD", [NODE_MOD_BODY] = "MODULE", [NODE_PANIC] = "PANIC", [NODE_RETURN] = "RETURN", [NODE_THROW] = "THROW", [NODE_WHILE] = "WHILE", [NODE_WHILE_LET] = "WHILE_LET", [NODE_FOR] = "FOR", [NODE_LOOP] = "LOOP", [NODE_TRY] = "TRY", [NODE_IF] = "IF", [NODE_IF_LET] = "IF_LET", [NODE_IF_CASE] = "IF_CASE", [NODE_GUARD_CASE] = "GUARD_CASE", [NODE_GUARD_LET] = "GUARD_LET", [NODE_MATCH] = "SWITCH", [NODE_MATCH_CASE] = "SWITCH_CASE", [NODE_CATCH] = "CATCH", [NODE_FN] = "FUNCTION", [NODE_VAR] = "VAR", [NODE_CONST] = "CONST", [NODE_STATIC] = "STATIC", [NODE_REF] = "REF", [NODE_PARAM] = "PARAM", [NODE_ATTRIBUTE] = "ATTRIBUTE", [NODE_BREAK] = "BREAK", [NODE_EXPR_STMT] = "EXPR_STMT", [NODE_RECORD] = "RECORD", [NODE_RECORD_FIELD] = "RECORD_FIELD", [NODE_RECORD_TYPE] = "RECORD_TYPE", [NODE_UNION] = "UNION", [NODE_UNION_VARIANT] = "UNION_VARIANT", [NODE_RECORD_LIT] = "RECORD_LIT", [NODE_RECORD_LIT_FIELD] = "RECORD_LIT_FIELD", [NODE_ARRAY_LIT] = "ARRAY_LIT", [NODE_ARRAY_INDEX] = "ARRAY_INDEX", [NODE_ACCESS] = "ACCESS", [NODE_SCOPE] = "SCOPE", [NODE_AS] = "AS", [NODE_RANGE] = "RANGE", [NODE_USE] = "USE", [NODE_PLACEHOLDER] = "PLACEHOLDER", }; /* Check if the node is a binary comparison operation. */ bool node_is_comp(node_t *n) { if (n->cls != NODE_BINOP) return false; binop_t op = n->val.binop.op; return op == OP_EQ || op == OP_NE || op == OP_LT || op == OP_GT || op == OP_LE || op == OP_GE || op == OP_AND || op == OP_OR; } /* Check if the node is a literal value. */ bool node_is_literal(node_t *n) { switch (n->cls) { case NODE_ARRAY_LIT: case NODE_ARRAY_REPEAT_LIT: case NODE_RECORD_LIT: case NODE_UNION_VARIANT: case NODE_NUMBER: case NODE_BOOL: case NODE_STRING: case NODE_CHAR: case NODE_NIL: case NODE_UNDEF: return true; default: return false; } } /* Check if the binary operator is a logical one. */ bool op_is_logical(binop_t op) { return op == OP_AND || op == OP_OR; } /* Access node pointers from a span. */ node_t **nodespan_ptrs(parser_t *p, nodespan_t span) { return &p->ptrs[span.idx]; } /* Allocate a new span from the parser's pointer pool. */ nodespan_t nodespan_alloc(parser_t *p, u16 cap) { nodespan_t span = { .idx = (u32)p->nptrs, .len = 0, .cap = cap }; p->nptrs += cap; return span; } /* Append a node to a span. Returns false on overflow. */ bool nodespan_push(parser_t *p, nodespan_t *span, node_t *node) { if (span->len >= span->cap) { u16 newcap = span->cap == 0 ? 8 : span->cap * 2; if (p->nptrs + newcap > MAX_NODEPTR_POOL) { return false; } u32 newidx = (u32)p->nptrs; for (u16 i = 0; i < span->len; i++) { p->ptrs[newidx + i] = p->ptrs[span->idx + i]; } span->idx = newidx; span->cap = newcap; p->nptrs += newcap; } p->ptrs[span->idx + span->len++] = node; return true; } /* Add a statement to a block node using module's parser. */ void node_block_add_stmt(module_t *mod, node_t *block, node_t *stmt) { nodespan_push(&mod->parser, &block->val.block.stmts, stmt); } void node_fn_add_param(parser_t *p, node_t *fn, node_t *param) { nodespan_push(p, &fn->val.fn_decl.params, param); }