From: Brendan Hansen Date: Tue, 29 Dec 2020 19:45:08 +0000 (-0600) Subject: bugfixes with procedure level bindings X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=22435009bb4cda6711463c961f714be16e692593;p=onyx.git bugfixes with procedure level bindings --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 5789ebbc..ea239113 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -533,7 +533,8 @@ struct AstBlock { Scope *scope; bh_arr(AstTyped *) allocate_exprs; - bh_arr(AstBinding *) bindings; + + Scope *binding_scope; }; struct AstDefer { AstNode_base; AstNode *stmt; }; struct AstFor { diff --git a/onyx b/onyx index 78d3f0e2..92f06c4e 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/poly_solidify.onyx b/progs/poly_solidify.onyx index 4bf90352..24462e93 100644 --- a/progs/poly_solidify.onyx +++ b/progs/poly_solidify.onyx @@ -22,7 +22,7 @@ main :: proc (args: [] cstr) { proc (b: f32) -> f64 { return ~~(b + 6); })); - arr : [..] i32; + arr : [..] f32; array.init(^arr); defer array.free(^arr); @@ -35,7 +35,20 @@ main :: proc (args: [] cstr) { } array_map :: proc (arr: [..] $T, f: proc (T) -> T) { + test2(); + + foo := #solidify math.max { T = T }; + is := (#type InternalStruct(T)).{ foo = foo(6, 2) }; + printf("%i\n", is.foo); + for ^v: arr do *v = f(*v); + + test2 :: proc () { test(); println("WORLD!!!!"); }; + test :: proc () { println("HELLO!!!"); }; + + InternalStruct :: struct ($SOMETHING) { + foo : SOMETHING; + }; } double :: proc (v: $V) -> V do return v * 2; \ No newline at end of file diff --git a/src/onyxparser.c b/src/onyxparser.c index d6d64331..b1d1e736 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -112,9 +112,18 @@ static OnyxToken* soft_expect_token(OnyxParser* parser, TokenType token_type) { } static void add_node_to_process(OnyxParser* parser, AstNode* node) { + Scope* scope = parser->file_scope; + + if (!bh_arr_is_empty(parser->block_stack)) { + Scope* binding_scope = parser->block_stack[bh_arr_length(parser->block_stack) - 1]->binding_scope; + + if (binding_scope != NULL) + scope = binding_scope; + } + bh_arr_push(parser->results.nodes_to_process, ((NodeToProcess) { .package = parser->package, - .scope = parser->file_scope, + .scope = scope, .node = node, })); } @@ -1008,9 +1017,21 @@ static b32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret) expect_token(parser, ':'); if (parser->curr->type == ':') { - AstBinding* binding = parse_top_level_binding(parser, symbol); + AstBlock* current_block = parser->block_stack[bh_arr_length(parser->block_stack) - 1]; + if (current_block->binding_scope == NULL) { + // TODO: Check this is right. I suspect it may allow more things to be + // valid than I want it to. + + Scope* parent_scope = parser->file_scope; + if (bh_arr_length(parser->block_stack) > 1) { + parent_scope = parser->block_stack[bh_arr_length(parser->block_stack) - 2]->binding_scope; + } - bh_arr_push(parser->block_stack[0]->bindings, binding); + current_block->binding_scope = scope_create(parser->allocator, parent_scope, current_block->token->pos); + } + + AstBinding* binding = parse_top_level_binding(parser, symbol); + symbol_introduce(current_block->binding_scope, symbol, binding->node); return 1; } @@ -1340,7 +1361,10 @@ static AstBlock* parse_block(OnyxParser* parser) { AstNode** next = &block->body; AstNode* stmt = NULL; while (parser->curr->type != '}') { - if (parser->hit_unexpected_token) return block; + if (parser->hit_unexpected_token) { + bh_arr_pop(parser->block_stack); + return block; + } stmt = parse_statement(parser); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 0b3a6584..5f7a668a 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -667,8 +667,8 @@ static void symres_block(AstBlock* block) { scope_enter(block->scope); bh_arr_push(semstate.block_stack, block); - bh_arr_each(AstBinding *, binding, block->bindings) - symbol_introduce(semstate.curr_scope, (*binding)->token, (*binding)->node); + if (block->binding_scope != NULL) + scope_include(block->scope, block->binding_scope, block->token->pos); if (block->body) symres_statement_chain(&block->body);