From 23ac46e9723b6eb11d1fbc885a814ecd05a8118e Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 22 Jun 2020 11:54:34 -0500 Subject: [PATCH] Splitting up code for easier maintainability --- Makefile | 1 + include/onyxsempass.h | 4 + onyx | Bin 173640 -> 177840 bytes progs/new_minimal.onyx | 6 +- src/onyxsempass.c | 292 +--------------------------------------- src/onyxsymres.c | 296 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 307 insertions(+), 292 deletions(-) create mode 100644 src/onyxsymres.c diff --git a/Makefile b/Makefile index bf09e282..817e8f10 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ OBJ_FILES=\ build/onyxlex.o \ build/onyxparser.o \ build/onyxsempass.o \ + build/onyxsymres.o \ build/onyxmsgs.o \ build/onyxutils.o \ build/onyxwasm.o \ diff --git a/include/onyxsempass.h b/include/onyxsempass.h index fc5f4eca..c2e6bcf7 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -23,6 +23,10 @@ typedef struct OnyxSemPassState { bh_table(SemPassSymbol *) symbols; } OnyxSemPassState; +// NOTE: Resolving all symbols in the tree +void onyx_resolve_symbols(OnyxSemPassState* state, OnyxAstNode* root_node); + +// NOTE: Full semantic pass OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs); void onyx_sempass(OnyxSemPassState* state, OnyxAstNode* root_node); diff --git a/onyx b/onyx index 8ad5333c93d3dee356e771b2cfbf2782cf75d8d4..dc020938d5f77feea550cb5b1c5cf7ab0ea2f26f 100755 GIT binary patch delta 41660 zcmbrn2Y6J)_cwlLdv3CuO>aOpg%najn)FV<&|B!Cqf{xB_xJxj&-?E4%$_qdr_Gr&bEn)*-nyh7xTmhjFg@5; zQth*#=dUT^^Sm#NhucG@V&CsynYZ;JH!E+$uHE6W}v7c=%oS*O%i z4tCtPCi@w7*%z9V$hwr}<*a7xXWyH-li9Sg#(CSA=l%l7Tl8kZq7ModU2VDO*3k^u zQLyNvftireWMRbxCmTJ}Ya4;j1dJ6`jINu5q` zPCtH!edya;uZqbr(|4&}DqB_duwD%l+wV(ln9LfLwQiVTVNJ^hHMN>q{jw)p{K?oq zzQL_(n}VWzrLB_KSBEIyl^QnR@^03! zZVw6;xBR_e(T##d=ga?66~%Y8Q?6shdwzexoOAiUzq`cvSjX?#0^i+^wM?DfUD-Ls z*Q(RArrpO6MX(o^G)}z`WAHV$kzLAcJ2|k@t~p{>q72YT5J6Q0u8qTlsEPj zbeU_~euX4F>@v^v*Ja=2uEUtmcdP4lXZx2FWwFInu%=*XRI{?zyK$3C-CI%g&z`cO zMbQ>kuWUvi8?$_M#_#tf9Eialr
    ^4ombo`fX=(ef#^xv5~$D{gNZE+(i=> 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 uhp$HbrrX i32 { d :: a + b; // Constant { - c : i32 = a * 2; + c : i32 = a * 2 + foo(5, 2); d : i32 = (c + a) * 2; } return c * d; } + +foo :: proc (a i32, b i32) -> i32 { + return a * 5 + b * 7; +} diff --git a/src/onyxsempass.c b/src/onyxsempass.c index dd2568be..7a36627e 100644 --- a/src/onyxsempass.c +++ b/src/onyxsempass.c @@ -17,296 +17,6 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc return state; } -static void symbol_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 b32 define_function(OnyxSemPassState* state, OnyxAstNodeFuncDef* func); -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_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_definition(OnyxSemPassState* state, OnyxAstNodeFuncDef* func); - -static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); - - SemPassSymbol* sp_sym = (SemPassSymbol *) bh_alloc_item(state->allocator, SemPassSymbol); - sp_sym->node = symbol; - sp_sym->shadowed = NULL; - - if (bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { - sp_sym->shadowed = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); - } - - bh_table_put(SemPassSymbol *, state->symbols, symbol->token->token, sp_sym); - - if (symbol->kind == ONYX_AST_NODE_KIND_LOCAL) { - OnyxAstNodeLocal* local = &symbol->as_local; - local->prev_local = state->curr_scope->last_local; - state->curr_scope->last_local = local; - } - - onyx_token_null_toggle(*symbol->token); -} - -static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); - - SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); - - if (sp_sym->shadowed) { - bh_table_put(SemPassSymbol *, state->symbols, symbol->token->token, sp_sym->shadowed); - } else { - bh_table_delete(SemPassSymbol *, state->symbols, symbol->token->token); - } - - onyx_token_null_toggle(*symbol->token); -} - -static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); - - if (!bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { - onyx_message_add(state->msgs, - ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL, - symbol->token->pos, - symbol->token->token); - - onyx_token_null_toggle(*symbol->token); - return NULL; - } - - SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); - - onyx_token_null_toggle(*symbol->token); - return sp_sym->node; -} - -static void scope_enter(OnyxSemPassState* state, OnyxAstNodeScope* scope) { - scope->prev_scope = state->curr_scope; - state->curr_scope = scope; -} - -static OnyxAstNodeScope* 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); - } - - state->curr_scope = state->curr_scope->prev_scope; - return state->curr_scope; -} - -static b32 define_function(OnyxSemPassState* state, OnyxAstNodeFuncDef* func) { - onyx_token_null_toggle(*func->token); - - // NOTE: If the function hasn't already been defined - if (!bh_table_has(SemPassSymbol *, state->symbols, func->token->token)) { - SemPassSymbol* sp_sym = bh_alloc_item(state->allocator, SemPassSymbol); - sp_sym->node = (OnyxAstNode *) func; - sp_sym->shadowed = NULL; - bh_table_put(SemPassSymbol *, state->symbols, func->token->token, sp_sym); - } else { - onyx_message_add(state->msgs, - ONYX_MESSAGE_TYPE_FUNCTION_REDEFINITION, - func->token->pos, - func->token->token); - - // NOTE: I really wish C had defer... - onyx_token_null_toggle(*func->token); - return 0; - } - - onyx_token_null_toggle(*func->token); - return 1; -} - -static void symres_local(OnyxSemPassState* state, OnyxAstNodeLocal** local) { - symbol_introduce(state, (OnyxAstNode *) *local); -} - -static void symres_call(OnyxSemPassState* state, OnyxAstNode* stmt) { - OnyxAstNodeCall* call = &stmt->as_call; - - OnyxAstNode* callee = symbol_resolve(state, call->callee); - if (callee) call->callee = callee; - else DEBUG_HERE; - - symres_statement_chain(state, call->arguments, &call->arguments); -} - -static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr) { - switch ((*expr)->kind) { - case ONYX_AST_NODE_KIND_ADD: - case ONYX_AST_NODE_KIND_MINUS: - case ONYX_AST_NODE_KIND_MULTIPLY: - case ONYX_AST_NODE_KIND_DIVIDE: - case ONYX_AST_NODE_KIND_MODULUS: - case ONYX_AST_NODE_KIND_EQUAL: - case ONYX_AST_NODE_KIND_NOT_EQUAL: - case ONYX_AST_NODE_KIND_LESS: - case ONYX_AST_NODE_KIND_LESS_EQUAL: - case ONYX_AST_NODE_KIND_GREATER: - case ONYX_AST_NODE_KIND_GREATER_EQUAL: - symres_expression(state, &(*expr)->left); - symres_expression(state, &(*expr)->right); - break; - - case ONYX_AST_NODE_KIND_NEGATE: - symres_expression(state, &(*expr)->left); - break; - - case ONYX_AST_NODE_KIND_CAST: - if ((*expr)->type == NULL) { - DEBUG_HERE; - return; - } - symres_expression(state, &(*expr)->left); - break; - - case ONYX_AST_NODE_KIND_CALL: symres_call(state, *expr); break; - - case ONYX_AST_NODE_KIND_BLOCK: symres_block(state, &(*expr)->as_block); - - case ONYX_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 ONYX_AST_NODE_KIND_LITERAL: break; - - default: - DEBUG_HERE; - break; - } -} - -static void symres_assignment(OnyxSemPassState* state, OnyxAstNode* assign) { - OnyxAstNode* lval = symbol_resolve(state, assign->left); - if (lval == NULL) return; - assign->left = lval; - - symres_expression(state, &assign->right); -} - -static void symres_return(OnyxSemPassState* state, OnyxAstNode* ret) { - if (ret->left) - symres_expression(state, &ret->left); -} - -static void symres_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { - symres_expression(state, &ifnode->cond); - if (ifnode->true_block) { - if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_BLOCK) - symres_block(state, &ifnode->true_block->as_block); - - else if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_IF) - symres_if(state, &ifnode->true_block->as_if); - - 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); - - else if (ifnode->false_block->kind == ONYX_AST_NODE_KIND_IF) - symres_if(state, &ifnode->false_block->as_if); - - else DEBUG_HERE; - } -} - -// NOTE: Returns 1 if the statment should be removed -static b32 symres_statement(OnyxSemPassState* state, OnyxAstNode* 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_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; - - default: return 0; - } -} - -static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, OnyxAstNode** trailer) { - while (walker) { - if (symres_statement(state, walker)) { - *trailer = walker->next; - - OnyxAstNode* tmp = walker->next; - walker->next = NULL; - walker = tmp; - } else { - trailer = &walker->next; - walker = walker->next; - } - } -} - -static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) { - scope_enter(state, block->scope); - if (block->body) - symres_statement_chain(state, block->body, &block->body); - scope_leave(state); -} - -static void symres_function_definition(OnyxSemPassState* state, OnyxAstNodeFuncDef* func) { - forll(OnyxAstNodeParam, param, func->params, next) { - symbol_introduce(state, (OnyxAstNode *) param); - } - - symres_block(state, func->body); - - forll(OnyxAstNodeParam, param, func->params, next) { - symbol_remove(state, (OnyxAstNode *) param); - } -} - void onyx_sempass(OnyxSemPassState* state, OnyxAstNode* root_node) { - OnyxAstNode* walker = root_node; - while (walker) { - switch (walker->kind) { - case ONYX_AST_NODE_KIND_FUNCDEF: - if (!define_function(state, &walker->as_funcdef)) return; - break; - - case ONYX_AST_NODE_KIND_FOREIGN: - if (walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF) { - if (!define_function(state, &walker->as_foreign.import->as_funcdef)) return; - } - break; - - default: break; - } - - walker = walker->next; - } - - // NOTE: First, resolve all symbols - walker = root_node; - while (walker) { - switch (walker->kind) { - case ONYX_AST_NODE_KIND_FUNCDEF: - symres_function_definition(state, &walker->as_funcdef); - break; - default: break; - } - - walker = walker->next; - } + onyx_resolve_symbols(state, root_node); } diff --git a/src/onyxsymres.c b/src/onyxsymres.c new file mode 100644 index 00000000..edccbecf --- /dev/null +++ b/src/onyxsymres.c @@ -0,0 +1,296 @@ +#define BH_DEBUG +#include "onyxsempass.h" + +static void symbol_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 b32 define_function(OnyxSemPassState* state, OnyxAstNodeFuncDef* func); +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_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_definition(OnyxSemPassState* state, OnyxAstNodeFuncDef* func); + +static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { + onyx_token_null_toggle(*symbol->token); + + SemPassSymbol* sp_sym = (SemPassSymbol *) bh_alloc_item(state->allocator, SemPassSymbol); + sp_sym->node = symbol; + sp_sym->shadowed = NULL; + + if (bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { + sp_sym->shadowed = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); + } + + bh_table_put(SemPassSymbol *, state->symbols, symbol->token->token, sp_sym); + + if (symbol->kind == ONYX_AST_NODE_KIND_LOCAL) { + OnyxAstNodeLocal* local = &symbol->as_local; + local->prev_local = state->curr_scope->last_local; + state->curr_scope->last_local = local; + } + + onyx_token_null_toggle(*symbol->token); +} + +static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol) { + onyx_token_null_toggle(*symbol->token); + + SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); + + if (sp_sym->shadowed) { + bh_table_put(SemPassSymbol *, state->symbols, symbol->token->token, sp_sym->shadowed); + } else { + bh_table_delete(SemPassSymbol *, state->symbols, symbol->token->token); + } + + onyx_token_null_toggle(*symbol->token); +} + +static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol) { + onyx_token_null_toggle(*symbol->token); + + if (!bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { + onyx_message_add(state->msgs, + ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL, + symbol->token->pos, + symbol->token->token); + + onyx_token_null_toggle(*symbol->token); + return NULL; + } + + SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); + + onyx_token_null_toggle(*symbol->token); + return sp_sym->node; +} + +static void scope_enter(OnyxSemPassState* state, OnyxAstNodeScope* scope) { + scope->prev_scope = state->curr_scope; + state->curr_scope = scope; +} + +static OnyxAstNodeScope* 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); + } + + state->curr_scope = state->curr_scope->prev_scope; + return state->curr_scope; +} + +static b32 define_function(OnyxSemPassState* state, OnyxAstNodeFuncDef* func) { + onyx_token_null_toggle(*func->token); + + // NOTE: If the function hasn't already been defined + if (!bh_table_has(SemPassSymbol *, state->symbols, func->token->token)) { + SemPassSymbol* sp_sym = bh_alloc_item(state->allocator, SemPassSymbol); + sp_sym->node = (OnyxAstNode *) func; + sp_sym->shadowed = NULL; + bh_table_put(SemPassSymbol *, state->symbols, func->token->token, sp_sym); + } else { + onyx_message_add(state->msgs, + ONYX_MESSAGE_TYPE_FUNCTION_REDEFINITION, + func->token->pos, + func->token->token); + + // NOTE: I really wish C had defer... + onyx_token_null_toggle(*func->token); + return 0; + } + + onyx_token_null_toggle(*func->token); + return 1; +} + +static void symres_local(OnyxSemPassState* state, OnyxAstNodeLocal** local) { + symbol_introduce(state, (OnyxAstNode *) *local); +} + +static void symres_call(OnyxSemPassState* state, OnyxAstNode* stmt) { + OnyxAstNodeCall* call = &stmt->as_call; + + OnyxAstNode* callee = symbol_resolve(state, call->callee); + if (callee) call->callee = callee; + else DEBUG_HERE; + + symres_statement_chain(state, call->arguments, &call->arguments); +} + +static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr) { + switch ((*expr)->kind) { + case ONYX_AST_NODE_KIND_ADD: + case ONYX_AST_NODE_KIND_MINUS: + case ONYX_AST_NODE_KIND_MULTIPLY: + case ONYX_AST_NODE_KIND_DIVIDE: + case ONYX_AST_NODE_KIND_MODULUS: + case ONYX_AST_NODE_KIND_EQUAL: + case ONYX_AST_NODE_KIND_NOT_EQUAL: + case ONYX_AST_NODE_KIND_LESS: + case ONYX_AST_NODE_KIND_LESS_EQUAL: + case ONYX_AST_NODE_KIND_GREATER: + case ONYX_AST_NODE_KIND_GREATER_EQUAL: + symres_expression(state, &(*expr)->left); + symres_expression(state, &(*expr)->right); + break; + + case ONYX_AST_NODE_KIND_NEGATE: + symres_expression(state, &(*expr)->left); + break; + + case ONYX_AST_NODE_KIND_CAST: + if ((*expr)->type == NULL) { + DEBUG_HERE; + return; + } + symres_expression(state, &(*expr)->left); + break; + + case ONYX_AST_NODE_KIND_CALL: symres_call(state, *expr); break; + + case ONYX_AST_NODE_KIND_BLOCK: symres_block(state, &(*expr)->as_block); + + case ONYX_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 ONYX_AST_NODE_KIND_LITERAL: break; + + default: + DEBUG_HERE; + break; + } +} + +static void symres_assignment(OnyxSemPassState* state, OnyxAstNode* assign) { + OnyxAstNode* lval = symbol_resolve(state, assign->left); + if (lval == NULL) return; + assign->left = lval; + + symres_expression(state, &assign->right); +} + +static void symres_return(OnyxSemPassState* state, OnyxAstNode* ret) { + if (ret->left) + symres_expression(state, &ret->left); +} + +static void symres_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { + symres_expression(state, &ifnode->cond); + if (ifnode->true_block) { + if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_BLOCK) + symres_block(state, &ifnode->true_block->as_block); + + else if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_IF) + symres_if(state, &ifnode->true_block->as_if); + + 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); + + else if (ifnode->false_block->kind == ONYX_AST_NODE_KIND_IF) + symres_if(state, &ifnode->false_block->as_if); + + else DEBUG_HERE; + } +} + +// NOTE: Returns 1 if the statment should be removed +static b32 symres_statement(OnyxSemPassState* state, OnyxAstNode* 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_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; + + default: return 0; + } +} + +static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, OnyxAstNode** trailer) { + while (walker) { + if (symres_statement(state, walker)) { + *trailer = walker->next; + + OnyxAstNode* tmp = walker->next; + walker->next = NULL; + walker = tmp; + } else { + trailer = &walker->next; + walker = walker->next; + } + } +} + +static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) { + scope_enter(state, block->scope); + if (block->body) + symres_statement_chain(state, block->body, &block->body); + scope_leave(state); +} + +static void symres_function_definition(OnyxSemPassState* state, OnyxAstNodeFuncDef* func) { + forll(OnyxAstNodeParam, param, func->params, next) { + symbol_introduce(state, (OnyxAstNode *) param); + } + + symres_block(state, func->body); + + forll(OnyxAstNodeParam, param, func->params, next) { + symbol_remove(state, (OnyxAstNode *) param); + } +} + +void onyx_resolve_symbols(OnyxSemPassState* state, OnyxAstNode* root_node) { + OnyxAstNode* walker = root_node; + while (walker) { + switch (walker->kind) { + case ONYX_AST_NODE_KIND_FUNCDEF: + if (!define_function(state, &walker->as_funcdef)) return; + break; + + case ONYX_AST_NODE_KIND_FOREIGN: + if (walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF) { + if (!define_function(state, &walker->as_foreign.import->as_funcdef)) return; + } + break; + + default: break; + } + + walker = walker->next; + } + + // NOTE: First, resolve all symbols + walker = root_node; + while (walker) { + switch (walker->kind) { + case ONYX_AST_NODE_KIND_FUNCDEF: + symres_function_definition(state, &walker->as_funcdef); + break; + default: break; + } + + walker = walker->next; + } +} -- 2.25.1