diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-06-12 21:21:18 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-06-12 21:21:18 +0100 |
| commit | ccda456c0a96f849e408bd707eca0a3baf9202b1 (patch) | |
| tree | 57abf5f3bbb1e103165bbb90d78f6a14d3a9e27f /src/checker.cpp | |
| parent | 83bad13e9e1bebd474768edf1a30e0682013149b (diff) | |
`foreign` blocks for procedures
Diffstat (limited to 'src/checker.cpp')
| -rw-r--r-- | src/checker.cpp | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/checker.cpp b/src/checker.cpp index 518b79e3e..df41c9f86 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -270,6 +270,7 @@ struct CheckerContext { String proc_name; Type * type_hint; DeclInfo * curr_proc_decl; + AstNode * curr_foreign_library; }; // CheckerInfo stores all the symbol information for a type-checked program @@ -1626,6 +1627,24 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco } case_end; + case_ast_node(fb, ForeignBlockDecl, decl); + AstNode *foreign_library = fb->foreign_library; + bool ok = true; + if (foreign_library->kind != AstNode_Ident) { + error_node(foreign_library, "foreign library name must be an identifier"); + ok = false; + } + + CheckerContext prev_context = c->context; + if (ok) { + c->context.curr_foreign_library = foreign_library; + } + + check_collect_entities(c, fb->decls, is_file_scope); + + c->context = prev_context; + case_end; + case_ast_node(pd, ProcDecl, decl); AstNode *name = pd->name; if (name->kind != AstNode_Ident) { @@ -1638,6 +1657,12 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco Entity *e = NULL; e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, pd->tags); + AstNode *fl = c->context.curr_foreign_library; + if (fl != NULL) { + GB_ASSERT(fl->kind == AstNode_Ident); + e->Procedure.foreign_library_ident = fl; + pd->tags |= ProcTag_foreign; + } d->proc_decl = decl; d->type_expr = pd->type; e->identifier = name; @@ -1652,14 +1677,14 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco } } + // NOTE(bill): `when` stmts need to be handled after the other as the condition may refer to something + // declared after this stmt in source if (!c->context.scope->is_file) { - // NOTE(bill): `when` stmts need to be handled after the other as the condition may refer to something - // declared after this stmt in source for_array(i, nodes) { AstNode *node = nodes[i]; switch (node->kind) { case_ast_node(ws, WhenStmt, node); - check_collect_entities_from_when_stmt(c, ws, is_file_scope); + check_collect_entities_from_when_stmt(c, ws, is_file_scope); case_end; } } |