From: Brendan Hansen Date: Fri, 17 Jul 2020 13:45:05 +0000 (-0500) Subject: Code cleanup X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=69153bb13fc7d0cb6d08f059909e484ecea6e5e7;p=onyx.git Code cleanup --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 7f6278f0..78f484c2 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -4,8 +4,6 @@ #include "onyxlex.h" #include "onyxtypes.h" -typedef struct AstNode AstNode; -typedef struct AstTyped AstTyped; typedef struct AstUnaryOp AstUnaryOp; typedef struct AstBinOp AstBinaryOp; typedef struct AstAssign AstAssign; @@ -21,7 +19,6 @@ typedef struct AstIf AstIf; typedef struct AstWhile AstWhile; typedef struct AstLocalGroup AstLocalGroup; -typedef struct AstType AstType; typedef struct AstBasicType AstBasicType; typedef struct AstPointerType AstPointerType; typedef struct AstFunctionType AstFunctionType; @@ -115,50 +112,69 @@ typedef enum BinaryOp { // 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 { - AstKind kind; - u32 flags; - OnyxToken *token; - AstNode *next; -}; -struct AstTyped { - AstKind kind; - u32 flags; - OnyxToken *token; - AstNode *next; - - // NOTE: 'type_node' is filled out by the parser. - // For a type such as '^^i32', the tree would look something like - // - // Typed Thing -> AstPointerType -> AstPointerType -> AstNode (symbol node) - // - // The symbol node will be filled out during symbol resolution. - // It will end up pointing to an AstBasicType that corresponds to - // the underlying type. - // - // 'type' is filled out afterwards. If it is NULL, the Type* is built - // using the type_node. This can then be used to typecheck this node. - AstType *type_node; - Type *type; +#define AstNode_members { \ + AstKind kind; \ + u32 flags; \ + OnyxToken *token; \ + AstNode *next; \ }; +#define AstNode_base struct AstNode_members; + +typedef struct AstNode AstNode; +struct AstNode AstNode_members; + +// Type Nodes +// NOTE: This node is very similar to an AstNode, just +// without the 'next' member. This is because types +// can't be in expressions so a 'next' thing +// doesn't make sense. +#define AstType_members { AstKind kind; u32 flags; char* name; } +#define AstType_base struct AstType_members; + +typedef struct AstType AstType; +struct AstType AstType_members; + +// NOTE: 'type_node' is filled out by the parser. \ +// For a type such as '^^i32', the tree would look something like +// +// Typed Thing -> AstPointerType -> AstPointerType -> AstNode (symbol node) +// +// The symbol node will be filled out during symbol resolution. +// It will end up pointing to an AstBasicType that corresponds to +// the underlying type. +// +// 'type' is filled out afterwards. If it is NULL, the Type* is built +// using the type_node. This can then be used to typecheck this node. +#define AstTyped_members { \ + AstKind kind; \ + u32 flags; \ + OnyxToken *token; \ + AstNode *next; \ + AstType *type_node; \ + Type *type; \ +} +#define AstTyped_base struct AstTyped_members; + +typedef struct AstTyped AstTyped; +struct AstTyped AstTyped_members; // Expression Nodes -struct AstBinOp { AstTyped base; BinaryOp operation; AstTyped *left, *right; }; -struct AstUnaryOp { AstTyped base; UnaryOp operation; AstTyped *expr; }; -struct AstAssign { AstNode base; AstTyped* lval; AstTyped* expr; }; -struct AstNumLit { AstTyped base; union { i32 i; i64 l; f32 f; f64 d; } value; }; -struct AstLocal { AstTyped base; AstLocal *prev_local; }; -struct AstReturn { AstNode base; AstTyped* expr; }; -struct AstCall { AstTyped base; AstArgument *arguments; AstNode *callee; }; -struct AstArgument { AstTyped base; AstTyped *value; }; +struct AstBinOp { AstTyped_base; BinaryOp operation; AstTyped *left, *right; }; +struct AstUnaryOp { AstTyped_base; UnaryOp operation; AstTyped *expr; }; +struct AstAssign { AstNode_base; AstTyped* lval; AstTyped* expr; }; +struct AstNumLit { AstTyped_base; union { i32 i; i64 l; f32 f; f64 d; } value; }; +struct AstLocal { AstTyped_base; AstLocal *prev_local; }; +struct AstReturn { AstNode_base; AstTyped* expr; }; +struct AstCall { AstTyped_base; AstArgument *arguments; AstNode *callee; }; +struct AstArgument { AstTyped_base; AstTyped *value; }; // Structure Nodes -struct AstLocalGroup { AstNode base; AstLocalGroup *prev_group; AstLocal *last_local; }; -struct AstBlock { AstNode base; AstNode *body; AstLocalGroup *locals; }; -struct AstWhile { AstNode base; AstTyped *cond; AstBlock *body; }; +struct AstLocalGroup { AstNode_base; AstLocalGroup *prev_group; AstLocal *last_local; }; +struct AstBlock { AstNode_base; AstNode *body; AstLocalGroup *locals; }; +struct AstWhile { AstNode_base; AstTyped *cond; AstBlock *body; }; struct AstIf { - AstNode base; + AstNode_base; AstTyped *cond; union { @@ -167,22 +183,16 @@ struct AstIf { } true_block, false_block; }; -// Type Nodes -// NOTE: This node is very similar to an AstNode, just -// without the 'next' member. This is because types -// can't be in expressions so a 'next' thing -// doesn't make sense. -struct AstType { AstKind kind; u32 flags; char* name; }; -struct AstBasicType { AstType base; Type* type; }; -struct AstPointerType { AstType base; AstType* elem; }; -struct AstFunctionType { AstType base; AstType* return_type; u64 param_count; AstType* params[]; }; +struct AstBasicType { AstType_base; Type* type; }; +struct AstPointerType { AstType_base; AstType* elem; }; +struct AstFunctionType { AstType_base; AstType* return_type; u64 param_count; AstType* params[]; }; // Top level nodes -struct AstBinding { AstTyped base; AstNode* node; }; -struct AstForeign { AstNode base; OnyxToken *mod_token, *name_token; AstNode *import; }; -struct AstUse { AstNode base; OnyxToken *filename; }; +struct AstBinding { AstTyped_base; AstNode* node; }; +struct AstForeign { AstNode_base; OnyxToken *mod_token, *name_token; AstNode *import; }; +struct AstUse { AstNode_base; OnyxToken *filename; }; struct AstGlobal { - AstTyped base; + AstTyped_base; union { // NOTE: Used when a global is exported with a specific name @@ -196,7 +206,7 @@ struct AstGlobal { }; }; struct AstFunction { - AstTyped base; + AstTyped_base; AstBlock *body; AstLocal *params; @@ -244,7 +254,7 @@ typedef enum OnyxIntrinsic { // NOTE: This needs to have 'arguments' in the // same position as AstNodeCall -struct AstIntrinsicCall { AstTyped base; AstArgument *arguments; OnyxIntrinsic intrinsic; }; +struct AstIntrinsicCall { AstTyped_base; AstArgument *arguments; OnyxIntrinsic intrinsic; }; // NOTE: Simple data structure for storing what comes out of the parser typedef struct ParserOutput { diff --git a/include/onyxsempass.h b/include/onyxsempass.h index c2d1a529..c5780fa6 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -7,12 +7,12 @@ #include "onyxastnodes.h" #include "onyxmsgs.h" -typedef struct SemPassSymbol { +typedef struct SemSymbol { AstNode *node; - struct SemPassSymbol *shadowed; -} SemPassSymbol; + struct SemSymbol *shadowed; +} SemSymbol; -typedef struct OnyxSemPassState { +typedef struct SemState { // NOTE: Adding node_allocator in case we need // to make any more node in the tree bh_allocator allocator, node_allocator; @@ -25,17 +25,17 @@ typedef struct OnyxSemPassState { Type* expected_return_type; // NOTE: All symbols a given point that we can resolve - bh_table(SemPassSymbol *) symbols; -} OnyxSemPassState; + bh_table(SemSymbol *) symbols; +} SemState; // NOTE: Resolving all symbols in the tree -void onyx_resolve_symbols(OnyxSemPassState* state, ParserOutput* program); +void onyx_resolve_symbols(SemState* state, ParserOutput* program); // NOTE: Inferring and checking types in the tree -void onyx_type_check(OnyxSemPassState* state, ParserOutput* program); +void onyx_type_check(SemState* state, ParserOutput* program); // NOTE: Full semantic pass -OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs); -void onyx_sempass(OnyxSemPassState* state, ParserOutput* program); +SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs); +void onyx_sempass(SemState* state, ParserOutput* program); #endif diff --git a/onyx b/onyx index fd4bedcb..6140e203 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyx.c b/src/onyx.c index d0a6da5f..127b8247 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -53,7 +53,7 @@ typedef enum CompilerProgress { typedef struct CompilerState { OnyxCompileOptions* options; - bh_arena ast_arena, msg_arena, sp_arena; + bh_arena ast_arena, msg_arena, sp_arena; bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc; bh_table(bh_file_contents) loaded_files; @@ -215,7 +215,7 @@ static i32 onyx_compile(CompilerState* compiler_state) { if (compiler_state->options->verbose_output) bh_printf("[Checking semantics]\n"); - OnyxSemPassState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs); + SemState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs); onyx_sempass(&sp_state, &compiler_state->parse_output); if (onyx_message_has_errors(&compiler_state->msgs)) { @@ -266,17 +266,8 @@ int main(int argc, char *argv[]) { global_heap_allocator = bh_managed_heap_allocator(&global_heap); OnyxCompileOptions compile_opts = compile_opts_parse(global_heap_allocator, argc, argv); - CompilerState compile_state = { - .parse_output = { - .top_level_bindings = NULL, - .nodes_to_process = NULL, - - .functions = NULL, - .globals = NULL, - }, - .wasm_mod = { 0 } - }; + CompilerState compile_state = { 0 }; compiler_state_init(&compile_state, &compile_opts); CompilerProgress compiler_progress = ONYX_COMPILER_PROGRESS_FAILED_READ; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 05f34e44..a41720b7 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -1,20 +1,20 @@ #define BH_DEBUG #include "onyxsempass.h" -static b32 check_function(OnyxSemPassState* state, AstFunction* func); -static b32 check_block(OnyxSemPassState* state, AstBlock* block); -static b32 check_statement_chain(OnyxSemPassState* state, AstNode* start); -static b32 check_statement(OnyxSemPassState* state, AstNode* stmt); -static b32 check_assignment(OnyxSemPassState* state, AstAssign* assign); -static b32 check_return(OnyxSemPassState* state, AstReturn* retnode); -static b32 check_if(OnyxSemPassState* state, AstIf* ifnode); -static b32 check_while(OnyxSemPassState* state, AstWhile* whilenode); -static b32 check_call(OnyxSemPassState* state, AstCall* call); -static b32 check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop); -static b32 check_expression(OnyxSemPassState* state, AstTyped* expr); -static b32 check_global(OnyxSemPassState* state, AstGlobal* global); - -static b32 check_assignment(OnyxSemPassState* state, AstAssign* assign) { +static b32 check_function(SemState* state, AstFunction* func); +static b32 check_block(SemState* state, AstBlock* block); +static b32 check_statement_chain(SemState* state, AstNode* start); +static b32 check_statement(SemState* state, AstNode* stmt); +static b32 check_assignment(SemState* state, AstAssign* assign); +static b32 check_return(SemState* state, AstReturn* retnode); +static b32 check_if(SemState* state, AstIf* ifnode); +static b32 check_while(SemState* state, AstWhile* whilenode); +static b32 check_call(SemState* state, AstCall* call); +static b32 check_binaryop(SemState* state, AstBinaryOp* binop); +static b32 check_expression(SemState* state, AstTyped* expr); +static b32 check_global(SemState* state, AstGlobal* global); + +static b32 check_assignment(SemState* state, AstAssign* assign) { if (assign->lval->kind == Ast_Kind_Symbol) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, @@ -26,7 +26,7 @@ static b32 check_assignment(OnyxSemPassState* state, AstAssign* assign) { if ((assign->lval->flags & Ast_Flag_Const) != 0 && assign->lval->type != NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_ASSIGN_CONST, - assign->base.token->pos, + assign->token->pos, assign->lval->token->text, assign->lval->token->length); return 1; } @@ -34,7 +34,7 @@ static b32 check_assignment(OnyxSemPassState* state, AstAssign* assign) { if ((assign->lval->flags & Ast_Flag_Lval) == 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_NOT_LVAL, - assign->base.token->pos, + assign->token->pos, assign->lval->token->text, assign->lval->token->length); return 1; } @@ -51,7 +51,7 @@ static b32 check_assignment(OnyxSemPassState* state, AstAssign* assign) { if (!types_are_compatible(assign->lval->type, assign->expr->type)) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_ASSIGNMENT_TYPE_MISMATCH, - assign->base.token->pos, + assign->token->pos, type_get_name(assign->lval->type), type_get_name(assign->expr->type)); return 1; @@ -61,7 +61,7 @@ static b32 check_assignment(OnyxSemPassState* state, AstAssign* assign) { return 0; } -static b32 check_return(OnyxSemPassState* state, AstReturn* retnode) { +static b32 check_return(SemState* state, AstReturn* retnode) { if (retnode->expr) { if (check_expression(state, retnode->expr)) return 1; @@ -77,7 +77,7 @@ static b32 check_return(OnyxSemPassState* state, AstReturn* retnode) { if (state->expected_return_type->Basic.size > 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - retnode->base.token->pos, + retnode->token->pos, "returning from non-void function without value"); return 1; } @@ -86,7 +86,7 @@ static b32 check_return(OnyxSemPassState* state, AstReturn* retnode) { return 0; } -static b32 check_if(OnyxSemPassState* state, AstIf* ifnode) { +static b32 check_if(SemState* state, AstIf* ifnode) { if (check_expression(state, ifnode->cond)) return 1; if (!type_is_bool(ifnode->cond->type)) { @@ -103,7 +103,7 @@ static b32 check_if(OnyxSemPassState* state, AstIf* ifnode) { return 0; } -static b32 check_while(OnyxSemPassState* state, AstWhile* whilenode) { +static b32 check_while(SemState* state, AstWhile* whilenode) { if (check_expression(state, whilenode->cond)) return 1; if (!type_is_bool(whilenode->cond->type)) { @@ -117,33 +117,33 @@ static b32 check_while(OnyxSemPassState* state, AstWhile* whilenode) { return check_block(state, whilenode->body); } -static b32 check_call(OnyxSemPassState* state, AstCall* call) { +static b32 check_call(SemState* state, AstCall* call) { AstFunction* callee = (AstFunction *) call->callee; - if (callee->base.kind == Ast_Kind_Symbol) { + if (callee->kind == Ast_Kind_Symbol) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, - callee->base.token->pos, - callee->base.token->text, callee->base.token->length); + callee->token->pos, + callee->token->text, callee->token->length); return 1; } - if (callee->base.type == NULL) { - callee->base.type = type_build_from_ast(state->node_allocator, callee->base.type_node); + if (callee->type == NULL) { + callee->type = type_build_from_ast(state->node_allocator, callee->type_node); } - if (callee->base.type->kind != Type_Kind_Function) { + if (callee->type->kind != Type_Kind_Function) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION, - call->base.token->pos, - callee->base.token->text, callee->base.token->length); + call->token->pos, + callee->token->text, callee->token->length); return 1; } // NOTE: If we calling an intrinsic function, translate the // call into an intrinsic call node. - if (callee->base.flags & Ast_Flag_Intrinsic) { - call->base.kind = Ast_Kind_Intrinsic_Call; + if (callee->flags & Ast_Flag_Intrinsic) { + call->kind = Ast_Kind_Intrinsic_Call; call->callee = NULL; token_toggle_end(callee->intrinsic_name); @@ -203,7 +203,7 @@ static b32 check_call(OnyxSemPassState* state, AstCall* call) { token_toggle_end(callee->intrinsic_name); } - call->base.type = callee->base.type->Function.return_type; + call->type = callee->type->Function.return_type; AstLocal* formal_param = callee->params; AstArgument* actual_param = call->arguments; @@ -212,30 +212,30 @@ static b32 check_call(OnyxSemPassState* state, AstCall* call) { while (formal_param != NULL && actual_param != NULL) { if (check_expression(state, (AstTyped *) actual_param)) return 1; - if (formal_param->base.type == NULL) { - formal_param->base.type = type_build_from_ast(state->node_allocator, formal_param->base.type_node); + if (formal_param->type == NULL) { + formal_param->type = type_build_from_ast(state->node_allocator, formal_param->type_node); } - if (!types_are_compatible(formal_param->base.type, actual_param->base.type)) { + if (!types_are_compatible(formal_param->type, actual_param->type)) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_FUNCTION_PARAM_TYPE_MISMATCH, - actual_param->base.token->pos, - callee->base.token->text, callee->base.token->length, - type_get_name(formal_param->base.type), + actual_param->token->pos, + callee->token->text, callee->token->length, + type_get_name(formal_param->type), arg_pos, - type_get_name(actual_param->base.type)); + type_get_name(actual_param->type)); return 1; } arg_pos++; - formal_param = (AstLocal *) formal_param->base.next; - actual_param = (AstArgument *) actual_param->base.next; + formal_param = (AstLocal *) formal_param->next; + actual_param = (AstArgument *) actual_param->next; } if (formal_param != NULL && actual_param == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - call->base.token->pos, + call->token->pos, "too few arguments to function call"); return 1; } @@ -243,7 +243,7 @@ static b32 check_call(OnyxSemPassState* state, AstCall* call) { if (formal_param == NULL && actual_param != NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - call->base.token->pos, + call->token->pos, "too many arguments to function call"); return 1; } @@ -251,14 +251,14 @@ static b32 check_call(OnyxSemPassState* state, AstCall* call) { return 0; } -static b32 check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop) { +static b32 check_binaryop(SemState* state, AstBinaryOp* binop) { if (check_expression(state, binop->left)) return 1; if (check_expression(state, binop->right)) return 1; if (binop->left->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, - binop->base.token->pos, + binop->token->pos, NULL, 0); return 1; } @@ -266,7 +266,7 @@ static b32 check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop) { if (binop->right->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, - binop->base.token->pos, + binop->token->pos, NULL, 0); return 1; } @@ -275,7 +275,7 @@ static b32 check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop) { || type_is_pointer(binop->right->type)) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - binop->base.token->pos, + binop->token->pos, "binary operations are not supported for pointers (yet)."); return 1; } @@ -283,7 +283,7 @@ static b32 check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop) { if (!types_are_compatible(binop->left->type, binop->right->type)) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE, - binop->base.token->pos, + binop->token->pos, type_get_name(binop->left->type), type_get_name(binop->right->type)); return 1; @@ -291,15 +291,15 @@ static b32 check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop) { if (binop->operation >= Binary_Op_Equal && binop->operation <= Binary_Op_Greater_Equal) { - binop->base.type = &basic_types[Basic_Kind_Bool]; + binop->type = &basic_types[Basic_Kind_Bool]; } else { - binop->base.type = binop->left->type; + binop->type = binop->left->type; } return 0; } -static b32 check_expression(OnyxSemPassState* state, AstTyped* expr) { +static b32 check_expression(SemState* state, AstTyped* expr) { if (expr->kind > Ast_Kind_Type_Start && expr->kind < Ast_Kind_Type_End) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, @@ -378,14 +378,14 @@ static b32 check_expression(OnyxSemPassState* state, AstTyped* expr) { return retval; } -static b32 check_global(OnyxSemPassState* state, AstGlobal* global) { - if (global->base.type == NULL) - global->base.type = type_build_from_ast(state->allocator, global->base.type_node); +static b32 check_global(SemState* state, AstGlobal* global) { + if (global->type == NULL) + global->type = type_build_from_ast(state->allocator, global->type_node); - if (global->base.type == NULL) { + if (global->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, - global->base.token->pos, + global->token->pos, global->exported_name->text, global->exported_name->length); @@ -395,7 +395,7 @@ static b32 check_global(OnyxSemPassState* state, AstGlobal* global) { return 0; } -static b32 check_statement(OnyxSemPassState* state, AstNode* stmt) { +static b32 check_statement(SemState* state, AstNode* stmt) { switch (stmt->kind) { case Ast_Kind_Assignment: return check_assignment(state, (AstAssign *) stmt); case Ast_Kind_Return: return check_return(state, (AstReturn *) stmt); @@ -408,7 +408,7 @@ static b32 check_statement(OnyxSemPassState* state, AstNode* stmt) { } } -static b32 check_statement_chain(OnyxSemPassState* state, AstNode* start) { +static b32 check_statement_chain(SemState* state, AstNode* start) { while (start) { if (check_statement(state, start)) return 1; start = start->next; @@ -417,15 +417,15 @@ static b32 check_statement_chain(OnyxSemPassState* state, AstNode* start) { return 0; } -static b32 check_block(OnyxSemPassState* state, AstBlock* block) { +static b32 check_block(SemState* state, AstBlock* block) { if (check_statement_chain(state, block->body)) return 1; forll(AstLocal, local, block->locals->last_local, prev_local) { - if (local->base.type == NULL) { + if (local->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, - local->base.token->pos, - local->base.token->text, local->base.token->length); + local->token->pos, + local->token->text, local->token->length); return 1; } } @@ -433,54 +433,54 @@ static b32 check_block(OnyxSemPassState* state, AstBlock* block) { return 0; } -static b32 check_function(OnyxSemPassState* state, AstFunction* func) { - for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->base.next) { - if (param->base.type == NULL) { - param->base.type = type_build_from_ast(state->node_allocator, param->base.type_node); +static b32 check_function(SemState* state, AstFunction* func) { + for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->next) { + if (param->type == NULL) { + param->type = type_build_from_ast(state->node_allocator, param->type_node); } - if (param->base.type == NULL) { + if (param->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - param->base.token->pos, + param->token->pos, "function parameter types must be known"); return 1; } - if (param->base.type->Basic.size == 0) { + if (param->type->Basic.size == 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - param->base.token->pos, + param->token->pos, "function parameters must have non-void types"); return 1; } } - if (func->base.type == NULL) { - func->base.type = type_build_from_ast(state->node_allocator, func->base.type_node); + if (func->type == NULL) { + func->type = type_build_from_ast(state->node_allocator, func->type_node); } - if ((func->base.flags & Ast_Flag_Exported) != 0) { - if ((func->base.flags & Ast_Flag_Foreign) != 0) { + if ((func->flags & Ast_Flag_Exported) != 0) { + if ((func->flags & Ast_Flag_Foreign) != 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - func->base.token->pos, + func->token->pos, "exporting a foreign function"); return 1; } - if ((func->base.flags & Ast_Flag_Intrinsic) != 0) { + if ((func->flags & Ast_Flag_Intrinsic) != 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - func->base.token->pos, + func->token->pos, "exporting a intrinsic function"); return 1; } - if ((func->base.flags & Ast_Flag_Inline) != 0) { + if ((func->flags & Ast_Flag_Inline) != 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - func->base.token->pos, + func->token->pos, "exporting a inlined function"); return 1; } @@ -488,13 +488,13 @@ static b32 check_function(OnyxSemPassState* state, AstFunction* func) { if (func->exported_name == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - func->base.token->pos, + func->token->pos, "exporting function without a name"); return 1; } } - state->expected_return_type = func->base.type->Function.return_type; + state->expected_return_type = func->type->Function.return_type; if (func->body) { return check_block(state, func->body); } @@ -502,7 +502,7 @@ static b32 check_function(OnyxSemPassState* state, AstFunction* func) { return 0; } -static b32 check_node(OnyxSemPassState* state, AstNode* node) { +static b32 check_node(SemState* state, AstNode* node) { switch (node->kind) { case Ast_Kind_Function: return check_function(state, (AstFunction *) node); case Ast_Kind_Block: return check_block(state, (AstBlock *) node); @@ -516,7 +516,7 @@ static b32 check_node(OnyxSemPassState* state, AstNode* node) { } } -void onyx_type_check(OnyxSemPassState* state, ParserOutput* program) { +void onyx_type_check(SemState* state, ParserOutput* program) { bh_arr_each(AstNode *, node, program->nodes_to_process) { check_node(state, *node); diff --git a/src/onyxparser.c b/src/onyxparser.c index a8ef82ec..6e860082 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -88,18 +88,18 @@ static OnyxToken* expect_token(OnyxParser* parser, TokenType token_type) { static AstNumLit* parse_numeric_literal(OnyxParser* parser) { AstNumLit* lit_node = make_node(AstNumLit, Ast_Kind_Literal); - lit_node->base.token = expect_token(parser, Token_Type_Literal_Numeric); - lit_node->base.flags |= Ast_Flag_Comptime; + lit_node->token = expect_token(parser, Token_Type_Literal_Numeric); + lit_node->flags |= Ast_Flag_Comptime; lit_node->value.l = 0ll; AstType* type; - token_toggle_end(lit_node->base.token); - char* tok = lit_node->base.token->text; + token_toggle_end(lit_node->token); + char* tok = lit_node->token->text; // NOTE: charset_contains() behaves more like string_contains() // so I'm using it in this case if (charset_contains(tok, '.')) { - if (tok[lit_node->base.token->length - 1] == 'f') { + if (tok[lit_node->token->length - 1] == 'f') { type = (AstType *) &basic_type_f32; lit_node->value.f = strtof(tok, NULL); } else { @@ -117,8 +117,8 @@ static AstNumLit* parse_numeric_literal(OnyxParser* parser) { lit_node->value.l = value; } - lit_node->base.type_node = type; - token_toggle_end(lit_node->base.token); + lit_node->type_node = type; + token_toggle_end(lit_node->token); return lit_node; } @@ -154,7 +154,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { negate_node->expr = factor; if ((factor->flags & Ast_Flag_Comptime) != 0) { - negate_node->base.flags |= Ast_Flag_Comptime; + negate_node->flags |= Ast_Flag_Comptime; } retval = (AstTyped *) negate_node; @@ -165,11 +165,11 @@ static AstTyped* parse_factor(OnyxParser* parser) { { AstUnaryOp* not_node = make_node(AstUnaryOp, Ast_Kind_Unary_Op); not_node->operation = Unary_Op_Not; - not_node->base.token = expect_token(parser, '!'); + not_node->token = expect_token(parser, '!'); not_node->expr = parse_factor(parser); if ((not_node->expr->flags & Ast_Flag_Comptime) != 0) { - not_node->base.flags |= Ast_Flag_Comptime; + not_node->flags |= Ast_Flag_Comptime; } retval = (AstTyped *) not_node; @@ -189,19 +189,19 @@ static AstTyped* parse_factor(OnyxParser* parser) { // NOTE: Function call AstCall* call_node = make_node(AstCall, Ast_Kind_Call); - call_node->base.token = expect_token(parser, '('); + call_node->token = expect_token(parser, '('); call_node->callee = (AstNode *) sym_node; AstArgument** prev = &call_node->arguments; AstArgument* curr = NULL; while (parser->curr->type != ')') { curr = make_node(AstArgument, Ast_Kind_Argument); - curr->base.token = parser->curr; + curr->token = parser->curr; curr->value = parse_expression(parser); - if (curr != NULL && curr->base.kind != Ast_Kind_Error) { + if (curr != NULL && curr->kind != Ast_Kind_Error) { *prev = curr; - prev = (AstArgument **) &curr->base.next; + prev = (AstArgument **) &curr->next; } if (parser->curr->type == ')') @@ -231,8 +231,8 @@ static AstTyped* parse_factor(OnyxParser* parser) { case Token_Type_Literal_True: { AstNumLit* bool_node = make_node(AstNumLit, Ast_Kind_Literal); - bool_node->base.type_node = (AstType *) &basic_type_bool; - bool_node->base.token = expect_token(parser, Token_Type_Literal_True); + bool_node->type_node = (AstType *) &basic_type_bool; + bool_node->token = expect_token(parser, Token_Type_Literal_True); bool_node->value.i = 1; retval = (AstTyped *) bool_node; break; @@ -241,8 +241,8 @@ static AstTyped* parse_factor(OnyxParser* parser) { case Token_Type_Literal_False: { AstNumLit* bool_node = make_node(AstNumLit, Ast_Kind_Literal); - bool_node->base.type_node = (AstType *) &basic_type_bool; - bool_node->base.token = expect_token(parser, Token_Type_Literal_False); + bool_node->type_node = (AstType *) &basic_type_bool; + bool_node->token = expect_token(parser, Token_Type_Literal_False); bool_node->value.i = 0; retval = (AstTyped *) bool_node; break; @@ -260,7 +260,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { consume_token(parser); AstUnaryOp* cast_node = make_node(AstUnaryOp, Ast_Kind_Unary_Op); - cast_node->base.type_node = parse_type(parser); + cast_node->type_node = parse_type(parser); cast_node->operation = Unary_Op_Cast; cast_node->expr = retval; retval = (AstTyped *) cast_node; @@ -338,7 +338,7 @@ static AstTyped* parse_expression(OnyxParser* parser) { AstBinaryOp* bin_op = make_node(AstBinaryOp, Ast_Kind_Binary_Op); bin_op->operation = bin_op_kind; - bin_op->base.token = bin_op_tok; + bin_op->token = bin_op_tok; while ( !bh_arr_is_empty(tree_stack) && get_precedence(bh_arr_last(tree_stack)->operation) >= get_precedence(bin_op_kind)) @@ -359,7 +359,7 @@ static AstTyped* parse_expression(OnyxParser* parser) { bin_op->right = right; if ((left->flags & Ast_Flag_Comptime) != 0 && (right->flags & Ast_Flag_Comptime) != 0) { - bin_op->base.flags |= Ast_Flag_Comptime; + bin_op->flags |= Ast_Flag_Comptime; } } } @@ -416,7 +416,7 @@ static AstWhile* parse_while_stmt(OnyxParser* parser) { AstBlock* body = parse_block(parser); AstWhile* while_node = make_node(AstWhile, Ast_Kind_While); - while_node->base.token = while_token; + while_node->token = while_token; while_node->cond = cond; while_node->body = body; @@ -453,19 +453,19 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { } AstLocal* local = make_node(AstLocal, Ast_Kind_Local); - local->base.token = symbol; - local->base.type_node = type_node; - local->base.flags |= Ast_Flag_Lval; // NOTE: DELETE + local->token = symbol; + local->type_node = type_node; + local->flags |= Ast_Flag_Lval; // NOTE: DELETE *ret = (AstNode *) local; if (parser->curr->type == '=' || parser->curr->type == ':') { if (parser->curr->type == ':') { - local->base.flags |= Ast_Flag_Const; + local->flags |= Ast_Flag_Const; } AstAssign* assignment = make_node(AstAssign, Ast_Kind_Assignment); - local->base.next = (AstNode *) assignment; - assignment->base.token = parser->curr; + local->next = (AstNode *) assignment; + assignment->token = parser->curr; consume_token(parser); AstTyped* expr = parse_expression(parser); @@ -473,7 +473,7 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { token_toggle_end(parser->curr); onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION, - assignment->base.token->pos, + assignment->token->pos, parser->curr->text); token_toggle_end(parser->curr); return 1; @@ -491,7 +491,7 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { case '=': { AstAssign* assignment = make_node(AstAssign, Ast_Kind_Assignment); - assignment->base.token = parser->curr; + assignment->token = parser->curr; consume_token(parser); AstNode* lval = make_node(AstNode, Ast_Kind_Symbol); @@ -519,7 +519,7 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { AstBinaryOp* bin_op_node = make_node(AstBinaryOp, Ast_Kind_Binary_Op); bin_op_node->operation = bin_op; - bin_op_node->base.token = parser->curr; + bin_op_node->token = parser->curr; consume_token(parser); AstTyped* expr = parse_expression(parser); @@ -530,7 +530,7 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { bin_op_node->right = expr; AstAssign* assign_node = make_node(AstAssign, Ast_Kind_Assignment); - assign_node->base.token = bin_op_node->base.token; + assign_node->token = bin_op_node->token; // TODO: Maybe I don't need to make another lval node? AstNode* lval = make_node(AstNode, Ast_Kind_Symbol); @@ -553,7 +553,7 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { // 'return' ? static AstReturn* parse_return_statement(OnyxParser* parser) { AstReturn* return_node = make_node(AstReturn, Ast_Kind_Return); - return_node->base.token = expect_token(parser, Token_Type_Keyword_Return); + return_node->token = expect_token(parser, Token_Type_Keyword_Return); AstTyped* expr = NULL; @@ -688,7 +688,7 @@ static AstType* parse_type(OnyxParser* parser) { if (parser->curr->type == '^') { consume_token(parser); AstPointerType* new = make_node(AstPointerType, Ast_Kind_Pointer_Type); - new->base.flags |= Basic_Flag_Pointer; + new->flags |= Basic_Flag_Pointer; *next_insertion = (AstType *) new; next_insertion = &new->elem; } @@ -743,14 +743,14 @@ static AstLocal* parse_function_params(OnyxParser* parser) { expect_token(parser, ':'); curr_param = make_node(AstLocal, Ast_Kind_Param); - curr_param->base.token = symbol; - curr_param->base.flags |= Ast_Flag_Const; - curr_param->base.type_node = parse_type(parser); + curr_param->token = symbol; + curr_param->flags |= Ast_Flag_Const; + curr_param->type_node = parse_type(parser); if (first_param == NULL) first_param = curr_param; - curr_param->base.next = NULL; - if (trailer) trailer->base.next = (AstNode *) curr_param; + curr_param->next = NULL; + if (trailer) trailer->next = (AstNode *) curr_param; trailer = curr_param; } @@ -779,11 +779,11 @@ static b32 parse_possible_directive(OnyxParser* parser, const char* dir) { static AstFunction* parse_function_definition(OnyxParser* parser) { AstFunction* func_def = make_node(AstFunction, Ast_Kind_Function); - func_def->base.token = expect_token(parser, Token_Type_Keyword_Proc); + func_def->token = expect_token(parser, Token_Type_Keyword_Proc); while (parser->curr->type == '#') { if (parse_possible_directive(parser, "intrinsic")) { - func_def->base.flags |= Ast_Flag_Intrinsic; + func_def->flags |= Ast_Flag_Intrinsic; if (parser->curr->type == Token_Type_Literal_String) { OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String); @@ -792,18 +792,18 @@ static AstFunction* parse_function_definition(OnyxParser* parser) { } else if (parse_possible_directive(parser, "inline")) { - func_def->base.flags |= Ast_Flag_Inline; + func_def->flags |= Ast_Flag_Inline; } else if (parse_possible_directive(parser, "foreign")) { func_def->foreign_module = expect_token(parser, Token_Type_Literal_String); func_def->foreign_name = expect_token(parser, Token_Type_Literal_String); - func_def->base.flags |= Ast_Flag_Foreign; + func_def->flags |= Ast_Flag_Foreign; } else if (parse_possible_directive(parser, "export")) { - func_def->base.flags |= Ast_Flag_Exported; + func_def->flags |= Ast_Flag_Exported; if (parser->curr->type == Token_Type_Literal_String) { OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String); @@ -835,23 +835,23 @@ static AstFunction* parse_function_definition(OnyxParser* parser) { u64 param_count = 0; for (AstLocal* param = params; param != NULL; - param = (AstLocal *) param->base.next) + param = (AstLocal *) param->next) param_count++; AstFunctionType* type_node = bh_alloc(parser->allocator, sizeof(AstFunctionType) + param_count * sizeof(AstType *)); - type_node->base.kind = Ast_Kind_Function_Type; + type_node->kind = Ast_Kind_Function_Type; type_node->param_count = param_count; type_node->return_type = return_type; u32 i = 0; for (AstLocal* param = params; param != NULL; - param = (AstLocal *) param->base.next) { - type_node->params[i] = param->base.type_node; + param = (AstLocal *) param->next) { + type_node->params[i] = param->type_node; i++; } - func_def->base.type_node = (AstType *) type_node; + func_def->type_node = (AstType *) type_node; func_def->body = parse_block(parser); @@ -861,18 +861,18 @@ static AstFunction* parse_function_definition(OnyxParser* parser) { // 'global' static AstTyped* parse_global_declaration(OnyxParser* parser) { AstGlobal* global_node = make_node(AstGlobal, Ast_Kind_Global); - global_node->base.token = expect_token(parser, Token_Type_Keyword_Global); + global_node->token = expect_token(parser, Token_Type_Keyword_Global); while (parser->curr->type == '#') { if (parse_possible_directive(parser, "foreign")) { global_node->foreign_module = expect_token(parser, Token_Type_Literal_String); global_node->foreign_name = expect_token(parser, Token_Type_Literal_String); - global_node->base.flags |= Ast_Flag_Foreign; + global_node->flags |= Ast_Flag_Foreign; } else if (parse_possible_directive(parser, "export")) { - global_node->base.flags |= Ast_Flag_Exported; + global_node->flags |= Ast_Flag_Exported; if (parser->curr->type == Token_Type_Literal_String) { OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String); @@ -891,8 +891,8 @@ static AstTyped* parse_global_declaration(OnyxParser* parser) { } } - global_node->base.type_node = parse_type(parser); - global_node->base.flags |= Ast_Flag_Lval; + global_node->type_node = parse_type(parser); + global_node->flags |= Ast_Flag_Lval; bh_arr_push(parser->results.nodes_to_process, (AstNode *) global_node); @@ -923,7 +923,7 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) { case Token_Type_Keyword_Use: { AstUse* use_node = make_node(AstUse, Ast_Kind_Use); - use_node->base.token = expect_token(parser, Token_Type_Keyword_Use); + use_node->token = expect_token(parser, Token_Type_Keyword_Use); use_node->filename = expect_token(parser, Token_Type_Literal_String); return (AstNode *) use_node; @@ -957,7 +957,7 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) { } AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding); - binding->base.token = symbol; + binding->token = symbol; binding->node = (AstNode *) node; return (AstNode *) binding; diff --git a/src/onyxsempass.c b/src/onyxsempass.c index 68ea2e2d..bc1d8524 100644 --- a/src/onyxsempass.c +++ b/src/onyxsempass.c @@ -2,8 +2,8 @@ #include "onyxsempass.h" #include "onyxutils.h" -OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs) { - OnyxSemPassState state = { +SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs) { + SemState state = { .allocator = alloc, .node_allocator = node_alloc, @@ -23,13 +23,13 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc // WASM, this function may not be needed. It brings all of the locals // 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(ParserOutput* program) { +static void hoist_locals(ParserOutput* program) { bh_arr(AstBlock*) traversal_queue = NULL; bh_arr_new(global_scratch_allocator, traversal_queue, 4); bh_arr_set_length(traversal_queue, 0); bh_arr_each(AstFunction *, func, program->functions) { - if ((*func)->base.flags & Ast_Flag_Intrinsic) continue; + if ((*func)->flags & Ast_Flag_Intrinsic) continue; AstLocalGroup* top_locals = (*func)->body->locals; @@ -37,7 +37,7 @@ static void collapse_scopes(ParserOutput* program) { while (!bh_arr_is_empty(traversal_queue)) { AstBlock* block = traversal_queue[0]; - if (block->base.kind == Ast_Kind_If) { + if (block->kind == Ast_Kind_If) { AstIf* if_node = (AstIf *) block; if (if_node->true_block.as_block != NULL) bh_arr_push(traversal_queue, if_node->true_block.as_block); @@ -81,12 +81,12 @@ static void collapse_scopes(ParserOutput* program) { } } -void onyx_sempass(OnyxSemPassState* state, ParserOutput* program) { +void onyx_sempass(SemState* state, ParserOutput* program) { onyx_resolve_symbols(state, program); if (onyx_message_has_errors(state->msgs)) return; onyx_type_check(state, program); if (onyx_message_has_errors(state->msgs)) return; - collapse_scopes(program); + hoist_locals(program); } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 2aa84b35..0db1bb0b 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -1,40 +1,40 @@ #define BH_DEBUG #include "onyxsempass.h" -static void symbol_introduce(OnyxSemPassState* state, OnyxToken* tkn, AstNode* symbol); -static void symbol_basic_type_introduce(OnyxSemPassState* state, AstBasicType* basic_type); -static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxToken* tkn, AstNode* symbol); -static void symbol_remove(OnyxSemPassState* state, OnyxToken* tkn); -static AstNode* symbol_resolve(OnyxSemPassState* state, OnyxToken* tkn); -static void local_group_enter(OnyxSemPassState* state, AstLocalGroup* local_group); -static void local_group_leave(OnyxSemPassState* state); - -static AstType* symres_type(OnyxSemPassState* state, AstType* type); -static void symres_local(OnyxSemPassState* state, AstLocal** local); -static void symres_call(OnyxSemPassState* state, AstCall* call); -static void symres_expression(OnyxSemPassState* state, AstTyped** expr); -static void symres_assignment(OnyxSemPassState* state, AstAssign* assign); -static void symres_return(OnyxSemPassState* state, AstReturn* ret); -static void symres_if(OnyxSemPassState* state, AstIf* ifnode); -static void symres_while(OnyxSemPassState* state, AstWhile* 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, AstBlock* block); -static void symres_function(OnyxSemPassState* state, AstFunction* func); -static void symres_global(OnyxSemPassState* state, AstGlobal* global); - -static void symbol_introduce(OnyxSemPassState* state, OnyxToken* tkn, AstNode* symbol) { +static void symbol_introduce(SemState* state, OnyxToken* tkn, AstNode* symbol); +static void symbol_basic_type_introduce(SemState* state, AstBasicType* basic_type); +static b32 symbol_unique_introduce(SemState* state, OnyxToken* tkn, AstNode* symbol); +static void symbol_remove(SemState* state, OnyxToken* tkn); +static AstNode* symbol_resolve(SemState* state, OnyxToken* tkn); +static void local_group_enter(SemState* state, AstLocalGroup* local_group); +static void local_group_leave(SemState* state); + +static AstType* symres_type(SemState* state, AstType* type); +static void symres_local(SemState* state, AstLocal** local); +static void symres_call(SemState* state, AstCall* call); +static void symres_expression(SemState* state, AstTyped** expr); +static void symres_assignment(SemState* state, AstAssign* assign); +static void symres_return(SemState* state, AstReturn* ret); +static void symres_if(SemState* state, AstIf* ifnode); +static void symres_while(SemState* state, AstWhile* whilenode); +static void symres_statement_chain(SemState* state, AstNode* walker, AstNode** trailer); +static b32 symres_statement(SemState* state, AstNode* stmt); +static void symres_block(SemState* state, AstBlock* block); +static void symres_function(SemState* state, AstFunction* func); +static void symres_global(SemState* state, AstGlobal* global); + +static void symbol_introduce(SemState* state, OnyxToken* tkn, AstNode* symbol) { token_toggle_end(tkn); - SemPassSymbol* sp_sym = (SemPassSymbol *) bh_alloc_item(state->allocator, SemPassSymbol); + SemSymbol* sp_sym = (SemSymbol *) bh_alloc_item(state->allocator, SemSymbol); sp_sym->node = symbol; sp_sym->shadowed = NULL; - if (bh_table_has(SemPassSymbol *, state->symbols, tkn->text)) { - sp_sym->shadowed = bh_table_get(SemPassSymbol *, state->symbols, tkn->text); + if (bh_table_has(SemSymbol *, state->symbols, tkn->text)) { + sp_sym->shadowed = bh_table_get(SemSymbol *, state->symbols, tkn->text); } - bh_table_put(SemPassSymbol *, state->symbols, tkn->text, sp_sym); + bh_table_put(SemSymbol *, state->symbols, tkn->text, sp_sym); if (symbol->kind == Ast_Kind_Local) { AstLocal* local = (AstLocal *) symbol; @@ -45,27 +45,27 @@ static void symbol_introduce(OnyxSemPassState* state, OnyxToken* tkn, AstNode* s token_toggle_end(tkn); } -static void symbol_remove(OnyxSemPassState* state, OnyxToken* tkn) { +static void symbol_remove(SemState* state, OnyxToken* tkn) { token_toggle_end(tkn); - SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, tkn->text); + SemSymbol* sp_sym = bh_table_get(SemSymbol *, state->symbols, tkn->text); if (sp_sym->shadowed) { - bh_table_put(SemPassSymbol *, state->symbols, tkn->text, sp_sym->shadowed); + bh_table_put(SemSymbol *, state->symbols, tkn->text, sp_sym->shadowed); } else { - bh_table_delete(SemPassSymbol *, state->symbols, tkn->text); + bh_table_delete(SemSymbol *, state->symbols, tkn->text); } token_toggle_end(tkn); } -static AstNode* symbol_resolve(OnyxSemPassState* state, OnyxToken* tkn) { +static AstNode* symbol_resolve(SemState* state, OnyxToken* tkn) { AstNode* res = NULL; while (res == NULL || res->kind == Ast_Kind_Symbol) { token_toggle_end(tkn); - if (!bh_table_has(SemPassSymbol *, state->symbols, tkn->text)) { + if (!bh_table_has(SemSymbol *, state->symbols, tkn->text)) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL, tkn->pos, @@ -75,7 +75,7 @@ static AstNode* symbol_resolve(OnyxSemPassState* state, OnyxToken* tkn) { return NULL; } - res = bh_table_get(SemPassSymbol *, state->symbols, tkn->text)->node; + res = bh_table_get(SemSymbol *, state->symbols, tkn->text)->node; token_toggle_end(tkn); tkn = res->token; @@ -84,37 +84,37 @@ static AstNode* symbol_resolve(OnyxSemPassState* state, OnyxToken* tkn) { return res; } -static void local_group_enter(OnyxSemPassState* state, AstLocalGroup* local_group) { +static void local_group_enter(SemState* state, AstLocalGroup* local_group) { local_group->prev_group = state->curr_local_group; state->curr_local_group = local_group; } -static void local_group_leave(OnyxSemPassState* state) { +static void local_group_leave(SemState* state) { assert(state->curr_local_group != NULL); for (AstLocal *walker = state->curr_local_group->last_local; walker != NULL; walker = walker->prev_local) { - symbol_remove(state, walker->base.token); + symbol_remove(state, walker->token); } state->curr_local_group = state->curr_local_group->prev_group; } -static void symbol_basic_type_introduce(OnyxSemPassState* state, AstBasicType* basic_type) { - SemPassSymbol* sp_sym = bh_alloc_item(state->allocator, SemPassSymbol); +static void symbol_basic_type_introduce(SemState* state, AstBasicType* basic_type) { + SemSymbol* sp_sym = bh_alloc_item(state->allocator, SemSymbol); sp_sym->node = (AstNode *) basic_type; sp_sym->shadowed = NULL; - bh_table_put(SemPassSymbol *, state->symbols, basic_type->base.name, sp_sym); + bh_table_put(SemSymbol *, state->symbols, basic_type->name, sp_sym); } -static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxToken* tkn, AstNode* symbol) { +static b32 symbol_unique_introduce(SemState* state, OnyxToken* tkn, AstNode* symbol) { token_toggle_end(tkn); // NOTE: If the function hasn't already been defined - if (!bh_table_has(SemPassSymbol *, state->symbols, tkn->text)) { - SemPassSymbol* sp_sym = bh_alloc_item(state->allocator, SemPassSymbol); + if (!bh_table_has(SemSymbol *, state->symbols, tkn->text)) { + SemSymbol* sp_sym = bh_alloc_item(state->allocator, SemSymbol); sp_sym->node = symbol; sp_sym->shadowed = NULL; - bh_table_put(SemPassSymbol *, state->symbols, tkn->text, sp_sym); + bh_table_put(SemSymbol *, state->symbols, tkn->text, sp_sym); } else { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_CONFLICTING_GLOBALS, @@ -130,7 +130,7 @@ static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxToken* tkn, AstN return 1; } -static AstType* symres_type(OnyxSemPassState* state, AstType* type) { +static AstType* symres_type(SemState* state, AstType* type) { if (type == NULL) return NULL; if (type->kind == Ast_Kind_Symbol) { @@ -162,12 +162,12 @@ static AstType* symres_type(OnyxSemPassState* state, AstType* type) { return NULL; } -static void symres_local(OnyxSemPassState* state, AstLocal** local) { - (*local)->base.type_node = symres_type(state, (*local)->base.type_node); - symbol_introduce(state, (*local)->base.token, (AstNode *) *local); +static void symres_local(SemState* state, AstLocal** local) { + (*local)->type_node = symres_type(state, (*local)->type_node); + symbol_introduce(state, (*local)->token, (AstNode *) *local); } -static void symres_call(OnyxSemPassState* state, AstCall* call) { +static void symres_call(SemState* state, AstCall* call) { AstNode* callee = symbol_resolve(state, call->callee->token); if (callee) call->callee = callee; @@ -184,15 +184,15 @@ static void symres_call(OnyxSemPassState* state, AstCall* call) { symres_statement_chain(state, (AstNode *) call->arguments, (AstNode **) &call->arguments); } -static void symres_unaryop(OnyxSemPassState* state, AstUnaryOp** unaryop) { +static void symres_unaryop(SemState* state, AstUnaryOp** unaryop) { if ((*unaryop)->operation == Unary_Op_Cast) { - (*unaryop)->base.type_node = symres_type(state, (*unaryop)->base.type_node); + (*unaryop)->type_node = symres_type(state, (*unaryop)->type_node); } symres_expression(state, &(*unaryop)->expr); } -static void symres_expression(OnyxSemPassState* state, AstTyped** expr) { +static void symres_expression(SemState* state, AstTyped** expr) { switch ((*expr)->kind) { case Ast_Kind_Binary_Op: symres_expression(state, &((AstBinaryOp *)(*expr))->left); @@ -225,7 +225,7 @@ static void symres_expression(OnyxSemPassState* state, AstTyped** expr) { } } -static void symres_assignment(OnyxSemPassState* state, AstAssign* assign) { +static void symres_assignment(SemState* state, AstAssign* assign) { AstTyped* lval = (AstTyped *) symbol_resolve(state, assign->lval->token); if (lval == NULL) return; assign->lval = lval; @@ -233,41 +233,41 @@ static void symres_assignment(OnyxSemPassState* state, AstAssign* assign) { symres_expression(state, &assign->expr); } -static void symres_return(OnyxSemPassState* state, AstReturn* ret) { +static void symres_return(SemState* state, AstReturn* ret) { if (ret->expr) symres_expression(state, &ret->expr); } -static void symres_if(OnyxSemPassState* state, AstIf* ifnode) { +static void symres_if(SemState* state, AstIf* ifnode) { symres_expression(state, &ifnode->cond); if (ifnode->true_block.as_if != NULL) { - if (ifnode->true_block.as_if->base.kind == Ast_Kind_Block) + if (ifnode->true_block.as_if->kind == Ast_Kind_Block) symres_block(state, ifnode->true_block.as_block); - else if (ifnode->true_block.as_if->base.kind == Ast_Kind_If) + else if (ifnode->true_block.as_if->kind == Ast_Kind_If) symres_if(state, ifnode->true_block.as_if); else DEBUG_HERE; } if (ifnode->false_block.as_if != NULL) { - if (ifnode->false_block.as_if->base.kind == Ast_Kind_Block) + if (ifnode->false_block.as_if->kind == Ast_Kind_Block) symres_block(state, ifnode->false_block.as_block); - else if (ifnode->false_block.as_if->base.kind == Ast_Kind_If) + else if (ifnode->false_block.as_if->kind == Ast_Kind_If) symres_if(state, ifnode->false_block.as_if); else DEBUG_HERE; } } -static void symres_while(OnyxSemPassState* state, AstWhile* whilenode) { +static void symres_while(SemState* state, AstWhile* whilenode) { symres_expression(state, &whilenode->cond); symres_block(state, whilenode->body); } // NOTE: Returns 1 if the statment should be removed -static b32 symres_statement(OnyxSemPassState* state, AstNode* stmt) { +static b32 symres_statement(SemState* state, AstNode* stmt) { switch (stmt->kind) { case Ast_Kind_Local: symres_local(state, (AstLocal **) &stmt); return 1; case Ast_Kind_Assignment: symres_assignment(state, (AstAssign *) stmt); return 0; @@ -282,7 +282,7 @@ static b32 symres_statement(OnyxSemPassState* state, AstNode* stmt) { } } -static void symres_statement_chain(OnyxSemPassState* state, AstNode* walker, AstNode** trailer) { +static void symres_statement_chain(SemState* state, AstNode* walker, AstNode** trailer) { while (walker) { if (symres_statement(state, walker)) { *trailer = walker->next; @@ -297,36 +297,36 @@ static void symres_statement_chain(OnyxSemPassState* state, AstNode* walker, Ast } } -static void symres_block(OnyxSemPassState* state, AstBlock* block) { +static void symres_block(SemState* state, AstBlock* block) { local_group_enter(state, block->locals); if (block->body) symres_statement_chain(state, block->body, &block->body); local_group_leave(state); } -static void symres_function(OnyxSemPassState* state, AstFunction* func) { - for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->base.next) { - param->base.type_node = symres_type(state, param->base.type_node); +static void symres_function(SemState* state, AstFunction* func) { + for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->next) { + param->type_node = symres_type(state, param->type_node); - symbol_introduce(state, param->base.token, (AstNode *) param); + symbol_introduce(state, param->token, (AstNode *) param); } - if (func->base.type_node != NULL) { - func->base.type_node = symres_type(state, func->base.type_node); + if (func->type_node != NULL) { + func->type_node = symres_type(state, func->type_node); } symres_block(state, func->body); - for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->base.next) { - symbol_remove(state, param->base.token); + for (AstLocal *param = func->params; param != NULL; param = (AstLocal *) param->next) { + symbol_remove(state, param->token); } } -static void symres_global(OnyxSemPassState* state, AstGlobal* global) { - global->base.type_node = symres_type(state, global->base.type_node); +static void symres_global(SemState* state, AstGlobal* global) { + global->type_node = symres_type(state, global->type_node); } -static void symres_top_node(OnyxSemPassState* state, AstNode** node) { +static void symres_top_node(SemState* state, AstNode** node) { switch ((*node)->kind) { case Ast_Kind_Call: case Ast_Kind_Unary_Op: @@ -350,7 +350,7 @@ static void symres_top_node(OnyxSemPassState* state, AstNode** node) { } } -void onyx_resolve_symbols(OnyxSemPassState* state, ParserOutput* program) { +void onyx_resolve_symbols(SemState* state, ParserOutput* program) { // NOTE: Add types to global scope symbol_basic_type_introduce(state, &basic_type_void); @@ -368,7 +368,7 @@ void onyx_resolve_symbols(OnyxSemPassState* state, ParserOutput* program) { symbol_basic_type_introduce(state, &basic_type_rawptr); bh_arr_each(AstBinding *, binding, program->top_level_bindings) - if (!symbol_unique_introduce(state, (*binding)->base.token, (*binding)->node)) return; + if (!symbol_unique_introduce(state, (*binding)->token, (*binding)->node)) return; bh_arr_each(AstNode *, node, program->nodes_to_process) symres_top_node(state, node); diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 56a9a025..752e4aaf 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -347,11 +347,11 @@ COMPILE_FUNC(if, AstIf* if_node) { if (if_node->true_block.as_if) { // NOTE: This is kind of gross, but making a function for this doesn't feel right - if (if_node->true_block.as_if->base.kind == Ast_Kind_If) { + if (if_node->true_block.as_if->kind == Ast_Kind_If) { forll (AstNode, stmt, (AstNode *) if_node->true_block.as_if, next) { compile_statement(mod, &code, stmt); } - } else if (if_node->true_block.as_if->base.kind == Ast_Kind_Block) { + } else if (if_node->true_block.as_if->kind == Ast_Kind_Block) { forll (AstNode, stmt, if_node->true_block.as_block->body, next) { compile_statement(mod, &code, stmt); } @@ -361,11 +361,11 @@ COMPILE_FUNC(if, AstIf* if_node) { if (if_node->false_block.as_if) { WI(WI_ELSE); - if (if_node->false_block.as_if->base.kind == Ast_Kind_If) { + if (if_node->false_block.as_if->kind == Ast_Kind_If) { forll (AstNode, stmt, (AstNode *) if_node->false_block.as_if, next) { compile_statement(mod, &code, stmt); } - } else if (if_node->false_block.as_if->base.kind == Ast_Kind_Block) { + } else if (if_node->false_block.as_if->kind == Ast_Kind_Block) { forll (AstNode, stmt, if_node->false_block.as_block->body, next) { compile_statement(mod, &code, stmt); } @@ -487,7 +487,7 @@ COMPILE_FUNC(unaryop, AstUnaryOp* unop) { switch (unop->operation) { case Unary_Op_Negate: { - TypeBasic* type = &unop->base.type->Basic; + TypeBasic* type = &unop->type->Basic; if (type->kind == Basic_Kind_I32 || type->kind == Basic_Kind_I16 @@ -533,7 +533,7 @@ COMPILE_FUNC(call, AstCall* call) { for (AstArgument *arg = call->arguments; arg != NULL; - arg = (AstArgument *) arg->base.next) { + arg = (AstArgument *) arg->next) { compile_expression(mod, &code, arg->value); } @@ -555,7 +555,7 @@ COMPILE_FUNC(intrinsic_call, AstIntrinsicCall* call) { if (place_arguments_normally) { for (AstArgument *arg = call->arguments; arg != NULL; - arg = (AstArgument *) arg->base.next) { + arg = (AstArgument *) arg->next) { compile_expression(mod, &code, arg->value); } } @@ -646,7 +646,7 @@ COMPILE_FUNC(expression, AstTyped* expr) { case Ast_Kind_Literal: { AstNumLit* lit = (AstNumLit *) expr; - WasmType lit_type = onyx_type_to_wasm_type(lit->base.type); + WasmType lit_type = onyx_type_to_wasm_type(lit->type); WasmInstruction instr = { WI_NOP, 0 }; if (lit_type == WASM_TYPE_INT32) { @@ -703,7 +703,7 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) { compile_expression(mod, &code, cast->expr); Type* from = cast->expr->type; - Type* to = cast->base.type; + Type* to = cast->type; i32 fromidx = 0, toidx = 0; if (from->Basic.flags & Basic_Flag_Integer) { @@ -756,8 +756,8 @@ static i32 generate_type_idx(OnyxWasmModule* mod, AstFunction* fd) { static char type_repr_buf[128]; char* t = type_repr_buf; - Type** param_type = fd->base.type->Function.params; - i32 param_count = fd->base.type->Function.param_count; + Type** param_type = fd->type->Function.params; + i32 param_count = fd->type->Function.param_count; i32 params_left = param_count; while (params_left-- > 0) { // HACK: Using these directly as part of a string feels weird but they are @@ -767,7 +767,7 @@ static i32 generate_type_idx(OnyxWasmModule* mod, AstFunction* fd) { } *(t++) = ':'; - WasmType return_type = onyx_type_to_wasm_type(fd->base.type->Function.return_type); + WasmType return_type = onyx_type_to_wasm_type(fd->type->Function.return_type); *(t++) = (char) return_type; *t = '\0'; @@ -796,11 +796,11 @@ static i32 generate_type_idx(OnyxWasmModule* mod, AstFunction* fd) { static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { // NOTE: Don't compile intrinsics - if (fd->base.flags & Ast_Flag_Intrinsic) return; + if (fd->flags & Ast_Flag_Intrinsic) return; i32 type_idx = generate_type_idx(mod, fd); - if (fd->base.flags & Ast_Flag_Foreign) { + if (fd->flags & Ast_Flag_Foreign) { WasmImport import = { .kind = WASM_FOREIGN_FUNCTION, .idx = type_idx, @@ -825,7 +825,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { bh_arr_new(mod->allocator, wasm_func.code, 4); - if (fd->base.flags & Ast_Flag_Exported) { + if (fd->flags & Ast_Flag_Exported) { token_toggle_end(fd->exported_name); i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) fd); @@ -844,7 +844,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { if (fd->body != NULL) { // NOTE: Generate the local map i32 localidx = 0; - for (AstLocal *param = fd->params; param != NULL; param = (AstLocal *) param->base.next) { + for (AstLocal *param = fd->params; param != NULL; param = (AstLocal *) param->next) { bh_imap_put(&mod->local_map, (u64) param, localidx++); } @@ -855,7 +855,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { u8* count = &wasm_func.locals.i32_count; fori (ti, 0, 3) { forll (AstLocal, local, fd->body->locals->last_local, prev_local) { - if (onyx_type_to_wasm_type(local->base.type) == local_types[ti]) { + if (onyx_type_to_wasm_type(local->type) == local_types[ti]) { bh_imap_put(&mod->local_map, (u64) local, localidx++); (*count)++; @@ -880,9 +880,9 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { } static void compile_global_declaration(OnyxWasmModule* module, AstGlobal* global) { - WasmType global_type = onyx_type_to_wasm_type(global->base.type); + WasmType global_type = onyx_type_to_wasm_type(global->type); - if (global->base.flags & Ast_Flag_Foreign) { + if (global->flags & Ast_Flag_Foreign) { WasmImport import = { .kind = WASM_FOREIGN_GLOBAL, .idx = global_type, @@ -896,11 +896,11 @@ static void compile_global_declaration(OnyxWasmModule* module, AstGlobal* global WasmGlobal glob = { .type = global_type, - .mutable = (global->base.flags & Ast_Flag_Const) == 0, + .mutable = (global->flags & Ast_Flag_Const) == 0, .initial_value = NULL, }; - if ((global->base.flags & Ast_Flag_Exported) != 0) { + if ((global->flags & Ast_Flag_Exported) != 0) { token_toggle_end(global->exported_name); i32 global_idx = (i32) bh_imap_get(&module->func_map, (u64) global); @@ -973,26 +973,26 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) { void onyx_wasm_module_compile(OnyxWasmModule* module, ParserOutput* program) { bh_arr_each(AstFunction *, function, program->functions) { - if ((*function)->base.flags & Ast_Flag_Foreign) { + if ((*function)->flags & Ast_Flag_Foreign) { bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); } } bh_arr_each(AstGlobal *, global, program->globals) { - if ((*global)->base.flags & Ast_Flag_Foreign) { + if ((*global)->flags & Ast_Flag_Foreign) { bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++); } } bh_arr_each(AstFunction *, function, program->functions) { - if ((*function)->base.flags & Ast_Flag_Foreign) continue; + if ((*function)->flags & Ast_Flag_Foreign) continue; - if (((*function)->base.flags & Ast_Flag_Intrinsic) == 0) + if (((*function)->flags & Ast_Flag_Intrinsic) == 0) bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); } bh_arr_each(AstGlobal *, global, program->globals) { - if ((*global)->base.flags & Ast_Flag_Foreign) continue; + if ((*global)->flags & Ast_Flag_Foreign) continue; bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++); }