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);
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);
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")) {
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;
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);
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) {
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);
}
}
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) {
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);
}