From: Brendan Hansen Date: Fri, 3 Jul 2020 04:30:39 +0000 (-0500) Subject: Refactored the AST node structure X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=98519319f1a692db706694964df35902884a7a93;p=onyx.git Refactored the AST node structure This involved rewriting a lot of the code that was there --- diff --git a/include/onyxlex.h b/include/onyxlex.h index 559a2030..ed65258e 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -3,7 +3,7 @@ #include "bh.h" -typedef enum OnyxTokenType { +typedef enum TokenType { TOKEN_TYPE_UNKNOWN, TOKEN_TYPE_END_STREAM, @@ -61,7 +61,7 @@ typedef enum OnyxTokenType { TOKEN_TYPE_LITERAL_BOOL_FALSE, TOKEN_TYPE_COUNT -} OnyxTokenType; +} TokenType; typedef struct OnyxFilePos { const char* filename; @@ -69,7 +69,7 @@ typedef struct OnyxFilePos { } OnyxFilePos; typedef struct OnyxToken { - OnyxTokenType type; + TokenType type; i32 length; char* token; OnyxFilePos pos; @@ -86,8 +86,8 @@ typedef struct OnyxTokenizer { bh_arr(OnyxToken) tokens; } OnyxTokenizer; -const char* onyx_get_token_type_name(OnyxTokenType tkn_type); -void onyx_token_null_toggle(OnyxToken tkn); +const char* onyx_get_token_type_name(TokenType tkn_type); +void onyx_token_null_toggle(OnyxToken* tkn); OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer); OnyxTokenizer onyx_tokenizer_create(bh_allocator allocator, bh_file_contents *fc); void onyx_tokenizer_free(OnyxTokenizer* tokenizer); diff --git a/include/onyxparser.h b/include/onyxparser.h index 1adf8287..095797a4 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -6,21 +6,24 @@ #include "onyxlex.h" #include "onyxmsgs.h" -typedef union OnyxAstNode OnyxAstNode; -typedef struct OnyxAstNodeUnaryOp OnyxAstNodeUnaryOp; -typedef struct OnyxAstNodeBinOp OnyxAstNodeBinOp; -typedef struct OnyxAstNodeNumLit OnyxAstNodeNumLit; -typedef struct OnyxAstNodeLocal OnyxAstNodeLocal; -typedef struct OnyxAstNodeScope OnyxAstNodeScope; -typedef struct OnyxAstNodeBlock OnyxAstNodeBlock; -typedef struct OnyxAstNodeIf OnyxAstNodeIf; -typedef struct OnyxAstNodeWhile OnyxAstNodeWhile; -typedef struct OnyxAstNodeParam OnyxAstNodeParam; -typedef struct OnyxAstNodeFunction OnyxAstNodeFunction; -typedef struct OnyxAstNodeForeign OnyxAstNodeForeign; -typedef struct OnyxAstNodeGlobal OnyxAstNodeGlobal; -typedef struct OnyxAstNodeCall OnyxAstNodeCall; -typedef struct OnyxAstNodeUse OnyxAstNodeUse; +typedef struct AstNode AstNode; +typedef struct AstNodeTyped AstNodeTyped; +typedef struct AstNodeUnaryOp AstNodeUnaryOp; +typedef struct AstNodeBinOp AstNodeBinOp; +typedef struct AstNodeAssign AstNodeAssign; +typedef struct AstNodeNumLit AstNodeNumLit; +typedef struct AstNodeLocal AstNodeLocal; +typedef struct AstNodeScope AstNodeScope; +typedef struct AstNodeReturn AstNodeReturn; +typedef struct AstNodeBlock AstNodeBlock; +typedef struct AstNodeIf AstNodeIf; +typedef struct AstNodeWhile AstNodeWhile; +typedef struct AstNodeFunction AstNodeFunction; +typedef struct AstNodeForeign AstNodeForeign; +typedef struct AstNodeGlobal AstNodeGlobal; +typedef struct AstNodeCall AstNodeCall; +typedef struct AstNodeArgument AstNodeArgument; +typedef struct AstNodeUse AstNodeUse; typedef struct OnyxParser { OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts @@ -29,62 +32,62 @@ typedef struct OnyxParser { // NOTE: Identifiers currently is only used to resolve type names // at parse time, since these are the only symbols we know. - bh_table(OnyxAstNode *) identifiers; + bh_table(AstNode *) identifiers; OnyxMessages *msgs; bh_allocator allocator; } OnyxParser; -typedef enum OnyxAstNodeKind { - ONYX_AST_NODE_KIND_ERROR, - ONYX_AST_NODE_KIND_PROGRAM, - ONYX_AST_NODE_KIND_USE, - - ONYX_AST_NODE_KIND_FUNCTION, - ONYX_AST_NODE_KIND_FOREIGN, - ONYX_AST_NODE_KIND_BLOCK, - ONYX_AST_NODE_KIND_SCOPE, - ONYX_AST_NODE_KIND_LOCAL, - ONYX_AST_NODE_KIND_GLOBAL, - ONYX_AST_NODE_KIND_SYMBOL, - - ONYX_AST_NODE_KIND_UNARY_OP, - ONYX_AST_NODE_KIND_BIN_OP, - - ONYX_AST_NODE_KIND_TYPE, - ONYX_AST_NODE_KIND_LITERAL, - ONYX_AST_NODE_KIND_PARAM, - ONYX_AST_NODE_KIND_ARGUMENT, - ONYX_AST_NODE_KIND_CALL, - ONYX_AST_NODE_KIND_ASSIGNMENT, - ONYX_AST_NODE_KIND_RETURN, - - ONYX_AST_NODE_KIND_IF, - ONYX_AST_NODE_KIND_WHILE, - ONYX_AST_NODE_KIND_BREAK, - ONYX_AST_NODE_KIND_CONTINUE, - - ONYX_AST_NODE_KIND_COUNT -} OnyxAstNodeKind; - -typedef enum OnyxTypeInfoKind { - ONYX_TYPE_INFO_KIND_UNKNOWN, - ONYX_TYPE_INFO_KIND_VOID, - ONYX_TYPE_INFO_KIND_BOOL, - - ONYX_TYPE_INFO_KIND_UINT32, - ONYX_TYPE_INFO_KIND_UINT64, - - ONYX_TYPE_INFO_KIND_INT32, - ONYX_TYPE_INFO_KIND_INT64, - - ONYX_TYPE_INFO_KIND_FLOAT32, - ONYX_TYPE_INFO_KIND_FLOAT64, - ONYX_TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit -} OnyxTypeInfoKind; - -typedef struct OnyxTypeInfo { - OnyxTypeInfoKind kind; +typedef enum AstNodeKind { + AST_NODE_KIND_ERROR, + AST_NODE_KIND_PROGRAM, + AST_NODE_KIND_USE, + + AST_NODE_KIND_FUNCTION, + AST_NODE_KIND_FOREIGN, + AST_NODE_KIND_BLOCK, + AST_NODE_KIND_SCOPE, + AST_NODE_KIND_LOCAL, + AST_NODE_KIND_GLOBAL, + AST_NODE_KIND_SYMBOL, + + AST_NODE_KIND_UNARY_OP, + AST_NODE_KIND_BIN_OP, + + AST_NODE_KIND_TYPE, + AST_NODE_KIND_LITERAL, + AST_NODE_KIND_PARAM, + AST_NODE_KIND_ARGUMENT, + AST_NODE_KIND_CALL, + AST_NODE_KIND_ASSIGNMENT, + AST_NODE_KIND_RETURN, + + AST_NODE_KIND_IF, + AST_NODE_KIND_WHILE, + AST_NODE_KIND_BREAK, + AST_NODE_KIND_CONTINUE, + + AST_NODE_KIND_COUNT +} AstNodeKind; + +typedef enum TypeInfoKind { + TYPE_INFO_KIND_UNKNOWN, + TYPE_INFO_KIND_VOID, + TYPE_INFO_KIND_BOOL, + + TYPE_INFO_KIND_UINT32, + TYPE_INFO_KIND_UINT64, + + TYPE_INFO_KIND_INT32, + TYPE_INFO_KIND_INT64, + + TYPE_INFO_KIND_FLOAT32, + TYPE_INFO_KIND_FLOAT64, + TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit +} TypeInfoKind; + +typedef struct TypeInfo { + TypeInfoKind kind; u32 size; // in bytes const char* name; u32 is_int : 1; @@ -92,9 +95,9 @@ typedef struct OnyxTypeInfo { u32 is_float : 1; u32 is_bool : 1; u32 is_known : 1; -} OnyxTypeInfo; +} TypeInfo; -extern OnyxTypeInfo builtin_types[]; +extern TypeInfo builtin_types[]; // NOTE: Some of these flags will overlap since there are // only 32-bits of flags to play with @@ -127,196 +130,147 @@ typedef enum OnyxBinaryOp { ONYX_BINARY_OP_GREATER_EQUAL = 10, } OnyxBinaryOp; -struct OnyxAstNodeBinOp { - OnyxAstNodeKind kind; +// NOTE: AstNode and AstNodeTyped need to be EXACTLY the same for +// all arguments existing in AstNode. I do this to avoid a nested +// "inheiritance" where you would have to say node.base.base.next +// for example +struct AstNode { + AstNodeKind kind; u32 flags; OnyxToken *token; - OnyxTypeInfo *type; - OnyxBinaryOp operation; - OnyxAstNode *next; - OnyxAstNode *left; - OnyxAstNode *right; + AstNode *next; }; -struct OnyxAstNodeUnaryOp { - OnyxAstNodeKind kind; +struct AstNodeTyped { + AstNodeKind kind; u32 flags; OnyxToken *token; - OnyxTypeInfo *type; + AstNode *next; + TypeInfo *type; +}; + +struct AstNodeBinOp { + AstNodeTyped base; + + OnyxBinaryOp operation; + + AstNodeTyped *left, *right; +}; + +struct AstNodeUnaryOp { + AstNodeTyped base; + OnyxUnaryOp operation; - OnyxAstNode *next; - OnyxAstNode *left; + + AstNodeTyped *expr; }; -struct OnyxAstNodeNumLit { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; +struct AstNodeAssign { + AstNode base; + + AstNodeTyped* lval; + AstNodeTyped* expr; +}; + +struct AstNodeNumLit { + AstNodeTyped base; + union { i32 i; i64 l; f32 f; f64 d; } value; }; -struct OnyxAstNodeLocal { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; // NOTE: Unused - OnyxAstNode *next; - OnyxAstNodeLocal *prev_local; +struct AstNodeLocal { + AstNodeTyped base; + + AstNodeLocal *prev_local; }; -struct OnyxAstNodeParam { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: Symbol name i.e. 'a', 'b' - OnyxTypeInfo *type; - u64 data; // NOTE: UNUSED - OnyxAstNodeParam *next; - OnyxAstNodeLocal *prev_local; +struct AstNodeReturn { + AstNode base; + + AstNodeTyped* expr; }; -struct OnyxAstNodeScope { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: UNUSED - OnyxTypeInfo *type; // NOTE: UNUSED - u64 data; // NOTE: UNUSED - OnyxAstNodeScope *prev_scope; - OnyxAstNodeLocal *last_local; +struct AstNodeScope { + AstNode base; + + AstNodeScope *prev_scope; + AstNodeLocal *last_local; }; -struct OnyxAstNodeBlock { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *return_type; - u64 data; // NOTE: UNUSED - OnyxAstNode *next; - OnyxAstNode *body; - OnyxAstNodeScope *scope; +struct AstNodeBlock { + AstNode base; + + AstNode *body; + AstNodeScope *scope; }; -struct OnyxAstNodeIf { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: UNUSED - u64 data; // NOTE: UNUSED - OnyxAstNode *false_block; - OnyxAstNode *next; - OnyxAstNode *cond; - OnyxAstNode *true_block; +struct AstNodeIf { + AstNode base; + + AstNodeTyped *cond; + AstNode *true_block; + AstNode *false_block; }; -struct OnyxAstNodeWhile { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: UNUSED - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxAstNode *cond; - OnyxAstNodeBlock *body; +struct AstNodeWhile { + AstNode base; + + AstNodeTyped *cond; + AstNodeBlock *body; }; -struct OnyxAstNodeFunction { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // This will point to the symbol token to identify it - OnyxTypeInfo *return_type; - u64 data; - OnyxAstNode *next; - OnyxAstNodeBlock *body; - OnyxAstNodeParam *params; +struct AstNodeFunction { + AstNodeTyped base; + + AstNodeBlock *body; + AstNodeLocal *params; }; -struct OnyxAstNodeForeign { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *mod_token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxToken *name_token; - OnyxAstNode *import; +struct AstNodeForeign { + AstNode base; + + OnyxToken *mod_token, *name_token; + AstNode *import; }; -struct OnyxAstNodeGlobal { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode* next; - OnyxAstNode* initial_value; +struct AstNodeGlobal { + AstNodeTyped base; + + AstNodeTyped *initial_value; }; -struct OnyxAstNodeCall { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; // NOTE: The type that the function returns - u64 data; - OnyxAstNode *next; - OnyxAstNode *callee; // NOTE: Function definition node - OnyxAstNode *arguments; // NOTE: Expressions that form the actual param list - // They will be chained down using the "next" property - // unless this becomes used by something else +struct AstNodeCall { + AstNodeTyped base; + + AstNode *callee; // NOTE: Function definition node + AstNodeArgument *arguments; // NOTE: Expressions that form the actual param list + // They will be chained down using the "next" property + // unless this becomes used by something else }; -struct OnyxAstNodeUse { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxToken *filename; +struct AstNodeArgument { + AstNodeTyped base; + + AstNodeTyped *value; }; -union OnyxAstNode { - - // Generic node structure for capturing all binary ops and statements - struct { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxAstNode *left; - OnyxAstNode *right; - }; - - OnyxAstNodeBlock as_block; - OnyxAstNodeParam as_param; - OnyxAstNodeLocal as_local; - OnyxAstNodeScope as_scope; - OnyxAstNodeCall as_call; - OnyxAstNodeNumLit as_numlit; - OnyxAstNodeBinOp as_binop; - OnyxAstNodeUnaryOp as_unaryop; - OnyxAstNodeIf as_if; - OnyxAstNodeWhile as_while; - OnyxAstNodeUse as_use; - OnyxAstNodeFunction as_function; - OnyxAstNodeGlobal as_global; - OnyxAstNodeForeign as_foreign; +struct AstNodeUse { + AstNode base; + + OnyxToken *filename; }; typedef struct OnyxProgram { - bh_arr(OnyxAstNodeUse *) uses; - bh_arr(OnyxAstNodeGlobal *) globals; - bh_arr(OnyxAstNodeFunction *) functions; - bh_arr(OnyxAstNodeForeign *) foreigns; + bh_arr(AstNodeUse *) uses; + bh_arr(AstNodeGlobal *) globals; + bh_arr(AstNodeFunction *) functions; + bh_arr(AstNodeForeign *) foreigns; } OnyxProgram; -const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind); -void* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind); +const char* onyx_ast_node_kind_string(AstNodeKind kind); +void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstNodeKind kind); OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs); void onyx_parser_free(OnyxParser* parser); -OnyxAstNode* onyx_parse(OnyxParser *parser); +AstNode* onyx_parse(OnyxParser *parser); #endif // #ifndef ONYXPARSER_H diff --git a/include/onyxsempass.h b/include/onyxsempass.h index eec02722..2e4b1d22 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -8,7 +8,7 @@ #include "onyxmsgs.h" typedef struct SemPassSymbol { - OnyxAstNode *node; + AstNode *node; struct SemPassSymbol *shadowed; } SemPassSymbol; @@ -19,10 +19,10 @@ typedef struct OnyxSemPassState { OnyxMessages *msgs; // NOTE: Used in symbol resolution phase - OnyxAstNodeScope* curr_scope; + AstNodeScope* curr_scope; // NOTE: Used in type checking phase - OnyxTypeInfo* expected_return_type; + TypeInfo* expected_return_type; bh_table(SemPassSymbol *) symbols; } OnyxSemPassState; diff --git a/include/onyxutils.h b/include/onyxutils.h index 07fa1e82..fa325d8c 100644 --- a/include/onyxutils.h +++ b/include/onyxutils.h @@ -8,4 +8,4 @@ extern bh_allocator global_scratch_allocator; extern bh_managed_heap global_heap; extern bh_allocator global_heap_allocator; -void onyx_ast_print(OnyxAstNode* program, i32 indent); +void onyx_ast_print(AstNode* program, i32 indent); diff --git a/onyx b/onyx index 2f2f2d9b..ead39f24 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyx.c b/src/onyx.c index 1239491d..4fbe8464 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -106,7 +106,7 @@ static void compile_opts_free(OnyxCompileOptions* opts) { bh_arr_free(opts->files); } -static OnyxAstNode* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) { +static AstNode* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) { // NOTE: Maybe don't want to recreate the tokenizer and parser for every file if (compiler_state->options->verbose_output) bh_printf("[Lexing] %s\n", file_contents->filename); @@ -142,33 +142,33 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc); fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename); - OnyxAstNode* root_node = parse_source_file(compiler_state, &fc); + AstNode* root_node = parse_source_file(compiler_state, &fc); if (compiler_state->options->print_ast) { onyx_ast_print(root_node, 0); bh_printf("\n"); } - OnyxAstNode* walker = root_node; + AstNode* walker = root_node; while (walker) { switch (walker->kind) { - case ONYX_AST_NODE_KIND_USE: - bh_arr_push(compiler_state->program.uses, &walker->as_use); + case AST_NODE_KIND_USE: + bh_arr_push(compiler_state->program.uses, (AstNodeUse *) walker); break; - case ONYX_AST_NODE_KIND_GLOBAL: - bh_arr_push(compiler_state->program.globals, &walker->as_global); + case AST_NODE_KIND_GLOBAL: + bh_arr_push(compiler_state->program.globals, (AstNodeGlobal *) walker); break; - case ONYX_AST_NODE_KIND_FOREIGN: - bh_arr_push(compiler_state->program.foreigns, &walker->as_foreign); + case AST_NODE_KIND_FOREIGN: + bh_arr_push(compiler_state->program.foreigns, (AstNodeForeign *) walker); break; - case ONYX_AST_NODE_KIND_FUNCTION: - bh_arr_push(compiler_state->program.functions, &walker->as_function); + case AST_NODE_KIND_FUNCTION: + bh_arr_push(compiler_state->program.functions, (AstNodeFunction *) walker); break; - case ONYX_AST_NODE_KIND_PROGRAM: + case AST_NODE_KIND_PROGRAM: // Dummy initial node break; @@ -180,7 +180,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* walker = walker->next; } - bh_arr_each(OnyxAstNodeUse *, use_node, compiler_state->program.uses) { + bh_arr_each(AstNodeUse *, use_node, compiler_state->program.uses) { char* formatted_name = bh_aprintf( global_heap_allocator, "%b.onyx", diff --git a/src/onyxlex.c b/src/onyxlex.c index 95c543a4..b16d9736 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -1,7 +1,7 @@ #include "bh.h" #include "onyxlex.h" -static const char* onyx_token_type_names[] = { +static const char* token_type_names[] = { "TOKEN_TYPE_UNKNOWN", "TOKEN_TYPE_END_STREAM", @@ -76,7 +76,7 @@ static const char* onyx_token_type_names[] = { } #endif -static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, OnyxTokenType type) { +static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, TokenType type) { i64 len = chars_match(tokenizer->curr, lit); if (len > 0) { if (is_word && char_is_alphanum(*(tokenizer->curr + len)) || charset_contains("_$", *(tokenizer->curr + len))) @@ -95,14 +95,14 @@ static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_ return 0; } -const char* onyx_get_token_type_name(OnyxTokenType tkn_type) { - return onyx_token_type_names[tkn_type]; +const char* onyx_get_token_type_name(TokenType tkn_type) { + return token_type_names[tkn_type]; } -void onyx_token_null_toggle(OnyxToken tkn) { +void onyx_token_null_toggle(OnyxToken* tkn) { static char backup = 0; - char tmp = tkn.token[tkn.length]; - tkn.token[tkn.length] = backup; + char tmp = tkn->token[tkn->length]; + tkn->token[tkn->length] = backup; backup = tmp; } diff --git a/src/onyxparser.c b/src/onyxparser.c index d3379eba..3bc38e8d 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -3,6 +3,9 @@ #include "onyxparser.h" #include "onyxutils.h" +// NOTE: The one weird define you need to know before read the code below +#define make_node(nclass, kind) onyx_ast_node_new(parser->allocator, sizeof(nclass), kind) + static const char* ast_node_names[] = { "ERROR", "PROGRAM", @@ -32,53 +35,53 @@ static const char* ast_node_names[] = { "BREAK", "CONTINUE", - "ONYX_AST_NODE_KIND_COUNT", + "AST_NODE_KIND_COUNT", }; -struct OnyxTypeInfo builtin_types[] = { - { ONYX_TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, - { ONYX_TYPE_INFO_KIND_VOID, 0, "void", 0, 0, 0, 0, 1 }, +struct TypeInfo builtin_types[] = { + { TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, + { TYPE_INFO_KIND_VOID, 0, "void", 0, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_BOOL, 1, "bool", 0, 1, 0, 1, 1 }, + { TYPE_INFO_KIND_BOOL, 1, "bool", 0, 1, 0, 1, 1 }, - { ONYX_TYPE_INFO_KIND_UINT32, 4, "u32", 1, 1, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_UINT64, 8, "u64", 1, 1, 0, 0, 1 }, + { TYPE_INFO_KIND_UINT32, 4, "u32", 1, 1, 0, 0, 1 }, + { TYPE_INFO_KIND_UINT64, 8, "u64", 1, 1, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_INT32, 4, "i32", 1, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_INT64, 8, "i64", 1, 0, 0, 0, 1 }, + { TYPE_INFO_KIND_INT32, 4, "i32", 1, 0, 0, 0, 1 }, + { TYPE_INFO_KIND_INT64, 8, "i64", 1, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_FLOAT32, 4, "f32", 0, 0, 1, 0, 1 }, - { ONYX_TYPE_INFO_KIND_FLOAT64, 8, "f64", 0, 0, 1, 0, 1}, - { ONYX_TYPE_INFO_KIND_SOFT_FLOAT, 8, "sf64", 0, 0, 1, 0, 1 }, + { TYPE_INFO_KIND_FLOAT32, 4, "f32", 0, 0, 1, 0, 1 }, + { TYPE_INFO_KIND_FLOAT64, 8, "f64", 0, 0, 1, 0, 1}, + { TYPE_INFO_KIND_SOFT_FLOAT, 8, "sf64", 0, 0, 1, 0, 1 }, { 0xffffffff } // Sentinel }; -static OnyxAstNode error_node = { { ONYX_AST_NODE_KIND_ERROR, 0, NULL, &builtin_types[0], 0, NULL, NULL, NULL } }; +static AstNode error_node = { AST_NODE_KIND_ERROR, 0, NULL, NULL }; // NOTE: Forward declarations static void parser_next_token(OnyxParser* parser); static void parser_prev_token(OnyxParser* parser); -static b32 is_terminating_token(OnyxTokenType token_type); -static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type); -static OnyxAstNodeScope* enter_scope(OnyxParser* parser); -static OnyxAstNodeScope* leave_scope(OnyxParser* parser); -static void insert_identifier(OnyxParser* parser, OnyxAstNode* ident, b32 is_local); -static void remove_identifier(OnyxParser* parser, OnyxAstNode* ident); -static OnyxAstNodeNumLit* parse_numeric_literal(OnyxParser* parser); -static OnyxAstNode* parse_factor(OnyxParser* parser); -static OnyxAstNode* parse_bin_op(OnyxParser* parser, OnyxAstNode* left); -static OnyxAstNode* parse_expression(OnyxParser* parser); -static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser); -static OnyxAstNodeWhile* parse_while_stmt(OnyxParser* parser); -static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret); -static OnyxAstNode* parse_return_statement(OnyxParser* parser); -static OnyxAstNodeBlock* parse_block(OnyxParser* parser); -static OnyxAstNode* parse_statement(OnyxParser* parser); -static OnyxTypeInfo* parse_type(OnyxParser* parser); -static OnyxAstNodeParam* parse_function_params(OnyxParser* parser); -static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser); -static OnyxAstNode* parse_top_level_statement(OnyxParser* parser); +static b32 is_terminating_token(TokenType token_type); +static OnyxToken* expect(OnyxParser* parser, TokenType token_type); +static AstNodeScope* enter_scope(OnyxParser* parser); +static AstNodeScope* leave_scope(OnyxParser* parser); +static void insert_identifier(OnyxParser* parser, AstNode* ident, b32 is_local); +static void remove_identifier(OnyxParser* parser, AstNode* ident); +static AstNodeNumLit* parse_numeric_literal(OnyxParser* parser); +static AstNodeTyped* parse_factor(OnyxParser* parser); +static AstNodeTyped* parse_bin_op(OnyxParser* parser, AstNode* left); +static AstNodeTyped* parse_expression(OnyxParser* parser); +static AstNodeIf* parse_if_stmt(OnyxParser* parser); +static AstNodeWhile* parse_while_stmt(OnyxParser* parser); +static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret); +static AstNodeReturn* parse_return_statement(OnyxParser* parser); +static AstNodeBlock* parse_block(OnyxParser* parser); +static AstNode* parse_statement(OnyxParser* parser); +static TypeInfo* parse_type(OnyxParser* parser); +static AstNodeLocal* parse_function_params(OnyxParser* parser); +static AstNodeFunction* parse_function_definition(OnyxParser* parser); +static AstNode* parse_top_level_statement(OnyxParser* parser); static void parser_next_token(OnyxParser* parser) { parser->prev_token = parser->curr_token; @@ -93,7 +96,7 @@ static void parser_prev_token(OnyxParser* parser) { parser->prev_token--; } -static b32 is_terminating_token(OnyxTokenType token_type) { +static b32 is_terminating_token(TokenType token_type) { switch (token_type) { case TOKEN_TYPE_SYM_SEMICOLON: case TOKEN_TYPE_CLOSE_BRACE: @@ -105,14 +108,14 @@ static b32 is_terminating_token(OnyxTokenType token_type) { } } -static void find_token(OnyxParser* parser, OnyxTokenType token_type) { +static void find_token(OnyxParser* parser, TokenType token_type) { while (parser->curr_token->type != token_type && !is_terminating_token(parser->curr_token->type)) { parser_next_token(parser); } } // Advances to next token no matter what -static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type) { +static OnyxToken* expect(OnyxParser* parser, TokenType token_type) { OnyxToken* token = parser->curr_token; parser_next_token(parser); @@ -127,51 +130,51 @@ static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type) { return token; } -static OnyxAstNodeNumLit* parse_numeric_literal(OnyxParser* parser) { - OnyxAstNodeNumLit* lit_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LITERAL); - lit_node->token = expect(parser, TOKEN_TYPE_LITERAL_NUMERIC); - lit_node->flags |= ONYX_AST_FLAG_COMPTIME; +static AstNodeNumLit* parse_numeric_literal(OnyxParser* parser) { + AstNodeNumLit* lit_node = make_node(AstNodeNumLit, AST_NODE_KIND_LITERAL); + lit_node->base.token = expect(parser, TOKEN_TYPE_LITERAL_NUMERIC); + lit_node->base.flags |= ONYX_AST_FLAG_COMPTIME; lit_node->value.l = 0ll; - onyx_token_null_toggle(*lit_node->token); + onyx_token_null_toggle(lit_node->base.token); - OnyxTypeInfo* type; - char* tok = lit_node->token->token; + TypeInfo* type; + char* tok = lit_node->base.token->token; // NOTE: charset_contains() behaves more like string_contains() // so I'm using it in this case if (charset_contains(tok, '.')) { - if (tok[lit_node->token->length - 1] == 'f') { - type = &builtin_types[ONYX_TYPE_INFO_KIND_FLOAT32]; + if (tok[lit_node->base.token->length - 1] == 'f') { + type = &builtin_types[TYPE_INFO_KIND_FLOAT32]; lit_node->value.f = strtof(tok, NULL); } else { - type = &builtin_types[ONYX_TYPE_INFO_KIND_FLOAT64]; + type = &builtin_types[TYPE_INFO_KIND_FLOAT64]; lit_node->value.d = strtod(tok, NULL); } } else { i64 value = strtoll(tok, NULL, 0); if (bh_abs(value) < ((u64) 1 << 32)) { - type = &builtin_types[ONYX_TYPE_INFO_KIND_INT32]; + type = &builtin_types[TYPE_INFO_KIND_INT32]; } else { - type = &builtin_types[ONYX_TYPE_INFO_KIND_INT64]; + type = &builtin_types[TYPE_INFO_KIND_INT64]; } lit_node->value.l = value; } - lit_node->type = type; - onyx_token_null_toggle(*lit_node->token); + lit_node->base.type = type; + onyx_token_null_toggle(lit_node->base.token); return lit_node; } -static OnyxAstNode* parse_factor(OnyxParser* parser) { - OnyxAstNode* retval = NULL; +static AstNodeTyped* parse_factor(OnyxParser* parser) { + AstNodeTyped* retval = NULL; switch (parser->curr_token->type) { case TOKEN_TYPE_OPEN_PAREN: { parser_next_token(parser); - OnyxAstNode* expr = parse_expression(parser); + AstNodeTyped* expr = parse_expression(parser); expect(parser, TOKEN_TYPE_CLOSE_PAREN); retval = expr; break; @@ -180,25 +183,24 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { case TOKEN_TYPE_SYM_MINUS: { parser_next_token(parser); - OnyxAstNode* factor = parse_factor(parser); + AstNodeTyped* factor = parse_factor(parser); - OnyxAstNodeUnaryOp* negate_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_UNARY_OP); + AstNodeUnaryOp* negate_node = make_node(AstNodeUnaryOp, AST_NODE_KIND_UNARY_OP); negate_node->operation = ONYX_UNARY_OP_NEGATE; - negate_node->left = factor; - negate_node->type = factor->type; + negate_node->expr = factor; if ((factor->flags & ONYX_AST_FLAG_COMPTIME) != 0) { - negate_node->flags |= ONYX_AST_FLAG_COMPTIME; + negate_node->base.flags |= ONYX_AST_FLAG_COMPTIME; } - retval = (OnyxAstNode *) negate_node; + retval = (AstNodeTyped *) negate_node; break; } case TOKEN_TYPE_SYMBOL: { OnyxToken* sym_token = expect(parser, TOKEN_TYPE_SYMBOL); - OnyxAstNode* sym_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + AstNodeTyped* sym_node = make_node(AstNode, AST_NODE_KIND_SYMBOL); sym_node->token = sym_token; if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) { @@ -207,23 +209,19 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { } // NOTE: Function call - OnyxAstNodeCall* call_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CALL); - call_node->token = expect(parser, TOKEN_TYPE_OPEN_PAREN); - call_node->callee = sym_node; - // NOTE: Return type is stored on function definition's type - // This may have to change if we want multiple returns - call_node->type = sym_node->type; - - OnyxAstNode** prev = &call_node->arguments; - OnyxAstNode* curr = NULL; + AstNodeCall* call_node = make_node(AstNodeCall, AST_NODE_KIND_CALL); + call_node->base.token = expect(parser, TOKEN_TYPE_OPEN_PAREN); + call_node->callee = (AstNode *) sym_node; + + AstNodeArgument** prev = &call_node->arguments; + AstNodeArgument* curr = NULL; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { - curr = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ARGUMENT); - curr->left = parse_expression(parser); - curr->type = curr->left->type; + curr = make_node(AstNodeArgument, AST_NODE_KIND_ARGUMENT); + curr->value = parse_expression(parser); - if (curr != NULL && curr->kind != ONYX_AST_NODE_KIND_ERROR) { + if (curr != NULL && curr->base.kind != AST_NODE_KIND_ERROR) { *prev = curr; - prev = &curr->next; + prev = (AstNodeArgument **) &curr->base.next; } if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN) @@ -235,38 +233,38 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { parser->curr_token->pos, onyx_get_token_type_name(TOKEN_TYPE_SYM_COMMA), onyx_get_token_type_name(parser->curr_token->type)); - return &error_node; + return (AstNodeTyped *) &error_node; } parser_next_token(parser); } parser_next_token(parser); - retval = (OnyxAstNode *) call_node; + retval = (AstNodeTyped *) call_node; break; } case TOKEN_TYPE_LITERAL_NUMERIC: - retval = (OnyxAstNode *) parse_numeric_literal(parser); + retval = (AstNodeTyped *) parse_numeric_literal(parser); break; case TOKEN_TYPE_LITERAL_BOOL_TRUE: { - OnyxAstNodeNumLit* bool_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LITERAL); - bool_node->type = &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]; - bool_node->token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_TRUE); + AstNodeNumLit* bool_node = make_node(AstNodeNumLit, AST_NODE_KIND_LITERAL); + bool_node->base.type = &builtin_types[TYPE_INFO_KIND_BOOL]; + bool_node->base.token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_TRUE); bool_node->value.i = 1; - retval = (OnyxAstNode *) bool_node; + retval = (AstNodeTyped *) bool_node; break; } case TOKEN_TYPE_LITERAL_BOOL_FALSE: { - OnyxAstNodeNumLit* bool_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LITERAL); - bool_node->type = &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]; - bool_node->token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_FALSE); + AstNodeNumLit* bool_node = make_node(AstNodeNumLit, AST_NODE_KIND_LITERAL); + bool_node->base.type = &builtin_types[TYPE_INFO_KIND_BOOL]; + bool_node->base.token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_FALSE); bool_node->value.i = 0; - retval = (OnyxAstNode *) bool_node; + retval = (AstNodeTyped *) bool_node; break; } @@ -281,11 +279,11 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_CAST) { parser_next_token(parser); - OnyxAstNodeUnaryOp* cast_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_UNARY_OP); + AstNodeUnaryOp* cast_node = make_node(AstNodeUnaryOp, AST_NODE_KIND_UNARY_OP); + cast_node->base.type = parse_type(parser); cast_node->operation = ONYX_UNARY_OP_CAST; - cast_node->type = parse_type(parser); - cast_node->left = retval; - retval = (OnyxAstNode *) cast_node; + cast_node->expr = retval; + retval = (AstNodeTyped *) cast_node; } return retval; @@ -312,14 +310,14 @@ static inline i32 get_precedence(OnyxBinaryOp kind) { } } -static OnyxAstNode* parse_expression(OnyxParser* parser) { - bh_arr(OnyxAstNodeBinOp*) tree_stack = NULL; +static AstNodeTyped* parse_expression(OnyxParser* parser) { + bh_arr(AstNodeBinOp*) tree_stack = NULL; bh_arr_new(global_scratch_allocator, tree_stack, 4); bh_arr_set_length(tree_stack, 0); - OnyxAstNode* left = parse_factor(parser); - OnyxAstNode* right; - OnyxAstNode* root = left; + AstNodeTyped* left = parse_factor(parser); + AstNodeTyped* right; + AstNodeTyped* root = left; OnyxBinaryOp bin_op_kind; OnyxToken* bin_op_tok; @@ -346,9 +344,9 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) { bin_op_tok = parser->curr_token; parser_next_token(parser); - OnyxAstNodeBinOp* bin_op = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BIN_OP); + AstNodeBinOp* bin_op = make_node(AstNodeBinOp, AST_NODE_KIND_BIN_OP); bin_op->operation = bin_op_kind; - bin_op->token = bin_op_tok; + bin_op->base.token = bin_op_tok; while ( !bh_arr_is_empty(tree_stack) && get_precedence(bh_arr_last(tree_stack)->operation) >= get_precedence(bin_op_kind)) @@ -357,20 +355,19 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) { if (bh_arr_is_empty(tree_stack)) { // NOTE: new is now the root node bin_op->left = root; - root = (OnyxAstNode *) bin_op; + root = (AstNodeTyped *) bin_op; } else { bin_op->left = bh_arr_last(tree_stack)->right; - bh_arr_last(tree_stack)->right = (OnyxAstNode *) bin_op; + bh_arr_last(tree_stack)->right = (AstNodeTyped *) bin_op; } bh_arr_push(tree_stack, bin_op); right = parse_factor(parser); bin_op->right = right; - bin_op->type = right->type; if ((left->flags & ONYX_AST_FLAG_COMPTIME) != 0 && (right->flags & ONYX_AST_FLAG_COMPTIME) != 0) { - bin_op->flags |= ONYX_AST_FLAG_COMPTIME; + bin_op->base.flags |= ONYX_AST_FLAG_COMPTIME; } } } @@ -379,14 +376,14 @@ expression_done: return root; } -static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser) { +static AstNodeIf* parse_if_stmt(OnyxParser* parser) { expect(parser, TOKEN_TYPE_KEYWORD_IF); - OnyxAstNode* cond = parse_expression(parser); - OnyxAstNode* true_block = (OnyxAstNode *) parse_block(parser); + AstNodeTyped* cond = parse_expression(parser); + AstNode* true_block = (AstNode *) parse_block(parser); - OnyxAstNodeIf* if_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_IF); - OnyxAstNodeIf* root_if = if_node; + AstNodeIf* if_node = make_node(AstNodeIf, AST_NODE_KIND_IF); + AstNodeIf* root_if = if_node; if_node->cond = cond; if (true_block != NULL) @@ -394,23 +391,23 @@ static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser) { while (parser->curr_token->type == TOKEN_TYPE_KEYWORD_ELSEIF) { parser_next_token(parser); - OnyxAstNodeIf* elseif_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_IF); + AstNodeIf* elseif_node = make_node(AstNodeIf, AST_NODE_KIND_IF); cond = parse_expression(parser); - true_block = (OnyxAstNode *) parse_block(parser); + true_block = (AstNode *) parse_block(parser); elseif_node->cond = cond; if (true_block != NULL) elseif_node->true_block = true_block; - if_node->false_block = (OnyxAstNode *) elseif_node; + if_node->false_block = (AstNode *) elseif_node; if_node = elseif_node; } if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_ELSE) { parser_next_token(parser); - OnyxAstNode* false_block = (OnyxAstNode *) parse_block(parser); + AstNode* false_block = (AstNode *) parse_block(parser); if (false_block != NULL) if_node->false_block = false_block; } @@ -418,14 +415,14 @@ static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser) { return root_if; } -static OnyxAstNodeWhile* parse_while_stmt(OnyxParser* parser) { +static AstNodeWhile* parse_while_stmt(OnyxParser* parser) { OnyxToken* while_token = expect(parser, TOKEN_TYPE_KEYWORD_WHILE); - OnyxAstNode* cond = parse_expression(parser); - OnyxAstNodeBlock* body = parse_block(parser); + AstNodeTyped* cond = parse_expression(parser); + AstNodeBlock* body = parse_block(parser); - OnyxAstNodeWhile* while_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_WHILE); - while_node->token = while_token; + AstNodeWhile* while_node = make_node(AstNodeWhile, AST_NODE_KIND_WHILE); + while_node->base.token = while_token; while_node->cond = cond; while_node->body = body; @@ -434,7 +431,7 @@ static OnyxAstNodeWhile* parse_while_stmt(OnyxParser* parser) { // Returns 1 if the symbol was consumed. Returns 0 otherwise // ret is set to the statement to insert -static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { +static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { if (parser->curr_token->type != TOKEN_TYPE_SYMBOL) return 0; OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); @@ -443,44 +440,44 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { case TOKEN_TYPE_SYM_COLON: { parser_next_token(parser); - OnyxTypeInfo* type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + TypeInfo* type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; // NOTE: var: type if (parser->curr_token->type == TOKEN_TYPE_SYMBOL) { type = parse_type(parser); } - OnyxAstNodeLocal* local = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LOCAL); - local->token = symbol; - local->type = type; - local->flags |= ONYX_AST_FLAG_LVAL; // NOTE: DELETE - *ret = (OnyxAstNode *) local; + AstNodeLocal* local = make_node(AstNodeLocal, AST_NODE_KIND_LOCAL); + local->base.token = symbol; + local->base.type = type; + local->base.flags |= ONYX_AST_FLAG_LVAL; // NOTE: DELETE + *ret = (AstNode *) local; if (parser->curr_token->type == TOKEN_TYPE_SYM_EQUALS || parser->curr_token->type == TOKEN_TYPE_SYM_COLON) { if (parser->curr_token->type == TOKEN_TYPE_SYM_COLON) { - local->flags |= ONYX_AST_FLAG_CONST; + local->base.flags |= ONYX_AST_FLAG_CONST; } - OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT); - local->next = assignment; - assignment->token = parser->curr_token; + AstNodeAssign* assignment = make_node(AstNodeAssign, AST_NODE_KIND_ASSIGNMENT); + local->base.next = (AstNode *) assignment; + assignment->base.token = parser->curr_token; parser_next_token(parser); - OnyxAstNode* expr = parse_expression(parser); + AstNodeTyped* expr = parse_expression(parser); if (expr == NULL) { - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION, - assignment->token->pos, + assignment->base.token->pos, parser->curr_token->token); - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); return 1; } - assignment->right = expr; + assignment->expr = expr; - OnyxAstNode* left_symbol = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + AstNode* left_symbol = make_node(AstNode, AST_NODE_KIND_SYMBOL); left_symbol->token = symbol; - assignment->left = left_symbol; + assignment->lval = (AstNodeTyped *) left_symbol; } return 1; } @@ -488,17 +485,17 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { // NOTE: Assignment case TOKEN_TYPE_SYM_EQUALS: { - OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT); - assignment->token = parser->curr_token; + AstNodeAssign* assignment = make_node(AstNodeAssign, AST_NODE_KIND_ASSIGNMENT); + assignment->base.token = parser->curr_token; parser_next_token(parser); - OnyxAstNode* lval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + AstNode* lval = make_node(AstNode, AST_NODE_KIND_SYMBOL); lval->token = symbol; - OnyxAstNode* rval = parse_expression(parser); - assignment->right = rval; - assignment->left = lval; - *ret = assignment; + AstNodeTyped* rval = parse_expression(parser); + assignment->expr = rval; + assignment->lval = (AstNodeTyped *) lval; + *ret = (AstNode *) assignment; return 1; } @@ -509,37 +506,37 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { return 0; } -static OnyxAstNode* parse_return_statement(OnyxParser* parser) { - OnyxAstNode* return_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_RETURN); - return_node->token = expect(parser, TOKEN_TYPE_KEYWORD_RETURN); +static AstNodeReturn* parse_return_statement(OnyxParser* parser) { + AstNodeReturn* return_node = make_node(AstNodeReturn, AST_NODE_KIND_RETURN); + return_node->base.token = expect(parser, TOKEN_TYPE_KEYWORD_RETURN); - OnyxAstNode* expr = NULL; + AstNodeTyped* expr = NULL; if (parser->curr_token->type != TOKEN_TYPE_SYM_SEMICOLON) { expr = parse_expression(parser); - if (expr == NULL || expr == &error_node) { - return &error_node; + if (expr == NULL || expr == (AstNodeTyped *) &error_node) { + return (AstNodeReturn *) &error_node; } else { - return_node->left = expr; + return_node->expr = expr; } } return return_node; } -static OnyxAstNode* parse_statement(OnyxParser* parser) { +static AstNode* parse_statement(OnyxParser* parser) { b32 needs_semicolon = 1; - OnyxAstNode* retval = NULL; + AstNode* retval = NULL; switch (parser->curr_token->type) { case TOKEN_TYPE_KEYWORD_RETURN: - retval = parse_return_statement(parser); + retval = (AstNode *) parse_return_statement(parser); break; case TOKEN_TYPE_OPEN_BRACE: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_block(parser); + retval = (AstNode *) parse_block(parser); break; case TOKEN_TYPE_SYMBOL: @@ -552,26 +549,26 @@ static OnyxAstNode* parse_statement(OnyxParser* parser) { case TOKEN_TYPE_SYM_BANG: case TOKEN_TYPE_LITERAL_NUMERIC: case TOKEN_TYPE_LITERAL_STRING: - retval = parse_expression(parser); + retval = (AstNode *) parse_expression(parser); break; case TOKEN_TYPE_KEYWORD_IF: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_if_stmt(parser); + retval = (AstNode *) parse_if_stmt(parser); break; case TOKEN_TYPE_KEYWORD_WHILE: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_while_stmt(parser); + retval = (AstNode *) parse_while_stmt(parser); break; case TOKEN_TYPE_KEYWORD_BREAK: - retval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BREAK); + retval = make_node(AstNode, AST_NODE_KIND_BREAK); retval->token = expect(parser, TOKEN_TYPE_KEYWORD_BREAK); break; case TOKEN_TYPE_KEYWORD_CONTINUE: - retval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CONTINUE); + retval = make_node(AstNode, AST_NODE_KIND_BREAK); retval->token = expect(parser, TOKEN_TYPE_KEYWORD_CONTINUE); break; @@ -595,9 +592,9 @@ static OnyxAstNode* parse_statement(OnyxParser* parser) { return retval; } -static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { - OnyxAstNodeBlock* block = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK); - OnyxAstNodeScope* scope = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SCOPE); +static AstNodeBlock* parse_block(OnyxParser* parser) { + AstNodeBlock* block = make_node(AstNodeBlock, AST_NODE_KIND_BLOCK); + AstNodeScope* scope = make_node(AstNodeScope, AST_NODE_KIND_SCOPE); block->scope = scope; // --- is for an empty block @@ -610,12 +607,12 @@ static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { expect(parser, TOKEN_TYPE_OPEN_BRACE); - OnyxAstNode** next = &block->body; - OnyxAstNode* stmt = NULL; + AstNode** next = &block->body; + AstNode* stmt = NULL; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_BRACE) { stmt = parse_statement(parser); - if (stmt != NULL && stmt->kind != ONYX_AST_NODE_KIND_ERROR) { + if (stmt != NULL && stmt->kind != AST_NODE_KIND_ERROR) { *next = stmt; while (stmt->next != NULL) stmt = stmt->next; @@ -628,29 +625,29 @@ static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { return block; } -static OnyxTypeInfo* parse_type(OnyxParser* parser) { - OnyxTypeInfo* type_info = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; +static TypeInfo* parse_type(OnyxParser* parser) { + TypeInfo* type_info = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); if (symbol == NULL) return type_info; - onyx_token_null_toggle(*symbol); + onyx_token_null_toggle(symbol); - if (!bh_table_has(OnyxAstNode*, parser->identifiers, symbol->token)) { + if (!bh_table_has(AstNode*, parser->identifiers, symbol->token)) { onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, symbol->pos, symbol->token); } else { - OnyxAstNode* type_info_node = bh_table_get(OnyxAstNode*, parser->identifiers, symbol->token); + AstNodeTyped* type_info_node = bh_table_get(AstNodeTyped*, parser->identifiers, symbol->token); - if (type_info_node->kind == ONYX_AST_NODE_KIND_TYPE) { + if (type_info_node->kind == AST_NODE_KIND_TYPE) { type_info = type_info_node->type; } } - onyx_token_null_toggle(*symbol); + onyx_token_null_toggle(symbol); return type_info; } -static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { +static AstNodeLocal* parse_function_params(OnyxParser* parser) { if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) return NULL; @@ -661,9 +658,9 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { return NULL; } - OnyxAstNodeParam* first_param = NULL; - OnyxAstNodeParam* curr_param = NULL; - OnyxAstNodeParam* trailer = NULL; + AstNodeLocal* first_param = NULL; + AstNodeLocal* curr_param = NULL; + AstNodeLocal* trailer = NULL; OnyxToken* symbol; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { @@ -672,15 +669,15 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { symbol = expect(parser, TOKEN_TYPE_SYMBOL); expect(parser, TOKEN_TYPE_SYM_COLON); - curr_param = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PARAM); - curr_param->token = symbol; - curr_param->type = parse_type(parser); - curr_param->flags |= ONYX_AST_FLAG_CONST; + curr_param = make_node(AstNodeLocal, AST_NODE_KIND_PARAM); + curr_param->base.token = symbol; + curr_param->base.flags |= ONYX_AST_FLAG_CONST; + curr_param->base.type = parse_type(parser); if (first_param == NULL) first_param = curr_param; - curr_param->next = NULL; - if (trailer) trailer->next = curr_param; + curr_param->base.next = NULL; + if (trailer) trailer->base.next = (AstNode *) curr_param; trailer = curr_param; } @@ -689,21 +686,21 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { return first_param; } -static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser) { +static AstNodeFunction* parse_function_definition(OnyxParser* parser) { expect(parser, TOKEN_TYPE_KEYWORD_PROC); - OnyxAstNodeFunction* func_def = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FUNCTION); + AstNodeFunction* func_def = make_node(AstNodeFunction, AST_NODE_KIND_FUNCTION); - OnyxAstNodeParam* params = parse_function_params(parser); + AstNodeLocal* params = parse_function_params(parser); func_def->params = params; if (parser->curr_token->type == TOKEN_TYPE_RIGHT_ARROW) { expect(parser, TOKEN_TYPE_RIGHT_ARROW); - OnyxTypeInfo* return_type = parse_type(parser); - func_def->return_type = return_type; + TypeInfo* return_type = parse_type(parser); + func_def->base.type = return_type; } else { - func_def->return_type = &builtin_types[ONYX_TYPE_INFO_KIND_VOID]; + func_def->base.type = &builtin_types[TYPE_INFO_KIND_VOID]; } func_def->body = parse_block(parser); @@ -711,62 +708,62 @@ static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser) { return func_def; } -static OnyxAstNode* parse_foreign(OnyxParser* parser) { +static AstNode* parse_foreign(OnyxParser* parser) { expect(parser, TOKEN_TYPE_KEYWORD_FOREIGN); - OnyxAstNodeForeign* foreign = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FOREIGN); + AstNodeForeign* foreign = make_node(AstNodeForeign, AST_NODE_KIND_FOREIGN); foreign->mod_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); foreign->name_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { - foreign->import = (OnyxAstNode *) parse_function_definition(parser); + foreign->import = (AstNode *) parse_function_definition(parser); } else { - OnyxTypeInfo* type = parse_type(parser); + TypeInfo* type = parse_type(parser); - OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); - global->type = type; - global->flags |= ONYX_AST_FLAG_LVAL; + AstNodeGlobal* global = make_node(AstNodeGlobal, AST_NODE_KIND_GLOBAL); + global->base.type = type; + global->base.flags |= ONYX_AST_FLAG_LVAL; - foreign->import = (OnyxAstNode *) global; + foreign->import = (AstNode *) global; } - return (OnyxAstNode *) foreign; + return (AstNode *) foreign; } -static OnyxAstNode* parse_top_level_constant_symbol(OnyxParser* parser) { +static AstNode* parse_top_level_constant_symbol(OnyxParser* parser) { if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { - return (OnyxAstNode *) parse_function_definition(parser); + return (AstNode *) parse_function_definition(parser); } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_STRUCT) { // Handle struct case assert(0); } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_FOREIGN) { - return (OnyxAstNode *) parse_foreign(parser); + return (AstNode *) parse_foreign(parser); } else { // Global constant with initial value - OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); + AstNodeGlobal* global = make_node(AstNodeGlobal, AST_NODE_KIND_GLOBAL); global->initial_value = parse_expression(parser); - global->type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; - global->flags |= ONYX_AST_FLAG_CONST; - global->flags |= ONYX_AST_FLAG_LVAL; - global->flags |= ONYX_AST_FLAG_COMPTIME; + global->base.type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; + global->base.flags |= ONYX_AST_FLAG_CONST; + global->base.flags |= ONYX_AST_FLAG_LVAL; + global->base.flags |= ONYX_AST_FLAG_COMPTIME; - return (OnyxAstNode *) global; + return (AstNode *) global; } } -static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { +static AstNode* parse_top_level_statement(OnyxParser* parser) { switch (parser->curr_token->type) { case TOKEN_TYPE_KEYWORD_USE: { - OnyxAstNodeUse* use_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_USE); - use_node->token = expect(parser, TOKEN_TYPE_KEYWORD_USE); + AstNodeUse* use_node = make_node(AstNodeUse, AST_NODE_KIND_USE); + use_node->base.token = expect(parser, TOKEN_TYPE_KEYWORD_USE); use_node->filename = expect(parser, TOKEN_TYPE_LITERAL_STRING); - return (OnyxAstNode *) use_node; + return (AstNode *) use_node; } case TOKEN_TYPE_KEYWORD_EXPORT: @@ -781,7 +778,7 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { break; } - OnyxAstNode* top_level_decl = parse_top_level_statement(parser); + AstNode* top_level_decl = parse_top_level_statement(parser); top_level_decl->flags |= ONYX_AST_FLAG_EXPORTED; return top_level_decl; } @@ -793,7 +790,7 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { expect(parser, TOKEN_TYPE_SYM_COLON); - OnyxTypeInfo* type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + TypeInfo* type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; if (parser->curr_token->type == TOKEN_TYPE_SYMBOL) { type = parse_type(parser); @@ -802,14 +799,14 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { if (parser->curr_token->type == TOKEN_TYPE_SYM_COLON) { parser_next_token(parser); - OnyxAstNode* node = parse_top_level_constant_symbol(parser); + AstNode* node = parse_top_level_constant_symbol(parser); - if (node->kind == ONYX_AST_NODE_KIND_GLOBAL) { - node->type = type; + if (node->kind == AST_NODE_KIND_GLOBAL) { + ((AstNodeGlobal *) node)->base.type = type; } - if (node->kind == ONYX_AST_NODE_KIND_FOREIGN) { - node->as_foreign.import->token = symbol; + if (node->kind == AST_NODE_KIND_FOREIGN) { + ((AstNodeForeign *) node)->import->token = symbol; } else { node->token = symbol; @@ -820,21 +817,21 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { } else if (parser->curr_token->type == TOKEN_TYPE_SYM_EQUALS) { parser_next_token(parser); - OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); - global->token = symbol; - global->flags |= ONYX_AST_FLAG_LVAL; + AstNodeGlobal* global = make_node(AstNodeGlobal, AST_NODE_KIND_GLOBAL); + global->base.token = symbol; + global->base.flags |= ONYX_AST_FLAG_LVAL; global->initial_value = parse_expression(parser); - global->type = type; + global->base.type = type; - return (OnyxAstNode *) global; + return (AstNode *) global; } else { - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, parser->curr_token->pos, parser->curr_token->token); - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); } return &error_node; @@ -851,21 +848,16 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { -const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind) { +const char* onyx_ast_node_kind_string(AstNodeKind kind) { return ast_node_names[kind]; } // NOTE: This returns a void* so I don't need to cast it everytime I use it -void* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind) { - OnyxAstNode* node = bh_alloc_item(alloc, OnyxAstNode); - node->kind = kind; - node->flags = 0; - node->token = NULL; - node->type = NULL; - node->data = 0; - node->next = NULL; - node->left = NULL; - node->right = NULL; +void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstNodeKind kind) { + void* node = bh_alloc(alloc, size); + + memset(node, 0, size); + *(AstNodeKind *) node = kind; return node; } @@ -875,11 +867,11 @@ OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, Onyx bh_table_init(bh_heap_allocator(), parser.identifiers, 61); - OnyxTypeInfo* it = &builtin_types[0]; + TypeInfo* it = &builtin_types[0]; while (it->kind != 0xffffffff) { - OnyxAstNode* tmp = onyx_ast_node_new(alloc, ONYX_AST_NODE_KIND_TYPE); + AstNodeTyped* tmp = onyx_ast_node_new(alloc, sizeof(AstNodeTyped), AST_NODE_KIND_TYPE); tmp->type = it; - bh_table_put(OnyxAstNode*, parser.identifiers, (char *)it->name, tmp); + bh_table_put(AstNode*, parser.identifiers, (char *)it->name, tmp); it++; } @@ -896,11 +888,11 @@ void onyx_parser_free(OnyxParser* parser) { bh_table_free(parser->identifiers); } -OnyxAstNode* onyx_parse(OnyxParser *parser) { - OnyxAstNode* program = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM); +AstNode* onyx_parse(OnyxParser *parser) { + AstNode* program = make_node(AstNode, AST_NODE_KIND_PROGRAM); - OnyxAstNode** prev_stmt = &program->next; - OnyxAstNode* curr_stmt = NULL; + AstNode** prev_stmt = &program->next; + AstNode* curr_stmt = NULL; while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) { curr_stmt = parse_top_level_statement(parser); diff --git a/src/onyxsempass.c b/src/onyxsempass.c index 856055f5..6bc95533 100644 --- a/src/onyxsempass.c +++ b/src/onyxsempass.c @@ -13,7 +13,7 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc .symbols = NULL, }; - bh_table_init(bh_heap_allocator(), state.symbols, 61); + bh_table_init(global_heap_allocator, state.symbols, 61); return state; } @@ -24,29 +24,29 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc // defined in sub-scopes up to the function-block level. This is a // requirement of WASM, but not of other targets. static void collapse_scopes(OnyxProgram* program) { - bh_arr(OnyxAstNodeBlock*) traversal_queue = NULL; + bh_arr(AstNodeBlock*) traversal_queue = NULL; bh_arr_new(global_scratch_allocator, traversal_queue, 4); bh_arr_set_length(traversal_queue, 0); - bh_arr_each(OnyxAstNodeFunction *, func, program->functions) { - OnyxAstNodeScope* top_scope = (*func)->body->scope; + bh_arr_each(AstNodeFunction *, func, program->functions) { + AstNodeScope* top_scope = (*func)->body->scope; bh_arr_push(traversal_queue, (*func)->body); while (!bh_arr_is_empty(traversal_queue)) { - OnyxAstNodeBlock* block = traversal_queue[0]; + AstNodeBlock* block = traversal_queue[0]; - if (block->kind == ONYX_AST_NODE_KIND_IF) { - OnyxAstNodeIf* if_node = (OnyxAstNodeIf *) block; + if (block->base.kind == AST_NODE_KIND_IF) { + AstNodeIf* if_node = (AstNodeIf *) block; if (if_node->true_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->true_block); + bh_arr_push(traversal_queue, (AstNodeBlock *) if_node->true_block); if (if_node->false_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->false_block); + bh_arr_push(traversal_queue, (AstNodeBlock *) if_node->false_block); } else { if (block->scope != top_scope && block->scope->last_local != NULL) { - OnyxAstNodeLocal* last_local = block->scope->last_local; + AstNodeLocal* last_local = block->scope->last_local; while (last_local && last_local->prev_local != NULL) last_local = last_local->prev_local; last_local->prev_local = top_scope->last_local; @@ -54,20 +54,20 @@ static void collapse_scopes(OnyxProgram* program) { block->scope->last_local = NULL; } - OnyxAstNode* walker = block->body; + AstNode* walker = block->body; while (walker) { - if (walker->kind == ONYX_AST_NODE_KIND_BLOCK) { - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker); + if (walker->kind == AST_NODE_KIND_BLOCK) { + bh_arr_push(traversal_queue, (AstNodeBlock *) walker); - } else if (walker->kind == ONYX_AST_NODE_KIND_WHILE) { - bh_arr_push(traversal_queue, walker->as_while.body); + } else if (walker->kind == AST_NODE_KIND_WHILE) { + bh_arr_push(traversal_queue, ((AstNodeWhile *) walker)->body); - } else if (walker->kind == ONYX_AST_NODE_KIND_IF) { - if (walker->as_if.true_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.true_block); + } else if (walker->kind == AST_NODE_KIND_IF) { + if (((AstNodeIf *) walker)->true_block) + bh_arr_push(traversal_queue, (AstNodeBlock *) ((AstNodeIf *) walker)->true_block); - if (walker->as_if.false_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.false_block); + if (((AstNodeIf *) walker)->false_block) + bh_arr_push(traversal_queue, (AstNodeBlock *) ((AstNodeIf *) walker)->false_block); } walker = walker->next; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 37c39aea..32abbbb8 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -1,26 +1,26 @@ #define BH_DEBUG #include "onyxsempass.h" -static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol); -static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxAstNode* symbol); -static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol); -static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol); -static void scope_enter(OnyxSemPassState* state, OnyxAstNodeScope* scope); -static OnyxAstNodeScope* scope_leave(OnyxSemPassState* state); -static void symres_local(OnyxSemPassState* state, OnyxAstNodeLocal** local); -static void symres_call(OnyxSemPassState* state, OnyxAstNode* call); -static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr); -static void symres_assignment(OnyxSemPassState* state, OnyxAstNode* assign); -static void symres_return(OnyxSemPassState* state, OnyxAstNode* ret); -static void symres_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode); -static void symres_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode); -static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, OnyxAstNode** trailer); -static b32 symres_statement(OnyxSemPassState* state, OnyxAstNode* stmt); -static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block); -static void symres_function(OnyxSemPassState* state, OnyxAstNodeFunction* func); - -static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static void symbol_introduce(OnyxSemPassState* state, AstNode* symbol); +static b32 symbol_unique_introduce(OnyxSemPassState* state, AstNode* symbol); +static void symbol_remove(OnyxSemPassState* state, AstNode* symbol); +static AstNode* symbol_resolve(OnyxSemPassState* state, AstNode* symbol); +static void scope_enter(OnyxSemPassState* state, AstNodeScope* scope); +static AstNodeScope* scope_leave(OnyxSemPassState* state); +static void symres_local(OnyxSemPassState* state, AstNodeLocal** local); +static void symres_call(OnyxSemPassState* state, AstNodeCall* call); +static void symres_expression(OnyxSemPassState* state, AstNode** expr); +static void symres_assignment(OnyxSemPassState* state, AstNodeAssign* assign); +static void symres_return(OnyxSemPassState* state, AstNodeReturn* ret); +static void symres_if(OnyxSemPassState* state, AstNodeIf* ifnode); +static void symres_while(OnyxSemPassState* state, AstNodeWhile* whilenode); +static void symres_statement_chain(OnyxSemPassState* state, AstNode* walker, AstNode** trailer); +static b32 symres_statement(OnyxSemPassState* state, AstNode* stmt); +static void symres_block(OnyxSemPassState* state, AstNodeBlock* block); +static void symres_function(OnyxSemPassState* state, AstNodeFunction* func); + +static void symbol_introduce(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); SemPassSymbol* sp_sym = (SemPassSymbol *) bh_alloc_item(state->allocator, SemPassSymbol); sp_sym->node = symbol; @@ -32,17 +32,17 @@ static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { bh_table_put(SemPassSymbol *, state->symbols, symbol->token->token, sp_sym); - if (symbol->kind == ONYX_AST_NODE_KIND_LOCAL) { - OnyxAstNodeLocal* local = &symbol->as_local; + if (symbol->kind == AST_NODE_KIND_LOCAL) { + AstNodeLocal* local = (AstNodeLocal *) symbol; local->prev_local = state->curr_scope->last_local; state->curr_scope->last_local = local; } - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); } -static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static void symbol_remove(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); @@ -52,11 +52,11 @@ static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol) { bh_table_delete(SemPassSymbol *, state->symbols, symbol->token->token); } - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); } -static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static AstNode* symbol_resolve(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); if (!bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { onyx_message_add(state->msgs, @@ -64,35 +64,35 @@ static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol) symbol->token->pos, symbol->token->token); - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return symbol; } SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return sp_sym->node; } -static void scope_enter(OnyxSemPassState* state, OnyxAstNodeScope* scope) { +static void scope_enter(OnyxSemPassState* state, AstNodeScope* scope) { scope->prev_scope = state->curr_scope; state->curr_scope = scope; } -static OnyxAstNodeScope* scope_leave(OnyxSemPassState* state) { +static AstNodeScope* scope_leave(OnyxSemPassState* state) { // NOTE: Can't leave a scope if there is no scope assert(state->curr_scope != NULL); - for (OnyxAstNodeLocal *walker = state->curr_scope->last_local; walker != NULL; walker = walker->prev_local) { - symbol_remove(state, (OnyxAstNode *) walker); + for (AstNodeLocal *walker = state->curr_scope->last_local; walker != NULL; walker = walker->prev_local) { + symbol_remove(state, (AstNode *) walker); } state->curr_scope = state->curr_scope->prev_scope; return state->curr_scope; } -static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static b32 symbol_unique_introduce(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); // NOTE: If the function hasn't already been defined if (!bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { @@ -107,51 +107,49 @@ static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) symbol->token->token); // NOTE: I really wish C had defer... - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return 0; } - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return 1; } -static void symres_local(OnyxSemPassState* state, OnyxAstNodeLocal** local) { - symbol_introduce(state, (OnyxAstNode *) *local); +static void symres_local(OnyxSemPassState* state, AstNodeLocal** local) { + symbol_introduce(state, (AstNode *) *local); } -static void symres_call(OnyxSemPassState* state, OnyxAstNode* stmt) { - OnyxAstNodeCall* call = &stmt->as_call; - - OnyxAstNode* callee = symbol_resolve(state, call->callee); +static void symres_call(OnyxSemPassState* state, AstNodeCall* call) { + AstNode* callee = symbol_resolve(state, call->callee); if (callee) call->callee = callee; else DEBUG_HERE; - symres_statement_chain(state, call->arguments, &call->arguments); + symres_statement_chain(state, (AstNode *) call->arguments, (AstNode **) &call->arguments); } -static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr) { +static void symres_expression(OnyxSemPassState* state, AstNode** expr) { switch ((*expr)->kind) { - case ONYX_AST_NODE_KIND_BIN_OP: - symres_expression(state, &(*expr)->left); - symres_expression(state, &(*expr)->right); + case AST_NODE_KIND_BIN_OP: + symres_expression(state, (AstNode **) &((AstNodeBinOp *)(*expr))->left); + symres_expression(state, (AstNode **) &((AstNodeBinOp *)(*expr))->right); break; - case ONYX_AST_NODE_KIND_UNARY_OP: - symres_expression(state, &(*expr)->left); + case AST_NODE_KIND_UNARY_OP: + symres_expression(state, (AstNode **) &((AstNodeUnaryOp *)(*expr))->expr); break; - case ONYX_AST_NODE_KIND_CALL: symres_call(state, *expr); break; + case AST_NODE_KIND_CALL: symres_call(state, (AstNodeCall *) *expr); break; - case ONYX_AST_NODE_KIND_BLOCK: symres_block(state, &(*expr)->as_block); break; + case AST_NODE_KIND_BLOCK: symres_block(state, (AstNodeBlock *) *expr); break; - case ONYX_AST_NODE_KIND_SYMBOL: + case AST_NODE_KIND_SYMBOL: *expr = symbol_resolve(state, *expr); break; // NOTE: This is a good case, since it means the symbol is already resolved - case ONYX_AST_NODE_KIND_LOCAL: break; + case AST_NODE_KIND_LOCAL: break; - case ONYX_AST_NODE_KIND_LITERAL: break; + case AST_NODE_KIND_LITERAL: break; default: DEBUG_HERE; @@ -159,69 +157,69 @@ static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr) { } } -static void symres_assignment(OnyxSemPassState* state, OnyxAstNode* assign) { - OnyxAstNode* lval = symbol_resolve(state, assign->left); +static void symres_assignment(OnyxSemPassState* state, AstNodeAssign* assign) { + AstNodeTyped* lval = (AstNodeTyped *) symbol_resolve(state, (AstNode *) assign->lval); if (lval == NULL) return; - assign->left = lval; + assign->lval = lval; - symres_expression(state, &assign->right); + symres_expression(state, (AstNode **) &assign->expr); } -static void symres_return(OnyxSemPassState* state, OnyxAstNode* ret) { - if (ret->left) - symres_expression(state, &ret->left); +static void symres_return(OnyxSemPassState* state, AstNodeReturn* ret) { + if (ret->expr) + symres_expression(state, (AstNode **) &ret->expr); } -static void symres_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { - symres_expression(state, &ifnode->cond); +static void symres_if(OnyxSemPassState* state, AstNodeIf* ifnode) { + symres_expression(state, (AstNode **) &ifnode->cond); if (ifnode->true_block) { - if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_BLOCK) - symres_block(state, &ifnode->true_block->as_block); + if (ifnode->true_block->kind == AST_NODE_KIND_BLOCK) + symres_block(state, (AstNodeBlock *) ifnode->true_block); - else if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_IF) - symres_if(state, &ifnode->true_block->as_if); + else if (ifnode->true_block->kind == AST_NODE_KIND_IF) + symres_if(state, (AstNodeIf *) ifnode->true_block); else DEBUG_HERE; } if (ifnode->false_block) { - if (ifnode->false_block->kind == ONYX_AST_NODE_KIND_BLOCK) - symres_block(state, &ifnode->false_block->as_block); + if (ifnode->false_block->kind == AST_NODE_KIND_BLOCK) + symres_block(state, (AstNodeBlock *) ifnode->false_block); - else if (ifnode->false_block->kind == ONYX_AST_NODE_KIND_IF) - symres_if(state, &ifnode->false_block->as_if); + else if (ifnode->false_block->kind == AST_NODE_KIND_IF) + symres_if(state, (AstNodeIf *) ifnode->false_block); else DEBUG_HERE; } } -static void symres_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode) { - symres_expression(state, &whilenode->cond); +static void symres_while(OnyxSemPassState* state, AstNodeWhile* whilenode) { + symres_expression(state, (AstNode **) &whilenode->cond); symres_block(state, whilenode->body); } // NOTE: Returns 1 if the statment should be removed -static b32 symres_statement(OnyxSemPassState* state, OnyxAstNode* stmt) { +static b32 symres_statement(OnyxSemPassState* state, AstNode* stmt) { switch (stmt->kind) { - case ONYX_AST_NODE_KIND_LOCAL: symres_local(state, (OnyxAstNodeLocal **) &stmt); return 1; - case ONYX_AST_NODE_KIND_ASSIGNMENT: symres_assignment(state, stmt); return 0; - case ONYX_AST_NODE_KIND_RETURN: symres_return(state, stmt); return 0; - case ONYX_AST_NODE_KIND_IF: symres_if(state, &stmt->as_if); return 0; - case ONYX_AST_NODE_KIND_WHILE: symres_while(state, &stmt->as_while); return 0; - case ONYX_AST_NODE_KIND_CALL: symres_call(state, stmt); return 0; - case ONYX_AST_NODE_KIND_ARGUMENT: symres_expression(state, (OnyxAstNode **) &stmt->left); return 0; - case ONYX_AST_NODE_KIND_BLOCK: symres_block(state, &stmt->as_block); return 0; + case AST_NODE_KIND_LOCAL: symres_local(state, (AstNodeLocal **) &stmt); return 1; + case AST_NODE_KIND_ASSIGNMENT: symres_assignment(state, (AstNodeAssign *) stmt); return 0; + case AST_NODE_KIND_RETURN: symres_return(state, (AstNodeReturn *) stmt); return 0; + case AST_NODE_KIND_IF: symres_if(state, (AstNodeIf *) stmt); return 0; + case AST_NODE_KIND_WHILE: symres_while(state, (AstNodeWhile *) stmt); return 0; + case AST_NODE_KIND_CALL: symres_call(state, (AstNodeCall *) stmt); return 0; + case AST_NODE_KIND_ARGUMENT: symres_expression(state, (AstNode **) &((AstNodeArgument *)stmt)->value); return 0; + case AST_NODE_KIND_BLOCK: symres_block(state, (AstNodeBlock *) stmt); return 0; default: return 0; } } -static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, OnyxAstNode** trailer) { +static void symres_statement_chain(OnyxSemPassState* state, AstNode* walker, AstNode** trailer) { while (walker) { if (symres_statement(state, walker)) { *trailer = walker->next; - OnyxAstNode* tmp = walker->next; + AstNode* tmp = walker->next; walker->next = NULL; walker = tmp; } else { @@ -231,43 +229,43 @@ static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, } } -static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) { +static void symres_block(OnyxSemPassState* state, AstNodeBlock* block) { scope_enter(state, block->scope); if (block->body) symres_statement_chain(state, block->body, &block->body); scope_leave(state); } -static void symres_function(OnyxSemPassState* state, OnyxAstNodeFunction* func) { - forll(OnyxAstNodeParam, param, func->params, next) { - symbol_introduce(state, (OnyxAstNode *) param); +static void symres_function(OnyxSemPassState* state, AstNodeFunction* func) { + for (AstNodeLocal *param = func->params; param != NULL; param = (AstNodeLocal *) param->base.next) { + symbol_introduce(state, (AstNode *) param); } symres_block(state, func->body); - forll(OnyxAstNodeParam, param, func->params, next) { - symbol_remove(state, (OnyxAstNode *) param); + for (AstNodeLocal *param = func->params; param != NULL; param = (AstNodeLocal *) param->base.next) { + symbol_remove(state, (AstNode *) param); } } void onyx_resolve_symbols(OnyxSemPassState* state, OnyxProgram* program) { // NOTE: First, introduce all global symbols - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) - if (!symbol_unique_introduce(state, (OnyxAstNode *) *global)) return; + bh_arr_each(AstNodeGlobal *, global, program->globals) + if (!symbol_unique_introduce(state, (AstNode *) *global)) return; - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) - if (!symbol_unique_introduce(state, (OnyxAstNode *) *function)) return; + bh_arr_each(AstNodeFunction *, function, program->functions) + if (!symbol_unique_introduce(state, (AstNode *) *function)) return; - bh_arr_each(OnyxAstNodeForeign *, foreign, program->foreigns) { - OnyxAstNodeKind import_kind = (*foreign)->import->kind; + bh_arr_each(AstNodeForeign *, foreign, program->foreigns) { + AstNodeKind import_kind = (*foreign)->import->kind; - if (import_kind == ONYX_AST_NODE_KIND_FUNCTION || import_kind == ONYX_AST_NODE_KIND_GLOBAL) + if (import_kind == AST_NODE_KIND_FUNCTION || import_kind == AST_NODE_KIND_GLOBAL) if (!symbol_unique_introduce(state, (*foreign)->import)) return; } // NOTE: Then, resolve all symbols in all functions - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) symres_function(state, *function); } diff --git a/src/onyxtypecheck.c b/src/onyxtypecheck.c index 9d2f96e3..1cc14cde 100644 --- a/src/onyxtypecheck.c +++ b/src/onyxtypecheck.c @@ -1,81 +1,81 @@ #define BH_DEBUG #include "onyxsempass.h" -static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* func); -static void typecheck_block(OnyxSemPassState* state, OnyxAstNodeBlock* block); -static void typecheck_statement_chain(OnyxSemPassState* state, OnyxAstNode* start); -static void typecheck_statement(OnyxSemPassState* state, OnyxAstNode* stmt); -static void typecheck_assignment(OnyxSemPassState* state, OnyxAstNode* assign); -static void typecheck_return(OnyxSemPassState* state, OnyxAstNode* retnode); -static void typecheck_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode); -static void typecheck_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode); -static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call); -static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr); -static void typecheck_global(OnyxSemPassState* state, OnyxAstNodeGlobal* global); - -static void typecheck_assignment(OnyxSemPassState* state, OnyxAstNode* assign) { - if (assign->left->kind == ONYX_AST_NODE_KIND_SYMBOL) { +static void typecheck_function(OnyxSemPassState* state, AstNodeFunction* func); +static void typecheck_block(OnyxSemPassState* state, AstNodeBlock* block); +static void typecheck_statement_chain(OnyxSemPassState* state, AstNode* start); +static void typecheck_statement(OnyxSemPassState* state, AstNode* stmt); +static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign); +static void typecheck_return(OnyxSemPassState* state, AstNodeReturn* retnode); +static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode); +static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode); +static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call); +static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr); +static void typecheck_global(OnyxSemPassState* state, AstNodeGlobal* global); + +static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign) { + if (assign->lval->kind == AST_NODE_KIND_SYMBOL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, - assign->left->token->pos, - assign->left->token->token, assign->left->token->length); + assign->lval->token->pos, + assign->lval->token->token, assign->lval->token->length); return; } - if ((assign->left->flags & ONYX_AST_FLAG_CONST) != 0 && assign->left->type->is_known) { + if ((assign->lval->flags & ONYX_AST_FLAG_CONST) != 0 && assign->lval->type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_ASSIGN_CONST, - assign->token->pos, - assign->left->token->token, assign->left->token->length); + assign->base.token->pos, + assign->lval->token->token, assign->lval->token->length); return; } - if ((assign->left->flags & ONYX_AST_FLAG_LVAL) == 0) { + if ((assign->lval->flags & ONYX_AST_FLAG_LVAL) == 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_NOT_LVAL, - assign->token->pos, - assign->left->token->token, assign->left->token->length); + assign->base.token->pos, + assign->lval->token->token, assign->lval->token->length); return; } - typecheck_expression(state, assign->right); + typecheck_expression(state, assign->expr); - if (!assign->left->type->is_known) { - assign->left->type = assign->right->type; + if (!assign->lval->type->is_known) { + assign->lval->type = assign->expr->type; } else { - if (assign->left->type != assign->right->type) { + if (assign->lval->type != assign->expr->type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_ASSIGNMENT_TYPE_MISMATCH, - assign->token->pos, - assign->left->type->name, assign->right->type->name); + assign->base.token->pos, + assign->lval->type->name, assign->expr->type->name); return; } } } -static void typecheck_return(OnyxSemPassState* state, OnyxAstNode* retnode) { - if (retnode->left) { - typecheck_expression(state, retnode->left); +static void typecheck_return(OnyxSemPassState* state, AstNodeReturn* retnode) { + if (retnode->expr) { + typecheck_expression(state, retnode->expr); - if (retnode->left->type != state->expected_return_type) { + if (retnode->expr->type != state->expected_return_type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_FUNCTION_RETURN_MISMATCH, - retnode->left->token->pos, - retnode->left->type->name, state->expected_return_type->name); + retnode->expr->token->pos, + retnode->expr->type->name, state->expected_return_type->name); } } else { if (state->expected_return_type->size > 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - retnode->token->pos, + retnode->base.token->pos, "returning from non-void function without value"); } } } -static void typecheck_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { +static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode) { typecheck_expression(state, ifnode->cond); - if (ifnode->cond->type != &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]) { + if (ifnode->cond->type != &builtin_types[TYPE_INFO_KIND_BOOL]) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, ifnode->cond->token->pos, @@ -87,9 +87,9 @@ static void typecheck_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { if (ifnode->false_block) typecheck_statement(state, ifnode->false_block); } -static void typecheck_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode) { +static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode) { typecheck_expression(state, whilenode->cond); - if (whilenode->cond->type != &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]) { + if (whilenode->cond->type != &builtin_types[TYPE_INFO_KIND_BOOL]) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, whilenode->cond->token->pos, @@ -100,53 +100,53 @@ static void typecheck_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode typecheck_block(state, whilenode->body); } -static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call) { - OnyxAstNodeFunction* callee = (OnyxAstNodeFunction *) call->callee; +static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call) { + AstNodeFunction* callee = (AstNodeFunction *) call->callee; - if (callee->kind == ONYX_AST_NODE_KIND_SYMBOL) { + if (callee->base.kind == AST_NODE_KIND_SYMBOL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, - callee->token->pos, - callee->token->token, callee->token->length); + callee->base.token->pos, + callee->base.token->token, callee->base.token->length); return; } - if (callee->kind != ONYX_AST_NODE_KIND_FUNCTION) { + if (callee->base.kind != AST_NODE_KIND_FUNCTION) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION, - call->token->pos, - callee->token->token, callee->token->length); + call->base.token->pos, + callee->base.token->token, callee->base.token->length); return; } - call->type = callee->return_type; + call->base.type = callee->base.type; - OnyxAstNodeParam* formal_param = callee->params; - OnyxAstNode* actual_param = call->arguments; + AstNodeLocal* formal_param = callee->params; + AstNodeArgument* actual_param = call->arguments; i32 arg_pos = 0; while (formal_param != NULL && actual_param != NULL) { - typecheck_expression(state, actual_param); + typecheck_expression(state, (AstNodeTyped *) actual_param); - if (formal_param->type != actual_param->type) { + if (formal_param->base.type != actual_param->base.type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_FUNCTION_PARAM_TYPE_MISMATCH, - call->token->pos, - callee->token->token, callee->token->length, - formal_param->type->name, arg_pos, - actual_param->type->name); + call->base.token->pos, + callee->base.token->token, callee->base.token->length, + formal_param->base.type->name, arg_pos, + actual_param->base.type->name); return; } arg_pos++; - formal_param = formal_param->next; - actual_param = actual_param->next; + formal_param = (AstNodeLocal *) formal_param->base.next; + actual_param = (AstNodeArgument *) actual_param->base.next; } if (formal_param != NULL && actual_param == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - call->token->pos, + call->base.token->pos, "too few arguments to function call"); return; } @@ -154,21 +154,21 @@ static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call) { if (formal_param == NULL && actual_param != NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - call->token->pos, + call->base.token->pos, "too many arguments to function call"); return; } } -static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { +static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr) { switch (expr->kind) { - case ONYX_AST_NODE_KIND_BIN_OP: - expr->type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + case AST_NODE_KIND_BIN_OP: + expr->type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; - typecheck_expression(state, expr->left); - typecheck_expression(state, expr->right); + typecheck_expression(state, ((AstNodeBinOp *) expr)->left); + typecheck_expression(state, ((AstNodeBinOp *) expr)->right); - if (expr->left->type == NULL) { + if (((AstNodeBinOp *) expr)->left->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, expr->token->pos, @@ -176,7 +176,7 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { return; } - if (expr->right->type == NULL) { + if (((AstNodeBinOp *) expr)->right->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, expr->token->pos, @@ -184,48 +184,48 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { return; } - if (expr->left->type != expr->right->type) { + if (((AstNodeBinOp *) expr)->left->type != ((AstNodeBinOp *) expr)->right->type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE, expr->token->pos, - expr->left->type->name, - expr->right->type->name); + ((AstNodeBinOp *) expr)->left->type->name, + ((AstNodeBinOp *) expr)->right->type->name); return; } - if (expr->as_binop.operation >= ONYX_BINARY_OP_EQUAL - && expr->as_binop.operation <= ONYX_BINARY_OP_GREATER_EQUAL) { - expr->type = &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]; + if (((AstNodeBinOp *) expr)->operation >= ONYX_BINARY_OP_EQUAL + && ((AstNodeBinOp *) expr)->operation <= ONYX_BINARY_OP_GREATER_EQUAL) { + expr->type = &builtin_types[TYPE_INFO_KIND_BOOL]; } else { - expr->type = expr->left->type; + expr->type = ((AstNodeBinOp *) expr)->left->type; } break; - case ONYX_AST_NODE_KIND_UNARY_OP: - if (expr->as_unaryop.operation != ONYX_UNARY_OP_CAST) { - typecheck_expression(state, expr->left); - expr->type = expr->left->type; + case AST_NODE_KIND_UNARY_OP: + if (((AstNodeUnaryOp *) expr)->operation != ONYX_UNARY_OP_CAST) { + typecheck_expression(state, ((AstNodeUnaryOp *) expr)->expr); + expr->type = ((AstNodeUnaryOp *) expr)->expr->type; } break; - case ONYX_AST_NODE_KIND_CALL: - typecheck_call(state, &expr->as_call); + case AST_NODE_KIND_CALL: + typecheck_call(state, (AstNodeCall *) expr); break; - case ONYX_AST_NODE_KIND_BLOCK: - typecheck_block(state, &expr->as_block); + case AST_NODE_KIND_BLOCK: + typecheck_block(state, (AstNodeBlock *) expr); break; - case ONYX_AST_NODE_KIND_SYMBOL: + case AST_NODE_KIND_SYMBOL: onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, expr->token->pos, expr->token->token, expr->token->length); break; - case ONYX_AST_NODE_KIND_LOCAL: - case ONYX_AST_NODE_KIND_PARAM: + case AST_NODE_KIND_LOCAL: + case AST_NODE_KIND_PARAM: if (!expr->type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, @@ -234,7 +234,7 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { } break; - case ONYX_AST_NODE_KIND_GLOBAL: + case AST_NODE_KIND_GLOBAL: if (!expr->type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, @@ -243,12 +243,12 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { } break; - case ONYX_AST_NODE_KIND_ARGUMENT: - typecheck_expression(state, expr->left); - expr->type = expr->left->type; + case AST_NODE_KIND_ARGUMENT: + typecheck_expression(state, ((AstNodeArgument *) expr)->value); + expr->type = ((AstNodeArgument *) expr)->value->type; break; - case ONYX_AST_NODE_KIND_LITERAL: + case AST_NODE_KIND_LITERAL: // NOTE: Literal types should have been decided // in the parser (for now). assert(expr->type->is_known); @@ -260,88 +260,88 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { } } -static void typecheck_global(OnyxSemPassState* state, OnyxAstNodeGlobal* global) { +static void typecheck_global(OnyxSemPassState* state, AstNodeGlobal* global) { if (global->initial_value) { typecheck_expression(state, global->initial_value); - if (global->type->is_known) { - if (global->type != global->initial_value->type) { + if (global->base.type->is_known) { + if (global->base.type != global->initial_value->type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_GLOBAL_TYPE_MISMATCH, - global->token->pos, - global->token->token, global->token->length, - global->type->name, global->initial_value->type->name); + global->base.token->pos, + global->base.token->token, global->base.token->length, + global->base.type->name, global->initial_value->type->name); return; } } else { if (global->initial_value->type) - global->type = global->initial_value->type; + global->base.type = global->initial_value->type; } } else { - if (!global->type || !global->type->is_known) { + if (!global->base.type || !global->base.type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - global->token->pos, + global->base.token->pos, "global variable with unknown type"); } } } -static void typecheck_statement(OnyxSemPassState* state, OnyxAstNode* stmt) { +static void typecheck_statement(OnyxSemPassState* state, AstNode* stmt) { switch (stmt->kind) { - case ONYX_AST_NODE_KIND_ASSIGNMENT: typecheck_assignment(state, stmt); break; - case ONYX_AST_NODE_KIND_RETURN: typecheck_return(state, stmt); break; - case ONYX_AST_NODE_KIND_IF: typecheck_if(state, &stmt->as_if); break; - case ONYX_AST_NODE_KIND_WHILE: typecheck_while(state, &stmt->as_while); break; - case ONYX_AST_NODE_KIND_CALL: typecheck_call(state, &stmt->as_call); break; - case ONYX_AST_NODE_KIND_BLOCK: typecheck_block(state, &stmt->as_block); break; + case AST_NODE_KIND_ASSIGNMENT: typecheck_assignment(state, (AstNodeAssign *) stmt); break; + case AST_NODE_KIND_RETURN: typecheck_return(state, (AstNodeReturn *) stmt); break; + case AST_NODE_KIND_IF: typecheck_if(state, (AstNodeIf *) stmt); break; + case AST_NODE_KIND_WHILE: typecheck_while(state, (AstNodeWhile *) stmt); break; + case AST_NODE_KIND_CALL: typecheck_call(state, (AstNodeCall *) stmt); break; + case AST_NODE_KIND_BLOCK: typecheck_block(state, (AstNodeBlock *) stmt); break; default: break; } } -static void typecheck_statement_chain(OnyxSemPassState* state, OnyxAstNode* start) { +static void typecheck_statement_chain(OnyxSemPassState* state, AstNode* start) { while (start) { typecheck_statement(state, start); start = start->next; } } -static void typecheck_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) { +static void typecheck_block(OnyxSemPassState* state, AstNodeBlock* block) { typecheck_statement_chain(state, block->body); - forll(OnyxAstNodeLocal, local, block->scope->last_local, prev_local) { - if (!local->type->is_known) { + forll(AstNodeLocal, local, block->scope->last_local, prev_local) { + if (!local->base.type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, - local->token->pos, - local->token->token, local->token->length); + local->base.token->pos, + local->base.token->token, local->base.token->length); return; } } } -static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* func) { - forll(OnyxAstNodeParam, param, func->params, next) { - if (!param->type->is_known) { +static void typecheck_function(OnyxSemPassState* state, AstNodeFunction* func) { + for (AstNodeLocal *param = func->params; param != NULL; param = (AstNodeLocal *) param->base.next) { + if (!param->base.type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - param->token->pos, + param->base.token->pos, "function parameter types must be known"); return; } - if (param->type->size == 0) { + if (param->base.type->size == 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - param->token->pos, + param->base.token->pos, "function parameters must have non-void types"); return; } } - state->expected_return_type = func->return_type; + state->expected_return_type = func->base.type; if (func->body) { typecheck_block(state, func->body); } @@ -349,9 +349,9 @@ static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* fun void onyx_type_check(OnyxSemPassState* state, OnyxProgram* program) { - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) + bh_arr_each(AstNodeGlobal *, global, program->globals) typecheck_global(state, *global); - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) typecheck_function(state, *function); } diff --git a/src/onyxutils.c b/src/onyxutils.c index 20726026..b5537cb4 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -10,208 +10,182 @@ bh_allocator global_heap_allocator; #define print_indent { if (indent > 0) bh_printf("\n"); for (int i = 0; i < indent; i++) bh_printf(" "); } -void onyx_ast_print(OnyxAstNode* node, i32 indent) { - if (node == NULL) return; - - print_indent; - bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind)); - - switch (node->kind) { - case ONYX_AST_NODE_KIND_USE: { - OnyxAstNodeUse* use_node = &node->as_use; - bh_printf("%b", use_node->filename->token, use_node->filename->length); - - if (use_node->next) - onyx_ast_print(use_node->next, indent); - - break; - } - - case ONYX_AST_NODE_KIND_FUNCTION: { - if (node->token) - bh_printf("(%b) ", node->token->token, node->token->length); - OnyxAstNodeFunction* fd = &node->as_function; - +void onyx_ast_print(AstNode* node, i32 indent) { + while (node) { print_indent; - bh_printf("Params "); - if (fd->params) - onyx_ast_print((OnyxAstNode *) fd->params, 0); + bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind)); - print_indent; - bh_printf("Returns %s", fd->return_type->name); + switch (node->kind) { + case AST_NODE_KIND_USE: { + AstNodeUse* use_node = (AstNodeUse *) node; + bh_printf("%b", use_node->filename->token, use_node->filename->length); - print_indent; - bh_printf("Body"); - if (fd->body) - onyx_ast_print((OnyxAstNode *) fd->body, indent + 1); + break; + } - if (fd->next) - onyx_ast_print((OnyxAstNode *) fd->next, indent); + case AST_NODE_KIND_FUNCTION: { + if (node->token) + bh_printf("(%b) ", node->token->token, node->token->length); + AstNodeFunction* fd = (AstNodeFunction *) node; - break; - } + print_indent; + bh_printf("Params "); + if (fd->params) + onyx_ast_print((AstNode *) fd->params, 0); - case ONYX_AST_NODE_KIND_PARAM: { - OnyxAstNodeParam* param = &node->as_param; - bh_printf("%b %s", param->token->token, param->token->length, param->type->name); - if (param->next && indent == 0) { - bh_printf(", "); - onyx_ast_print((OnyxAstNode *) param->next, 0); - } + print_indent; + bh_printf("Returns %s", fd->base.type->name); - break; - } + print_indent; + bh_printf("Body"); + if (fd->body) + onyx_ast_print((AstNode *) fd->body, indent + 1); - case ONYX_AST_NODE_KIND_BLOCK: { - OnyxAstNodeBlock* block = &node->as_block; - if (block->scope) { - onyx_ast_print((OnyxAstNode *) block->scope, indent + 1); + break; } - if (block->body) { - onyx_ast_print((OnyxAstNode *) block->body, indent + 1); - } + case AST_NODE_KIND_PARAM: { + AstNodeLocal* param = (AstNodeLocal *) node; + bh_printf("%b %s", param->base.token->token, param->base.token->length, param->base.type->name); + if (param->base.next && indent == 0) { + bh_printf(", "); + onyx_ast_print((AstNode *) param->base.next, 0); + } - if (block->next) { - onyx_ast_print(block->next, indent); + return; } - break; - } + case AST_NODE_KIND_BLOCK: { + AstNodeBlock* block = (AstNodeBlock *) node; + if (block->scope) { + onyx_ast_print((AstNode *) block->scope, indent + 1); + } - case ONYX_AST_NODE_KIND_SCOPE: { - OnyxAstNodeScope* scope = &node->as_scope; - if (scope->last_local) { - onyx_ast_print((OnyxAstNode *) scope->last_local, 0); + if (block->body) { + onyx_ast_print((AstNode *) block->body, indent + 1); + } + + break; } - break; - } + case AST_NODE_KIND_SCOPE: { + AstNodeScope* scope = (AstNodeScope *) scope; + if (scope->last_local) { + onyx_ast_print((AstNode *) scope->last_local, 0); + } - case ONYX_AST_NODE_KIND_LOCAL: { - OnyxAstNodeLocal* local = &node->as_local; - bh_printf("%b %s", local->token->token, local->token->length, local->type->name); - if (local->prev_local && indent == 0) { - bh_printf(", "); - onyx_ast_print((OnyxAstNode *) local->prev_local, 0); - } else if (local->next && indent != 0) { - onyx_ast_print(local->next, indent); + break; } - break; - } - case ONYX_AST_NODE_KIND_GLOBAL: { - OnyxAstNodeGlobal* global = &node->as_global; - bh_printf("%b %s", global->token->token, global->token->length, global->type->name); - if (global->initial_value) { - onyx_ast_print(global->initial_value, indent + 1); + case AST_NODE_KIND_LOCAL: { + AstNodeLocal* local = (AstNodeLocal *) node; + bh_printf("%b %s", local->base.token->token, local->base.token->length, local->base.type->name); + if (local->prev_local && indent == 0) { + bh_printf(", "); + onyx_ast_print((AstNode *) local->prev_local, 0); + } + break; } - if (node->next) { - onyx_ast_print(node->next, indent); + case AST_NODE_KIND_GLOBAL: { + AstNodeGlobal* global = (AstNodeGlobal *) node; + bh_printf("%b %s", global->base.token->token, global->base.token->length, global->base.type->name); + if (global->initial_value) { + onyx_ast_print((AstNode *) global->initial_value, indent + 1); + } + + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; } - break; - } - case ONYX_AST_NODE_KIND_SYMBOL: { - bh_printf("%b", node->token->token, node->token->length); - if (node->next) { - onyx_ast_print(node->next, indent); + case AST_NODE_KIND_SYMBOL: { + bh_printf("%b", node->token->token, node->token->length); + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; } - break; - } - case ONYX_AST_NODE_KIND_RETURN: { - if (node->left) { - onyx_ast_print(node->left, indent + 1); + case AST_NODE_KIND_RETURN: { + AstNodeReturn* ret = (AstNodeReturn *) node; + if (ret->expr) { + onyx_ast_print((AstNode *) ret->expr, indent + 1); + } + + break; } - break; - } + case AST_NODE_KIND_LITERAL: { + AstNodeNumLit* lit = (AstNodeNumLit *) node; + bh_printf("(%s) %b", lit->base.type->name, lit->base.token->token, lit->base.token->length); - case ONYX_AST_NODE_KIND_LITERAL: { - bh_printf("(%s) %b", node->type->name, node->token->token, node->token->length); - if (node->next) { - onyx_ast_print(node->next, indent); + break; } - break; - } - case ONYX_AST_NODE_KIND_CALL: { - OnyxAstNodeCall* call = &node->as_call; - if (call->callee) { - if (call->callee->kind == ONYX_AST_NODE_KIND_FUNCTION) { - bh_printf("function: %b", call->callee->token->token, call->callee->token->length); - } else { - onyx_ast_print(call->callee, indent + 1); + case AST_NODE_KIND_CALL: { + AstNodeCall* call = (AstNodeCall *) node; + if (call->callee) { + if (call->callee->kind == AST_NODE_KIND_FUNCTION) { + bh_printf("function: %b", call->callee->token->token, call->callee->token->length); + } else { + onyx_ast_print(call->callee, indent + 1); + } } + onyx_ast_print((AstNode *) call->arguments, indent + 1); + + break; } - onyx_ast_print(call->arguments, indent + 1); - if (call->next) { - onyx_ast_print(call->next, indent); - } - break; - } - case ONYX_AST_NODE_KIND_FOREIGN: { - OnyxAstNodeForeign* foreign = &node->as_foreign; - bh_printf("%b:%b", - foreign->mod_token->token, foreign->mod_token->length, - foreign->name_token->token, foreign->name_token->length); + case AST_NODE_KIND_FOREIGN: { + AstNodeForeign* foreign = (AstNodeForeign *) node; + bh_printf("%b:%b", + foreign->mod_token->token, foreign->mod_token->length, + foreign->name_token->token, foreign->name_token->length); - if (foreign->import) { - onyx_ast_print(foreign->import, indent + 1); - } + if (foreign->import) { + onyx_ast_print(foreign->import, indent + 1); + } - if (foreign->next) { - onyx_ast_print(foreign->next, indent); + break; } - break; - } - case ONYX_AST_NODE_KIND_IF: { - OnyxAstNodeIf* if_node = &node->as_if; - if (if_node->cond) { - print_indent; - bh_printf("Condition:"); - onyx_ast_print(if_node->cond, indent + 1); - } - if (if_node->true_block) { - print_indent; - bh_printf("True block:"); - onyx_ast_print(if_node->true_block, indent + 1); - } - if (if_node->false_block) { - print_indent; - bh_printf("False block:"); - onyx_ast_print(if_node->false_block, indent + 1); - } - if (if_node->next) { - onyx_ast_print(if_node->next, indent); + case AST_NODE_KIND_IF: { + AstNodeIf* if_node = (AstNodeIf *) node; + if (if_node->cond) { + print_indent; + bh_printf("Condition:"); + onyx_ast_print((AstNode *) if_node->cond, indent + 1); + } + if (if_node->true_block) { + print_indent; + bh_printf("True block:"); + onyx_ast_print(if_node->true_block, indent + 1); + } + if (if_node->false_block) { + print_indent; + bh_printf("False block:"); + onyx_ast_print(if_node->false_block, indent + 1); + } + + break; } - break; - } - case ONYX_AST_NODE_KIND_BIN_OP: { - OnyxAstNodeBinOp* binop = &node->as_binop; - bh_printf("%b", binop->token->token, binop->token->length); + case AST_NODE_KIND_BIN_OP: { + AstNodeBinOp* binop = (AstNodeBinOp *) node; + bh_printf("%b", binop->base.token->token, binop->base.token->length); - onyx_ast_print(node->left, indent + 1); - onyx_ast_print(node->right, indent + 1); - if (node->next) { - onyx_ast_print(node->next, indent); - } + onyx_ast_print((AstNode *) binop->left, indent + 1); + onyx_ast_print((AstNode *) binop->right, indent + 1); - break; - } + break; + } - default: { - onyx_ast_print(node->left, indent + 1); - onyx_ast_print(node->right, indent + 1); - if (node->next) { - onyx_ast_print(node->next, indent); + default: + break; } - break; - } + + node = node->next; } } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 206883f2..f8796556 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -195,7 +195,7 @@ static const char* wi_string(WasmInstructionType wit) { } } -static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) { +static WasmType onyx_type_to_wasm_type(TypeInfo* type) { if (type->is_bool) return WASM_TYPE_INT32; else if (type->is_int) { if (type->size == 4) return WASM_TYPE_INT32; @@ -209,25 +209,25 @@ static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) { return WASM_TYPE_VOID; } -static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFunction* fd); -static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBlock* block); -static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* stmt); -static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* lval); -static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* assign); -static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeIf* if_node); -static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeWhile* while_node); -static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBinOp* binop); -static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* unop); -static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* expr); -static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* cast); -static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* ret); - -static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFunction* fd) { +static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeFunction* fd); +static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBlock* block); +static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNode* stmt); +static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* lval); +static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeAssign* assign); +static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeIf* if_node); +static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeWhile* while_node); +static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBinOp* binop); +static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* unop); +static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* expr); +static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* cast); +static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeReturn* ret); + +static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeFunction* fd) { if (fd->body == NULL) return; bh_arr(WasmInstruction) code = *pcode; - forll (OnyxAstNode, stmt, fd->body->body, next) { + forll (AstNode, stmt, fd->body->body, next) { compile_statement(mod, &code, stmt); } @@ -236,12 +236,12 @@ static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* *pcode = code; } -static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBlock* block) { +static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBlock* block) { bh_arr(WasmInstruction) code = *pcode; bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_START, 0x40 })); - forll (OnyxAstNode, stmt, block->body, next) { + forll (AstNode, stmt, block->body, next) { compile_statement(mod, &code, stmt); } @@ -276,19 +276,19 @@ static void compile_structured_jump(OnyxWasmModule* mod, bh_arr(WasmInstruction) *pcode = code; } -static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* stmt) { +static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNode* stmt) { bh_arr(WasmInstruction) code = *pcode; switch (stmt->kind) { - case ONYX_AST_NODE_KIND_SCOPE: break; - case ONYX_AST_NODE_KIND_RETURN: compile_return(mod, &code, stmt); break; - case ONYX_AST_NODE_KIND_ASSIGNMENT: compile_assignment(mod, &code, stmt); break; - case ONYX_AST_NODE_KIND_IF: compile_if(mod, &code, (OnyxAstNodeIf *) stmt); break; - case ONYX_AST_NODE_KIND_WHILE: compile_while(mod, &code, (OnyxAstNodeWhile *) stmt); break; - case ONYX_AST_NODE_KIND_BREAK: compile_structured_jump(mod, &code, 0); break; - case ONYX_AST_NODE_KIND_CONTINUE: compile_structured_jump(mod, &code, 1); break; - case ONYX_AST_NODE_KIND_CALL: compile_expression(mod, &code, stmt); break; - case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, &code, (OnyxAstNodeBlock *) stmt); break; + case AST_NODE_KIND_SCOPE: break; + case AST_NODE_KIND_RETURN: compile_return(mod, &code, (AstNodeReturn *) stmt); break; + case AST_NODE_KIND_ASSIGNMENT: compile_assignment(mod, &code, (AstNodeAssign *) stmt); break; + case AST_NODE_KIND_IF: compile_if(mod, &code, (AstNodeIf *) stmt); break; + case AST_NODE_KIND_WHILE: compile_while(mod, &code, (AstNodeWhile *) stmt); break; + case AST_NODE_KIND_BREAK: compile_structured_jump(mod, &code, 0); break; + case AST_NODE_KIND_CONTINUE: compile_structured_jump(mod, &code, 1); break; + case AST_NODE_KIND_CALL: compile_expression(mod, &code, (AstNodeTyped *) stmt); break; + case AST_NODE_KIND_BLOCK: compile_block(mod, &code, (AstNodeBlock *) stmt); break; default: break; } @@ -296,15 +296,15 @@ static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcod *pcode = code; } -static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* lval) { +static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* lval) { bh_arr(WasmInstruction) code = *pcode; - if (lval->kind == ONYX_AST_NODE_KIND_LOCAL || lval->kind == ONYX_AST_NODE_KIND_PARAM) { + if (lval->kind == AST_NODE_KIND_LOCAL || lval->kind == AST_NODE_KIND_PARAM) { i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) lval); bh_arr_push(code, ((WasmInstruction){ WI_LOCAL_SET, localidx })); - } else if (lval->kind == ONYX_AST_NODE_KIND_GLOBAL) { + } else if (lval->kind == AST_NODE_KIND_GLOBAL) { i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) lval); bh_arr_push(code, ((WasmInstruction){ WI_GLOBAL_SET, globalidx })); @@ -316,7 +316,7 @@ static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pc *pcode = code; } -static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeIf* if_node) { +static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeIf* if_node) { bh_arr(WasmInstruction) code = *pcode; compile_expression(mod, &code, if_node->cond); @@ -327,12 +327,12 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, Onyx if (if_node->true_block) { // NOTE: This is kind of gross, but making a function for this doesn't feel right - if (if_node->true_block->kind == ONYX_AST_NODE_KIND_IF) { - forll (OnyxAstNode, stmt, if_node->true_block, next) { + if (if_node->true_block->kind == AST_NODE_KIND_IF) { + forll (AstNode, stmt, if_node->true_block, next) { compile_statement(mod, &code, stmt); } - } else if (if_node->true_block->kind == ONYX_AST_NODE_KIND_BLOCK) { - forll (OnyxAstNode, stmt, if_node->true_block->as_block.body, next) { + } else if (if_node->true_block->kind == AST_NODE_KIND_BLOCK) { + forll (AstNode, stmt, ((AstNodeBlock *) if_node->true_block)->body, next) { compile_statement(mod, &code, stmt); } } @@ -341,12 +341,12 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, Onyx if (if_node->false_block) { bh_arr_push(code, ((WasmInstruction){ WI_ELSE, 0x00 })); - if (if_node->false_block->kind == ONYX_AST_NODE_KIND_IF) { - forll (OnyxAstNode, stmt, if_node->false_block, next) { + if (if_node->false_block->kind == AST_NODE_KIND_IF) { + forll (AstNode, stmt, if_node->false_block, next) { compile_statement(mod, &code, stmt); } - } else if (if_node->false_block->kind == ONYX_AST_NODE_KIND_BLOCK) { - forll (OnyxAstNode, stmt, if_node->false_block->as_block.body, next) { + } else if (if_node->false_block->kind == AST_NODE_KIND_BLOCK) { + forll (AstNode, stmt, ((AstNodeBlock *) if_node->false_block)->body, next) { compile_statement(mod, &code, stmt); } } @@ -359,7 +359,7 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, Onyx *pcode = code; } -static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeWhile* while_node) { +static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeWhile* while_node) { bh_arr(WasmInstruction) code = *pcode; bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_START, 0x40 })); @@ -372,7 +372,7 @@ static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, O bh_arr_push(mod->structured_jump_target, 1); bh_arr_push(mod->structured_jump_target, 2); - forll (OnyxAstNode, stmt, while_node->body->body, next) { + forll (AstNode, stmt, while_node->body->body, next) { compile_statement(mod, &code, stmt); } @@ -387,11 +387,11 @@ static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, O *pcode = code; } -static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* assign) { +static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeAssign* assign) { bh_arr(WasmInstruction) code = *pcode; - compile_expression(mod, &code, assign->right); - compile_assign_lval(mod, &code, assign->left); + compile_expression(mod, &code, assign->expr); + compile_assign_lval(mod, &code, assign->lval); *pcode = code; } @@ -414,7 +414,7 @@ static const WasmInstructionType binop_map[][4] = { /* GTE */ { WI_I32_GE_S, WI_I64_GE_S, WI_F32_GE, WI_F64_GE }, }; -static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBinOp* binop) { +static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBinOp* binop) { bh_arr(WasmInstruction) code = *pcode; b32 is_sign_significant = 0; @@ -461,31 +461,31 @@ static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, O *pcode = code; } -static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* unop) { +static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* unop) { bh_arr(WasmInstruction) code = *pcode; switch (unop->operation) { case ONYX_UNARY_OP_NEGATE: { - OnyxTypeInfoKind type_kind = unop->type->kind; + TypeInfoKind type_kind = unop->base.type->kind; - if (type_kind == ONYX_TYPE_INFO_KIND_INT32) { + if (type_kind == TYPE_INFO_KIND_INT32) { bh_arr_push(code, ((WasmInstruction){ WI_I32_CONST, 0x00 })); - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); bh_arr_push(code, ((WasmInstruction){ WI_I32_SUB, 0x00 })); - } else if (type_kind == ONYX_TYPE_INFO_KIND_INT64) { + } else if (type_kind == TYPE_INFO_KIND_INT64) { bh_arr_push(code, ((WasmInstruction){ WI_I64_CONST, 0x00 })); - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); bh_arr_push(code, ((WasmInstruction){ WI_I64_SUB, 0x00 })); } else { - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); - if (type_kind == ONYX_TYPE_INFO_KIND_FLOAT32) + if (type_kind == TYPE_INFO_KIND_FLOAT32) bh_arr_push(code, ((WasmInstruction){ WI_F32_NEG, 0x00 })); - if (type_kind == ONYX_TYPE_INFO_KIND_FLOAT64) + if (type_kind == TYPE_INFO_KIND_FLOAT64) bh_arr_push(code, ((WasmInstruction){ WI_F32_NEG, 0x00 })); } @@ -493,7 +493,7 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, } case ONYX_UNARY_OP_NOT: - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); bh_arr_push(code, ((WasmInstruction){ WI_I32_EQZ, 0x00 })); break; @@ -503,20 +503,20 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, *pcode = code; } -static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* expr) { +static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* expr) { bh_arr(WasmInstruction) code = *pcode; switch (expr->kind) { - case ONYX_AST_NODE_KIND_BIN_OP: - compile_binop(mod, &code, &expr->as_binop); + case AST_NODE_KIND_BIN_OP: + compile_binop(mod, &code, (AstNodeBinOp *) expr); break; - case ONYX_AST_NODE_KIND_UNARY_OP: - compile_unaryop(mod, &code, &expr->as_unaryop); + case AST_NODE_KIND_UNARY_OP: + compile_unaryop(mod, &code, (AstNodeUnaryOp *) expr); break; - case ONYX_AST_NODE_KIND_LOCAL: - case ONYX_AST_NODE_KIND_PARAM: + case AST_NODE_KIND_LOCAL: + case AST_NODE_KIND_PARAM: { i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) expr); @@ -524,7 +524,7 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco break; } - case ONYX_AST_NODE_KIND_GLOBAL: + case AST_NODE_KIND_GLOBAL: { i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) expr); @@ -532,10 +532,10 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco break; } - case ONYX_AST_NODE_KIND_LITERAL: + case AST_NODE_KIND_LITERAL: { - OnyxAstNodeNumLit* lit = &expr->as_numlit; - WasmType lit_type = onyx_type_to_wasm_type(lit->type); + AstNodeNumLit* lit = (AstNodeNumLit *) expr; + WasmType lit_type = onyx_type_to_wasm_type(lit->base.type); WasmInstruction instr = { WI_NOP, 0 }; if (lit_type == WASM_TYPE_INT32) { @@ -556,13 +556,15 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco break; } - case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, &code, (OnyxAstNodeBlock *) expr); break; + case AST_NODE_KIND_BLOCK: compile_block(mod, &code, (AstNodeBlock *) expr); break; - case ONYX_AST_NODE_KIND_CALL: + case AST_NODE_KIND_CALL: { - OnyxAstNodeCall* call = &expr->as_call; - forll (OnyxAstNode, arg, call->arguments, next) { - compile_expression(mod, &code, arg->left); + AstNodeCall* call = (AstNodeCall *) expr; + for (AstNodeArgument *arg = call->arguments; + arg != NULL; + arg = (AstNodeArgument *) arg->base.next) { + compile_expression(mod, &code, arg->value); } i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee); @@ -590,13 +592,13 @@ static const WasmInstructionType cast_map[][6] = { /* F64 */ { WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, }, }; -static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* cast) { +static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* cast) { bh_arr(WasmInstruction) code = *pcode; - compile_expression(mod, &code, cast->left); + compile_expression(mod, &code, cast->expr); - OnyxTypeInfo* from = cast->left->type; - OnyxTypeInfo* to = cast->type; + TypeInfo* from = cast->expr->type; + TypeInfo* to = cast->base.type; i32 fromidx = 0, toidx = 0; if (from->is_int) { @@ -627,11 +629,11 @@ static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, On *pcode = code; } -static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* ret) { +static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeReturn* ret) { bh_arr(WasmInstruction) code = *pcode; - if (ret->left) { - compile_expression(mod, &code, ret->left); + if (ret->expr) { + compile_expression(mod, &code, ret->expr); } bh_arr_push(code, ((WasmInstruction){ WI_RETURN, 0x00 })); @@ -639,22 +641,22 @@ static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, *pcode = code; } -static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { +static i32 generate_type_idx(OnyxWasmModule* mod, AstNodeFunction* fd) { static char type_repr_buf[128]; char* t = type_repr_buf; - OnyxAstNodeParam* param = fd->params; + AstNodeLocal* param = fd->params; i32 param_count = 0; while (param) { // HACK: Using these directly as part of a string feels weird but they are // valid characters so I don't think it is going to be much of an issue - *(t++) = (char) onyx_type_to_wasm_type(param->type); + *(t++) = (char) onyx_type_to_wasm_type(param->base.type); param_count++; - param = param->next; + param = (AstNodeLocal *) param->base.next; } *(t++) = ':'; - WasmType return_type = onyx_type_to_wasm_type(fd->return_type); + WasmType return_type = onyx_type_to_wasm_type(fd->base.type); *(t++) = (char) return_type; *t = '\0'; @@ -681,7 +683,7 @@ static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { return type_idx; } -static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { +static void compile_function(OnyxWasmModule* mod, AstNodeFunction* fd) { i32 type_idx = generate_type_idx(mod, fd); WasmFunc wasm_func = { @@ -697,8 +699,8 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { bh_arr_new(mod->allocator, wasm_func.code, 4); - if (fd->flags & ONYX_AST_FLAG_EXPORTED) { - onyx_token_null_toggle(*fd->token); + if (fd->base.flags & ONYX_AST_FLAG_EXPORTED) { + onyx_token_null_toggle(fd->base.token); i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) fd); @@ -706,17 +708,17 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { .kind = WASM_FOREIGN_FUNCTION, .idx = func_idx, }; - bh_table_put(WasmExport, mod->exports, fd->token->token, wasm_export); + bh_table_put(WasmExport, mod->exports, fd->base.token->token, wasm_export); mod->export_count++; - onyx_token_null_toggle(*fd->token); + onyx_token_null_toggle(fd->base.token); } // If there is no body then don't process the code if (fd->body != NULL) { // NOTE: Generate the local map i32 localidx = 0; - forll (OnyxAstNodeParam, param, fd->params, next) { + for (AstNodeLocal *param = fd->params; param != NULL; param = (AstNodeLocal *) param->base.next) { bh_imap_put(&mod->local_map, (u64) param, localidx++); } @@ -726,8 +728,8 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { // is the same as the order of the local_types above u8* count = &wasm_func.locals.i32_count; fori (ti, 0, 3) { - forll (OnyxAstNodeLocal, local, fd->body->scope->last_local, prev_local) { - if (onyx_type_to_wasm_type(local->type) == local_types[ti]) { + forll (AstNodeLocal, local, fd->body->scope->last_local, prev_local) { + if (onyx_type_to_wasm_type(local->base.type) == local_types[ti]) { bh_imap_put(&mod->local_map, (u64) local, localidx++); (*count)++; @@ -751,23 +753,23 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { bh_imap_clear(&mod->local_map); } -static void compile_global_declaration(OnyxWasmModule* module, OnyxAstNodeGlobal* global) { +static void compile_global_declaration(OnyxWasmModule* module, AstNodeGlobal* global) { WasmGlobal glob = { - .type = onyx_type_to_wasm_type(global->type), - .mutable = (global->flags & ONYX_AST_FLAG_CONST) == 0, + .type = onyx_type_to_wasm_type(global->base.type), + .mutable = (global->base.flags & ONYX_AST_FLAG_CONST) == 0, .initial_value = NULL, }; if (!global->initial_value) { onyx_message_add(module->msgs, ONYX_MESSAGE_TYPE_LITERAL, - global->token->pos, + global->base.token->pos, "global without initial value"); return; } - if ((global->flags & ONYX_AST_FLAG_EXPORTED) != 0) { - onyx_token_null_toggle(*global->token); + if ((global->base.flags & ONYX_AST_FLAG_EXPORTED) != 0) { + onyx_token_null_toggle(global->base.token); i32 global_idx = (i32) bh_imap_get(&module->func_map, (u64) global); @@ -775,19 +777,19 @@ static void compile_global_declaration(OnyxWasmModule* module, OnyxAstNodeGlobal .kind = WASM_FOREIGN_GLOBAL, .idx = global_idx, }; - bh_table_put(WasmExport, module->exports, global->token->token, wasm_export); + bh_table_put(WasmExport, module->exports, global->base.token->token, wasm_export); module->export_count++; - onyx_token_null_toggle(*global->token); + onyx_token_null_toggle(global->base.token); } compile_expression(module, &glob.initial_value, global->initial_value); bh_arr_push(module->globals, glob); } -static void compile_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) { - if (foreign->import->kind == ONYX_AST_NODE_KIND_FUNCTION) { - i32 type_idx = generate_type_idx(module, &foreign->import->as_function); +static void compile_foreign(OnyxWasmModule* module, AstNodeForeign* foreign) { + if (foreign->import->kind == AST_NODE_KIND_FUNCTION) { + i32 type_idx = generate_type_idx(module, (AstNodeFunction *) foreign->import); WasmImport import = { .kind = WASM_FOREIGN_FUNCTION, @@ -798,8 +800,8 @@ static void compile_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) bh_arr_push(module->imports, import); - } else if (foreign->import->kind == ONYX_AST_NODE_KIND_GLOBAL) { - WasmType global_type = onyx_type_to_wasm_type(foreign->import->type); + } else if (foreign->import->kind == AST_NODE_KIND_GLOBAL) { + WasmType global_type = onyx_type_to_wasm_type(((AstNodeGlobal *) foreign->import)->base.type); WasmImport import = { .kind = WASM_FOREIGN_GLOBAL, @@ -864,14 +866,14 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) { void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program) { // NOTE: First, introduce all indicies for globals and functions - bh_arr_each(OnyxAstNodeForeign *, foreign, program->foreigns) { - OnyxAstNodeKind import_kind = (*foreign)->import->kind; + bh_arr_each(AstNodeForeign *, foreign, program->foreigns) { + AstNodeKind import_kind = (*foreign)->import->kind; - if (import_kind == ONYX_AST_NODE_KIND_FUNCTION) { + if (import_kind == AST_NODE_KIND_FUNCTION) { module->next_func_idx++; bh_imap_put(&module->func_map, (u64) (*foreign)->import, module->next_import_func_idx++); } - else if (import_kind == ONYX_AST_NODE_KIND_GLOBAL) { + else if (import_kind == AST_NODE_KIND_GLOBAL) { module->next_global_idx++; bh_imap_put(&module->global_map, (u64) (*foreign)->import, module->next_import_func_idx++); } @@ -879,18 +881,18 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program) { compile_foreign(module, *foreign); } - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) + bh_arr_each(AstNodeGlobal *, global, program->globals) bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++); // NOTE: Then, compile everything - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) compile_function(module, *function); - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) + bh_arr_each(AstNodeGlobal *, global, program->globals) compile_global_declaration(module, *global); }