diff --git a/core/encoding/cel/cel.odin b/core/encoding/cel/cel.odin index 754d8cbfa..fe36978c2 100644 --- a/core/encoding/cel/cel.odin +++ b/core/encoding/cel/cel.odin @@ -91,7 +91,7 @@ print :: proc(p: ^Parser, pretty := false) { } create_from_string :: proc(src: string) -> (^Parser, bool) { - return init(cast([]byte)src); + return init(transmute([]byte)src); } @@ -726,8 +726,8 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo case Kind.Add: n := len(a) + len(b); data := make([]byte, n); - copy(data[:], cast([]byte)a); - copy(data[len(a):], cast([]byte)b); + copy(data[:], a); + copy(data[len(a):], b); s := string(data); append(&p.allocated_strings, s); return s, true; diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 60839b21b..f3d894f3f 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -95,17 +95,17 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error { buf: [386]byte; str := strconv.append_float(buf[1:], val, 'f', 2*ti.size, 8*ti.size); - str = string(buf[:len(str)+1]); - if str[1] == '+' || str[1] == '-' { - str = str[1:]; + s := buf[:len(str)+1]; + if s[1] == '+' || s[1] == '-' { + s = s[1:]; } else { - str[0] = '+'; + s[0] = '+'; } - if str[0] == '+' { - str = str[1:]; + if s[0] == '+' { + s = s[1:]; } - write_string(b, str); + write_string(b, string(s)); case Type_Info_Complex: return Marshal_Error.Unsupported_Type; diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin index 63f4a758b..36a68f31c 100644 --- a/core/encoding/json/parser.odin +++ b/core/encoding/json/parser.odin @@ -174,7 +174,7 @@ parse_array :: proc(p: ^Parser) -> (value: Value, err: Error) { clone_string :: proc(s: string, allocator: mem.Allocator) -> string { n := len(s); b := make([]byte, n+1, allocator); - copy(b, cast([]byte)s); + copy(b, s); b[n] = 0; return string(b[:n]); } @@ -349,7 +349,7 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a } b := make([]byte, len(s) + 2*utf8.UTF_MAX, allocator); - w := copy(b, cast([]byte)s[0:i]); + w := copy(b, s[0:i]); loop: for i < len(s) { c := s[i]; switch { diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 467ae0f15..33ca6294c 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -654,32 +654,32 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { buf: [386]byte; str := strconv.append_float(buf[1:], v, 'f', prec, bit_size); - str = string(buf[:len(str)+1]); - if str[1] == '+' || str[1] == '-' { - str = str[1:]; + b := buf[:len(str)+1]; + if b[1] == '+' || b[1] == '-' { + b = b[1:]; } else { - str[0] = '+'; + b[0] = '+'; } - if fi.space && !fi.plus && str[0] == '+' { - str[0] = ' '; + if fi.space && !fi.plus && b[0] == '+' { + b[0] = ' '; } - if len(str) > 1 && (str[1] == 'N' || str[1] == 'I') { - strings.write_string(fi.buf, str); + if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') { + strings.write_string(fi.buf, string(b)); return; } - if fi.plus || str[0] != '+' { - if fi.zero && fi.width_set && fi.width > len(str) { - strings.write_byte(fi.buf, str[0]); - fmt_write_padding(fi, fi.width - len(str)); - strings.write_string(fi.buf, str[1:]); + if fi.plus || b[0] != '+' { + if fi.zero && fi.width_set && fi.width > len(b) { + strings.write_byte(fi.buf, b[0]); + fmt_write_padding(fi, fi.width - len(b)); + strings.write_string(fi.buf, string(b[1:])); } else { - _pad(fi, str); + _pad(fi, string(b)); } } else { - _pad(fi, str[1:]); + _pad(fi, string(b[1:])); } case 'e', 'E': @@ -688,32 +688,32 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { buf: [386]byte; str := strconv.append_float(buf[1:], v, 'e', prec, bit_size); - str = string(buf[:len(str)+1]); - if str[1] == '+' || str[1] == '-' { - str = str[1:]; + b := buf[:len(str)+1]; + if b[1] == '+' || b[1] == '-' { + b = b[1:]; } else { - str[0] = '+'; + b[0] = '+'; } - if fi.space && !fi.plus && str[0] == '+' { - str[0] = ' '; + if fi.space && !fi.plus && b[0] == '+' { + b[0] = ' '; } - if len(str) > 1 && (str[1] == 'N' || str[1] == 'I') { - strings.write_string(fi.buf, str); + if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') { + strings.write_string(fi.buf, string(b)); return; } if fi.plus || str[0] != '+' { - if fi.zero && fi.width_set && fi.width > len(str) { - strings.write_byte(fi.buf, str[0]); - fmt_write_padding(fi, fi.width - len(str)); - strings.write_string(fi.buf, str[1:]); + if fi.zero && fi.width_set && fi.width > len(b) { + strings.write_byte(fi.buf, b[0]); + fmt_write_padding(fi, fi.width - len(b)); + strings.write_string(fi.buf, string(b[1:])); } else { - _pad(fi, str); + _pad(fi, string(b)); } } else { - _pad(fi, str[1:]); + _pad(fi, string(b[1:])); } case 'h', 'H': @@ -1353,7 +1353,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { actual_field_count := len(info.names); n := uintptr(info.soa_len); - + if info.soa_kind == .Slice { actual_field_count = len(info.names)-1; // len diff --git a/core/os/os.odin b/core/os/os.odin index 7b3eac764..2b651c218 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -5,7 +5,7 @@ import "core:strconv" import "core:unicode/utf8" write_string :: proc(fd: Handle, str: string) -> (int, Errno) { - return write(fd, cast([]byte)str); + return write(fd, transmute([]byte)str); } write_byte :: proc(fd: Handle, b: byte) -> (int, Errno) { diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 6944be60d..4ee652e82 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -418,11 +418,24 @@ default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code @builtin -copy :: proc "contextless" (dst, src: $T/[]$E) -> int { +copy_slice :: proc "contextless" (dst, src: $T/[]$E) -> int { n := max(0, min(len(dst), len(src))); if n > 0 do mem_copy(&dst[0], &src[0], n*size_of(E)); return n; } +@builtin +copy_from_string :: proc "contextless" (dst: $T/[]$E/u8, src: $S/string) -> int { + n := max(0, min(len(dst), len(src))); + if n > 0 { + d := &dst[0]; + s := (transmute(Raw_String)src).data; + mem_copy(d, s, n); + } + return n; +} +@builtin +copy :: proc{copy_slice, copy_from_string}; + @@ -559,6 +572,10 @@ append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) a.len += arg_len; } } +@builtin +append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) { + append_elem(array, transmute([]E)arg, loc); +} @builtin reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> bool { @@ -754,7 +771,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l } } -@builtin append :: proc{append_elem, append_elems}; +@builtin append :: proc{append_elem, append_elems, append_elem_string}; @builtin append_soa :: proc{append_soa_elem, append_soa_elems}; @@ -1091,11 +1108,11 @@ _fnv64a :: proc(data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 { default_hash :: proc(data: []byte) -> u64 { return _fnv64a(data); } -default_hash_string :: proc(s: string) -> u64 do return default_hash(([]byte)(s)); +default_hash_string :: proc(s: string) -> u64 do return default_hash(transmute([]byte)(s)); source_code_location_hash :: proc(s: Source_Code_Location) -> u64 { - hash := _fnv64a(cast([]byte)s.file_path); + hash := _fnv64a(transmute([]byte)s.file_path); hash = hash ~ (u64(s.line) * 0x100000001b3); hash = hash ~ (u64(s.column) * 0x100000001b3); return hash; diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 88c591a2c..ec6cec953 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -369,17 +369,27 @@ memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_ return 0; } +@private +Raw_String :: struct { + data: ^byte, + len: int, +}; + string_eq :: proc "contextless" (a, b: string) -> bool { + x := transmute(Raw_String)a; + y := transmute(Raw_String)b; switch { - case len(a) != len(b): return false; - case len(a) == 0: return true; - case &a[0] == &b[0]: return true; + case x.len != y.len: return false; + case x.len == 0: return true; + case x.data == y.data: return true; } return string_cmp(a, b) == 0; } string_cmp :: proc "contextless" (a, b: string) -> int { - return memory_compare(&a[0], &b[0], min(len(a), len(b))); + x := transmute(Raw_String)a; + y := transmute(Raw_String)b; + return memory_compare(x.data, y.data, min(x.len, y.len)); } string_ne :: inline proc "contextless" (a, b: string) -> bool { return !string_eq(a, b); } @@ -398,10 +408,6 @@ cstring_len :: proc "contextless" (s: cstring) -> int { } cstring_to_string :: proc "contextless" (s: cstring) -> string { - Raw_String :: struct { - data: ^byte, - len: int, - }; if s == nil do return ""; ptr := (^byte)(s); n := cstring_len(s); diff --git a/core/sort/sort.odin b/core/sort/sort.odin index 898f3b630..24ca8fafc 100644 --- a/core/sort/sort.odin +++ b/core/sort/sort.odin @@ -282,5 +282,7 @@ compare_f64s :: proc(a, b: f64) -> int { return 0; } compare_strings :: proc(a, b: string) -> int { - return mem.compare_byte_ptrs(&a[0], &b[0], min(len(a), len(b))); + x := transmute(mem.Raw_String)a; + y := transmute(mem.Raw_String)b; + return mem.compare_byte_ptrs(x.data, y.data, min(x.len, y.len)); } diff --git a/core/strconv/generic_float.odin b/core/strconv/generic_float.odin index 24cbf3b15..536b03742 100644 --- a/core/strconv/generic_float.odin +++ b/core/strconv/generic_float.odin @@ -56,7 +56,7 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, precision, bit_size: int) } else { s = "+Inf"; } - n := copy(buf, cast([]byte)s); + n := copy(buf, transmute([]byte)s); return buf[:n]; case 0: // denormalized diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index 447178bc3..a6aa600d5 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -187,8 +187,8 @@ parse_f64 :: proc(s: string) -> f64 { append_bool :: proc(buf: []byte, b: bool) -> string { n := 0; - if b do n = copy(buf, cast([]byte)"true"); - else do n = copy(buf, cast([]byte)"false"); + if b do n = copy(buf, "true"); + else do n = copy(buf, "false"); return string(buf[:n]); } @@ -260,7 +260,7 @@ quote_rune :: proc(buf: []byte, r: rune) -> string { } write_string :: inline proc(buf: []byte, i: ^int, s: string) { if i^ < len(buf) { - n := copy(buf[i^:], cast([]byte)s); + n := copy(buf[i^:], s); i^ += n; } } diff --git a/core/strings/builder.odin b/core/strings/builder.odin index f7dac04ba..21f50d823 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -62,7 +62,7 @@ write_rune :: proc(b: ^Builder, r: rune) -> int { } write_string :: proc(b: ^Builder, s: string) { - write_bytes(b, cast([]byte)s); + write_bytes(b, transmute([]byte)s); } write_bytes :: proc(b: ^Builder, x: []byte) { diff --git a/core/strings/strings.odin b/core/strings/strings.odin index d55ad7e66..96c4aeff8 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -5,14 +5,14 @@ import "core:unicode/utf8" clone :: proc(s: string, allocator := context.allocator) -> string { c := make([]byte, len(s)+1, allocator); - copy(c, cast([]byte)s); + copy(c, s); c[len(s)] = 0; return string(c[:len(s)]); } clone_to_cstring :: proc(s: string, allocator := context.allocator) -> cstring { c := make([]byte, len(s)+1, allocator); - copy(c, cast([]byte)s); + copy(c, s); c[len(s)] = 0; return cstring(&c[0]); } @@ -20,7 +20,7 @@ clone_to_cstring :: proc(s: string, allocator := context.allocator) -> cstring { @(deprecated="Please use 'strings.clone'") new_string :: proc(s: string, allocator := context.allocator) -> string { c := make([]byte, len(s)+1, allocator); - copy(c, cast([]byte)s); + copy(c, s); c[len(s)] = 0; return string(c[:len(s)]); } @@ -28,7 +28,7 @@ new_string :: proc(s: string, allocator := context.allocator) -> string { @(deprecated="Please use 'strings.clone_to_cstring'") new_cstring :: proc(s: string, allocator := context.allocator) -> cstring { c := make([]byte, len(s)+1, allocator); - copy(c, cast([]byte)s); + copy(c, s); c[len(s)] = 0; return cstring(&c[0]); } @@ -43,7 +43,7 @@ string_from_ptr :: proc(ptr: ^byte, len: int) -> string { } compare :: proc(lhs, rhs: string) -> int { - return mem.compare(cast([]byte)lhs, cast([]byte)rhs); + return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs); } contains_rune :: proc(s: string, r: rune) -> int { @@ -130,10 +130,10 @@ join :: proc(a: []string, sep: string, allocator := context.allocator) -> string } b := make([]byte, n, allocator); - i := copy(b, cast([]byte)a[0]); + i := copy(b, a[0]); for s in a[1:] { - i += copy(b[i:], cast([]byte)sep); - i += copy(b[i:], cast([]byte)s); + i += copy(b[i:], sep); + i += copy(b[i:], s); } return string(b); } @@ -150,7 +150,7 @@ concatenate :: proc(a: []string, allocator := context.allocator) -> string { b := make([]byte, n, allocator); i := 0; for s in a { - i += copy(b[i:], cast([]byte)s); + i += copy(b[i:], s); } return string(b); } @@ -416,7 +416,7 @@ repeat :: proc(s: string, count: int, allocator := context.allocator) -> string } b := make([]byte, len(s)*count, allocator); - i := copy(b, cast([]byte)s); + i := copy(b, s); for i < len(b) { // 2^N trick to reduce the need to copy copy(b[i:], b[:i]); i *= 2; @@ -460,11 +460,11 @@ replace :: proc(s, old, new: string, n: int, allocator := context.allocator) -> } else { j += index(s[start:], old); } - w += copy(t[w:], cast([]byte)s[start:j]); - w += copy(t[w:], cast([]byte)new); + w += copy(t[w:], s[start:j]); + w += copy(t[w:], new); start = j + len(old); } - w += copy(t[w:], cast([]byte)s[start:]); + w += copy(t[w:], s[start:]); output = string(t[0:w]); return; } @@ -705,7 +705,7 @@ reverse :: proc(s: string, allocator := context.allocator) -> string { for len(str) > 0 { _, w := utf8.decode_rune_in_string(str); i -= w; - copy(buf[i:], cast([]byte)str[:w]); + copy(buf[i:], str[:w]); str = str[w:]; } return string(buf); diff --git a/core/sys/win32/general.odin b/core/sys/win32/general.odin index 16853c5cd..ee8575913 100644 --- a/core/sys/win32/general.odin +++ b/core/sys/win32/general.odin @@ -752,14 +752,16 @@ utf8_to_utf16 :: proc(s: string, allocator := context.temp_allocator) -> []u16 { return nil; } - n := multi_byte_to_wide_char(CP_UTF8, MB_ERR_INVALID_CHARS, cstring(&s[0]), i32(len(s)), nil, 0); + b := transmute([]byte)s; + cstr := cstring(&b[0]); + n := multi_byte_to_wide_char(CP_UTF8, MB_ERR_INVALID_CHARS, cstr, i32(len(s)), nil, 0); if n == 0 { return nil; } text := make([]u16, n+1, allocator); - n1 := multi_byte_to_wide_char(CP_UTF8, MB_ERR_INVALID_CHARS, cstring(&s[0]), i32(len(s)), Wstring(&text[0]), i32(n)); + n1 := multi_byte_to_wide_char(CP_UTF8, MB_ERR_INVALID_CHARS, cstr, i32(len(s)), Wstring(&text[0]), i32(n)); if n1 == 0 { delete(text, allocator); return nil; diff --git a/core/unicode/utf8/utf8.odin b/core/unicode/utf8/utf8.odin index bbf3994cd..6d0b32f48 100644 --- a/core/unicode/utf8/utf8.odin +++ b/core/unicode/utf8/utf8.odin @@ -90,7 +90,7 @@ encode_rune :: proc(c: rune) -> ([4]u8, int) { return buf, 4; } -decode_rune_in_string :: inline proc(s: string) -> (rune, int) do return decode_rune(cast([]u8)s); +decode_rune_in_string :: inline proc(s: string) -> (rune, int) do return decode_rune(transmute([]u8)s); decode_rune :: proc(s: []u8) -> (rune, int) { n := len(s); if n < 1 { @@ -130,7 +130,7 @@ decode_rune :: proc(s: []u8) -> (rune, int) { -decode_last_rune_in_string :: inline proc(s: string) -> (rune, int) do return decode_last_rune(cast([]u8)s); +decode_last_rune_in_string :: inline proc(s: string) -> (rune, int) do return decode_last_rune(transmute([]u8)s); decode_last_rune :: proc(s: []u8) -> (rune, int) { r: rune; size: int; @@ -260,7 +260,7 @@ valid_string :: proc(s: string) -> bool { rune_start :: inline proc(b: u8) -> bool do return b&0xc0 != 0x80; -rune_count_in_string :: inline proc(s: string) -> int do return rune_count(cast([]u8)s); +rune_count_in_string :: inline proc(s: string) -> int do return rune_count(transmute([]u8)s); rune_count :: proc(s: []u8) -> int { count := 0; n := len(s); diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 8a0d283c2..865c7e565 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -493,8 +493,8 @@ String path_to_fullpath(gbAllocator a, String s) { // Replace Windows style separators for (isize i = 0; i < result.len; i++) { - if (result[i] == '\\') { - result[i] = '/'; + if (result.text[i] == '\\') { + result.text[i] = '/'; } } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index bb95f875e..ca089a745 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1559,7 +1559,7 @@ void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type } else if (are_types_identical(src, dst)) { error_line("\tSuggestion: the expression may be directly casted to type %s\n", b); } else if (are_types_identical(src, t_string) && is_type_u8_slice(dst)) { - error_line("\tSuggestion: a string may be casted to %s\n", a, b); + error_line("\tSuggestion: a string may be transmuted to %s\n", b); } else if (is_type_u8_slice(src) && are_types_identical(dst, t_string)) { error_line("\tSuggestion: the expression may be casted to %s\n", b); } @@ -1600,7 +1600,7 @@ void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { error_line("\tSuggestion: for an integer to be casted to a pointer, it must be converted to 'uintptr' first\n"); } } else if (are_types_identical(src, t_string) && is_type_u8_slice(dst)) { - error_line("\tSuggestion: a string may be casted to %s\n", a, b); + error_line("\tSuggestion: a string may be transmuted to %s\n", b); } else if (is_type_u8_slice(src) && are_types_identical(dst, t_string)) { error_line("\tSuggestion: the expression may be casted to %s\n", b); } @@ -2193,7 +2193,7 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { } if ((is_type_string(src) && !is_type_cstring(src)) && is_type_u8_slice(dst)) { // if (is_type_typed(src)) { - return true; + // return true; // } } // cstring -> string @@ -2726,7 +2726,7 @@ void update_expr_value(CheckerContext *c, Ast *e, ExactValue value) { void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_type) { gbString expr_str = expr_to_string(operand->expr); gbString type_str = type_to_string(target_type); - char *extra_text = ""; + char const *extra_text = ""; if (operand->mode == Addressing_Constant) { if (big_int_is_zero(&operand->value.value_integer)) { @@ -3397,7 +3397,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 BuiltinProc *bp = &builtin_procs[id]; { - char *err = nullptr; + char const *err = nullptr; if (ce->args.count < bp->arg_count) { err = "Too few"; } else if (ce->args.count > bp->arg_count && !bp->variadic) { @@ -5408,7 +5408,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } if (error_code != 0) { err = CallArgumentError_TooManyArguments; - char *err_fmt = "Too many arguments for '%s', expected %td arguments"; + char const *err_fmt = "Too many arguments for '%s', expected %td arguments"; if (error_code < 0) { err = CallArgumentError_TooFewArguments; err_fmt = "Too few arguments for '%s', expected %td arguments"; @@ -6181,7 +6181,6 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type if (proc->kind == Entity_Variable) { sep = ":="; } - // error_line("\t%.*s %s %s at %.*s(%td:%td) with score %lld\n", LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column, cast(long long)valids[i].score); error_line("\t%.*s%.*s%.*s %s %s at %.*s(%td:%td)\n", LIT(prefix), LIT(prefix_sep), LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column); } if (procs.count > 0) { @@ -6751,7 +6750,7 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Type *t void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { check_expr_base(c, o, e, t); check_not_tuple(c, o); - char *err_str = nullptr; + char const *err_str = nullptr; switch (o->mode) { case Addressing_NoValue: err_str = "used as a value"; @@ -6779,7 +6778,8 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count, *max_count = o->value.value_string.len; } if (o->mode != Addressing_Immutable && o->mode != Addressing_Constant) { - o->mode = Addressing_Variable; + // o->mode = Addressing_Variable; + o->mode = Addressing_Value; } o->type = t_u8; return true; diff --git a/src/check_type.cpp b/src/check_type.cpp index c9e8f3a89..550761d78 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1186,7 +1186,12 @@ bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Typ return false; } - if (t->kind == Type_Struct) { + if (is_type_untyped(t)) { + Operand o = {Addressing_Value}; + o.type = default_type(type); + bool can_convert = check_cast_internal(ctx, &o, specialization); + return can_convert; + } else if (t->kind == Type_Struct) { if (t->Struct.polymorphic_parent == specialization) { return true; } diff --git a/src/checker.cpp b/src/checker.cpp index c189b8e6f..db9deb9ab 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -619,7 +619,7 @@ AstPackage *get_core_package(CheckerInfo *info, String name) { } -void add_package_dependency(CheckerContext *c, char *package_name, char *name) { +void add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup(p->scope, n); diff --git a/src/common.cpp b/src/common.cpp index f47ad69eb..779554ecc 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -753,8 +753,8 @@ String path_to_full_path(gbAllocator a, String path) { String res = string_trim_whitespace(make_string_c(fullpath)); #if defined(GB_SYSTEM_WINDOWS) for (isize i = 0; i < res.len; i++) { - if (res[i] == '\\') { - res[i] = '/'; + if (res.text[i] == '\\') { + res.text[i] = '/'; } } #endif diff --git a/src/ir.cpp b/src/ir.cpp index c9f42ea8e..debd982c8 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -38,6 +38,8 @@ struct irModule { // NOTE(bill): To prevent strings from being copied a lot // Mainly used for file names Map const_strings; // Key: String + Map const_string_byte_slices; // Key: String + Map constant_value_to_global; // Key: irValue * Entity * entry_point_entity; @@ -892,6 +894,10 @@ irValue *ir_emit_array_epi(irProcedure *proc, irValue *s, i32 index); irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index); irValue *ir_emit_bitcast(irProcedure *proc, irValue *data, Type *type); irValue *ir_emit_byte_swap(irProcedure *proc, irValue *value, Type *t); +irValue *ir_find_or_add_entity_string(irModule *m, String str); +irValue *ir_find_or_add_entity_string_byte_slice(irModule *m, String str); + + irValue *ir_alloc_value(irValueKind kind) { irValue *v = gb_alloc_item(ir_allocator(), irValue); @@ -1404,8 +1410,6 @@ irValue *ir_de_emit(irProcedure *proc, irValue *instr) { return instr; } - - irValue *ir_const_int(i64 i) { return ir_value_constant(t_int, exact_value_i64(i)); } @@ -1436,8 +1440,9 @@ irValue *ir_const_f64(f64 f) { irValue *ir_const_bool(bool b) { return ir_value_constant(t_bool, exact_value_bool(b != 0)); } -irValue *ir_const_string(String s) { - return ir_value_constant(t_string, exact_value_string(s)); +irValue *ir_const_string(irModule *m, String s) { + return ir_find_or_add_entity_string(m, s); + // return ir_value_constant(t_string, exact_value_string(s)); } irValue *ir_value_procedure(irModule *m, Entity *entity, Type *type, Ast *type_expr, Ast *body, String name) { @@ -1479,7 +1484,7 @@ irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefi return value; } -irBlock *ir_new_block(irProcedure *proc, Ast *node, char *label) { +irBlock *ir_new_block(irProcedure *proc, Ast *node, char const *label) { Scope *scope = nullptr; if (node != nullptr) { scope = scope_of_node(node); @@ -1557,7 +1562,7 @@ irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) { if (is_type_slice(type)) { if (value.kind == ExactValue_String) { GB_ASSERT(is_type_u8_slice(type)); - return ir_value_constant(type, value); + return ir_find_or_add_entity_string_byte_slice(m, value.value_string); } else { ast_node(cl, CompoundLit, value.value_compound); @@ -1591,6 +1596,27 @@ irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) { } irValue *ir_add_global_string_array(irModule *m, String string) { + + irValue *global_constant_value = nullptr; + { + HashKey key = hash_string(string); + irValue **found = map_get(&m->const_string_byte_slices, key); + if (found != nullptr) { + global_constant_value = *found; + + irValue **global_found = map_get(&m->constant_value_to_global, hash_pointer(global_constant_value)); + if (global_found != nullptr) { + return *global_found; + } + } + } + + if (global_constant_value == nullptr) { + global_constant_value = ir_find_or_add_entity_string_byte_slice(m, string); + } + Type *type = ir_type(global_constant_value); + + isize max_len = 6+8+1; u8 *str = cast(u8 *)gb_alloc_array(ir_allocator(), u8, max_len); isize len = gb_snprintf(cast(char *)str, max_len, "str$%x", m->global_string_index); @@ -1599,13 +1625,16 @@ irValue *ir_add_global_string_array(irModule *m, String string) { String name = make_string(str, len-1); Token token = {Token_String}; token.string = name; - Type *type = alloc_type_array(t_u8, string.len+1); - ExactValue ev = exact_value_string(string); - Entity *entity = alloc_entity_constant(nullptr, token, type, ev); - irValue *g = ir_value_global(entity, ir_add_module_constant(m, type, ev)); + + Entity *entity = alloc_entity_constant(nullptr, token, type, exact_value_string(string)); + + irValue *g = ir_value_global(entity, global_constant_value); g->Global.is_private = true; g->Global.is_unnamed_addr = true; - // g->Global.is_constant = true; + g->Global.is_constant = true; + + map_set(&m->constant_value_to_global, hash_pointer(global_constant_value), g); + ir_module_add_value(m, entity, g); map_set(&m->members, hash_string(name), g); @@ -4506,7 +4535,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal right = ir_emit_conv(proc, right, t_string); } - char *runtime_proc = nullptr; + char const *runtime_proc = nullptr; switch (op_kind) { case Token_CmpEq: runtime_proc = "string_eq"; break; case Token_NotEq: runtime_proc = "string_ne"; break; @@ -5023,12 +5052,26 @@ irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base, irValue *ir_find_or_add_entity_string(irModule *m, String str) { - irValue **found = map_get(&m->const_strings, hash_string(str)); + HashKey key = hash_string(str); + irValue **found = map_get(&m->const_strings, key); if (found != nullptr) { return *found; } - irValue *v = ir_const_string(str); - map_set(&m->const_strings, hash_string(str), v); + irValue *v = ir_value_constant(t_string, exact_value_string(str)); + map_set(&m->const_strings, key, v); + return v; + +} + +irValue *ir_find_or_add_entity_string_byte_slice(irModule *m, String str) { + HashKey key = hash_string(str); + irValue **found = map_get(&m->const_string_byte_slices, key); + if (found != nullptr) { + return *found; + } + Type *t = alloc_type_array(t_u8, str.len+1); + irValue *v = ir_value_constant(t, exact_value_string(str)); + map_set(&m->const_string_byte_slices, key, v); return v; } @@ -10497,15 +10540,17 @@ void ir_init_module(irModule *m, Checker *c) { m->generate_debug_info = build_context.ODIN_OS == "windows" && build_context.word_size == 8; } - map_init(&m->values, heap_allocator()); - map_init(&m->members, heap_allocator()); - map_init(&m->debug_info, heap_allocator()); - map_init(&m->entity_names, heap_allocator()); - map_init(&m->anonymous_proc_lits, heap_allocator()); - array_init(&m->procs, heap_allocator()); - array_init(&m->procs_to_generate, heap_allocator()); - array_init(&m->foreign_library_paths, heap_allocator()); - map_init(&m->const_strings, heap_allocator()); + map_init(&m->values, heap_allocator()); + map_init(&m->members, heap_allocator()); + map_init(&m->debug_info, heap_allocator()); + map_init(&m->entity_names, heap_allocator()); + map_init(&m->anonymous_proc_lits, heap_allocator()); + array_init(&m->procs, heap_allocator()); + array_init(&m->procs_to_generate, heap_allocator()); + array_init(&m->foreign_library_paths, heap_allocator()); + map_init(&m->const_strings, heap_allocator()); + map_init(&m->const_string_byte_slices, heap_allocator()); + map_init(&m->constant_value_to_global, heap_allocator()); // Default states m->stmt_state_flags = 0; @@ -10644,6 +10689,8 @@ void ir_destroy_module(irModule *m) { map_destroy(&m->anonymous_proc_lits); map_destroy(&m->debug_info); map_destroy(&m->const_strings); + map_destroy(&m->const_string_byte_slices); + map_destroy(&m->constant_value_to_global); array_free(&m->procs); array_free(&m->procs_to_generate); array_free(&m->foreign_library_paths); @@ -10805,7 +10852,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info tag = ir_emit_conv(proc, variant_ptr, t_type_info_named_ptr); // TODO(bill): Which is better? The mangled name or actual name? - irValue *name = ir_const_string(t->Named.type_name->token.string); + irValue *name = ir_const_string(proc->module, t->Named.type_name->token.string); irValue *gtip = ir_get_type_info_ptr(proc, t->Named.base); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), name); @@ -10996,7 +11043,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info ir_emit_store(proc, type_info, ir_type_info(proc, f->type)); if (f->token.string.len > 0) { irValue *name = ir_emit_ptr_offset(proc, memory_names, index); - ir_emit_store(proc, name, ir_const_string(f->token.string)); + ir_emit_store(proc, name, ir_const_string(proc->module, f->token.string)); } } @@ -11030,7 +11077,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *v = ir_value_constant(t->Enum.base_type, value); ir_emit_store_union_variant(proc, value_ep, v, ir_type(v)); - ir_emit_store(proc, name_ep, ir_const_string(fields[i]->token.string)); + ir_emit_store(proc, name_ep, ir_const_string(proc->module, fields[i]->token.string)); } irValue *v_count = ir_const_int(fields.count); @@ -11144,7 +11191,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info ir_emit_store(proc, type_info, ir_type_info(proc, f->type)); if (f->token.string.len > 0) { irValue *name = ir_emit_ptr_offset(proc, memory_names, index); - ir_emit_store(proc, name, ir_const_string(f->token.string)); + ir_emit_store(proc, name, ir_const_string(proc->module, f->token.string)); } ir_emit_store(proc, offset, ir_const_uintptr(foffset)); ir_emit_store(proc, is_using, ir_const_bool((f->flags&EntityFlag_Using) != 0)); @@ -11153,7 +11200,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info String tag_string = t->Struct.tags[source_index]; if (tag_string.len > 0) { irValue *tag_ptr = ir_emit_ptr_offset(proc, memory_tags, index); - ir_emit_store(proc, tag_ptr, ir_const_string(tag_string)); + ir_emit_store(proc, tag_ptr, ir_const_string(proc->module, tag_string)); } } @@ -11204,7 +11251,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *bit_ep = ir_emit_array_epi(proc, bit_array, cast(i32)i); irValue *offset_ep = ir_emit_array_epi(proc, offset_array, cast(i32)i); - ir_emit_store(proc, name_ep, ir_const_string(f->token.string)); + ir_emit_store(proc, name_ep, ir_const_string(proc->module, f->token.string)); ir_emit_store(proc, bit_ep, ir_const_i32(f->type->BitFieldValue.bits)); ir_emit_store(proc, offset_ep, ir_const_i32(t->BitField.offsets[i])); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 6ed11eb57..201c9d1d6 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -44,7 +44,7 @@ void ir_file_buffer_write(irFileBuffer *f, void const *data, isize len) { } -void ir_fprintf(irFileBuffer *f, char *fmt, ...) { +void ir_fprintf(irFileBuffer *f, char const *fmt, ...) { va_list va; va_start(va, fmt); isize len = gb_snprintf_va(f->buf, IR_FILE_BUFFER_BUF_LEN-1, fmt, va); diff --git a/src/main.cpp b/src/main.cpp index a71249519..fc6dab911 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,7 @@ gb_global Timings global_timings = {0}; // NOTE(bill): 'name' is used in debugging and profiling modes -i32 system_exec_command_line_app(char *name, char *fmt, ...) { +i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { #if defined(GB_SYSTEM_WINDOWS) STARTUPINFOW start_info = {gb_size_of(STARTUPINFOW)}; PROCESS_INFORMATION pi = {0}; @@ -121,7 +121,7 @@ i32 system_exec_command_line_app(char *name, char *fmt, ...) { -Array setup_args(int argc, char **argv) { +Array setup_args(int argc, char const **argv) { gbAllocator a = heap_allocator(); #if defined(GB_SYSTEM_WINDOWS) @@ -154,7 +154,7 @@ Array setup_args(int argc, char **argv) { -void print_usage_line(i32 indent, char *fmt, ...) { +void print_usage_line(i32 indent, char const *fmt, ...) { while (indent --> 0) { gb_printf_err("\t"); } @@ -858,7 +858,7 @@ void remove_temp_files(String output_base) { gb_memmove(data.data, output_base.text, n); #define EXT_REMOVE(s) do { \ gb_memmove(data.data+n, s, gb_size_of(s)); \ - gb_file_remove(cast(char *)data.data); \ + gb_file_remove(cast(char const *)data.data); \ } while (0) EXT_REMOVE(".ll"); EXT_REMOVE(".bc"); @@ -923,7 +923,7 @@ i32 exec_llvm_llc(String output_base) { #endif } -int main(int arg_count, char **arg_ptr) { +int main(int arg_count, char const **arg_ptr) { if (arg_count < 2) { usage(make_string_c(arg_ptr[0])); return 1; @@ -1153,7 +1153,7 @@ int main(int arg_count, char **arg_ptr) { lib_str = gb_string_appendc(lib_str, lib_str_buf); } - char *output_ext = "exe"; + char const *output_ext = "exe"; gbString link_settings = gb_string_make_reserve(heap_allocator(), 256); defer (gb_string_free(link_settings)); @@ -1319,8 +1319,8 @@ int main(int arg_count, char **arg_ptr) { // Unlike the Win32 linker code, the output_ext includes the dot, because // typically executable files on *NIX systems don't have extensions. String output_ext = {}; - char *link_settings = ""; - char *linker; + char const *link_settings = ""; + char const *linker; if (build_context.is_dll) { // Shared libraries are .dylib on MacOS and .so on Linux. #if defined(GB_SYSTEM_OSX) diff --git a/src/parser.cpp b/src/parser.cpp index cfa6d7981..be3991add 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -379,7 +379,7 @@ Ast *clone_ast(Ast *node) { } -void error(Ast *node, char *fmt, ...) { +void error(Ast *node, char const *fmt, ...) { Token token = {}; if (node != nullptr) { token = ast_token(node); @@ -393,7 +393,7 @@ void error(Ast *node, char *fmt, ...) { } } -void error_no_newline(Ast *node, char *fmt, ...) { +void error_no_newline(Ast *node, char const *fmt, ...) { Token token = {}; if (node != nullptr) { token = ast_token(node); @@ -407,14 +407,14 @@ void error_no_newline(Ast *node, char *fmt, ...) { } } -void warning(Ast *node, char *fmt, ...) { +void warning(Ast *node, char const *fmt, ...) { va_list va; va_start(va, fmt); warning_va(ast_token(node), fmt, va); va_end(va); } -void syntax_error(Ast *node, char *fmt, ...) { +void syntax_error(Ast *node, char const *fmt, ...) { va_list va; va_start(va, fmt); syntax_error_va(ast_token(node), fmt, va); @@ -1178,7 +1178,7 @@ Token expect_token(AstFile *f, TokenKind kind) { return prev; } -Token expect_token_after(AstFile *f, TokenKind kind, char *msg) { +Token expect_token_after(AstFile *f, TokenKind kind, char const *msg) { Token prev = f->curr_token; if (prev.kind != kind) { String p = token_strings[prev.kind]; diff --git a/src/string.cpp b/src/string.cpp index 1d14c3987..9551821aa 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -15,10 +15,10 @@ struct String { u8 * text; isize len; - u8 &operator[](isize i) { - GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i); - return text[i]; - } + // u8 &operator[](isize i) { + // GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i); + // return text[i]; + // } u8 const &operator[](isize i) const { GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i); return text[i]; @@ -48,29 +48,29 @@ struct String16 { }; -gb_inline String make_string(u8 *text, isize len) { +gb_inline String make_string(u8 const *text, isize len) { String s; - s.text = text; + s.text = cast(u8 *)text; if (len < 0) { - len = gb_strlen(cast(char *)text); + len = gb_strlen(cast(char const *)text); } s.len = len; return s; } -gb_inline String16 make_string16(wchar_t *text, isize len) { +gb_inline String16 make_string16(wchar_t const *text, isize len) { String16 s; - s.text = text; + s.text = cast(wchar_t *)text; s.len = len; return s; } -isize string16_len(wchar_t *s) { +isize string16_len(wchar_t const *s) { if (s == nullptr) { return 0; } - wchar_t *p = s; + wchar_t const *p = s; while (*p) { p++; } @@ -78,11 +78,11 @@ isize string16_len(wchar_t *s) { } -gb_inline String make_string_c(char *text) { +gb_inline String make_string_c(char const *text) { return make_string(cast(u8 *)cast(void *)text, gb_strlen(text)); } -gb_inline String16 make_string16_c(wchar_t *text) { +gb_inline String16 make_string16_c(wchar_t const *text) { return make_string16(text, string16_len(text)); } @@ -366,30 +366,30 @@ String copy_string(gbAllocator a, String const &s) { #if defined(GB_SYSTEM_WINDOWS) - int convert_multibyte_to_widechar(char *multibyte_input, int input_length, wchar_t *output, int output_size) { + int convert_multibyte_to_widechar(char const *multibyte_input, int input_length, wchar_t *output, int output_size) { return MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, multibyte_input, input_length, output, output_size); } - int convert_widechar_to_multibyte(wchar_t *widechar_input, int input_length, char *output, int output_size) { + int convert_widechar_to_multibyte(wchar_t const *widechar_input, int input_length, char *output, int output_size) { return WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, widechar_input, input_length, output, output_size, nullptr, nullptr); } #elif defined(GB_SYSTEM_UNIX) || defined(GB_SYSTEM_OSX) #include - int convert_multibyte_to_widechar(char *multibyte_input, usize input_length, wchar_t *output, usize output_size) { + int convert_multibyte_to_widechar(char const *multibyte_input, usize input_length, wchar_t *output, usize output_size) { iconv_t conv = iconv_open("WCHAR_T", "UTF-8"); size_t result = iconv(conv, cast(char **)&multibyte_input, &input_length, cast(char **)&output, &output_size); iconv_close(conv); - return (int) result; + return cast(int)result; } - int convert_widechar_to_multibyte(wchar_t* widechar_input, usize input_length, char* output, usize output_size) { + int convert_widechar_to_multibyte(wchar_t const *widechar_input, usize input_length, char* output, usize output_size) { iconv_t conv = iconv_open("UTF-8", "WCHAR_T"); - size_t result = iconv(conv, (char**) &widechar_input, &input_length, (char**) &output, &output_size); + size_t result = iconv(conv, cast(char**) &widechar_input, &input_length, cast(char **)&output, &output_size); iconv_close(conv); - return (int) result; + return cast(int)result; } #else #error Implement system diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 4b0db7ac4..caf93a97a 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -227,7 +227,7 @@ void end_error_block(void) { } -#define ERROR_OUT_PROC(name) void name(char *fmt, va_list va) +#define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va) typedef ERROR_OUT_PROC(ErrorOutProc); ERROR_OUT_PROC(default_error_out_va) { @@ -259,14 +259,14 @@ ERROR_OUT_PROC(default_error_out_va) { ErrorOutProc *error_out_va = default_error_out_va; -void error_out(char *fmt, ...) { +void error_out(char const *fmt, ...) { va_list va; va_start(va, fmt); error_out_va(fmt, va); va_end(va); } -void warning_va(Token token, char *fmt, va_list va) { +void warning_va(Token token, char const *fmt, va_list va) { gb_mutex_lock(&global_error_collector.mutex); global_error_collector.warning_count++; // NOTE(bill): Duplicate error, skip it @@ -283,7 +283,7 @@ void warning_va(Token token, char *fmt, va_list va) { } -void error_va(Token token, char *fmt, va_list va) { +void error_va(Token token, char const *fmt, va_list va) { gb_mutex_lock(&global_error_collector.mutex); global_error_collector.count++; // NOTE(bill): Duplicate error, skip it @@ -301,13 +301,13 @@ void error_va(Token token, char *fmt, va_list va) { } } -void error_line_va(char *fmt, va_list va) { +void error_line_va(char const *fmt, va_list va) { gb_mutex_lock(&global_error_collector.mutex); error_out_va(fmt, va); gb_mutex_unlock(&global_error_collector.mutex); } -void error_no_newline_va(Token token, char *fmt, va_list va) { +void error_no_newline_va(Token token, char const *fmt, va_list va) { gb_mutex_lock(&global_error_collector.mutex); global_error_collector.count++; // NOTE(bill): Duplicate error, skip it @@ -326,7 +326,7 @@ void error_no_newline_va(Token token, char *fmt, va_list va) { } -void syntax_error_va(Token token, char *fmt, va_list va) { +void syntax_error_va(Token token, char const *fmt, va_list va) { gb_mutex_lock(&global_error_collector.mutex); global_error_collector.count++; // NOTE(bill): Duplicate error, skip it @@ -345,7 +345,7 @@ void syntax_error_va(Token token, char *fmt, va_list va) { } } -void syntax_warning_va(Token token, char *fmt, va_list va) { +void syntax_warning_va(Token token, char const *fmt, va_list va) { gb_mutex_lock(&global_error_collector.mutex); global_error_collector.warning_count++; // NOTE(bill): Duplicate error, skip it @@ -363,21 +363,21 @@ void syntax_warning_va(Token token, char *fmt, va_list va) { -void warning(Token token, char *fmt, ...) { +void warning(Token token, char const *fmt, ...) { va_list va; va_start(va, fmt); warning_va(token, fmt, va); va_end(va); } -void error(Token token, char *fmt, ...) { +void error(Token token, char const *fmt, ...) { va_list va; va_start(va, fmt); error_va(token, fmt, va); va_end(va); } -void error(TokenPos pos, char *fmt, ...) { +void error(TokenPos pos, char const *fmt, ...) { va_list va; va_start(va, fmt); Token token = {}; @@ -386,7 +386,7 @@ void error(TokenPos pos, char *fmt, ...) { va_end(va); } -void error_line(char *fmt, ...) { +void error_line(char const *fmt, ...) { va_list va; va_start(va, fmt); error_line_va(fmt, va); @@ -394,14 +394,14 @@ void error_line(char *fmt, ...) { } -void syntax_error(Token token, char *fmt, ...) { +void syntax_error(Token token, char const *fmt, ...) { va_list va; va_start(va, fmt); syntax_error_va(token, fmt, va); va_end(va); } -void syntax_error(TokenPos pos, char *fmt, ...) { +void syntax_error(TokenPos pos, char const *fmt, ...) { va_list va; va_start(va, fmt); Token token = {}; @@ -410,7 +410,7 @@ void syntax_error(TokenPos pos, char *fmt, ...) { va_end(va); } -void syntax_warning(Token token, char *fmt, ...) { +void syntax_warning(Token token, char const *fmt, ...) { va_list va; va_start(va, fmt); syntax_warning_va(token, fmt, va); @@ -418,7 +418,7 @@ void syntax_warning(Token token, char *fmt, ...) { } -void compiler_error(char *fmt, ...) { +void compiler_error(char const *fmt, ...) { va_list va; va_start(va, fmt); @@ -506,7 +506,7 @@ void restore_tokenizer_state(Tokenizer *t, TokenizerState *state) { } -void tokenizer_err(Tokenizer *t, char *msg, ...) { +void tokenizer_err(Tokenizer *t, char const *msg, ...) { va_list va; isize column = t->read_curr - t->line+1; if (column < 1) {