added relative file loads
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 22 May 2021 23:04:43 +0000 (18:04 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 22 May 2021 23:04:43 +0000 (18:04 -0500)
12 files changed:
bin/onyx
core/alloc.onyx
core/math.onyx
core/std.onyx
docs/bugs
include/bh.h
misc/onyx.sublime-syntax
modules/immediate_mode/module.onyx
modules/js_events/module.onyx
modules/webgl2/module.onyx
src/onyx.c
src/onyxwasm.c

index c8087029211c2efacfc986b9126eb5ea30fa0239..8b041462c9620aaf04f32cb4226d3c956d6ee596 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 169e8df58a03a234e214482f5a57c4ee682b46e4..1fc81f024b1eec705cc42b396029b38eae7947a5 100644 (file)
@@ -1,11 +1,11 @@
 package core.alloc
 
-#load "core/alloc/arena"
-#load "core/alloc/fixed"
-#load "core/alloc/heap"
-#load "core/alloc/ring"
-#load "core/alloc/pool"
-#load "core/alloc/logging"
+#load "./alloc/arena"
+#load "./alloc/fixed"
+#load "./alloc/heap"
+#load "./alloc/ring"
+#load "./alloc/pool"
+#load "./alloc/logging"
 
 TEMPORARY_ALLOCATOR_SIZE :: 1 << 12; // 4Kb
 
index 1fc8a7a818dee884cac907f3ecb4660fc162db2c..cd21285154c2457ef41d0bf97d361d31fa0a8354 100644 (file)
@@ -250,7 +250,7 @@ clamp :: (v: $T, lo: T, hi: T) -> T {
 
 sqrt :: proc { wasm.sqrt_f32, wasm.sqrt_f64, sqrt_poly }
 sqrt_poly :: (x: $T) -> T {
-    return ~~ sqrt_f64(~~ x);
+    return ~~ wasm.sqrt_f64(~~ x);
 }
 
 abs :: proc { wasm.abs_f32, wasm.abs_f64, abs_poly }
index 677d0e65faa622abf78dd3ab6fa463bd2a6e75e0..1e861a6a6610969bb88008a19b086a9dac4af2a9 100644 (file)
@@ -1,47 +1,47 @@
 package core
 
 
-#load "core/alloc"
-#load "core/memory"
+#load "./alloc"
+#load "./memory"
 
-#load "core/container/array"
-#load "core/container/map"
-#load "core/container/list"
-#load "core/container/iter"
+#load "./container/array"
+#load "./container/map"
+#load "./container/list"
+#load "./container/iter"
 
-#load "core/conv"
-#load "core/math"
-#load "core/random"
+#load "./conv"
+#load "./math"
+#load "./random"
 
-#load "core/string"
-#load "core/string/builder"
-#load "core/string/reader"
+#load "./string"
+#load "./string/builder"
+#load "./string/reader"
 
-#load "core/intrinsics/onyx"
-#load "core/intrinsics/wasm"
+#load "./intrinsics/onyx"
+#load "./intrinsics/wasm"
 
-#load "core/io/io"
-#load "core/io/stream"
-#load "core/io/reader"
-#load "core/io/writer"
-#load "core/io/binary"
-#load "core/io/binary_reader"
+#load "./io/io"
+#load "./io/stream"
+#load "./io/reader"
+#load "./io/writer"
+#load "./io/binary"
+#load "./io/binary_reader"
 
-#load "core/runtime/build_opts"
-#load "core/runtime/common"
+#load "./runtime/build_opts"
+#load "./runtime/common"
 
 #private_file runtime :: package runtime
 #if runtime.Runtime == runtime.Runtime_Wasi {
-    #load "core/runtime/wasi"
-    #load "core/wasi"
-    #load "core/io/file"
-    #load "core/env"
+    #load "./runtime/wasi"
+    #load "./wasi"
+    #load "./io/file"
+    #load "./env"
 }
 
 #if runtime.Runtime == runtime.Runtime_Js {
-    #load "core/runtime/js"
+    #load "./runtime/js"
 }
 
 #if runtime.Runtime != runtime.Runtime_Custom {
-    #load "core/stdio"
+    #load "./stdio"
 }
index 6bffad62bdb26a9ec73345488eaede47572d92f3..d3d19cde48b94fe80050c57e61c068f96559e8e6 100644 (file)
--- a/docs/bugs
+++ b/docs/bugs
@@ -1,5 +1,48 @@
 List of known bugs:
 
+[ ] Compound assignment operators such as += evaluate the location of their left-value twice.
+    Not only is this bad for efficiency, if the value requires calling a function, that
+    function will be called twice instead of once. This is a simple code generation fix,
+    but will require not destroying this information in the checking phase of the compiler.
+
+[ ] This currently does not work but I think it should:
+
+    baked_proc :: (x: $T, $func: (T) -> T) -> T {
+        return func(x);
+    }
+
+    The problem is that 'T' is an unresolved symbol because the context of the function type
+    does not have the solved value of T in it.
+
+[ ] Top level implicit typed arrays/struct literals are not correctly being marked as compile-time.
+
+    Vec2 :: struct { x, y: i32; }
+    
+    Hex_Directions := Vec2.[
+        .{  1, 0 }, .{  1, -1 }, .{ 0, -1 }, 
+        .{ -1, 0 }, .{ -1,  1 }, .{ 0,  1 }, 
+    ];
+
+[ ] :UnaryFieldAccessIsGross
+
+[ ] Segfault when trying to immediately access type inferred array literal.
+    println( (.[ 1, 2, 3, 4, 5 ])[0] );
+
+[ ] Why are character literals signed????
+
+[ ] Aliasing in many cases does not work. For example:
+    
+    SomeNamespace :: struct {
+        foo :: () { ... }
+        bar :: ...
+    }
+
+    {
+        SN :: SomeNamespace
+
+        SN.foo()
+    }
+
 [X] Enum parsing causes segfaults if the syntax is not EXACTLY what is expected. Some cases that break:
     enum { Foo, Bar, Baz };
     enum { Foo; Bar; Baz };
@@ -23,19 +66,6 @@ List of known bugs:
 
     foo := Foo.{};        OR          foo := new(Foo);
 
-[ ] Aliasing in many cases does not work. For example:
-    
-    SomeNamespace :: struct {
-        foo :: () { ... }
-        bar :: ...
-    }
-
-    {
-        SN :: SomeNamespace
-
-        SN.foo()
-    }
-
 [X] There is a segfault when passing an anonymous struct literal to an untyped vararg.
     Should just need to detect this case and provide an error message since this doesn't
     make any sense semantically.
@@ -46,30 +76,6 @@ List of known bugs:
 
     vararg_proc(.{ 1, 2 });
 
-[ ] This currently does not work but I think it should:
-
-    baked_proc :: (x: $T, $func: (T) -> T) -> T {
-        return func(x);
-    }
-
-    The problem is that 'T' is an unresolved symbol because the context of the function type
-    does not have the solved value of T in it.
-
-[ ] Top level implicit typed arrays/struct literals are not correctly being marked as compile-time.
-
-    Vec2 :: struct { x, y: i32; }
-    
-    Hex_Directions := Vec2.[
-        .{  1, 0 }, .{  1, -1 }, .{ 0, -1 }, 
-        .{ -1, 0 }, .{ -1,  1 }, .{ 0,  1 }, 
-    ];
-
-[ ] :UnaryFieldAccessIsGross
-
-[ ] Segfault when trying to immediately access type inferred array literal.
-    println( (.[ 1, 2, 3, 4, 5 ])[0] );
-
-[ ] Why are character literals signed????
 
 [X] `fallthrough` in a for loop does not emit deferred statments correctly.
 
index 962d180383220f9d67fd303bfc1a8ced2b17e0fc..bf5623efd2c215800739012b2f39181c56b55833 100644 (file)
@@ -290,6 +290,7 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc);
 // Allocator based string functions
 //-------------------------------------------------------------------------------------
 
+b32 bh_str_starts_with(char* str, char* start);
 b32 bh_str_ends_with(char* str, char* end);
 char* bh_strdup(bh_allocator a, char* str);
 
@@ -373,6 +374,7 @@ i32 bh_file_write(bh_file* file, void* buffer, isize buff_size);
 i64 bh_file_size(bh_file* file);
 b32 bh_file_exists(char const* filename);
 char* bh_path_get_full_name(char const* filename, bh_allocator a);
+char* bh_path_get_parent(char const* filename, bh_allocator a);
 
 #define bh_file_read_contents(allocator_, x) _Generic((x), \
     bh_file*: bh_file_read_contents_bh_file, \
@@ -1218,6 +1220,15 @@ u8* double_to_ieee754(f64 f, b32 reverse) {
 //-------------------------------------------------------------------------------------
 // STRING IMPLEMENTATION
 //-------------------------------------------------------------------------------------
+b32 bh_str_starts_with(char* str, char* start) {
+    char* s = str;
+    char* p = start;
+
+    while (*s != '\0' && *p != '\0' && *s == *p) s++, p++;
+
+    return *p == '\0';
+}
+
 b32 bh_str_ends_with(char* str, char* end) {
     i32 slen = strlen(str);
     i32 elen = strlen(end);
@@ -1551,7 +1562,16 @@ b32 bh_file_exists(char const* filename) {
 
 char* bh_path_get_full_name(char const* filename, bh_allocator a) {
 #if defined(_BH_WINDOWS)
-    #error "Not supported."
+    char buffer[4096];
+    GetFullPathNameA(filename, 4096, buffer, NULL);
+
+    i32 len = strlen(buffer);
+    char* result = bh_alloc_array(a, char, len + 1);
+    memmove(result, buffer, len);
+    result[len] = 0;
+
+    return result;
+
 #elif defined(_BH_LINUX)
     char* p = realpath(filename, NULL);    
 
@@ -1570,6 +1590,23 @@ char* bh_path_get_full_name(char const* filename, bh_allocator a) {
 #endif
 }
 
+// NOTE: This assumes the filename is the full path, not relative to anything else.
+char* bh_path_get_parent(char const* filename, bh_allocator a) {
+#if defined(_BH_LINUX)
+    #define DIR_SEPARATOR '/'
+#elif defined(_BH_WINDOWS)
+    #define DIR_SEPARATOR '\\'
+#endif
+
+    char* result = bh_strdup(a, (char *) filename);
+    char* end = result + strlen(result);
+    while (*end != DIR_SEPARATOR && end != result) *end-- = '\0';
+
+    return result;
+
+#undef DIR_SEPARATOR
+}
+
 #endif // ifndef BH_NO_FILE
 
 
index 9f42e42d58dfadd5909cd7bcd96b4e6966317c75..3a4308810620d8e4a6eecf4c83dd115a9b36a05c 100644 (file)
@@ -64,7 +64,7 @@ contexts:
 
     - match: '([a-zA-Z_][a-zA-Z0-9_]*)\s*::\s*(struct)'
       captures:
-        1: entity.name.struct
+        1: entity.name.type
         2: keyword.control.onyx
 
     - match: '([a-zA-Z_][a-zA-Z0-9_]*)\s*::\s*(enum)'
index 1e88679ace6da0d0cca07e464e13b212aaddaac6..acdc17694575651162121b8a2a6ba458369b7a07 100644 (file)
@@ -1,5 +1,5 @@
 
 package immediate_mode
 
-#load "modules/immediate_mode/immediate_renderer"
-#load "modules/immediate_mode/gl_utils"
+#load "./immediate_renderer"
+#load "./gl_utils"
index 23215cf3b5d0053ec37ebd81c41e934918a561fa..a4abd4c94abe16556432c3aa1b80805ccf7f04f0 100644 (file)
@@ -1,2 +1,2 @@
 
-#load "modules/js_events/js_events"
+#load "./js_events"
index 77b04ea5c0298ab928d246f3ccc2950d70726dfd..72e16e53d691800617ccc41d49803b36cab831e5 100644 (file)
@@ -1,2 +1,2 @@
 
-#load "modules/webgl2/webgl2"
+#load "./webgl2"
index ec2e54d5774ed293d7c48cc172b25d1993589413..01c5977cdc6d34063ea884143b3364254b5faf8c 100644 (file)
@@ -211,6 +211,8 @@ static void context_free() {
 // another time.                                        -brendanfh 2020/10/09
 // :RelativeFiles This should lookup for the file relative to "relative_to"
 static char* lookup_included_file(char* filename, char* relative_to) {
+    assert(relative_to != NULL);
+
     static char path[256];
     fori (i, 0, 256) path[i] = 0;
 
@@ -231,6 +233,17 @@ static char* lookup_included_file(char* filename, char* relative_to) {
 
     fori (i, 0, 128) if (fn[i] == '/') fn[i] = DIR_SEPARATOR;
 
+    if (bh_str_starts_with(filename, "./")) {
+        if (relative_to[strlen(relative_to) - 1] != DIR_SEPARATOR)
+            bh_snprintf(path, 256, "%s%c%s", relative_to, DIR_SEPARATOR, fn);
+        else
+            bh_snprintf(path, 256, "%s%s", relative_to, fn);
+
+        if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator);
+
+        return fn;
+    }
+
     bh_arr_each(const char *, folder, context.options->included_folders) {
         if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR)
             bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn);
@@ -257,9 +270,8 @@ static void parse_source_file(bh_file_contents* file_contents) {
 
 static void process_source_file(char* filename, OnyxFilePos error_pos) {
     bh_arr_each(bh_file_contents, fc, context.loaded_files) {
-        // CLEANUP: Add duplicate resolutions, such as
-        //          ./foo and ./test/../foo
-        // should be the same thing.
+        // Duplicates are detected here and since these filenames will be the full path,
+        // string comparing them should be all that is necessary.
         if (!strcmp(fc->filename, filename)) return;
     }
 
@@ -286,7 +298,13 @@ static void process_load_entity(Entity* ent) {
     AstInclude* include = ent->include;
 
     if (include->kind == Ast_Kind_Load_File) {
-        char* filename = lookup_included_file(include->name, NULL);
+        // :RelativeFiles
+        const char* parent_file = include->token->pos.filename;
+        if (parent_file == NULL) parent_file = ".";
+
+        char* parent_folder = bh_path_get_parent(parent_file, global_scratch_allocator);
+        
+        char* filename = lookup_included_file(include->name, parent_folder);
         char* formatted_name = bh_strdup(global_heap_allocator, filename);
 
         process_source_file(formatted_name, include->token->pos);
index 4ae3a6fb75371489b040d80eda7809cf720254c0..43b21cb15b21dcaa445fecadebdee8d8210420ae 100644 (file)
@@ -363,7 +363,7 @@ EMIT_FUNC(structured_jump, AstJump* jump) {
         i32 i = bh_arr_length(mod->deferred_stmts) - 1;
         i32 d = bh_arr_length(mod->structured_jump_target) - (labelidx + 1);
 
-        while (i >= 0 && mod->deferred_stmts[i].depth > d) {
+        while (i >= 0 && (i32) mod->deferred_stmts[i].depth > d) {
             emit_deferred_stmt(mod, &code, mod->deferred_stmts[i]);
             i--;
         }