From: Brendan Hansen Date: Sat, 22 May 2021 23:04:43 +0000 (-0500) Subject: added relative file loads X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3991cfc9665dd4a8370c7751e5c3f582c56273cd;p=onyx.git added relative file loads --- diff --git a/bin/onyx b/bin/onyx index c8087029..8b041462 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/alloc.onyx b/core/alloc.onyx index 169e8df5..1fc81f02 100644 --- a/core/alloc.onyx +++ b/core/alloc.onyx @@ -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 diff --git a/core/math.onyx b/core/math.onyx index 1fc8a7a8..cd212851 100644 --- a/core/math.onyx +++ b/core/math.onyx @@ -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 } diff --git a/core/std.onyx b/core/std.onyx index 677d0e65..1e861a6a 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -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" } diff --git a/docs/bugs b/docs/bugs index 6bffad62..d3d19cde 100644 --- 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. diff --git a/include/bh.h b/include/bh.h index 962d1803..bf5623ef 100644 --- a/include/bh.h +++ b/include/bh.h @@ -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 diff --git a/misc/onyx.sublime-syntax b/misc/onyx.sublime-syntax index 9f42e42d..3a430881 100644 --- a/misc/onyx.sublime-syntax +++ b/misc/onyx.sublime-syntax @@ -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)' diff --git a/modules/immediate_mode/module.onyx b/modules/immediate_mode/module.onyx index 1e88679a..acdc1769 100644 --- a/modules/immediate_mode/module.onyx +++ b/modules/immediate_mode/module.onyx @@ -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" diff --git a/modules/js_events/module.onyx b/modules/js_events/module.onyx index 23215cf3..a4abd4c9 100644 --- a/modules/js_events/module.onyx +++ b/modules/js_events/module.onyx @@ -1,2 +1,2 @@ -#load "modules/js_events/js_events" +#load "./js_events" diff --git a/modules/webgl2/module.onyx b/modules/webgl2/module.onyx index 77b04ea5..72e16e53 100644 --- a/modules/webgl2/module.onyx +++ b/modules/webgl2/module.onyx @@ -1,2 +1,2 @@ -#load "modules/webgl2/webgl2" +#load "./webgl2" diff --git a/src/onyx.c b/src/onyx.c index ec2e54d5..01c5977c 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -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); diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 4ae3a6fb..43b21cb1 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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--; }