"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/onyx",
- "args": ["progs/stack_based.onyx"],
+ "args": ["-verbose", "-I", "progs/", "progs/stack_based.onyx"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
--- /dev/null
+package memory
+
+use "intrinsics"
+
+use package printing { print }
+use package intrinsics {
+ memory_size, memory_grow
+}
+
+// Need to define this somewhere
+null :: cast(rawptr) 0;
+
+AllocAction :: enum {
+ Alloc;
+ Free;
+ Resize;
+}
+
+alloc_proc :: #type proc (rawptr, AllocAction, u32, u32, rawptr) -> rawptr;
+
+Allocator :: struct {
+ data: rawptr;
+ func: alloc_proc;
+}
+
+alloc :: proc (use a: ^Allocator, size: u32) -> rawptr {
+ return func(data, AllocAction.Alloc, size, 16, null);
+}
+
+free :: proc (use a: ^Allocator, ptr: rawptr) {
+ func(data, AllocAction.Free, 0, 0, ptr);
+}
+
+
+
+
+
+
+
+heap_allocator : Allocator;
+
+#private
+heap_state : struct {
+ free_list : ^heap_block;
+ next_alloc : rawptr;
+ remaining_space : u32;
+}
+
+#private
+heap_block :: struct {
+ size : u32;
+ next : ^heap_block;
+}
+
+heap_init :: proc {
+ heap_state.free_list = null;
+ heap_state.next_alloc = __heap_start;
+ heap_state.remaining_space = (memory_size() << 16) - cast(u32) __heap_start;
+
+ heap_allocator.data = ^heap_state;
+ heap_allocator.func = heap_alloc_proc;
+}
+
+#private
+heap_alloc :: proc (size_: u32, align: u32) -> rawptr {
+ if size_ == 0 do return null;
+
+ size := size_ + sizeof heap_block;
+ if size % align != 0 {
+ size += align - (size % align);
+ }
+
+ prev := ^heap_state.free_list;
+ hb := heap_state.free_list;
+ while hb != null {
+ if hb.size >= size {
+ *prev = hb.next;
+ hb.next = null;
+
+ return cast(rawptr) (cast(u32) hb + sizeof heap_block);
+ }
+
+ prev = ^hb.next;
+ hb = hb.next;
+ }
+
+ if size < heap_state.remaining_space {
+ ret := cast(^heap_block) heap_state.next_alloc;
+ ret.size = size;
+ ret.next = null;
+
+ heap_state.next_alloc = cast(rawptr) (cast(u32) heap_state.next_alloc + size);
+ heap_state.remaining_space -= size;
+
+ return cast(rawptr) (cast(u32) ret + sizeof heap_block);
+ }
+
+ new_pages :: ((size - heap_state.remaining_space) >> 16) + 1;
+ if memory_grow(new_pages) == -1 {
+ // out of memory
+ return null;
+ }
+ heap_state.remaining_space += new_pages << 16;
+
+ ret := cast(^heap_block) heap_state.next_alloc;
+ ret.size = size;
+ ret.next = null;
+
+ heap_state.next_alloc = cast(rawptr) (cast(u32) heap_state.next_alloc + size);
+ heap_state.remaining_space -= size;
+
+ return cast(rawptr) (cast(u32) ret + sizeof heap_block);
+}
+
+#private
+heap_free :: proc (ptr: rawptr) {
+ hb_ptr := cast(^heap_block) (cast(u32) ptr - sizeof heap_block);
+
+ // DEBUGGING: Fills freed memory with 0's
+ // for i: 0, hb_ptr.size do (cast(^u8) ptr)[i] = cast(u8) 0;
+
+ hb_ptr.next = heap_state.free_list;
+ heap_state.free_list = hb_ptr;
+}
+
+#private
+heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {
+ if aa == AllocAction.Alloc do return heap_alloc(size, align);
+ if aa == AllocAction.Free {
+ heap_free(oldptr);
+ return null;
+ }
+
+ return null;
+}
+
+malloc :: proc (size: u32) -> rawptr do return alloc(^heap_allocator, size);
+mfree :: proc (ptr: rawptr) do free(^heap_allocator, ptr);
--- /dev/null
+package intrinsics
+
+memory_size :: proc #intrinsic -> i32 ---
+memory_grow :: proc #intrinsic (val: i32) -> i32 ---
+
+clz_i32 :: proc #intrinsic (val: i32) -> i32 ---
+ctz_i32 :: proc #intrinsic (val: i32) -> i32 ---
+popcnt_i32 :: proc #intrinsic (val: i32) -> i32 ---
+and_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+or_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+xor_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+shl_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+slr_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+sar_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+rotl_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+rotr_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
+
+clz_i64 :: proc #intrinsic (val: i64) -> i64 ---
+ctz_i64 :: proc #intrinsic (val: i64) -> i64 ---
+popcnt_i64 :: proc #intrinsic (val: i64) -> i64 ---
+and_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+or_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+xor_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+shl_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+slr_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+sar_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+rotl_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+rotr_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
+
+abs_f32 :: proc #intrinsic (val: f32) -> f32 ---
+ceil_f32 :: proc #intrinsic (val: f32) -> f32 ---
+floor_f32 :: proc #intrinsic (val: f32) -> f32 ---
+trunc_f32 :: proc #intrinsic (val: f32) -> f32 ---
+nearest_f32 :: proc #intrinsic (val: f32) -> f32 ---
+sqrt_f32 :: proc #intrinsic (val: f32) -> f32 ---
+min_f32 :: proc #intrinsic (lhs: f32, rhs: f32) -> f32 ---
+max_f32 :: proc #intrinsic (lhs: f32, rhs: f32) -> f32 ---
+copysign_f32 :: proc #intrinsic (lhs: f32, rhs: f32) -> f32 ---
+
+abs_f64 :: proc #intrinsic (val: f64) -> f64 ---
+ceil_f64 :: proc #intrinsic (val: f64) -> f64 ---
+floor_f64 :: proc #intrinsic (val: f64) -> f64 ---
+trunc_f64 :: proc #intrinsic (val: f64) -> f64 ---
+nearest_f64 :: proc #intrinsic (val: f64) -> f64 ---
+sqrt_f64 :: proc #intrinsic (val: f64) -> f64 ---
+min_f64 :: proc #intrinsic (lhs: f64, rhs: f64) -> f64 ---
+max_f64 :: proc #intrinsic (lhs: f64, rhs: f64) -> f64 ---
+copysign_f64 :: proc #intrinsic (lhs: f64, rhs: f64) -> f64 ---
--- /dev/null
+package printing
+
+print_bool :: proc #foreign "host" "print" (value: bool) ---
+print_i32 :: proc #foreign "host" "print" (value: i32) ---
+print_f32 :: proc #foreign "host" "print" (value: f32) ---
+print_i64 :: proc #foreign "host" "print" (value: i64) ---
+print_f64 :: proc #foreign "host" "print" (value: f64) ---
+
+PrintableArray :: struct {
+ data: ^u8;
+ len: i32;
+}
+
+print_i32arr :: proc (arr: [] i32, len: i32) {
+ for i: 0, len do print(arr[i]);
+}
+
+print_i64arr :: proc (arr: [] i64, len: i32) {
+ for i: 0, len do print(arr[i]);
+}
+
+print_f32arr :: proc (arr: [] f32, len: i32) {
+ for i: 0, len do print(arr[i]);
+}
+
+print_f64arr :: proc (arr: [] f64, len: i32) {
+ for i: 0, len do print(arr[i]);
+}
+
+// NOTE: print null-terminated string
+print_str_by_byte :: proc (str: ^u8) {
+ c := str;
+ while *c != cast(u8) 0 {
+ print(cast(i32) (*c));
+ c += 1;
+ }
+}
+
+print_str :: proc #foreign "host" "print_str" (str: ^u8) ---
+
+print_str_len :: proc (str: [] u8, len: i32) {
+ for i: 0, len do print(cast(i32) str[i]);
+}
+
+print_u64_with_base :: proc (n_: u64, base: u64) {
+ n := n_;
+ str: [128] u8;
+ for i: 0, 128 do str[i] = #char "\0";
+
+ c := cast(^u8) ^str[127];
+ *c = #char "\0";
+ c -= 1;
+
+ if n == 0l {
+ *c = #char "0";
+ c -= 1;
+ } else {
+ while n > 0l {
+ m :: n % base;
+
+ ch := cast(u8) 0;
+
+ // TODO: Replace with array lookup when array literals are added
+ if m == 0l do ch = #char "0";
+ elseif m == 1l do ch = #char "1";
+ elseif m == 2l do ch = #char "2";
+ elseif m == 3l do ch = #char "3";
+ elseif m == 4l do ch = #char "4";
+ elseif m == 5l do ch = #char "5";
+ elseif m == 6l do ch = #char "6";
+ elseif m == 7l do ch = #char "7";
+ elseif m == 8l do ch = #char "8";
+ elseif m == 9l do ch = #char "9";
+ elseif m == 10l do ch = #char "A";
+ elseif m == 11l do ch = #char "B";
+ elseif m == 12l do ch = #char "C";
+ elseif m == 13l do ch = #char "D";
+ elseif m == 14l do ch = #char "E";
+ elseif m == 15l do ch = #char "F";
+
+ *c = ch;
+ c -= 1;
+
+ n /= base;
+ }
+ }
+
+ if base == 16l {
+ *c = #char "x";
+ c -= 1;
+ *c = #char "0";
+ c -= 1;
+ }
+
+ if base == 2l {
+ *c = #char "b";
+ c -= 1;
+ *c = #char "0";
+ c -= 1;
+ }
+
+ print(c + 1);
+}
+
+print_u64 :: proc (n: u64) do print_u64_with_base(n, 10l);
+print_hex :: proc (n: u64) do print_u64_with_base(n, 16l);
+print_bin :: proc (n: u64) do print_u64_with_base(n, 2l);
+print_ptr :: proc (p: rawptr) do print_hex(cast(u64) p);
+
+print :: proc #overloaded {
+ print_bool,
+ print_i32,
+ print_f32,
+ print_i64,
+ print_f64,
+
+ print_i32arr,
+ print_i64arr,
+ print_f32arr,
+ print_f64arr,
+
+ print_str,
+ print_str_len,
+}
[X] Properly checking binary operators
- Shouldn't be able to add two structs/arrays together
+ [X] Include other directories to search for files
+
+ [ ] 'use' enums and packages at an arbitrary scope
+
[ ] Array literals
[ ] Struct literals
[ ] Top level variable initialization
- Works for numeric literals
- [ ] 'use' enums and packages at an arbitrary scope
-
[ ] Better checking for casts
- Checking which things are allowed to cast to/from should be checked in the checker,
not in the wasm generatation
// Allocator based string functions
//-------------------------------------------------------------------------------------
+b32 bh_str_ends_with(char* str, char* end);
char* bh_strdup(bh_allocator a, char* str);
//-------------------------------------------------------------------------------------
// STRING IMPLEMENTATION
//-------------------------------------------------------------------------------------
+b32 bh_str_ends_with(char* str, char* end) {
+ i32 slen = strlen(str);
+ i32 elen = strlen(end);
+
+ char* s = str + slen - 1;
+ char* e = end + elen - 1;
+
+ while (*e == *s && e != end && s != str) e--, s--;
+
+ return e == end;
+}
+
char* bh_strdup(bh_allocator a, char* str) {
u32 len = strlen(str);
char* buf = bh_alloc(a, len + 1);
+++ /dev/null
-package memory
-
-use "progs/intrinsics"
-
-use package printing { print }
-use package intrinsics {
- memory_size, memory_grow
-}
-
-// Need to define this somewhere
-null :: cast(rawptr) 0;
-
-AllocAction :: enum {
- Alloc;
- Free;
- Resize;
-}
-
-alloc_proc :: #type proc (rawptr, AllocAction, u32, u32, rawptr) -> rawptr;
-
-Allocator :: struct {
- data: rawptr;
- func: alloc_proc;
-}
-
-alloc :: proc (use a: ^Allocator, size: u32) -> rawptr {
- return func(data, AllocAction.Alloc, size, 16, null);
-}
-
-free :: proc (use a: ^Allocator, ptr: rawptr) {
- func(data, AllocAction.Free, 0, 0, ptr);
-}
-
-
-
-
-
-
-
-heap_allocator : Allocator;
-
-#private
-heap_state : struct {
- free_list : ^heap_block;
- next_alloc : rawptr;
- remaining_space : u32;
-}
-
-#private
-heap_block :: struct {
- size : u32;
- next : ^heap_block;
-}
-
-heap_init :: proc {
- heap_state.free_list = null;
- heap_state.next_alloc = __heap_start;
- heap_state.remaining_space = (memory_size() << 16) - cast(u32) __heap_start;
-
- heap_allocator.data = ^heap_state;
- heap_allocator.func = heap_alloc_proc;
-}
-
-#private
-heap_alloc :: proc (size_: u32, align: u32) -> rawptr {
- if size_ == 0 do return null;
-
- size := size_ + sizeof heap_block;
- if size % align != 0 {
- size += align - (size % align);
- }
-
- prev := ^heap_state.free_list;
- hb := heap_state.free_list;
- while hb != null {
- if hb.size >= size {
- *prev = hb.next;
- hb.next = null;
-
- return cast(rawptr) (cast(u32) hb + sizeof heap_block);
- }
-
- prev = ^hb.next;
- hb = hb.next;
- }
-
- if size < heap_state.remaining_space {
- ret := cast(^heap_block) heap_state.next_alloc;
- ret.size = size;
- ret.next = null;
-
- heap_state.next_alloc = cast(rawptr) (cast(u32) heap_state.next_alloc + size);
- heap_state.remaining_space -= size;
-
- return cast(rawptr) (cast(u32) ret + sizeof heap_block);
- }
-
- new_pages :: ((size - heap_state.remaining_space) >> 16) + 1;
- if memory_grow(new_pages) == -1 {
- // out of memory
- return null;
- }
- heap_state.remaining_space += new_pages << 16;
-
- ret := cast(^heap_block) heap_state.next_alloc;
- ret.size = size;
- ret.next = null;
-
- heap_state.next_alloc = cast(rawptr) (cast(u32) heap_state.next_alloc + size);
- heap_state.remaining_space -= size;
-
- return cast(rawptr) (cast(u32) ret + sizeof heap_block);
-}
-
-#private
-heap_free :: proc (ptr: rawptr) {
- hb_ptr := cast(^heap_block) (cast(u32) ptr - sizeof heap_block);
-
- // DEBUGGING: Fills freed memory with 0's
- // for i: 0, hb_ptr.size do (cast(^u8) ptr)[i] = cast(u8) 0;
-
- hb_ptr.next = heap_state.free_list;
- heap_state.free_list = hb_ptr;
-}
-
-#private
-heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {
- if aa == AllocAction.Alloc do return heap_alloc(size, align);
- if aa == AllocAction.Free {
- heap_free(oldptr);
- return null;
- }
-
- return null;
-}
-
-malloc :: proc (size: u32) -> rawptr do return alloc(^heap_allocator, size);
-mfree :: proc (ptr: rawptr) do free(^heap_allocator, ptr);
+++ /dev/null
-package intrinsics
-
-memory_size :: proc #intrinsic -> i32 ---
-memory_grow :: proc #intrinsic (val: i32) -> i32 ---
-
-clz_i32 :: proc #intrinsic (val: i32) -> i32 ---
-ctz_i32 :: proc #intrinsic (val: i32) -> i32 ---
-popcnt_i32 :: proc #intrinsic (val: i32) -> i32 ---
-and_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-or_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-xor_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-shl_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-slr_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-sar_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-rotl_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-rotr_i32 :: proc #intrinsic (lhs: i32, rhs: i32) -> i32 ---
-
-clz_i64 :: proc #intrinsic (val: i64) -> i64 ---
-ctz_i64 :: proc #intrinsic (val: i64) -> i64 ---
-popcnt_i64 :: proc #intrinsic (val: i64) -> i64 ---
-and_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-or_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-xor_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-shl_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-slr_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-sar_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-rotl_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-rotr_i64 :: proc #intrinsic (lhs: i64, rhs: i64) -> i64 ---
-
-abs_f32 :: proc #intrinsic (val: f32) -> f32 ---
-ceil_f32 :: proc #intrinsic (val: f32) -> f32 ---
-floor_f32 :: proc #intrinsic (val: f32) -> f32 ---
-trunc_f32 :: proc #intrinsic (val: f32) -> f32 ---
-nearest_f32 :: proc #intrinsic (val: f32) -> f32 ---
-sqrt_f32 :: proc #intrinsic (val: f32) -> f32 ---
-min_f32 :: proc #intrinsic (lhs: f32, rhs: f32) -> f32 ---
-max_f32 :: proc #intrinsic (lhs: f32, rhs: f32) -> f32 ---
-copysign_f32 :: proc #intrinsic (lhs: f32, rhs: f32) -> f32 ---
-
-abs_f64 :: proc #intrinsic (val: f64) -> f64 ---
-ceil_f64 :: proc #intrinsic (val: f64) -> f64 ---
-floor_f64 :: proc #intrinsic (val: f64) -> f64 ---
-trunc_f64 :: proc #intrinsic (val: f64) -> f64 ---
-nearest_f64 :: proc #intrinsic (val: f64) -> f64 ---
-sqrt_f64 :: proc #intrinsic (val: f64) -> f64 ---
-min_f64 :: proc #intrinsic (lhs: f64, rhs: f64) -> f64 ---
-max_f64 :: proc #intrinsic (lhs: f64, rhs: f64) -> f64 ---
-copysign_f64 :: proc #intrinsic (lhs: f64, rhs: f64) -> f64 ---
+++ /dev/null
-package printing
-
-print_bool :: proc #foreign "host" "print" (value: bool) ---
-print_i32 :: proc #foreign "host" "print" (value: i32) ---
-print_f32 :: proc #foreign "host" "print" (value: f32) ---
-print_i64 :: proc #foreign "host" "print" (value: i64) ---
-print_f64 :: proc #foreign "host" "print" (value: f64) ---
-
-PrintableArray :: struct {
- data: ^u8;
- len: i32;
-}
-
-print_i32arr :: proc (arr: [] i32, len: i32) {
- for i: 0, len do print(arr[i]);
-}
-
-print_i64arr :: proc (arr: [] i64, len: i32) {
- for i: 0, len do print(arr[i]);
-}
-
-print_f32arr :: proc (arr: [] f32, len: i32) {
- for i: 0, len do print(arr[i]);
-}
-
-print_f64arr :: proc (arr: [] f64, len: i32) {
- for i: 0, len do print(arr[i]);
-}
-
-// NOTE: print null-terminated string
-print_str_by_byte :: proc (str: ^u8) {
- c := str;
- while *c != cast(u8) 0 {
- print(cast(i32) (*c));
- c += 1;
- }
-}
-
-print_str :: proc #foreign "host" "print_str" (str: ^u8) ---
-
-print_str_len :: proc (str: [] u8, len: i32) {
- for i: 0, len do print(cast(i32) str[i]);
-}
-
-print_u64_with_base :: proc (n_: u64, base: u64) {
- n := n_;
- str: [128] u8;
- for i: 0, 128 do str[i] = cast(u8) 0;
-
- c := cast(^u8) ^str[127];
- *c = #char "\0";
- c -= 1;
-
- if n == 0l {
- *c = #char "0";
- c -= 1;
- } else {
- while n > 0l {
- m :: n % base;
-
- ch := cast(u8) 0;
-
- // TODO: Replace with array lookup when array literals are added
- if m == 0l do ch = #char "0";
- elseif m == 1l do ch = #char "1";
- elseif m == 2l do ch = #char "2";
- elseif m == 3l do ch = #char "3";
- elseif m == 4l do ch = #char "4";
- elseif m == 5l do ch = #char "5";
- elseif m == 6l do ch = #char "6";
- elseif m == 7l do ch = #char "7";
- elseif m == 8l do ch = #char "8";
- elseif m == 9l do ch = #char "9";
- elseif m == 10l do ch = #char "A";
- elseif m == 11l do ch = #char "B";
- elseif m == 12l do ch = #char "C";
- elseif m == 13l do ch = #char "D";
- elseif m == 14l do ch = #char "E";
- elseif m == 15l do ch = #char "F";
-
- *c = ch;
- c -= 1;
-
- n /= base;
- }
- }
-
- if base == 16l {
- *c = #char "x";
- c -= 1;
- *c = #char "0";
- c -= 1;
- }
-
- if base == 2l {
- *c = #char "b";
- c -= 1;
- *c = #char "0";
- c -= 1;
- }
-
- print(c + 1);
-}
-
-print_u64 :: proc (n: u64) do print_u64_with_base(n, 10l);
-print_hex :: proc (n: u64) do print_u64_with_base(n, 16l);
-print_bin :: proc (n: u64) do print_u64_with_base(n, 2l);
-print_ptr :: proc (p: rawptr) do print_hex(cast(u64) p);
-
-print :: proc #overloaded {
- print_bool,
- print_i32,
- print_f32,
- print_i64,
- print_f64,
-
- print_i32arr,
- print_i64arr,
- print_f32arr,
- print_f64arr,
-
- print_str,
- print_str_len,
-}
package main
-use "progs/print_funcs"
-use "progs/alloc"
+use "printing"
+use "alloc"
use package printing
use package memory
start :: proc #export {
heap_init();
+
print("Hello, World!");
print_hex(cast(u64) some_value);
print("Hello, World!");
u32 verbose_output : 1;
u32 print_ast : 1;
+ bh_arr(const char *) included_folders;
bh_arr(const char *) files;
const char* target_file;
} OnyxCompileOptions;
};
bh_arr_new(alloc, options.files, 1);
+ bh_arr_new(alloc, options.included_folders, 1);
+
+ // NOTE: Add the current folder
+ bh_arr_push(options.included_folders, ".");
fori(i, 1, argc - 1) {
if (!strcmp(argv[i], "-help")) {
else if (!strcmp(argv[i], "-verbose")) {
options.verbose_output = 1;
}
+ else if (!strcmp(argv[i], "-I")) {
+ options.action = ONYX_COMPILE_ACTION_COMPILE;
+ bh_arr_push(options.included_folders, argv[++i]);
+ }
else {
options.action = ONYX_COMPILE_ACTION_COMPILE;
bh_arr_push(options.files, argv[i]);
+static char* lookup_included_file(CompilerState* cs, OnyxToken* filename) {
+ static char path[256];
+ fori (i, 0, 511) path[i] = 0;
+
+ static char fn[128];
+ token_toggle_end(filename);
+ if (!bh_str_ends_with(filename->text, ".onyx")) {
+ bh_snprintf(fn, 128, "%s.onyx", filename->text);
+ } else {
+ bh_snprintf(fn, 128, "%s", filename->text);
+ }
+ token_toggle_end(filename);
+
+ bh_arr_each(const char *, folder, cs->options->included_folders) {
+ if ((*folder)[strlen(*folder) - 1] != '/')
+ bh_snprintf(path, 256, "%s/%s", *folder, fn);
+ else
+ bh_snprintf(path, 256, "%s%s", *folder, fn);
+ if (bh_file_exists(path)) return path;
+ }
+
+ return fn;
+}
static ParseResults parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) {
// NOTE: Maybe don't want to recreate the tokenizer and parser for every file
static void merge_parse_results(CompilerState* compiler_state, ParseResults* results) {
bh_arr_each(AstIncludeFile *, include, results->files) {
- char* formatted_name = bh_aprintf(
- global_heap_allocator,
- "%b.onyx",
- (*include)->filename->text, (*include)->filename->length);
+ char* filename = lookup_included_file(compiler_state, (*include)->filename);
+ char* formatted_name = bh_strdup(global_heap_allocator, filename);
bh_arr_push(compiler_state->queued_files, formatted_name);
}