From: Brendan Hansen Date: Thu, 28 Apr 2022 18:04:59 +0000 (-0500) Subject: bugfixes and bindable foreign blocks X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8a4a27fdda913a7d6047b960a21a1d73c22d1107;p=onyx.git bugfixes and bindable foreign blocks --- diff --git a/include/astnodes.h b/include/astnodes.h index 0974be01..9b4d76dd 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -1294,7 +1294,7 @@ struct AstCodeBlock { }; struct AstDirectiveInsert { - AstNode_base; + AstTyped_base; AstTyped *code_expr; }; @@ -1320,8 +1320,9 @@ struct AstDirectiveLibrary { }; struct AstForeignBlock { - AstNode_base; + AstTyped_base; + Scope* scope; OnyxToken *module_name; bh_arr(struct Entity *) captured_entities; }; diff --git a/src/checker.c b/src/checker.c index b48439a7..3279919c 100644 --- a/src/checker.c +++ b/src/checker.c @@ -1904,6 +1904,7 @@ CheckStatus check_expression(AstTyped** pexpr) { case Ast_Kind_Unary_Field_Access: break; case Ast_Kind_Constraint_Sentinel: break; case Ast_Kind_Switch_Case: break; + case Ast_Kind_Foreign_Block: break; default: retval = Check_Error; diff --git a/src/parser.c b/src/parser.c index 46d38785..348415b6 100644 --- a/src/parser.c +++ b/src/parser.c @@ -2810,6 +2810,25 @@ static AstDirectiveInit* parse_init_directive(OnyxParser *parser, OnyxToken *tok return init; } +static AstForeignBlock* parse_foreign_block(OnyxParser* parser, OnyxToken *token) { + // :LinearTokenDependent + AstForeignBlock *fb = make_node(AstForeignBlock, Ast_Kind_Foreign_Block); + fb->token = token; + fb->module_name = expect_token(parser, Token_Type_Literal_String); + + bh_arr_new(global_heap_allocator, fb->captured_entities, 4); + bh_arr_push(parser->alternate_entity_placement_stack, &fb->captured_entities); + + expect_token(parser, '{'); + parse_top_level_statements_until(parser, '}'); + expect_token(parser, '}'); + + bh_arr_pop(parser->alternate_entity_placement_stack); + ENTITY_SUBMIT(fb); + + return fb; +} + static AstTyped* parse_top_level_expression(OnyxParser* parser) { if (parser->curr->type == Token_Type_Keyword_Global) return parse_global_declaration(parser); if (parser->curr->type == Token_Type_Keyword_Struct) return (AstTyped *) parse_struct(parser); @@ -2844,6 +2863,11 @@ static AstTyped* parse_top_level_expression(OnyxParser* parser) { distinct->base_type = parse_type(parser); return (AstTyped *) distinct; } + + if (parse_possible_directive(parser, "foreign")) { + AstForeignBlock *foreign = parse_foreign_block(parser, parser->curr - 2); + return (AstTyped *) foreign; + } } return parse_expression(parser, 1); @@ -3060,20 +3084,7 @@ static void parse_top_level_statement(OnyxParser* parser) { return; } else if (parse_possible_directive(parser, "foreign")) { - // :LinearTokenDependent - AstForeignBlock *fb = make_node(AstForeignBlock, Ast_Kind_Foreign_Block); - fb->token = parser->curr - 2; - fb->module_name = expect_token(parser, Token_Type_Literal_String); - - bh_arr_new(global_heap_allocator, fb->captured_entities, 4); - bh_arr_push(parser->alternate_entity_placement_stack, &fb->captured_entities); - - expect_token(parser, '{'); - parse_top_level_statements_until(parser, '}'); - expect_token(parser, '}'); - - bh_arr_pop(parser->alternate_entity_placement_stack); - ENTITY_SUBMIT(fb); + parse_foreign_block(parser, parser->curr - 2); return; } else if (parse_possible_directive(parser, "operator")) { diff --git a/src/symres.c b/src/symres.c index 3d4f9f29..c2cf26de 100644 --- a/src/symres.c +++ b/src/symres.c @@ -694,9 +694,11 @@ static SymresStatus symres_switch(AstSwitch* switchnode) { static SymresStatus symres_use(AstUse* use) { SYMRES(expression, &use->expr); + AstTyped *use_expr = (AstTyped *) strip_aliases((AstNode *) use->expr); + // :EliminatingSymres - if (use->expr->kind == Ast_Kind_Package) { - AstPackage* package = (AstPackage *) use->expr; + if (use_expr->kind == Ast_Kind_Package) { + AstPackage* package = (AstPackage *) use_expr; SYMRES(package, package); if (package->package->scope == curr_scope) return Symres_Success; @@ -731,8 +733,42 @@ static SymresStatus symres_use(AstUse* use) { return Symres_Success; } - if (use->expr->kind == Ast_Kind_Enum_Type) { - AstEnumType* et = (AstEnumType *) use->expr; + if (use_expr->kind == Ast_Kind_Foreign_Block) { + AstForeignBlock* fb = (AstForeignBlock *) use_expr; + if (fb->entity->state <= Entity_State_Resolve_Symbols) return Symres_Yield_Macro; + + if (fb->scope == curr_scope) return Symres_Success; + + if (use->only == NULL) { + OnyxFilePos pos = { 0 }; + if (use->token != NULL) + pos = use->token->pos; + + scope_include(curr_scope, fb->scope, pos); + + } else { + bh_arr_each(QualifiedUse, qu, use->only) { + AstNode* thing = symbol_resolve(fb->scope, qu->symbol_name); + if (thing == NULL) { // :SymresStall + if (report_unresolved_symbols) { + onyx_report_error(qu->symbol_name->pos, Error_Critical, + "The symbol '%b' was not found in this package.", + qu->symbol_name->text, qu->symbol_name->length); + return Symres_Error; + } else { + return Symres_Yield_Macro; + } + } + + symbol_introduce(curr_scope, qu->as_name, thing); + } + } + + return Symres_Success; + } + + if (use_expr->kind == Ast_Kind_Enum_Type) { + AstEnumType* et = (AstEnumType *) use_expr; bh_arr_each(AstEnumValue *, ev, et->values) symbol_introduce(curr_scope, (*ev)->token, (AstNode *) *ev); @@ -740,8 +776,8 @@ static SymresStatus symres_use(AstUse* use) { return Symres_Success; } - if (use->expr->kind == Ast_Kind_Struct_Type) { - AstStructType* st = (AstStructType *) use->expr; + if (use_expr->kind == Ast_Kind_Struct_Type) { + AstStructType* st = (AstStructType *) use_expr; if (!st->scope) return Symres_Success; if (use->only == NULL) { @@ -764,27 +800,27 @@ static SymresStatus symres_use(AstUse* use) { return Symres_Success; } - if (use->expr->type_node == NULL && use->expr->type == NULL) goto cannot_use; + if (use_expr->type_node == NULL && use_expr->type == NULL) goto cannot_use; // :EliminatingSymres - AstType* effective_type = use->expr->type_node; + AstType* effective_type = use_expr->type_node; if (effective_type->kind == Ast_Kind_Pointer_Type) effective_type = ((AstPointerType *) effective_type)->elem; if (effective_type->kind == Ast_Kind_Struct_Type || effective_type->kind == Ast_Kind_Poly_Call_Type) { - if (use->expr->type == NULL) - use->expr->type = type_build_from_ast(context.ast_alloc, use->expr->type_node); - if (use->expr->type == NULL) goto cannot_use; + if (use_expr->type == NULL) + use_expr->type = type_build_from_ast(context.ast_alloc, use_expr->type_node); + if (use_expr->type == NULL) goto cannot_use; - Type* st = use->expr->type; + Type* st = use_expr->type; if (st->kind == Type_Kind_Pointer) st = st->Pointer.elem; fori (i, 0, shlen(st->Struct.members)) { StructMember* value = st->Struct.members[i].value; - AstFieldAccess* fa = make_field_access(context.ast_alloc, use->expr, value->name); + AstFieldAccess* fa = make_field_access(context.ast_alloc, use_expr, value->name); symbol_raw_introduce(curr_scope, value->name, use->token->pos, (AstNode *) fa); } @@ -1445,6 +1481,9 @@ static SymresStatus symres_polyquery(AstPolyQuery *query) { } static SymresStatus symres_foreign_block(AstForeignBlock *fb) { + if (fb->scope == NULL) + fb->scope = scope_create(context.ast_alloc, curr_scope, fb->token->pos); + bh_arr_each(Entity *, pent, fb->captured_entities) { Entity *ent = *pent; if (ent->type == Entity_Type_Function_Header) { @@ -1464,6 +1503,22 @@ static SymresStatus symres_foreign_block(AstForeignBlock *fb) { continue; } + if (ent->type == Entity_Type_Binding) { + AstBinding* new_binding = onyx_ast_node_new(context.ast_alloc, sizeof(AstBinding), Ast_Kind_Binding); + new_binding->token = ent->binding->token; + new_binding->node = ent->binding->node; + + Entity e; + memset(&e, 0, sizeof(e)); + e.type = Entity_Type_Binding; + e.state = Entity_State_Introduce_Symbols; + e.binding = new_binding; + e.scope = fb->scope; + e.package = ent->package; + + entity_heap_insert(&context.entities, e); + } + if (ent->type != Entity_Type_Function) { entity_heap_insert_existing(&context.entities, ent); } diff --git a/src/utils.c b/src/utils.c index f65c26ad..b7d99036 100644 --- a/src/utils.c +++ b/src/utils.c @@ -204,6 +204,15 @@ all_types_peeled_off: return symbol_raw_resolve(package->package->scope, symbol); } + case Ast_Kind_Foreign_Block: { + AstForeignBlock* fb = (AstForeignBlock *) node; + + if (fb->scope == NULL) + return NULL; + + return symbol_raw_resolve(fb->scope, symbol); + } + case Ast_Kind_Enum_Type: { AstEnumType* etype = (AstEnumType *) node; return symbol_raw_resolve(etype->scope, symbol); diff --git a/src/wasm_emit.c b/src/wasm_emit.c index 07884a2c..bf140889 100644 --- a/src/wasm_emit.c +++ b/src/wasm_emit.c @@ -3565,6 +3565,7 @@ static void emit_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node) { static b32 emit_raw_data_(OnyxWasmModule* mod, ptr data, AstTyped* node) { b32 retval = 1; + node = (AstTyped *) strip_aliases((AstNode *) node); if (node_is_type((AstNode *) node)) { Type* constructed_type = type_build_from_ast(context.ast_alloc, (AstType *) node);