added char literals and fixed cast bugs
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 10 Aug 2020 13:54:03 +0000 (08:54 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 10 Aug 2020 13:54:03 +0000 (08:54 -0500)
docs/plan
onyx
progs/print_funcs.onyx
progs/stack_based.onyx
src/onyxparser.c
src/onyxwasm.c

index 7c5ac2ca1a231f9c0329b21fa9222fd060293692..ca7bcea67018d4e90699bd840782d49f9d4b0a81 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -148,13 +148,13 @@ HOW:
 
         [X] Be smart about when to use the stack versus use the wasm locals
 
-        [ ] Better numeric literals
+        [X] Better numeric literals
             - suffix 'f' for float32
             - no suffix 'f', but has decimal for float64
             - suffix 'l' for int64
             - nothing special for i32 or below
 
-        [ ] Char literals
+        [X] Char literals
 
         [ ] Properly checking binary operators
             - Shouldn't be able to add two structs/arrays together
diff --git a/onyx b/onyx
index 85f516464e0eeaa952f31e064c2f09299c68e940..5c7d161715bb4e7c70c41744143e35291c75aa90 100755 (executable)
Binary files a/onyx and b/onyx differ
index 575e0f5b403e50dc8fc7eca8217763ba218b6c23..8abf5672ac070c697e7f81d3292f6f99ad20adaa 100644 (file)
@@ -48,33 +48,33 @@ print_u64_with_base :: proc (n_: u64, base: u64) {
     for i: 0, 128 do str[i] = cast(u8) 0;
 
     c := cast(^u8) ^str[127];
-    *c = cast(u8) 0;
+    *c = #char "\0";
     c -= 1;
 
     if n == 0l {
-        *c = cast(u8) 0x30;
+        *c = #char "0";
         c -= 1;
     } else {
         while n > 0l {
             m :: n % base;
 
             ch := cast(u8) 0;
-            if m == 0l do ch = cast(u8) 0x30;
-            if m == 1l do ch = cast(u8) 0x31;
-            if m == 2l do ch = cast(u8) 0x32;
-            if m == 3l do ch = cast(u8) 0x33;
-            if m == 4l do ch = cast(u8) 0x34;
-            if m == 5l do ch = cast(u8) 0x35;
-            if m == 6l do ch = cast(u8) 0x36;
-            if m == 7l do ch = cast(u8) 0x37;
-            if m == 8l do ch = cast(u8) 0x38;
-            if m == 9l do ch = cast(u8) 0x39;
-            if m == 10l do ch = cast(u8) 0x41;
-            if m == 11l do ch = cast(u8) 0x42;
-            if m == 12l do ch = cast(u8) 0x43;
-            if m == 13l do ch = cast(u8) 0x44;
-            if m == 14l do ch = cast(u8) 0x45;
-            if m == 15l do ch = cast(u8) 0x46;
+            if m == 0l do  ch = #char "0";
+            if m == 1l do  ch = #char "1";
+            if m == 2l do  ch = #char "2";
+            if m == 3l do  ch = #char "3";
+            if m == 4l do  ch = #char "4";
+            if m == 5l do  ch = #char "5";
+            if m == 6l do  ch = #char "6";
+            if m == 7l do  ch = #char "7";
+            if m == 8l do  ch = #char "8";
+            if m == 9l do  ch = #char "9";
+            if m == 10l do ch = #char "A";
+            if m == 11l do ch = #char "B";
+            if m == 12l do ch = #char "C";
+            if m == 13l do ch = #char "D";
+            if m == 14l do ch = #char "E";
+            if m == 15l do ch = #char "F";
 
             *c = ch;
             c -= 1;
@@ -84,16 +84,16 @@ print_u64_with_base :: proc (n_: u64, base: u64) {
     }
 
     if base == 16l {
-        *c = cast(u8) 0x78;
+        *c = #char "x";
         c -= 1;
-        *c = cast(u8) 0x30;
+        *c = #char "0";
         c -= 1;
     }
 
     if base == 2l {
-        *c = cast(u8) 0x62;
+        *c = #char "b";
         c -= 1;
-        *c = cast(u8) 0x30;
+        *c = #char "0";
         c -= 1;
     }
 
index 364ce91067f2f5581af323a63c6107c11dfac313..75a8dd43b02457dfbfec5b5a9a11fa27af8edbc8 100644 (file)
@@ -53,6 +53,8 @@ start :: proc #export {
     print_bin(42l);
     print_hex(42l);
 
+    print_hex(cast(u64) #char "a");
+
     a := 12345;
 
     arr: [N][N] i32;
index 67749e1d6283b87814b3b6234caa6cc9ce85f84a..8849e451510b84265f1c139012ea054917d54316 100644 (file)
@@ -319,6 +319,38 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                 retval = (AstTyped *) fc;
                 break;
             }
+            else if (parse_possible_directive(parser, "char")) {
+                AstNumLit* char_lit = make_node(AstNumLit, Ast_Kind_NumLit);
+                char_lit->flags |= Ast_Flag_Comptime;
+                char_lit->type_node = (AstType *) &basic_type_u8;
+
+                char_lit->token = expect_token(parser, Token_Type_Literal_String);
+
+                if (char_lit->token->text[0] != '\\') {
+                    char_lit->value.i = char_lit->token->text[0];
+                } else {
+                    switch (char_lit->token->text[1]) {
+                        case '0': char_lit->value.i = '\0'; break;
+                        case 'a': char_lit->value.i = '\a'; break;
+                        case 'b': char_lit->value.i = '\b'; break;
+                        case 'f': char_lit->value.i = '\f'; break;
+                        case 'n': char_lit->value.i = '\n'; break;
+                        case 't': char_lit->value.i = '\t'; break;
+                        case 'r': char_lit->value.i = '\r'; break;
+                        case 'v': char_lit->value.i = '\v'; break;
+                        case 'e': char_lit->value.i = '\e'; break;
+                        default: {
+                            onyx_message_add(Msg_Type_Literal,
+                                    char_lit->token->pos,
+                                    "invalid escaped character");
+                            break;
+                        }
+                    }
+                }
+
+                retval = (AstTyped *) char_lit;
+                break;
+            }
 
             onyx_message_add(Msg_Type_Literal,
                     parser->curr->pos,
index 7033abef074946bab2102bcc120893b309c7da7f..75fc778b9e629a90e2c5a18c571b806fa81ff7ee 100644 (file)
@@ -1174,17 +1174,19 @@ COMPILE_FUNC(expression, AstTyped* expr) {
     *pcode = code;
 }
 
-static const WasmInstructionType cast_map[][9] = {
-    //          I8              I16                 I32                 U32                I64                U64                F32                F64                PTR
-    /* I8  */ { WI_NOP,         WI_I32_EXTEND_8_S,  WI_I32_EXTEND_8_S,  WI_NOP,            WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_UNREACHABLE },
-    /* I16 */ { WI_NOP,         WI_NOP,             WI_I32_EXTEND_16_S, WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U, WI_UNREACHABLE },
-    /* I32 */ { WI_NOP,         WI_NOP,             WI_NOP,             WI_NOP,            WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S, WI_NOP },
-    /* U32 */ { WI_NOP,         WI_NOP,             WI_NOP,             WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U, WI_NOP },
-    /* I64 */ { WI_NOP,         WI_NOP,             WI_I32_FROM_I64,    WI_I32_FROM_I64,   WI_NOP,            WI_NOP,            WI_F32_FROM_I64_S, WI_F64_FROM_I64_S, WI_I32_FROM_I64 },
-    /* U64 */ { WI_NOP,         WI_NOP,             WI_I32_FROM_I64,    WI_I32_FROM_I64,   WI_NOP,            WI_NOP,            WI_F32_FROM_I64_U, WI_F64_FROM_I64_U, WI_I32_FROM_I64 },
-    /* F32 */ { WI_UNREACHABLE, WI_UNREACHABLE,     WI_I32_FROM_F32_S,  WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP,            WI_F64_FROM_F32,   WI_UNREACHABLE },
-    /* F64 */ { WI_UNREACHABLE, WI_UNREACHABLE,     WI_I32_FROM_F64_S,  WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64,   WI_NOP,            WI_UNREACHABLE },
-    /* PTR */ { WI_UNREACHABLE, WI_UNREACHABLE,     WI_NOP,             WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_NOP },
+static const WasmInstructionType cast_map[][11] = {
+    //          I8              U8                  I16                 U16                I32                 U32                I64                U64                F32                F64                PTR
+    /* I8  */ { WI_NOP,         WI_NOP,             WI_I32_EXTEND_8_S,  WI_NOP,            WI_I32_EXTEND_8_S,  WI_NOP,            WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_UNREACHABLE },
+    /* U8  */ { WI_NOP,         WI_NOP,             WI_NOP,             WI_NOP,            WI_NOP,             WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_UNREACHABLE },
+    /* I16 */ { WI_NOP,         WI_NOP,             WI_NOP,             WI_NOP,            WI_I32_EXTEND_16_S, WI_NOP,            WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_UNREACHABLE },
+    /* U16 */ { WI_NOP,         WI_NOP,             WI_NOP,             WI_NOP,            WI_NOP,             WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_UNREACHABLE },
+    /* I32 */ { WI_NOP,         WI_NOP,             WI_NOP,             WI_NOP,            WI_NOP,             WI_NOP,            WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S, WI_NOP },
+    /* U32 */ { WI_NOP,         WI_NOP,             WI_NOP,             WI_NOP,            WI_NOP,             WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U, WI_NOP },
+    /* I64 */ { WI_NOP,         WI_I32_FROM_I64,    WI_I32_FROM_I64,    WI_I32_FROM_I64,   WI_I32_FROM_I64,    WI_I32_FROM_I64,   WI_NOP,            WI_NOP,            WI_F32_FROM_I64_S, WI_F64_FROM_I64_S, WI_I32_FROM_I64 },
+    /* U64 */ { WI_NOP,         WI_I32_FROM_I64,    WI_I32_FROM_I64,    WI_I32_FROM_I64,   WI_I32_FROM_I64,    WI_I32_FROM_I64,   WI_NOP,            WI_NOP,            WI_F32_FROM_I64_U, WI_F64_FROM_I64_U, WI_I32_FROM_I64 },
+    /* F32 */ { WI_UNREACHABLE, WI_UNREACHABLE,     WI_UNREACHABLE,     WI_UNREACHABLE,    WI_I32_FROM_F32_S,  WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP,            WI_F64_FROM_F32,   WI_UNREACHABLE },
+    /* F64 */ { WI_UNREACHABLE, WI_UNREACHABLE,     WI_UNREACHABLE,     WI_UNREACHABLE,    WI_I32_FROM_F64_S,  WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64,   WI_NOP,            WI_UNREACHABLE },
+    /* PTR */ { WI_UNREACHABLE, WI_UNREACHABLE,     WI_UNREACHABLE,     WI_UNREACHABLE,    WI_NOP,             WI_NOP,            WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE,    WI_UNREACHABLE,    WI_NOP },
 };
 
 COMPILE_FUNC(cast, AstUnaryOp* cast) {
@@ -1229,49 +1231,36 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) {
     }
 
     i32 fromidx = -1, toidx = -1;
-    if (from->Basic.flags & Basic_Flag_Pointer) {
-        fromidx = 8;
+    if (from->Basic.flags & Basic_Flag_Pointer || from->kind == Type_Kind_Array) {
+        fromidx = 10;
     }
     else if (from->Basic.flags & Basic_Flag_Integer) {
         b32 unsign = (from->Basic.flags & Basic_Flag_Unsigned) != 0;
 
-        if      (from->Basic.size == 1 && !unsign) fromidx = 0;
-        else if (from->Basic.size == 1 && unsign)  fromidx = -1;
-        else if (from->Basic.size == 2 && !unsign) fromidx = 1;
-        else if (from->Basic.size == 2 && unsign)  fromidx = -1;
-        else if (from->Basic.size == 4 && !unsign) fromidx = 2;
-        else if (from->Basic.size == 4 && unsign)  fromidx = 3;
-        else if (from->Basic.size == 8 && !unsign) fromidx = 4;
-        else if (from->Basic.size == 8 && unsign)  fromidx = 5;
+        fromidx = log2_dumb(from->Basic.size) * 2 + unsign;
     }
     else if (from->Basic.flags & Basic_Flag_Float) {
-        if      (from->Basic.size == 4) fromidx = 6;
-        else if (from->Basic.size == 8) fromidx = 7;
+        if      (from->Basic.size == 4) fromidx = 8;
+        else if (from->Basic.size == 8) fromidx = 9;
     }
 
-    if (to->Basic.flags & Basic_Flag_Pointer) {
-        toidx = 8;
+    if (to->Basic.flags & Basic_Flag_Pointer || to->kind == Type_Kind_Array) {
+        toidx = 10;
     }
     else if (to->Basic.flags & Basic_Flag_Integer) {
         b32 unsign = (to->Basic.flags & Basic_Flag_Unsigned) != 0;
 
-        if      (to->Basic.size == 1 && !unsign) toidx = 0;
-        else if (to->Basic.size == 1 && unsign)  toidx = -1;
-        else if (to->Basic.size == 2 && !unsign) toidx = 1;
-        else if (to->Basic.size == 2 && unsign)  toidx = -1;
-        else if (to->Basic.size == 4 && !unsign) toidx = 2;
-        else if (to->Basic.size == 4 && unsign)  toidx = 3;
-        else if (to->Basic.size == 8 && !unsign) toidx = 4;
-        else if (to->Basic.size == 8 && unsign)  toidx = 5;
+        toidx = log2_dumb(to->Basic.size) * 2 + unsign;
     }
     else if (to->Basic.flags & Basic_Flag_Float) {
-        if      (to->Basic.size == 4) toidx = 6;
-        else if (to->Basic.size == 8) toidx = 7;
+        if      (to->Basic.size == 4) toidx = 8;
+        else if (to->Basic.size == 8) toidx = 9;
     }
 
     if (fromidx != -1 && toidx != -1) {
         WasmInstructionType cast_op = cast_map[fromidx][toidx];
         if (cast_op == WI_UNREACHABLE) {
+            bh_printf("%d %d\n", fromidx, toidx);
             onyx_message_add(Msg_Type_Literal,
                     cast->token->pos,
                     "bad cast");