diff --git a/TODO.md b/TODO.md index a516d78..e199417 100644 --- a/TODO.md +++ b/TODO.md @@ -626,7 +626,11 @@ - `heap.free(ptr ?*mut u8) void` forwards to C `free`, including `none` / null - typed allocation, allocator parameters, arenas/pools, build-mode heap policy, and escaping-allocation diagnostics remain deferred -26. comptime polymorphism (zig inspired) +26. import from project "root" (implemented) + - imports beginning with `@` resolve from the compiler process cwd / project root + - `heap :: import "@std/mem/heap"` works from any package depth without `../../../` path math + +27. comptime polymorphism (zig inspired) ## A word on multi-unwrap diff --git a/compiler/loader/loader.odin b/compiler/loader/loader.odin index bf165bf..6b14d8b 100644 --- a/compiler/loader/loader.odin +++ b/compiler/loader/loader.odin @@ -25,6 +25,7 @@ State :: struct { allocator: mem.Allocator, c_options: cimport.Options, selected: target.Target, + project_root: string, record_identities: [dynamic]string, record_types: [dynamic]types.Type, root_failed: bool, @@ -100,7 +101,13 @@ resolve_import_path :: proc(state: ^State, importing_path, import_path: string) if filepath.is_abs(import_path) { return "", false } - joined, join_error := filepath.join({importing_path, import_path}, state.allocator) + base := importing_path + path := import_path + if strings.has_prefix(import_path, "@") { + base = state.project_root + path = import_path[1:] + } + joined, join_error := filepath.join({base, path}, state.allocator) if join_error != nil { return "", false } @@ -1406,6 +1413,10 @@ load :: proc( selected := target.DEFAULT, ) -> (ast.Module, bool) { module := ast.init_module(allocator) + project_root, project_root_ok := filepath.abs(".", allocator) + if !project_root_ok { + project_root = strings.clone(".", allocator) + } state := State{ module=&module, sources=sources, @@ -1415,10 +1426,12 @@ load :: proc( allocator=allocator, c_options=c_options, selected=selected, + project_root=project_root, } state.record_identities.allocator = allocator state.record_types.allocator = allocator defer { + delete(state.project_root, allocator) for identity in state.record_identities { delete(identity, allocator) } diff --git a/examples/programs/heap/main.bro b/examples/programs/heap/main.bro index 001be61..5e9941b 100644 --- a/examples/programs/heap/main.bro +++ b/examples/programs/heap/main.bro @@ -1,4 +1,4 @@ -heap :: import "../../../std/mem/heap" +heap :: import "@std/mem/heap" printf c_func(fmt *c_char, ...) c_int