From 84413766ccc952f6e2f87cc07b06c5a78a1364e1 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 2 Apr 2023 16:46:43 -0500 Subject: [PATCH] changed: foreign directives no longer require string literals --- compiler/include/astnodes.h | 17 +++++++++-------- compiler/src/astnodes.c | 8 ++++++++ compiler/src/checker.c | 5 +++++ compiler/src/parser.c | 6 +++--- compiler/src/symres.c | 16 ++++++++++++++-- compiler/src/wasm_emit.c | 10 ++++++---- compiler/src/wasm_type_table.h | 10 ++++++---- tests/aoc-2021/day04.onyx | 5 +---- 8 files changed, 52 insertions(+), 25 deletions(-) diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index c9fd21af..ab95741d 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -583,6 +583,11 @@ struct Arguments { i32 used_argument_count; }; +typedef struct ForeignReference { + AstTyped *module_name; + AstTyped *import_name; +} ForeignReference; + // Base Nodes #define AstNode_base \ @@ -1064,8 +1069,7 @@ struct AstGlobal { char* name; - OnyxToken* foreign_module; - OnyxToken* foreign_name; + ForeignReference foreign; }; struct AstParam { // HACK CLEANUP: This does not need to have a local buried inside of it. @@ -1294,11 +1298,7 @@ struct AstFunction { union { OnyxToken* intrinsic_name; - // NOTE: Used when the function is declared as foreign - struct { - OnyxToken* foreign_module; - OnyxToken* foreign_name; - }; + ForeignReference foreign; }; struct Entity* entity_header; @@ -1455,7 +1455,7 @@ struct AstForeignBlock { AstTyped_base; Scope* scope; - OnyxToken *module_name; + AstTyped *module_name; bh_arr(struct Entity *) captured_entities; u32 foreign_block_number; @@ -1844,6 +1844,7 @@ AstNumLit* make_bool_literal(bh_allocator, b32 b); AstNumLit* make_int_literal(bh_allocator a, i64 value); AstNumLit* make_float_literal(bh_allocator a, f64 value); AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high); +AstStrLit* make_string_literal(bh_allocator a, OnyxToken *token); AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right); AstArgument* make_argument(bh_allocator a, AstTyped* value); AstFieldAccess* make_field_access(bh_allocator a, AstTyped* node, char* field); diff --git a/compiler/src/astnodes.c b/compiler/src/astnodes.c index 3227cab7..cfab106c 100644 --- a/compiler/src/astnodes.c +++ b/compiler/src/astnodes.c @@ -1488,6 +1488,14 @@ AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* hig return rl; } +AstStrLit* make_string_literal(bh_allocator a, OnyxToken *token) { + AstStrLit *str = onyx_ast_node_new(a, sizeof(AstStrLit), Ast_Kind_StrLit); + str->flags |= Ast_Flag_Comptime; + str->type_node = builtin_string_type; + str->token = token; + return str; +} + AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right) { AstBinaryOp* binop_node = onyx_ast_node_new(a, sizeof(AstBinaryOp), Ast_Kind_Binary_Op); binop_node->left = left; diff --git a/compiler/src/checker.c b/compiler/src/checker.c index 01b56267..be9c4f2c 100644 --- a/compiler/src/checker.c +++ b/compiler/src/checker.c @@ -2924,6 +2924,11 @@ CheckStatus check_function_header(AstFunction* func) { func->type = type_build_function_type(context.ast_alloc, func); if (func->type == NULL) YIELD(func->token->pos, "Waiting for function type to be constructed"); + if (func->foreign.import_name) { + CHECK(expression, &func->foreign.module_name); + CHECK(expression, &func->foreign.import_name); + } + return Check_Success; } diff --git a/compiler/src/parser.c b/compiler/src/parser.c index 17ae7a42..1d06f1ab 100644 --- a/compiler/src/parser.c +++ b/compiler/src/parser.c @@ -2615,8 +2615,8 @@ static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* tok } 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->foreign.module_name = parse_expression(parser, 0); + func_def->foreign.import_name = parse_expression(parser, 0); func_def->is_foreign = 1; } @@ -3040,7 +3040,7 @@ static AstForeignBlock* parse_foreign_block(OnyxParser* parser, OnyxToken *token fb->uses_dyncall = 1; } - fb->module_name = expect_token(parser, Token_Type_Literal_String); + fb->module_name = parse_expression(parser, 0); // // This has a fun implication that there cannot be foreign blocks in the builtin diff --git a/compiler/src/symres.c b/compiler/src/symres.c index d6600aac..f56d4a50 100644 --- a/compiler/src/symres.c +++ b/compiler/src/symres.c @@ -1017,6 +1017,11 @@ SymresStatus symres_function_header(AstFunction* func) { SYMRES(expression, (AstTyped **) &func->deprecated_warning); } + if (func->foreign.import_name) { + SYMRES(expression, &func->foreign.module_name); + SYMRES(expression, &func->foreign.import_name); + } + scope_leave(); return Symres_Success; @@ -1592,6 +1597,13 @@ static SymresStatus symres_foreign_block(AstForeignBlock *fb) { if (fb->scope == NULL) fb->scope = scope_create(context.ast_alloc, current_scope, fb->token->pos); + SYMRES(expression, &fb->module_name); + + if (fb->module_name->kind != Ast_Kind_StrLit) { + onyx_report_error(fb->token->pos, Error_Critical, "Expected module name to be a compile-time string literal."); + return Symres_Error; + } + bh_arr_each(Entity *, pent, fb->captured_entities) { Entity *ent = *pent; if (ent->type == Entity_Type_Function_Header) { @@ -1600,8 +1612,8 @@ static SymresStatus symres_foreign_block(AstForeignBlock *fb) { return Symres_Error; } - ent->function->foreign_name = ent->function->intrinsic_name; // Hmm... This might not be right? - ent->function->foreign_module = fb->module_name; + ent->function->foreign.import_name = make_string_literal(context.ast_alloc, ent->function->intrinsic_name); + ent->function->foreign.module_name = fb->module_name; ent->function->is_foreign = 1; ent->function->is_foreign_dyncall = fb->uses_dyncall; ent->function->entity = NULL; diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index 2c377c02..7595168e 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -4160,9 +4160,11 @@ static void emit_foreign_function(OnyxWasmModule* mod, AstFunction* fd) { i32 type_idx = generate_type_idx(mod, fd->type); char *module, *name; + OnyxToken *foreign_module = fd->foreign.module_name->token; + OnyxToken *foreign_import = fd->foreign.import_name->token; if (fd->is_foreign_dyncall) { - module = bh_aprintf(global_heap_allocator, "dyncall:%b", fd->foreign_module->text, fd->foreign_module->length); + module = bh_aprintf(global_heap_allocator, "dyncall:%b", foreign_module->text, foreign_module->length); char type_encoding[65] = {0}; encode_type_as_dyncall_symbol(type_encoding, fd->type->Function.return_type); @@ -4171,11 +4173,11 @@ static void emit_foreign_function(OnyxWasmModule* mod, AstFunction* fd) { encode_type_as_dyncall_symbol(type_encoding, param->local->type); } - name = bh_aprintf(global_heap_allocator, "%b:%s", fd->foreign_name->text, fd->foreign_name->length, type_encoding); + name = bh_aprintf(global_heap_allocator, "%b:%s", foreign_import->text, foreign_import->length, type_encoding); } else { - module = bh_aprintf(global_heap_allocator, "%b", fd->foreign_module->text, fd->foreign_module->length); - name = bh_aprintf(global_heap_allocator, "%b", fd->foreign_name->text, fd->foreign_name->length); + module = bh_aprintf(global_heap_allocator, "%b", foreign_module->text, foreign_module->length); + name = bh_aprintf(global_heap_allocator, "%b", foreign_import->text, foreign_import->length); } WasmImport import = { diff --git a/compiler/src/wasm_type_table.h b/compiler/src/wasm_type_table.h index fc620bce..33f4c5b8 100644 --- a/compiler/src/wasm_type_table.h +++ b/compiler/src/wasm_type_table.h @@ -662,9 +662,10 @@ static u64 build_foreign_blocks(OnyxWasmModule* module) { AstFunction *func = (AstFunction *) fb->scope->symbols[i].value; if (func->kind != Ast_Kind_Function) continue; + OnyxToken *import_name = func->foreign.import_name->token; u32 func_name_base = foreign_buffer.length; - u32 func_name_length = func->foreign_name->length; - bh_buffer_append(&foreign_buffer, func->foreign_name->text, func_name_length); + u32 func_name_length = import_name->length; + bh_buffer_append(&foreign_buffer, import_name->text, func_name_length); name_offsets[funcs_length] = func_name_base; name_lengths[funcs_length] = func_name_length; @@ -681,9 +682,10 @@ static u64 build_foreign_blocks(OnyxWasmModule* module) { bh_buffer_write_u32(&foreign_buffer, func_types[i]); } + OnyxToken *module_name = fb->module_name->token; u32 name_base = foreign_buffer.length; - u32 name_length = fb->module_name->length; - bh_buffer_append(&foreign_buffer, fb->module_name->text, name_length); + u32 name_length = module_name->length; + bh_buffer_append(&foreign_buffer, module_name->text, name_length); bh_buffer_align(&foreign_buffer, 8); foreign_info[index] = foreign_buffer.length; diff --git a/tests/aoc-2021/day04.onyx b/tests/aoc-2021/day04.onyx index f63e2ab8..9566b3ef 100644 --- a/tests/aoc-2021/day04.onyx +++ b/tests/aoc-2021/day04.onyx @@ -1,5 +1,3 @@ -#load "core/std" - use core {*} Cell :: u8 @@ -29,8 +27,7 @@ main :: (args) => { boards: [..] Board; while !io.reader_empty(&reader) { - array.insert_empty(&boards, boards.count); - board := &boards[boards.count - 1]; + board := array.alloc_one(&boards); board.has_won = false; memory.set(&board.marked, 0, sizeof typeof board.marked); -- 2.25.1