mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Basic module system (only file namespacing)
This commit is contained in:
+4
-7
@@ -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)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-31
@@ -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) {
|
switch (decl->kind) {
|
||||||
continue;
|
case_ast_node(id, ImportDecl, decl);
|
||||||
}
|
HashKey key = hash_string(id->fullpath);
|
||||||
#if 1
|
auto found = map_get(&file_scopes, key);
|
||||||
ast_node(id, ImportDecl, decl);
|
GB_ASSERT_MSG(found != NULL, "Unable to find scope for file: %.*s", LIT(id->fullpath));
|
||||||
|
Scope *scope = *found;
|
||||||
HashKey key = hash_string(id->fullpath);
|
b32 previously_added = false;
|
||||||
auto found = map_get(&file_scopes, key);
|
gb_for_array(import_index, file_scope->imported) {
|
||||||
GB_ASSERT_MSG(found != NULL, "Unable to find scope for file: %.*s", LIT(id->fullpath));
|
Scope *prev = file_scope->imported[import_index];
|
||||||
Scope *scope = *found;
|
if (prev == scope) {
|
||||||
b32 previously_added = false;
|
previously_added = true;
|
||||||
gb_for_array(import_index, file_scope->imported) {
|
break;
|
||||||
Scope *prev = file_scope->imported[import_index];
|
}
|
||||||
if (prev == scope) {
|
|
||||||
previously_added = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
if (!previously_added) {
|
||||||
if (!previously_added) {
|
gb_array_append(file_scope->imported, scope);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-4
@@ -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;
|
||||||
DeclInfo *decl = entry->value;
|
|
||||||
|
|
||||||
String name = e->token.string;
|
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) {
|
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 original_name = name;
|
||||||
String name = original_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
@@ -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
@@ -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) {
|
if (node->kind == AstNode_ImportDecl) {
|
||||||
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) {
|
|
||||||
auto *id = &node->ImportDecl;
|
auto *id = &node->ImportDecl;
|
||||||
String file_str = id->relpath.string;
|
String file_str = id->relpath.string;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user