can include other folders in search path
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 11 Aug 2020 03:11:59 +0000 (22:11 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 11 Aug 2020 03:11:59 +0000 (22:11 -0500)
12 files changed:
.vimspector.json
core/alloc.onyx [new file with mode: 0644]
core/intrinsics.onyx [new file with mode: 0644]
core/printing.onyx [new file with mode: 0644]
docs/plan
include/bh.h
onyx
progs/alloc.onyx [deleted file]
progs/intrinsics.onyx [deleted file]
progs/print_funcs.onyx [deleted file]
progs/stack_based.onyx
src/onyx.c

index 41b49cb7edeea24d2e72e29ac8b8d72d358a9898..3423b8e3a1d43a607d79280eafda28685761fa56 100644 (file)
@@ -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 (file)
index 0000000..7fe3247
--- /dev/null
@@ -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 (file)
index 0000000..cf4364d
--- /dev/null
@@ -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 (file)
index 0000000..dc56e88
--- /dev/null
@@ -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,
+}
index f025768a3aa48cd6c44c6ffeeae47bec93111daf..9035a49fdff76c0dcf075603022a125a834a5c88 100644 (file)
--- 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
index b3085d29baa1fbee533f49f027852279e1c35559..6dbf7d1b7d36fa12df0919eaf619aef260e41876 100644 (file)
@@ -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 1234b0255ab602b1de965ce85577d7e1c6429f09..7970dd77d1f14611472c14a3e7c52b43baa2f3ad 100755 (executable)
Binary files a/onyx and b/onyx differ
diff --git a/progs/alloc.onyx b/progs/alloc.onyx
deleted file mode 100644 (file)
index ec753e5..0000000
+++ /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 (file)
index cf4364d..0000000
+++ /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 (file)
index a9a63b5..0000000
+++ /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,
-}
index 7ddfcd13d93f3158117060f61416290db5be6c74..ce416371efc8f9f3888a1ae71dcded9fcb91e366 100644 (file)
@@ -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!");
index 253b4effc91366652bb3fea12c85001b94a20631..6e663a7c4d436a431e8cda589ddfa1b03999ad4d 100644 (file)
@@ -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);
     }