From: Brendan Hansen Date: Tue, 11 Aug 2020 03:11:59 +0000 (-0500) Subject: can include other folders in search path X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=f3a40f23e832346d98b393226a0c9af0d2ef4e20;p=onyx.git can include other folders in search path --- diff --git a/.vimspector.json b/.vimspector.json index 41b49cb7..3423b8e3 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -6,7 +6,7 @@ "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": [], diff --git a/core/alloc.onyx b/core/alloc.onyx new file mode 100644 index 00000000..7fe32477 --- /dev/null +++ b/core/alloc.onyx @@ -0,0 +1,138 @@ +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); diff --git a/core/intrinsics.onyx b/core/intrinsics.onyx new file mode 100644 index 00000000..cf4364dc --- /dev/null +++ b/core/intrinsics.onyx @@ -0,0 +1,48 @@ +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 --- diff --git a/core/printing.onyx b/core/printing.onyx new file mode 100644 index 00000000..dc56e887 --- /dev/null +++ b/core/printing.onyx @@ -0,0 +1,124 @@ +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, +} diff --git a/docs/plan b/docs/plan index f025768a..9035a49f 100644 --- a/docs/plan +++ b/docs/plan @@ -159,6 +159,10 @@ HOW: [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 @@ -166,8 +170,6 @@ HOW: [ ] 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 diff --git a/include/bh.h b/include/bh.h index b3085d29..6dbf7d1b 100644 --- a/include/bh.h +++ b/include/bh.h @@ -283,6 +283,7 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc); // Allocator based string functions //------------------------------------------------------------------------------------- +b32 bh_str_ends_with(char* str, char* end); char* bh_strdup(bh_allocator a, char* str); @@ -1200,6 +1201,18 @@ u8* double_to_ieee754(f64 f, b32 reverse) { //------------------------------------------------------------------------------------- // 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); diff --git a/onyx b/onyx index 1234b025..7970dd77 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/alloc.onyx b/progs/alloc.onyx deleted file mode 100644 index ec753e5e..00000000 --- a/progs/alloc.onyx +++ /dev/null @@ -1,138 +0,0 @@ -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); diff --git a/progs/intrinsics.onyx b/progs/intrinsics.onyx deleted file mode 100644 index cf4364dc..00000000 --- a/progs/intrinsics.onyx +++ /dev/null @@ -1,48 +0,0 @@ -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 --- diff --git a/progs/print_funcs.onyx b/progs/print_funcs.onyx deleted file mode 100644 index a9a63b57..00000000 --- a/progs/print_funcs.onyx +++ /dev/null @@ -1,124 +0,0 @@ -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, -} diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx index 7ddfcd13..ce416371 100644 --- a/progs/stack_based.onyx +++ b/progs/stack_based.onyx @@ -1,7 +1,7 @@ package main -use "progs/print_funcs" -use "progs/alloc" +use "printing" +use "alloc" use package printing use package memory @@ -48,6 +48,7 @@ some_value := 20 + 30 * 4 + 15 / 5; start :: proc #export { heap_init(); + print("Hello, World!"); print_hex(cast(u64) some_value); print("Hello, World!"); diff --git a/src/onyx.c b/src/onyx.c index 253b4eff..6e663a7c 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -37,6 +37,7 @@ typedef struct OnyxCompileOptions { u32 verbose_output : 1; u32 print_ast : 1; + bh_arr(const char *) included_folders; bh_arr(const char *) files; const char* target_file; } OnyxCompileOptions; @@ -54,6 +55,10 @@ static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char }; 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")) { @@ -70,6 +75,10 @@ static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char 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]); @@ -148,7 +157,30 @@ static void compiler_state_free(CompilerState* cs) { +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 @@ -171,10 +203,8 @@ static i32 sort_entities(const void* e1, const void* e2) { 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); }