Browse Source

Basic module system (only file namespacing)

Ginger Bill 9 years ago
parent
commit
bb109b47d6
6 changed files with 80 additions and 82 deletions
  1. 4 7
      code/demo.odin
  2. 7 0
      code/win32.odin
  3. 29 30
      src/checker/checker.cpp
  4. 38 3
      src/codegen/codegen.cpp
  5. 1 1
      src/main.cpp
  6. 1 41
      src/parser.cpp

+ 4 - 7
code/demo.odin

@@ -1,13 +1,10 @@
-// #load "basic.odin"
-#import "runtime.odin"
 #import "print.odin"
 #import "print.odin"
 
 
+test_proc :: proc() {
+	println("Hello?")
+}
+
 
 
 main :: proc() {
 main :: proc() {
 	println("% % % %", "Hellope", true, 6.28, {4}int{1, 2, 3, 4})
 	println("% % % %", "Hellope", true, 6.28, {4}int{1, 2, 3, 4})
-	x: struct #ordered {
-		x, y: int
-		z: f32
-	}
-	println("%", x)
 }
 }

+ 7 - 0
code/win32.odin

@@ -1,6 +1,12 @@
 #foreign_system_library "user32"
 #foreign_system_library "user32"
 #foreign_system_library "gdi32"
 #foreign_system_library "gdi32"
 
 
+
+test_proc :: proc() {
+	x := "Goodbye?"
+}
+
+
 HANDLE    :: type rawptr
 HANDLE    :: type rawptr
 HWND      :: type HANDLE
 HWND      :: type HANDLE
 HDC       :: type HANDLE
 HDC       :: type HANDLE
@@ -398,3 +404,4 @@ Key_Code :: enum i32 {
 	PA1        = 0xFD,
 	PA1        = 0xFD,
 	OEM_CLEAR  = 0xFE,
 	OEM_CLEAR  = 0xFE,
 }
 }
+

+ 29 - 30
src/checker/checker.cpp

@@ -117,6 +117,7 @@ struct Scope {
 	b32 is_proc;
 	b32 is_proc;
 	b32 is_global;
 	b32 is_global;
 	b32 is_file;
 	b32 is_file;
+	b32 is_init;
 };
 };
 
 
 enum ExprKind {
 enum ExprKind {
@@ -819,6 +820,10 @@ void check_parsed_files(Checker *c) {
 		scope = make_scope(c->global_scope, c->allocator);
 		scope = make_scope(c->global_scope, c->allocator);
 		scope->is_global = f->is_global_scope;
 		scope->is_global = f->is_global_scope;
 		scope->is_file   = true;
 		scope->is_file   = true;
+		if (i == 0) {
+			// NOTE(bill): First file is always the initial file
+			scope->is_init = true;
+		}
 
 
 		if (scope->is_global) {
 		if (scope->is_global) {
 			gb_array_append(c->global_scope->shared, scope);
 			gb_array_append(c->global_scope->shared, scope);
@@ -844,9 +849,6 @@ void check_parsed_files(Checker *c) {
 			switch (decl->kind) {
 			switch (decl->kind) {
 			case_ast_node(bd, BadDecl, decl);
 			case_ast_node(bd, BadDecl, decl);
 			case_end;
 			case_end;
-			case_ast_node(ld, LoadDecl, decl);
-				// NOTE(bill): ignore
-			case_end;
 			case_ast_node(id, ImportDecl, decl);
 			case_ast_node(id, ImportDecl, decl);
 				// NOTE(bill): Handle later
 				// NOTE(bill): Handle later
 			case_end;
 			case_end;
@@ -947,37 +949,34 @@ void check_parsed_files(Checker *c) {
 
 
 		gb_for_array(decl_index, f->decls) {
 		gb_for_array(decl_index, f->decls) {
 			AstNode *decl = f->decls[decl_index];
 			AstNode *decl = f->decls[decl_index];
-			if (decl->kind != AstNode_ImportDecl) {
-				continue;
-			}
-	#if 1
-			ast_node(id, ImportDecl, decl);
-
-			HashKey key = hash_string(id->fullpath);
-			auto found = map_get(&file_scopes, key);
-			GB_ASSERT_MSG(found != NULL, "Unable to find scope for file: %.*s", LIT(id->fullpath));
-			Scope *scope = *found;
-			b32 previously_added = false;
-			gb_for_array(import_index, file_scope->imported) {
-				Scope *prev = file_scope->imported[import_index];
-				if (prev == scope) {
-					previously_added = true;
-					break;
+			switch (decl->kind) {
+			case_ast_node(id, ImportDecl, decl);
+				HashKey key = hash_string(id->fullpath);
+				auto found = map_get(&file_scopes, key);
+				GB_ASSERT_MSG(found != NULL, "Unable to find scope for file: %.*s", LIT(id->fullpath));
+				Scope *scope = *found;
+				b32 previously_added = false;
+				gb_for_array(import_index, file_scope->imported) {
+					Scope *prev = file_scope->imported[import_index];
+					if (prev == scope) {
+						previously_added = true;
+						break;
+					}
+				}
+				if (!previously_added) {
+					gb_array_append(file_scope->imported, scope);
 				}
 				}
-			}
-			if (!previously_added) {
-				gb_array_append(file_scope->imported, scope);
-			}
 
 
-			// NOTE(bill): Add imported entities to this file's scope
-			gb_for_array(elem_index, scope->elements.entries) {
-				Entity *e = scope->elements.entries[elem_index].value;
-				// NOTE(bill): Do not add other imported entities
-				if (e->scope == scope) {
-					add_entity(c, file_scope, NULL, e);
+				// NOTE(bill): Add imported entities to this file's scope
+				gb_for_array(elem_index, scope->elements.entries) {
+					Entity *e = scope->elements.entries[elem_index].value;
+					// NOTE(bill): Do not add other imported entities
+					if (e->scope == scope) {
+						add_entity(c, file_scope, NULL, e);
+					}
 				}
 				}
+			case_end;
 			}
 			}
-	#endif
 		}
 		}
 	}
 	}
 
 

+ 38 - 3
src/codegen/codegen.cpp

@@ -66,12 +66,45 @@ void ssa_gen_tree(ssaGen *s) {
 	gb_for_array(i, info->entities.entries) {
 	gb_for_array(i, info->entities.entries) {
 		auto *entry = &info->entities.entries[i];
 		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
+		String name = e->token.string;
+
 		DeclInfo *decl = entry->value;
 		DeclInfo *decl = entry->value;
+		Scope *scope = e->scope;
+		if (scope->is_global ||
+		    scope->is_init) {
+
+		} else {
+			// NOTE(bill): prefix names not in the init scope
+			// TODO(bill): make robust and not just rely on the file's name
+			String path = e->token.pos.file;
+			char *str = gb_alloc_array(a, char, path.len+1);
+			gb_memcopy(str, path.text, path.len);
+			str[path.len] = 0;
+			for (isize i = 0; i < path.len; i++) {
+				if (str[i] == '\\') {
+					str[i] = '/';
+				}
+			}
+			char const *base = gb_path_base_name(str);
+			char const *ext = gb_path_extension(base);
+			isize base_len = ext-1-base;
+
+			isize new_len = base_len + 1 + name.len;
+			u8 *new_name = gb_alloc_array(a, u8, new_len);
+			gb_memcopy(new_name, base, base_len);
+			new_name[base_len] = '.';
+			gb_memcopy(new_name+base_len+1, name.text, name.len);
+
+			name = make_string(new_name, new_len);
+			// gb_printf("%.*s\n", new_len, new_name);
+		}
 
 
-		String name = e->token.string;
 
 
 		switch (e->kind) {
 		switch (e->kind) {
 		case Entity_TypeName:
 		case Entity_TypeName:
+			GB_ASSERT(e->type->kind == Type_Named);
+			// HACK(bill): Rename type's name for ssa gen
+			e->type->Named.name = name;
 			ssa_gen_global_type_name(m, e, name);
 			ssa_gen_global_type_name(m, e, name);
 			break;
 			break;
 
 
@@ -107,9 +140,11 @@ void ssa_gen_tree(ssaGen *s) {
 
 
 		case Entity_Procedure: {
 		case Entity_Procedure: {
 			auto *pd = &decl->proc_decl->ProcDecl;
 			auto *pd = &decl->proc_decl->ProcDecl;
-			String original_name = e->token.string;
-			String name = original_name;
+			String original_name = name;
 			AstNode *body = pd->body;
 			AstNode *body = pd->body;
+			if (pd->tags & ProcTag_foreign) {
+				name = pd->name->Ident.string;
+			}
 			if (pd->foreign_name.len > 0) {
 			if (pd->foreign_name.len > 0) {
 				name = pd->foreign_name;
 				name = pd->foreign_name;
 			}
 			}

+ 1 - 1
src/main.cpp

@@ -103,7 +103,7 @@ int main(int argc, char **argv) {
 
 
 	PRINT_TIMER("Semantic Checker");
 	PRINT_TIMER("Semantic Checker");
 #endif
 #endif
-#if 0
+#if 1
 	ssaGen ssa = {};
 	ssaGen ssa = {};
 	if (!ssa_gen_init(&ssa, &checker))
 	if (!ssa_gen_init(&ssa, &checker))
 		return 1;
 		return 1;

+ 1 - 41
src/parser.cpp

@@ -230,7 +230,6 @@ AST_NODE_KIND(_DeclBegin,      "", struct{}) \
 			String  foreign_name; \
 			String  foreign_name; \
 		}) \
 		}) \
 	AST_NODE_KIND(TypeDecl,   "type declaration",   struct { Token token; AstNode *name, *type; }) \
 	AST_NODE_KIND(TypeDecl,   "type declaration",   struct { Token token; AstNode *name, *type; }) \
-	AST_NODE_KIND(LoadDecl,   "load declaration",   struct { Token token, filepath; }) \
 	AST_NODE_KIND(ImportDecl, "import declaration", struct { \
 	AST_NODE_KIND(ImportDecl, "import declaration", struct { \
 		Token token, relpath; \
 		Token token, relpath; \
 		String fullpath; \
 		String fullpath; \
@@ -410,8 +409,6 @@ Token ast_node_token(AstNode *node) {
 		return node->ProcDecl.name->Ident;
 		return node->ProcDecl.name->Ident;
 	case AstNode_TypeDecl:
 	case AstNode_TypeDecl:
 		return node->TypeDecl.token;
 		return node->TypeDecl.token;
-	case AstNode_LoadDecl:
-		return node->LoadDecl.token;
 	case AstNode_ImportDecl:
 	case AstNode_ImportDecl:
 		return node->ImportDecl.token;
 		return node->ImportDecl.token;
 	case AstNode_ForeignSystemLibrary:
 	case AstNode_ForeignSystemLibrary:
@@ -886,14 +883,6 @@ gb_inline AstNode *make_type_decl(AstFile *f, Token token, AstNode *name, AstNod
 	return result;
 	return result;
 }
 }
 
 
-gb_inline AstNode *make_load_decl(AstFile *f, Token token, Token filepath) {
-	AstNode *result = make_node(f, AstNode_LoadDecl);
-	result->LoadDecl.token = token;
-	result->LoadDecl.filepath = filepath;
-	return result;
-}
-
-
 gb_inline AstNode *make_import_decl(AstFile *f, Token token, Token relpath) {
 gb_inline AstNode *make_import_decl(AstFile *f, Token token, Token relpath) {
 	AstNode *result = make_node(f, AstNode_ImportDecl);
 	AstNode *result = make_node(f, AstNode_ImportDecl);
 	result->ImportDecl.token = token;
 	result->ImportDecl.token = token;
@@ -2551,13 +2540,6 @@ AstNode *parse_stmt(AstFile *f) {
 			}
 			}
 			ast_file_err(f, token, "You cannot use #global_scope within a procedure. This must be done at the file scope.");
 			ast_file_err(f, token, "You cannot use #global_scope within a procedure. This must be done at the file scope.");
 			return make_bad_decl(f, token, f->cursor[0]);
 			return make_bad_decl(f, token, f->cursor[0]);
-		} else if (are_strings_equal(tag, make_string("load"))) {
-			Token file_path = expect_token(f, Token_String);
-			if (f->curr_proc == NULL) {
-				return make_load_decl(f, s->TagStmt.token, file_path);
-			}
-			ast_file_err(f, token, "You cannot use #load within a procedure. This must be done at the file scope.");
-			return make_bad_decl(f, token, file_path);
 		} else if (are_strings_equal(tag, make_string("import"))) {
 		} else if (are_strings_equal(tag, make_string("import"))) {
 			Token file_path = expect_token(f, Token_String);
 			Token file_path = expect_token(f, Token_String);
 			if (f->curr_proc == NULL) {
 			if (f->curr_proc == NULL) {
@@ -2796,29 +2778,7 @@ void parse_file(Parser *p, AstFile *f) {
 			// NOTE(bill): Sanity check
 			// NOTE(bill): Sanity check
 			ast_file_err(f, ast_node_token(node), "Only declarations are allowed at file scope");
 			ast_file_err(f, ast_node_token(node), "Only declarations are allowed at file scope");
 		} else {
 		} else {
-			if (node->kind == AstNode_LoadDecl) {
-				auto *id = &node->LoadDecl;
-				String file_str = id->filepath.string;
-
-				if (!is_import_path_valid(file_str)) {
-					ast_file_err(f, ast_node_token(node), "Invalid `load` path");
-					continue;
-				}
-
-				isize str_len = base_dir.len+file_str.len;
-				u8 *str = gb_alloc_array(gb_heap_allocator(), u8, str_len+1);
-				defer (gb_free(gb_heap_allocator(), str));
-
-				gb_memcopy(str, base_dir.text, base_dir.len);
-				gb_memcopy(str+base_dir.len, file_str.text, file_str.len);
-				str[str_len] = '\0';
-				char *path_str = gb_path_get_full_name(gb_heap_allocator(), cast(char *)str);
-				String import_file = make_string(path_str);
-
-				if (!try_add_import_path(p, import_file, node)) {
-					gb_free(gb_heap_allocator(), import_file.text);
-				}
-			} else if (node->kind == AstNode_ImportDecl) {
+			if (node->kind == AstNode_ImportDecl) {
 				auto *id = &node->ImportDecl;
 				auto *id = &node->ImportDecl;
 				String file_str = id->relpath.string;
 				String file_str = id->relpath.string;