diff --git a/code/demo.odin b/code/demo.odin index ba157a977..af7f453c5 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -14,5 +14,9 @@ #import "utf16.odin"; main :: proc() { - + if x := 0; x < 0 { + fmt.println(x); + } else { + fmt.println(x); + } } diff --git a/core/os_windows.odin b/core/os_windows.odin index ecb093ab4..ab8a26920 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -194,9 +194,6 @@ last_write_time_by_name :: proc(name: string) -> File_Time { } - - - read_entire_file :: proc(name: string) -> ([]byte, bool) { buf: [300]byte; copy(buf[..], cast([]byte)name); @@ -208,13 +205,12 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) { defer close(fd); length: i64; - file_size_ok := win32.GetFileSizeEx(cast(win32.Handle)fd, ^length) != 0; - if !file_size_ok { + if ok := win32.GetFileSizeEx(cast(win32.Handle)fd, ^length) != 0; !ok { return nil, false; } data := make([]byte, length); - if ^data[0] == nil { + if data == nil { return nil, false; } diff --git a/core/utf16.odin b/core/utf16.odin new file mode 100644 index 000000000..a01261493 --- /dev/null +++ b/core/utf16.odin @@ -0,0 +1,58 @@ +REPLACEMENT_CHAR :: '\uFFFD'; +MAX_RUNE :: '\U0010FFFF'; + +_surr1 :: 0xd800; +_surr2 :: 0xdc00; +_surr3 :: 0xe000; +_surr_self :: 0x10000; + + +is_surrogate :: proc(r: rune) -> bool { + return _surr1 <= r && r < _surr3; +} + +decode_surrogate_pair :: proc(r1, r2: rune) -> rune { + if _surr1 <= r1 && r1 < _surr2 && _surr2 <= r2 && r2 < _surr3 { + return (r1-_surr1)<<10 | (r2 - _surr2) + _surr_self; + } + return REPLACEMENT_CHAR; +} + + +encode_surrogate_pair :: proc(r: rune) -> (r1, r2: rune) { + if r < _surr_self || r > MAX_RUNE { + return REPLACEMENT_CHAR, REPLACEMENT_CHAR; + } + r -= _surr_self; + return _surr1 + (r>>10)&0x3ff, _surr2 + r&0x3ff; +} + +encode :: proc(d: []u16, s: []rune) { + n := len(s); + for r in s { + if r >= _surr_self { + n++; + } + } + + max_n := min(len(d), n); + n = 0; + + for r in s { + match { + case 0 <= r && r < _surr1, _surr3 <= r && r < _surr_self: + d[n] = cast(u16)r; + n++; + + case _surr_self <= r && r <= MAX_RUNE: + r1, r2 := encode_surrogate_pair(r); + d[n] = cast(u16)r1; + d[n+1] = cast(u16)r2; + n += 2; + + default: + d[n] = cast(u16)REPLACEMENT_CHAR; + n++; + } + } +} diff --git a/src/check_expr.c b/src/check_expr.c index 5370f76b3..cbca5b41b 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -3950,7 +3950,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id id == BuiltinProc_kmag) { if (!is_type_quaternion(x->type)) { gbString s = type_to_string(x->type); - error_node(call, "Argument has type `%s`, expected a complex type", s); + error_node(call, "Argument has type `%s`, expected a quaternion type", s); gb_string_free(s); return false; } @@ -5455,71 +5455,6 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t o->type = t; o->mode = Addressing_OptionalOk; } break; - case Token_down_cast: { - if (o->mode == Addressing_Constant) { - gbString expr_str = expr_to_string(o->expr); - error_node(o->expr, "Cannot `down_cast` a constant expression: `%s`", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - if (is_type_untyped(o->type)) { - gbString expr_str = expr_to_string(o->expr); - error_node(o->expr, "Cannot `down_cast` an untyped expression: `%s`", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - if (!(is_type_pointer(o->type) && is_type_pointer(t))) { - gbString expr_str = expr_to_string(o->expr); - error_node(o->expr, "Can only `down_cast` pointers: `%s`", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - Type *src = type_deref(o->type); - Type *dst = type_deref(t); - Type *bsrc = base_type(src); - Type *bdst = base_type(dst); - - if (!(is_type_struct(bsrc) || is_type_raw_union(bsrc))) { - gbString expr_str = expr_to_string(o->expr); - error_node(o->expr, "Can only `down_cast` pointer from structs or unions: `%s`", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - if (!(is_type_struct(bdst) || is_type_raw_union(bdst))) { - gbString expr_str = expr_to_string(o->expr); - error_node(o->expr, "Can only `down_cast` pointer to structs or unions: `%s`", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - String param_name = check_down_cast_name(dst, src); - if (param_name.len == 0) { - gbString expr_str = expr_to_string(o->expr); - error_node(o->expr, "Illegal `down_cast`: `%s`", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - o->mode = Addressing_Value; - o->type = t; - } break; - default: GB_PANIC("Unknown cast expression"); diff --git a/src/ir.c b/src/ir.c index 13d1af22c..5a2c766b9 100644 --- a/src/ir.c +++ b/src/ir.c @@ -3468,9 +3468,11 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { ir_emit_comment(proc, str_lit("cast - transmute")); return ir_emit_transmute(proc, e, type); + #if 0 case Token_down_cast: ir_emit_comment(proc, str_lit("cast - down_cast")); return ir_emit_down_cast(proc, e, type); + #endif case Token_union_cast: ir_emit_comment(proc, str_lit("cast - union_cast")); @@ -4596,6 +4598,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { ir_emit_store(proc, v, ir_emit_transmute(proc, ir_build_expr(proc, ce->expr), type)); return ir_addr(v); } + #if 0 case Token_down_cast: { ir_emit_comment(proc, str_lit("Cast - down_cast")); // NOTE(bill): Needed for dereference of pointer conversion @@ -4604,6 +4607,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { ir_emit_store(proc, v, ir_emit_down_cast(proc, ir_build_expr(proc, ce->expr), type)); return ir_addr(v); } + #endif case Token_union_cast: { ir_emit_comment(proc, str_lit("Cast - union_cast")); // NOTE(bill): Needed for dereference of pointer conversion diff --git a/src/parser.c b/src/parser.c index a9cae2710..8e56279ab 100644 --- a/src/parser.c +++ b/src/parser.c @@ -2056,7 +2056,6 @@ AstNode *parse_unary_expr(AstFile *f, bool lhs) { case Token_cast: case Token_transmute: - case Token_down_cast: case Token_union_cast: { Token token = f->curr_token; next_token(f); diff --git a/src/tokenizer.c b/src/tokenizer.c index 2ef1a7add..b800a1273 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -108,7 +108,6 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_immutable, "immutable"), \ TOKEN_KIND(Token_cast, "cast"), \ TOKEN_KIND(Token_transmute, "transmute"), \ - TOKEN_KIND(Token_down_cast, "down_cast"), \ TOKEN_KIND(Token_union_cast, "union_cast"), \ TOKEN_KIND(Token_context, "context"), \ TOKEN_KIND(Token_push_context, "push_context"), \