Changed cast syntax; added basic heap allocator in onyx
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 29 Jul 2020 22:17:48 +0000 (17:17 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 29 Jul 2020 22:17:48 +0000 (17:17 -0500)
20 files changed:
docs/plan
include/onyxastnodes.h
include/onyxlex.h
misc/onyx.sublime-syntax
misc/onyx.vim
onyx
progs/alloc.onyx [new file with mode: 0644]
progs/alloc_test.onyx [new file with mode: 0644]
progs/arrays.onyx
progs/basic.onyx
progs/ez.onyx
progs/fcf.onyx
progs/print_funcs.onyx
progs/structs.onyx
progs/ufc.onyx
src/onyx.c
src/onyxchecker.c
src/onyxlex.c
src/onyxparser.c
src/onyxtypes.c

index 5da7f55998c6ea3fc2b9b873aef8acc8af47dd7a..a8f1956beb05d3d81f24229a0a2e3e8ece4ac375 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -132,6 +132,14 @@ HOW:
 
         [X] Procedures as arguments
 
+        [ ] Deferred statements
+
+        [ ] Pointer math
+
+        [ ] Better checking for casts
+
+        [ ] Hex literals
+
         [ ] Start work on evaluating compile time known values.
             - An expression marked COMPTIME will be reduced to its value in the parse tree.
 
index bde66fe2124654a3a4f1d44887759f0da8be3d24..af36357434204a1d337f171d7ef4e5f94e95ff93 100644 (file)
@@ -489,6 +489,11 @@ static inline b32 binop_is_assignment(AstBinaryOp* binop) {
             && binop->operation <= Binary_Op_Assign_End);
 }
 
+static inline b32 binop_is_compare(AstBinaryOp* binop) {
+    return (binop->operation >= Binary_Op_Equal
+            && binop->operation <= Binary_Op_Greater_Equal);
+}
+
 static inline b32 node_is_type(AstNode* node) {
     return (node->kind > Ast_Kind_Type_Start) && (node->kind < Ast_Kind_Type_End);
 }
index be2f15103958c8ccd63eaed78c569d07b697b2b4..5410ae4bdacee36f2247f57f374a41458a500e8e 100644 (file)
@@ -20,6 +20,7 @@ typedef enum TokenType {
     Token_Type_Keyword_Return,
     Token_Type_Keyword_Global,
     Token_Type_Keyword_Proc,
+    Token_Type_Keyword_As,
     Token_Type_Keyword_Cast,
     Token_Type_Keyword_While,
     Token_Type_Keyword_For,
index 457791a6c928645ef31c109b8206d85a029d02e7..7e44579bf11993ee82e1e135e220e703795fad7d 100644 (file)
@@ -23,13 +23,13 @@ contexts:
     # strings in YAML. When using single quoted strings, only single quotes
     # need to be escaped: this is done by using two single quotes next to each
     # other.
-    - match: '\b(package|struct|proc|use|global|enum|if|elseif|else|for|while|do|break|continue|return|as|sizeof|alignof)\b'
+    - match: '\b(package|struct|proc|use|global|enum|if|elseif|else|for|while|do|break|continue|return|as|cast|sizeof|alignof)\b'
       scope: keyword.control.onyx
 
     - match: '\b(bool|void|i8|u8|i16|u16|i32|u32|i64|u64|f32|f64|rawptr)\b'
       scope: constant.type.onyx
 
-    - match: '\b(true|false)\b'
+    - match: '\b(true|false|null)\b'
       scope: constant.boolean.onyx
 
     # Numbers
index 5a6bfbf112d118a1aa7a141f0420dbe8e65d0cda..e8c8b761ff753eb800b7a0a006fad69187d922a2 100644 (file)
@@ -14,7 +14,7 @@ syn keyword onyxKeyword package struct proc use global
 syn keyword onyxKeyword if elseif else
 syn keyword onyxKeyword for while do
 syn keyword onyxKeyword break continue return
-syn keyword onyxKeyword as sizeof alignof
+syn keyword onyxKeyword as cast sizeof alignof
 
 syn keyword onyxType bool void
 syn keyword onyxType i8 u8
@@ -31,11 +31,14 @@ syn keyword onyxCommentStart    contained TODO NOTE BUG HACK
 
 syn region onyxComment start="//" end="$" keepend contains=onyxCommentStart
 
+syn region onyxDirective start="#" end=" " keepend
+
 hi def link onyxKeyword          Statement
 hi def link onyxType             Type
 hi def link onyxComment          Comment
 hi def link onyxCommentStart     Todo
 hi def link onyxConstant         Constant
+hi def link onyxDirective        Constant
 
 let b:current_syntax = "onyx"
 let &cpo = s:cpo_save
diff --git a/onyx b/onyx
index 4aefaecbf229c99399ff5e4553c603684a32ed2e..10d3bbe2ac6f73e0d98adb162947ad2927080364 100755 (executable)
Binary files a/onyx and b/onyx differ
diff --git a/progs/alloc.onyx b/progs/alloc.onyx
new file mode 100644 (file)
index 0000000..064665e
--- /dev/null
@@ -0,0 +1,74 @@
+package alloc
+
+use "progs/intrinsics"
+
+use package printing { print }
+
+use package intrinsics {
+    memory_size, memory_grow
+}
+
+// Need to define this somewhere
+null :: cast(rawptr) 0;
+
+heap_state : struct {
+    free_list       : ^heap_block;
+    next_alloc      : rawptr;
+    remaining_space : u32;
+}
+
+heap_block :: struct {
+    size : i32;
+    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_align_to :: 16
+
+heap_alloc :: proc (size_: i32) -> rawptr {
+    if size_ == 0 return null;
+
+    size := size_ + sizeof heap_block;
+    if size % heap_align_to != 0 {
+        size += heap_align_to - (size % heap_align_to);
+    }
+
+    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);
+    }
+    
+    // grow the memory with memory_grow
+    return cast(rawptr) -1;
+}
+
+heap_free :: proc (ptr: rawptr) {
+    hb_ptr := cast(^heap_block) (cast(u32) ptr - sizeof heap_block);
+    hb_ptr.next = heap_state.free_list;
+    heap_state.free_list = hb_ptr;
+}
\ No newline at end of file
diff --git a/progs/alloc_test.onyx b/progs/alloc_test.onyx
new file mode 100644 (file)
index 0000000..72fa5af
--- /dev/null
@@ -0,0 +1,41 @@
+use "progs/alloc"
+use "progs/print_funcs"
+
+use package alloc
+use package printing
+
+proc #export "main" {
+       asdf :: "staring asdfkjasd asdflkjasdflkajsdflk";
+       heap_init();
+
+       first := cast([] i32) heap_alloc(sizeof [4] i32);
+       for i: 0, 4 first[i] = i * 2;
+
+       second := cast([] f32) heap_alloc(sizeof [24] f32);
+       for i: 0, 24 second[i] = cast(f32) i;
+
+       print(cast(u32) first);
+       print(cast(u32) second);
+
+       for i: 0, 4 print(first[i]);
+       for i: 0, 24 print(second[i]);
+
+       heap_free(first);
+
+       third := cast(^i32) heap_alloc(sizeof i32);
+
+       print(cast(u32) third);
+       *third = 1234;
+       print(*third);
+
+       heap_free(second);
+
+       fourth := cast([] i32) heap_alloc(sizeof [128]i32);
+       print(cast(u32) fourth);
+
+       fifth := cast(^i32) heap_alloc(sizeof i32);
+       print(cast(u32) fifth);
+
+       sixth := heap_alloc(8 << 16);
+       print(cast(u32) sixth);
+}
\ No newline at end of file
index 9353aa68f0e8855df2f82c6f7c90bbee8b6df231..7dff60d535de195fc3ab46227b786c070ca4a37f 100644 (file)
@@ -46,7 +46,7 @@ str_test :: proc #export {
     // Address of and dereference cancel each other out
     print(^*hello_str);
 
-    print(hello_str as []u8, 5);
+    print(cast([] u8) hello_str, 5);
 
     for i: 0, 10, 2 print(i);
 
@@ -61,7 +61,7 @@ abs_i32 :: proc (n: i32) -> i32 {
 // Don't need to bind this function to a symbol
 proc #export "main" {
     len :: 10;
-    global_arr = alloc(sizeof [10]i32) as []i32;
+    global_arr = cast([] i32) alloc(sizeof [10]i32);
 
     for i: 0, len global_arr[i] = (len - i) * 10;
 
@@ -86,19 +86,19 @@ proc #export "main" {
 
 
 alloc :: proc (size: u32) -> rawptr {
-    heap_u32    :: __heap_start as ^u32;
+    heap_u32    :: cast(^i32) __heap_start;
 
     curr_offset := *heap_u32;
     if curr_offset == 0 curr_offset = 8;
 
     *heap_u32   = curr_offset + size;
 
-    return ((__heap_start as u32) + curr_offset) as rawptr;
+    return cast(rawptr) (cast(u32) __heap_start  + curr_offset);
 }
 
 alloc_2darr :: proc (rows: u32, cols: u32) -> []^i32 {
-    arr := alloc(rows * 4) as []^i32;
-    for i: 0, cols arr[i] = alloc(cols * 4) as ^i32;
+    arr := cast([] ^i32) alloc(rows * 4);
+    for i: 0, cols arr[i] = cast(^i32) alloc(cols * 4);
     return arr;
 }
 
index 5b9de01f56e1e815845da9e3d54ef05e5636d2a2..31dcbc3fe3eab235ed1d0de22e5dabec086af33b 100644 (file)
@@ -62,7 +62,7 @@ main :: proc #export {
     }
 
     cond :: true;
-    print(test(cond) as i32);
+    print(cast(i32) test(cond));
 }
 
 use "progs/intrinsics"
index 061cf1029064a37eae5b0de3c1a2c8b0873f035d..8f80c7e46acf2be0105788c37ebcd8f14058a4e0 100644 (file)
@@ -19,11 +19,11 @@ foo_sum :: proc (use this: ^Foo) -> i32 {
 }
 
 foo_other :: proc (use this: ^Foo) {
-    print(st as i32);
+    print(cast(i32) st);
 }
 
 asdf :: proc (pa: PrintableArray) {
-    for i: 0, pa.len print(pa.data[i] as i32);
+    for i: 0, pa.len print(cast(i32) pa.data[i]);
 }
 
 SomeType :: enum {
@@ -34,7 +34,7 @@ SomeType :: enum {
 }
 
 print_st :: proc (st: SomeType, other: i32) {
-    print(st as i32);
+    print(cast(i32) st);
 }
 
 single_int : u32
@@ -45,7 +45,7 @@ array : [N] Foo
 proc #export "main" {
     print("Hello World! this is slightly longer\n");
 
-    print(__heap_start as i32);
+    print(cast(i32) __heap_start);
 
     single_int = 10;
     print(single_int);
@@ -56,7 +56,7 @@ proc #export "main" {
     st: SomeType = SomeType.Value4;
     print_st(st, 10);
 
-    foo := __heap_start as ^Foo;
+    foo := cast(^Foo) __heap_start;
     foo.x = 123;
     foo.y = 321;
     foo.st = st;
@@ -65,8 +65,8 @@ proc #export "main" {
     print(foo_sum(foo));
     print_st(foo.st, 20);
 
-    pa := (__heap_start as i32 + sizeof Foo) as ^PrintableArray;
-    pa.data = __heap_start as ^u8;
+    pa := cast(^PrintableArray) (cast(i32) __heap_start + sizeof Foo);
+    pa.data = cast(^u8) __heap_start;
     pa.len = 5;
     asdf(*pa);
 
index 3fceb30ecc789911a68f7205c7994c0df5e0af72..b16687add944a1d52b5d892c2d3bdcc2d22c992c 100644 (file)
@@ -43,12 +43,12 @@ array_map :: proc (arr: I32Array, map: proc (i32) -> i32) {
 }
 
 minus_one :: proc (n: i32) -> i32 { return n - 1; }
-double :: proc (n: i32) -> i32 { return n << 1; }
+double    :: proc (n: i32) -> i32 { return n << 1; }
 
 proc #export "main" {
     call_me(echo, 10);
 
-    print(add as my_int);
+    print(cast(my_int) add);
 
     funcs[0] = add;
     funcs[1] = sub;
@@ -58,7 +58,7 @@ proc #export "main" {
 
     for i: 0, 5 print(funcs[i](10, 3));
 
-    dc := __heap_start as ^DeferredCall;
+    dc := cast(^DeferredCall) __heap_start;
     dc.func = add;
     dc.left = 40;
     dc.right = 19;
@@ -66,14 +66,14 @@ proc #export "main" {
     print(execute(dc));
 
     len :: 10;
-    data := (__heap_start as i32 + sizeof DeferredCall) as ^i32;
+    data := cast(^i32) (cast(i32) __heap_start + sizeof DeferredCall);
     for i: 0, len data[i] = i;
-    print(data as [] i32, len);
+    print(cast([] i32) data, len);
 
     add_one :: proc (n: i32) -> i32 { return n + 1; };
 
     array_map(len, data, add_one);
-    print(data as [] i32, len);
+    print(cast([] i32) data, len);
 
     cheese := Cheeses.Cheddar;
 
@@ -98,11 +98,10 @@ proc #export "main" {
             break;
         }
     }
-
 }
 
 Cheeses :: enum {
     Cheddar;
     Muenster;
     Mozerella;
-}
\ No newline at end of file
+}
index 3f48aab3d9c7008511d4405e5964d42f7d57db81..15f17cbbeae6b03279dbe788259985d91972244f 100644 (file)
@@ -30,14 +30,14 @@ print_f64arr :: proc (arr: [] f64, len: i32) {
 // NOTE: print null-terminated string
 print_str :: proc (str: ^u8) {
     c := str;
-    while *c != 0 as u8 {
-        print((*c) as i32);
-        c = (c as i32 + 1) as ^u8;
+    while *c != cast(u8) 0 {
+        print(cast(i32) (*c));
+        c = cast(^u8) (cast(i32) c + 1);
     }
 }
 
 print_str_len :: proc (str: [] u8, len: i32) {
-    for i: 0, len print(str[i] as i32);
+    for i: 0, len print(cast(i32) str[i]);
 }
 
 print :: proc #overloaded {
index b05fa267ca26dbd572f0a8db6cb2894687c79b7b..e1c16c798b488a161ea90d10ff0b7942be62b695 100644 (file)
@@ -15,18 +15,18 @@ Foo :: struct {
 }
 
 alloc :: proc (size: u32) -> rawptr {
-    heap_u32    :: __heap_start as ^u32;
+    heap_u32    :: cast(^u32) __heap_start;
 
     curr_offset := *heap_u32;
     if curr_offset == 0 curr_offset = 8;
 
     *heap_u32   = curr_offset + size;
 
-    return ((__heap_start as u32) + curr_offset) as rawptr;
+    return cast(rawptr) (cast(u32) __heap_start + curr_offset);
 }
 
 foo_make :: proc -> ^Foo {
-    return alloc(sizeof Foo) as ^Foo; 
+    return cast(^Foo) alloc(sizeof Foo);
 }
 
 foo_get :: proc (fooarr: []Foo, i: i32) -> ^Foo {
@@ -54,7 +54,7 @@ Link :: struct {
 }
 
 link_create :: proc (data: i32, parent: ^^Link) {
-    link := alloc(sizeof Link) as ^Link;
+    link := cast(^Link) alloc(sizeof Link);
     link.data = data;
     link.next = *parent;
     *parent = link;
@@ -64,7 +64,7 @@ link_print :: proc (start: ^Link) -> i32 {
     count := 0;
 
     walker := start;
-    while (walker as i32) != 0 {
+    while cast(i32) walker != 0 {
         print(walker.data);
         walker = walker.next;
         count += 1;
@@ -74,8 +74,8 @@ link_print :: proc (start: ^Link) -> i32 {
 }
 
 link_test :: proc #export "main4" {
-    node_head := alloc(sizeof ^Link) as ^^Link;
-    *node_head = 0 as ^Link;
+    node_head := cast(^^Link) alloc(sizeof ^Link);
+    *node_head = cast(^Link) 0;
 
     link_create(0, node_head);
     link_create(1, node_head);
@@ -90,8 +90,8 @@ link_test :: proc #export "main4" {
 
 // TODO: Make everything below this comment work
 multi_arr :: proc #export "main2" {
-    arr1 := alloc(sizeof [5][5] i32) as [5][5] i32; // Sizeof 25 * 4
-    arr2 := alloc(sizeof [5]^ i32) as [5]^ i32; // Sizeof 20
+    arr1 := cast([5][5] i32) alloc(sizeof [5][5] i32); // Sizeof 25 * 4
+    arr2 := cast([5] ^i32) alloc(sizeof [5]^ i32); // Sizeof 20
 
     arr2[3][2] = 5; // (arr1 + (3 * 5 * 4) + (2 * 4))
     print(arr2[3][2]);
@@ -110,11 +110,11 @@ Vec3 :: struct {
 }
 
 v2magnitude :: proc (v: ^Vec2) -> f32 {
-    return sqrt_f32((v.x * v.x + v.y * v.y) as f32);
+    return sqrt_f32(cast(f32) (v.x * v.x + v.y * v.y));
 }
 
 v3magnitude :: proc (v: ^Vec3) -> f32 {
-    return sqrt_f32((v.x * v.x + v.y * v.y + v.z * v.z) as f32);
+    return sqrt_f32(cast(f32) (v.x * v.x + v.y * v.y + v.z * v.z));
 }
 
 magnitude :: proc #overloaded { v2magnitude, v3magnitude };
@@ -138,12 +138,12 @@ print_bar :: proc (bar: Bar) {
 }
 
 proc #export "main" {
-    v2 := alloc(sizeof Vec2) as ^Vec2;
+    v2 := cast(^Vec2) alloc(sizeof Vec2);
     v2.x = 5;
     v2.y = 12;
     print(v2.magnitude());
 
-    v3 := alloc(sizeof Vec3) as ^Vec3;
+    v3 := cast(^Vec3) alloc(sizeof Vec3);
     v3.x = 1;
     v3.y = 1;
     v3.z = 1;
@@ -153,10 +153,10 @@ proc #export "main" {
 
     print((1).minus(2));
 
-    foo := alloc(sizeof Fool) as ^Fool;
-    foo.bar = alloc(sizeof Bar) as ^Bar;
+    foo := cast(^Fool) alloc(sizeof Fool);
+    foo.bar = cast(^Bar) alloc(sizeof Bar);
     foo.bar.i = 50;
-    foo.bar.j = 70 as i64;
+    foo.bar.j = cast(i64) 70;
 
     (*foo.bar).print_bar();
 }
@@ -185,10 +185,10 @@ soa_test :: proc #export "main9" {
 
     // print(sizeof SOA);  // 240
 
-    soa := alloc(sizeof SOA + 20 * sizeof Vec2) as ^SOA;
+    soa := cast(^SOA) alloc(sizeof SOA + 20 * sizeof Vec2);
 
     for i: 0, 10 {
-        soa.things[i] = alloc(sizeof Vec2) as ^Vec2;
+        soa.things[i] = cast(^Vec2) alloc(sizeof Vec2);
     }
 
     soa.velocities[2].x = 10;
@@ -208,7 +208,7 @@ soa_test :: proc #export "main9" {
     print(soa.positions[6].x);
     print(soa.positions[6].y);
 
-    m_arr := alloc(sizeof [5][5]i32) as [5][5]i32;
+    m_arr := cast([5][5] i32) alloc(sizeof [5][5]i32);
 
     for y: 0, 5 {
         for x: 0, 5 {
@@ -216,5 +216,5 @@ soa_test :: proc #export "main9" {
         }
     }
 
-    for i: 0, 25 print((m_arr as [] i32)[i]);
+    for i: 0, 25 print((cast([] i32) m_arr)[i]);
 }
\ No newline at end of file
index fb88f6ac43767bd19473fb0dd2cdbf1b72111d56..7d352acb20e97e3e95253570f8263290d8612d5d 100644 (file)
@@ -1,17 +1,20 @@
+// EVERYTHING IN THIS FILE IS VERY BROKEN SINCE UFC HAS BEEN
+// DISABLED.
+
 use "progs/intrinsics"
 use "progs/print_funcs"
 
 use package printing as printing
 
 alloc :: proc (size: u32) -> rawptr {
-    heap_u32    :: __heap_start as ^u32;
+    heap_u32    :: cast(^u32) __heap_start;
 
     curr_offset := *heap_u32;
     if curr_offset == 0 curr_offset = 8;
 
     *heap_u32   = curr_offset + size;
 
-    return ((__heap_start as u32) + curr_offset) as rawptr;
+    return cast(rawptr) (cast(u32) __heap_start + curr_offset);
 }
 
 
@@ -42,7 +45,7 @@ Vec2 :: struct {
 }
 
 vec2_magnitude :: proc (use v: ^Vec2) -> i32 {
-       return sqrt_f32(x * x + y * y) as i32;
+       return cast(i32) sqrt_f32(x * x + y * y);
 }
 
 Vec3 :: struct {
@@ -69,7 +72,7 @@ dot :: proc (v: Vec2, u: Vec2) -> f32 {
 
 
 proc #export "main" {
-       vec := alloc(sizeof Vec2) as ^Vec2;
+       vec := cast(^Vec2) alloc(sizeof Vec2);
        vec.x = 5.0f;
        vec.y = 12.0f;
 
@@ -84,7 +87,7 @@ proc #export "main" {
        printing.print(dot(2.0f, 4.0f, -6.0f, 3.0f));
 
 
-       v3 := alloc(sizeof Vec3) as ^Vec3;
+       v3 := cast(^Vec3) alloc(sizeof Vec3);
        v3.x = 5.0f;
        v3.y = 12.0f;
        v3.z = 13.0f;
index 6c12f62bfac79fd31aa82f48460ef5fc7b5d203f..58debdeb8322b7f4be3e5bd0d43f95dca983b59e 100644 (file)
@@ -404,49 +404,3 @@ int main(int argc, char *argv[]) {
 
     return compiler_progress != ONYX_COMPILER_PROGRESS_SUCCESS;
 }
-
-// NOTE: Old bits of code that may be useful again at some point.
-#if 0
-    bh_printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr));
-
-    bh_arr_each(OnyxToken, it, token_arr) {
-        onyx_token_null_toggle(*it);
-        bh_printf("%s (%s:%l:%l)\n", onyx_get_token_type_name(it->type), it->pos.filename, it->pos.line, it->pos.column);
-        onyx_token_null_toggle(*it);
-    }
-#endif
-
-#if 0
-    // NOTE: Ensure type table made correctly
-
-    bh_printf("Type map:\n");
-    bh_hash_each_start(i32, wasm_mod.type_map);
-        bh_printf("%s -> %d\n", key, value);
-    bh_hash_each_end;
-
-    bh_printf("Type list:\n");
-    WasmFuncType** func_type = wasm_mod.functypes;
-    while (!bh_arr_end(wasm_mod.functypes, func_type)) {
-        for (int p = 0; p < (*func_type)->param_count; p++) {
-            bh_printf("%c ", (*func_type)->param_types[p]);
-        }
-        bh_printf("-> ");
-        bh_printf("%c\n", (*func_type)->return_type);
-
-        func_type++;
-    }
-#endif
-
-#if 0
-    // NOTE: Ensure the export table was built correctly
-
-    bh_printf("Function types:\n");
-    bh_arr_each(WasmFunc, func_it, wasm_mod.funcs) {
-        bh_printf("%d\n", func_it->type_idx);
-    }
-
-    bh_printf("Exports:\n");
-    bh_hash_each_start(WasmExport, wasm_mod.exports);
-        bh_printf("%s: %d %d\n", key, value.kind, value.idx);
-    bh_hash_each_end;
-#endif
index 4f2281234fdcbf094a08d6f4cf12094372679892..0bf8eadedf0edf83c88eaa974f06176cc8b1525d 100644 (file)
@@ -403,8 +403,9 @@ CHECK(binaryop, AstBinaryOp* binop, b32 assignment_is_ok) {
         }
 
     } else {
-        if (type_is_pointer(binop->left->type)
-                || type_is_pointer(binop->right->type)) {
+        if (!binop_is_compare(binop) &&
+                (type_is_pointer(binop->left->type)
+                || type_is_pointer(binop->right->type))) {
             onyx_message_add(Msg_Type_Literal,
                     binop->token->pos,
                     "binary operations are not supported for pointers (yet).");
index 8012a6ff028951a4ae44a0c387b20b6e7bb25de5..b2570d12398357cdb8e7707112e781f5a51322ff 100644 (file)
@@ -19,6 +19,7 @@ static const char* token_type_names[] = {
     "global",
     "proc",
     "as",
+    "cast",
     "while",
     "for",
     "break",
@@ -153,7 +154,8 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
     LITERAL_TOKEN("global",     1, Token_Type_Keyword_Global);
     LITERAL_TOKEN("return",     1, Token_Type_Keyword_Return);
     LITERAL_TOKEN("proc",       1, Token_Type_Keyword_Proc);
-    LITERAL_TOKEN("as",         1, Token_Type_Keyword_Cast);
+    LITERAL_TOKEN("as",         1, Token_Type_Keyword_As);
+    LITERAL_TOKEN("cast",       1, Token_Type_Keyword_Cast);
     LITERAL_TOKEN("while",      1, Token_Type_Keyword_While);
     LITERAL_TOKEN("for",        1, Token_Type_Keyword_For);
     LITERAL_TOKEN("break",      1, Token_Type_Keyword_Break);
index fe58c454b588f151831b74ab38b5f31a3be722ae..c439108a8e6d0a3c0d8f79d0fad49f798f8533c5 100644 (file)
@@ -188,6 +188,19 @@ static AstTyped* parse_factor(OnyxParser* parser) {
             break;
         }
 
+        case Token_Type_Keyword_Cast: {
+            AstUnaryOp* cast_node = make_node(AstUnaryOp, Ast_Kind_Unary_Op);
+            cast_node->token = expect_token(parser, Token_Type_Keyword_Cast);
+            expect_token(parser, '(');
+            cast_node->type_node = parse_type(parser);
+            expect_token(parser, ')');
+            cast_node->operation = Unary_Op_Cast;
+            cast_node->expr = parse_factor(parser);
+
+            retval = (AstTyped *) cast_node;
+            break;
+        }
+
         case Token_Type_Keyword_Sizeof: {
             AstSizeOf* so_node = make_node(AstSizeOf, Ast_Kind_Size_Of);
             so_node->token = expect_token(parser, Token_Type_Keyword_Sizeof);
@@ -272,8 +285,7 @@ static AstTyped* parse_factor(OnyxParser* parser) {
             return NULL;
     }
 
-    while (parser->curr->type == '[' || parser->curr->type == Token_Type_Keyword_Cast
-        || parser->curr->type == '.' || parser->curr->type == '(') {
+    while (parser->curr->type == '[' || parser->curr->type == '.' || parser->curr->type == '(') {
 
         switch ((u16) parser->curr->type) {
             case '[': {
@@ -298,17 +310,6 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                 break;
             }
 
-            case Token_Type_Keyword_Cast: {
-                AstUnaryOp* cast_node = make_node(AstUnaryOp, Ast_Kind_Unary_Op);
-                cast_node->token = expect_token(parser, Token_Type_Keyword_Cast);
-                cast_node->type_node = parse_type(parser);
-                cast_node->operation = Unary_Op_Cast;
-                cast_node->expr = retval;
-
-                retval = (AstTyped *) cast_node;
-                break;
-            }
-
             case '(': {
                 AstCall* call_node = make_node(AstCall, Ast_Kind_Call);
                 call_node->token = expect_token(parser, '(');
@@ -1234,8 +1235,7 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) {
                 pack_symbol->token = expect_token(parser, Token_Type_Symbol);
                 upack->package = (AstPackage *) pack_symbol;
 
-                // followed by 'as'
-                if (parser->curr->type == Token_Type_Keyword_Cast) {
+                if (parser->curr->type == Token_Type_Keyword_As) {
                     consume_token(parser);
                     upack->alias = expect_token(parser, Token_Type_Symbol);
                 }
@@ -1249,7 +1249,7 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) {
                         AstAlias* alias = make_node(AstAlias, Ast_Kind_Alias);
                         alias->token = expect_token(parser, Token_Type_Symbol);
 
-                        if (parser->curr->type == Token_Type_Keyword_Cast) {
+                        if (parser->curr->type == Token_Type_Keyword_As) {
                             consume_token(parser);
                             alias->alias = expect_token(parser, Token_Type_Symbol);
                         } else {
index 1c94e1be9b25162b3d1839b6afcb9ec914d1fdf9..467b91aba352db88cc49d9e07d0a925f813cc506 100644 (file)
@@ -39,6 +39,10 @@ b32 types_are_surface_compatible(Type* t1, Type* t2) {
                 if ((t1->Basic.flags & Basic_Flag_Integer) && (t2->Basic.flags & Basic_Flag_Integer)) {
                     return t1->Basic.size == t2->Basic.size;
                 }
+
+                if (t1->Basic.kind == Basic_Kind_Rawptr && type_is_pointer(t2)) {
+                    return 1;
+                }
             }
             break;
 
@@ -105,12 +109,20 @@ b32 types_are_compatible(Type* t1, Type* t2) {
                     return t1->Basic.size == t2->Basic.size;
                 }
             }
+
+            if (t1->Basic.kind == Basic_Kind_Rawptr && type_is_pointer(t2)) {
+                return 1;
+            }
             break;
 
         case Type_Kind_Pointer: {
             if (t2->kind == Type_Kind_Pointer) {
                 return types_are_compatible(t1->Pointer.elem, t2->Pointer.elem);
             }
+
+            if (t2->kind == Type_Kind_Basic && t2->Basic.kind == Basic_Kind_Rawptr)
+                return 1;
+
             break;
         }