From: Brendan Hansen Date: Mon, 10 Aug 2020 13:54:03 +0000 (-0500) Subject: added char literals and fixed cast bugs X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=1916e9035e71756f2310aca61c0a11e8466dca3f;p=onyx.git added char literals and fixed cast bugs --- diff --git a/docs/plan b/docs/plan index 7c5ac2ca..ca7bcea6 100644 --- 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 85f51646..5c7d1617 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/print_funcs.onyx b/progs/print_funcs.onyx index 575e0f5b..8abf5672 100644 --- a/progs/print_funcs.onyx +++ b/progs/print_funcs.onyx @@ -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; } diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx index 364ce910..75a8dd43 100644 --- a/progs/stack_based.onyx +++ b/progs/stack_based.onyx @@ -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; diff --git a/src/onyxparser.c b/src/onyxparser.c index 67749e1d..8849e451 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -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, diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 7033abef..75fc778b 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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");