Basic module system (only file namespacing)

This commit is contained in:
Ginger Bill
2016-09-14 14:16:01 +01:00
parent a60e6bedd9
commit bb109b47d6
6 changed files with 82 additions and 84 deletions

View File

@@ -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)
}

View File

@@ -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,
}

View File

@@ -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
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;