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
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 }
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"
}
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 };
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.
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.
// 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);
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, \
//-------------------------------------------------------------------------------------
// 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);
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);
#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
- 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)'
package immediate_mode
-#load "modules/immediate_mode/immediate_renderer"
-#load "modules/immediate_mode/gl_utils"
+#load "./immediate_renderer"
+#load "./gl_utils"
-#load "modules/js_events/js_events"
+#load "./js_events"
-#load "modules/webgl2/webgl2"
+#load "./webgl2"
// 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;
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);
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;
}
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);
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--;
}