From b78e970698cc154474c3c6a8b49214f9e3d4dfe7 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Wed, 26 Apr 2017 23:51:13 +0100 Subject: [PATCH] Fix issue #48 dependency issue --- src/check_decl.c | 11 +++++++++-- src/check_expr.c | 10 ++++------ src/checker.c | 37 ++++++++++++++++++++----------------- src/parser.c | 4 ++++ 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/check_decl.c b/src/check_decl.c index ff9e2a88c..4535a3b89 100644 --- a/src/check_decl.c +++ b/src/check_decl.c @@ -535,7 +535,6 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod c->context.decl = decl; c->context.proc_name = proc_name; - GB_ASSERT(type->kind == Type_Proc); if (type->Proc.param_count > 0) { TypeTuple *params = &type->Proc.params->Tuple; @@ -588,8 +587,16 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod check_scope_usage(c, c->context.scope); - c->context = old_context; + + if (decl->parent != NULL) { + // NOTE(bill): Add the dependencies from the procedure literal (lambda) + for_array(i, decl->deps.entries) { + HashKey key = decl->deps.entries.e[i].key; + Entity *e = cast(Entity *)key.ptr; + map_bool_set(&decl->parent->deps, key, true); + } + } } diff --git a/src/check_expr.c b/src/check_expr.c index b183d3ccb..47b5d0ab6 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -1075,7 +1075,8 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { case Type_Vector: // Could be in C too case Type_Record: { - i64 size = type_size_of(a, original_type); + i64 align = type_align_of(a, original_type); + i64 size = type_size_of(a, original_type); switch (8*size) { case 8: new_type = t_u8; break; case 16: new_type = t_u16; break; @@ -5016,14 +5017,12 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t case_end; case_ast_node(pl, ProcLit, node); - // check_open_scope(c, pl->type); - CheckerContext prev_context = c->context; - + DeclInfo *decl = NULL; Type *type = alloc_type(c->allocator, Type_Proc); check_open_scope(c, pl->type); { - DeclInfo *decl = make_declaration_info(c->allocator, c->context.scope); + decl = make_declaration_info(c->allocator, c->context.scope, c->context.decl); decl->proc_lit = pl->type; c->context.decl = decl; @@ -5041,7 +5040,6 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t return kind; } check_procedure_later(c, c->curr_ast_file, empty_token, decl, type, pl->body, pl->tags); - } check_close_scope(c); diff --git a/src/checker.c b/src/checker.c index 495a0a750..9d0d8aa2c 100644 --- a/src/checker.c +++ b/src/checker.c @@ -187,19 +187,21 @@ typedef struct BlockLabel { } BlockLabel; // DeclInfo is used to store information of certain declarations to allow for "any order" usage -typedef struct DeclInfo { - Scope *scope; +typedef struct DeclInfo DeclInfo; +struct DeclInfo { + DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment + Scope * scope; - Entity **entities; - isize entity_count; + Entity ** entities; + isize entity_count; - AstNode *type_expr; - AstNode *init_expr; - AstNode *proc_lit; // AstNode_ProcLit + AstNode * type_expr; + AstNode * init_expr; + AstNode * proc_lit; // AstNode_ProcLit - MapBool deps; // Key: Entity * + MapBool deps; // Key: Entity * Array(BlockLabel) labels; -} DeclInfo; +}; // ProcedureInfo stores the information needed for checking a procedure @@ -344,15 +346,16 @@ typedef Array(DelayedEntity) DelayedEntities; -void init_declaration_info(DeclInfo *d, Scope *scope) { - d->scope = scope; +void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { + d->parent = parent; + d->scope = scope; map_bool_init(&d->deps, heap_allocator()); array_init(&d->labels, heap_allocator()); } -DeclInfo *make_declaration_info(gbAllocator a, Scope *scope) { +DeclInfo *make_declaration_info(gbAllocator a, Scope *scope, DeclInfo *parent) { DeclInfo *d = gb_alloc_item(a, DeclInfo); - init_declaration_info(d, scope); + init_declaration_info(d, scope, parent); return d; } @@ -1459,7 +1462,7 @@ void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope) Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_cap); DeclInfo *di = NULL; if (vd->values.count > 0) { - di = make_declaration_info(heap_allocator(), c->context.scope); + di = make_declaration_info(heap_allocator(), c->context.scope, c->context.decl); di->entities = entities; di->type_expr = vd->type; di->init_expr = vd->values.e[0]; @@ -1494,7 +1497,7 @@ void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope) DeclInfo *d = di; if (d == NULL) { AstNode *init_expr = value; - d = make_declaration_info(heap_allocator(), e->scope); + d = make_declaration_info(heap_allocator(), e->scope, c->context.decl); d->type_expr = vd->type; d->init_expr = init_expr; } @@ -1520,7 +1523,7 @@ void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope) init = vd->values.e[i]; } - DeclInfo *d = make_declaration_info(c->allocator, c->context.scope); + DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl); Entity *e = NULL; AstNode *up_init = unparen_expr(init); @@ -1911,7 +1914,7 @@ void check_parsed_files(Checker *c) { } f->scope = scope; - f->decl_info = make_declaration_info(c->allocator, f->scope); + f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl); HashKey key = hash_string(f->tokenizer.fullpath); map_scope_set(&file_scopes, key, scope); map_ast_file_set(&c->info.files, key, f); diff --git a/src/parser.c b/src/parser.c index a0a215789..f46a24b45 100644 --- a/src/parser.c +++ b/src/parser.c @@ -3866,6 +3866,10 @@ ParseFileError parse_files(Parser *p, char *init_filename) { if (err != ParseFile_None) { if (err == ParseFile_EmptyFile) { + if (str_eq(import_path, init_fullpath)) { + gb_printf_err("Initial file is empty - %.*s\n", LIT(init_fullpath)); + gb_exit(1); + } return ParseFile_None; }