From bb109b47d6b43547481a695ed9401aca95cbdf0e Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Wed, 14 Sep 2016 14:16:01 +0100 Subject: [PATCH] Basic module system (only file namespacing) --- code/demo.odin | 11 +++----- code/win32.odin | 7 +++++ src/checker/checker.cpp | 61 ++++++++++++++++++++--------------------- src/codegen/codegen.cpp | 43 ++++++++++++++++++++++++++--- src/main.cpp | 2 +- src/parser.cpp | 42 +--------------------------- 6 files changed, 82 insertions(+), 84 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index 24da86658..3b22859e2 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,13 +1,10 @@ -// #load "basic.odin" -#import "runtime.odin" #import "print.odin" +test_proc :: proc() { + println("Hello?") +} + main :: proc() { println("% % % %", "Hellope", true, 6.28, {4}int{1, 2, 3, 4}) - x: struct #ordered { - x, y: int - z: f32 - } - println("%", x) } diff --git a/code/win32.odin b/code/win32.odin index 2bc927ecb..794812054 100644 --- a/code/win32.odin +++ b/code/win32.odin @@ -1,6 +1,12 @@ #foreign_system_library "user32" #foreign_system_library "gdi32" + +test_proc :: proc() { + x := "Goodbye?" +} + + HANDLE :: type rawptr HWND :: type HANDLE HDC :: type HANDLE @@ -398,3 +404,4 @@ Key_Code :: enum i32 { PA1 = 0xFD, OEM_CLEAR = 0xFE, } + diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp index c09e3f78d..19df9a1b4 100644 --- a/src/checker/checker.cpp +++ b/src/checker/checker.cpp @@ -117,6 +117,7 @@ struct Scope { b32 is_proc; b32 is_global; b32 is_file; + b32 is_init; }; enum ExprKind { @@ -819,6 +820,10 @@ void check_parsed_files(Checker *c) { scope = make_scope(c->global_scope, c->allocator); scope->is_global = f->is_global_scope; scope->is_file = true; + if (i == 0) { + // NOTE(bill): First file is always the initial file + scope->is_init = true; + } if (scope->is_global) { gb_array_append(c->global_scope->shared, scope); @@ -844,9 +849,6 @@ void check_parsed_files(Checker *c) { switch (decl->kind) { case_ast_node(bd, BadDecl, decl); case_end; - case_ast_node(ld, LoadDecl, decl); - // NOTE(bill): ignore - case_end; case_ast_node(id, ImportDecl, decl); // NOTE(bill): Handle later case_end; @@ -947,37 +949,34 @@ void check_parsed_files(Checker *c) { gb_for_array(decl_index, f->decls) { 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); - } - - // 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); + 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); + } + } + case_end; } - #endif } } diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 888df4a1a..43f894fb4 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -66,12 +66,45 @@ void ssa_gen_tree(ssaGen *s) { gb_for_array(i, info->entities.entries) { auto *entry = &info->entities.entries[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; - DeclInfo *decl = entry->value; - String name = e->token.string; + 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); + } + + switch (e->kind) { 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); break; @@ -107,9 +140,11 @@ void ssa_gen_tree(ssaGen *s) { case Entity_Procedure: { auto *pd = &decl->proc_decl->ProcDecl; - String original_name = e->token.string; - String name = original_name; + String original_name = name; AstNode *body = pd->body; + if (pd->tags & ProcTag_foreign) { + name = pd->name->Ident.string; + } if (pd->foreign_name.len > 0) { name = pd->foreign_name; } diff --git a/src/main.cpp b/src/main.cpp index 6c599c5c3..e3d819ffb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,7 +103,7 @@ int main(int argc, char **argv) { PRINT_TIMER("Semantic Checker"); #endif -#if 0 +#if 1 ssaGen ssa = {}; if (!ssa_gen_init(&ssa, &checker)) return 1; diff --git a/src/parser.cpp b/src/parser.cpp index 0136b2cfe..7f4e842ae 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -230,7 +230,6 @@ AST_NODE_KIND(_DeclBegin, "", struct{}) \ String foreign_name; \ }) \ 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 { \ Token token, relpath; \ String fullpath; \ @@ -410,8 +409,6 @@ Token ast_node_token(AstNode *node) { return node->ProcDecl.name->Ident; case AstNode_TypeDecl: return node->TypeDecl.token; - case AstNode_LoadDecl: - return node->LoadDecl.token; case AstNode_ImportDecl: return node->ImportDecl.token; case AstNode_ForeignSystemLibrary: @@ -886,14 +883,6 @@ gb_inline AstNode *make_type_decl(AstFile *f, Token token, AstNode *name, AstNod 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) { AstNode *result = make_node(f, AstNode_ImportDecl); 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."); 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"))) { Token file_path = expect_token(f, Token_String); if (f->curr_proc == NULL) { @@ -2796,29 +2778,7 @@ void parse_file(Parser *p, AstFile *f) { // NOTE(bill): Sanity check ast_file_err(f, ast_node_token(node), "Only declarations are allowed at file scope"); } 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; String file_str = id->relpath.string;