Browse Source

Fix issue #48 dependency issue

Ginger Bill 8 years ago
parent
commit
b78e970698
4 changed files with 37 additions and 25 deletions
  1. 9 2
      src/check_decl.c
  2. 4 6
      src/check_expr.c
  3. 20 17
      src/checker.c
  4. 4 0
      src/parser.c

+ 9 - 2
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);
+		}
+	}
 }
 
 

+ 4 - 6
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);
 

+ 20 - 17
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);

+ 4 - 0
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;
 			}