mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-06 10:44:06 +00:00
Make procedure parameters just named values rather than copied variables
This commit is contained in:
@@ -20,29 +20,29 @@ decimal_to_string :: proc(buf: []byte, a: ^Decimal) -> string {
|
||||
|
||||
// TODO(bill): make this work with a buffer that's not big enough
|
||||
assert(len(buf) >= n);
|
||||
buf = buf[0:n];
|
||||
b := buf[0:n];
|
||||
|
||||
if a.count == 0 {
|
||||
buf[0] = '0';
|
||||
return string(buf[0:1]);
|
||||
b[0] = '0';
|
||||
return string(b[0:1]);
|
||||
}
|
||||
|
||||
w := 0;
|
||||
if a.decimal_point <= 0 {
|
||||
buf[w] = '0'; w += 1;
|
||||
buf[w] = '.'; w += 1;
|
||||
w += digit_zero(buf[w : w-a.decimal_point]);
|
||||
w += copy(buf[w:], a.digits[0:a.count]);
|
||||
b[w] = '0'; w += 1;
|
||||
b[w] = '.'; w += 1;
|
||||
w += digit_zero(b[w : w-a.decimal_point]);
|
||||
w += copy(b[w:], a.digits[0:a.count]);
|
||||
} else if a.decimal_point < a.count {
|
||||
w += copy(buf[w:], a.digits[0:a.decimal_point]);
|
||||
buf[w] = '.'; w += 1;
|
||||
w += copy(buf[w:], a.digits[a.decimal_point : a.count]);
|
||||
w += copy(b[w:], a.digits[0:a.decimal_point]);
|
||||
b[w] = '.'; w += 1;
|
||||
w += copy(b[w:], a.digits[a.decimal_point : a.count]);
|
||||
} else {
|
||||
w += copy(buf[w:], a.digits[0:a.count]);
|
||||
w += digit_zero(buf[w : w+a.decimal_point-a.count]);
|
||||
w += copy(b[w:], a.digits[0:a.count]);
|
||||
w += digit_zero(b[w : w+a.decimal_point-a.count]);
|
||||
}
|
||||
|
||||
return string(buf[0:w]);
|
||||
return string(b[0:w]);
|
||||
}
|
||||
|
||||
// trim trailing zeros
|
||||
@@ -56,10 +56,10 @@ trim :: proc(a: ^Decimal) {
|
||||
}
|
||||
|
||||
|
||||
assign :: proc(a: ^Decimal, i: u64) {
|
||||
assign :: proc(a: ^Decimal, idx: u64) {
|
||||
buf: [64]byte;
|
||||
n := 0;
|
||||
for i > 0 {
|
||||
for i := idx; i > 0; {
|
||||
j := i/10;
|
||||
i -= 10*j;
|
||||
buf[n] = byte('0'+i);
|
||||
@@ -175,11 +175,11 @@ shift_left :: proc(a: ^Decimal, k: uint) {
|
||||
trim(a);
|
||||
}
|
||||
|
||||
shift :: proc(a: ^Decimal, k: int) {
|
||||
shift :: proc(a: ^Decimal, i: int) {
|
||||
uint_size :: 8*size_of(uint);
|
||||
max_shift :: uint_size-4;
|
||||
|
||||
switch {
|
||||
switch k := i; {
|
||||
case a.count == 0:
|
||||
// no need to update
|
||||
case k > 0:
|
||||
|
||||
@@ -783,7 +783,8 @@ fmt_pointer :: proc(fi: ^Info, p: rawptr, verb: rune) {
|
||||
}
|
||||
}
|
||||
|
||||
enum_value_to_string :: proc(v: any) -> (string, bool) {
|
||||
enum_value_to_string :: proc(val: any) -> (string, bool) {
|
||||
v := val;
|
||||
v.id = runtime.typeid_base(v.id);
|
||||
type_info := type_info_of(v.id);
|
||||
|
||||
@@ -890,8 +891,8 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") {
|
||||
if ti == nil {
|
||||
return false;
|
||||
}
|
||||
ti = runtime.type_info_base(ti);
|
||||
switch info in ti.variant {
|
||||
t := runtime.type_info_base(ti);
|
||||
switch info in t.variant {
|
||||
case runtime.Type_Info_Integer:
|
||||
switch info.endianness {
|
||||
case .Platform: return false;
|
||||
|
||||
@@ -377,7 +377,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
return nil;
|
||||
}
|
||||
|
||||
alignment = clamp(alignment, 1, 8*size_of(Stack_Allocation_Header{}.padding)/2);
|
||||
align := clamp(alignment, 1, 8*size_of(Stack_Allocation_Header{}.padding)/2);
|
||||
|
||||
raw_alloc :: proc(s: ^Small_Stack, size, alignment: int) -> rawptr {
|
||||
curr_addr := uintptr(&s.data[0]) + uintptr(s.offset);
|
||||
@@ -400,7 +400,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
return raw_alloc(s, size, alignment);
|
||||
return raw_alloc(s, size, align);
|
||||
case .Free:
|
||||
if old_memory == nil {
|
||||
return nil;
|
||||
@@ -429,7 +429,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
|
||||
case .Resize:
|
||||
if old_memory == nil {
|
||||
return raw_alloc(s, size, alignment);
|
||||
return raw_alloc(s, size, align);
|
||||
}
|
||||
if size == 0 {
|
||||
return nil;
|
||||
@@ -452,7 +452,7 @@ small_stack_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
return old_memory;
|
||||
}
|
||||
|
||||
ptr := raw_alloc(s, size, alignment);
|
||||
ptr := raw_alloc(s, size, align);
|
||||
copy(ptr, old_memory, min(old_size, size));
|
||||
return ptr;
|
||||
}
|
||||
@@ -568,9 +568,10 @@ dynamic_pool_alloc :: proc(using pool: ^Dynamic_Pool, bytes: int) -> rawptr {
|
||||
}
|
||||
|
||||
|
||||
extra := alignment - (bytes % alignment);
|
||||
bytes += extra;
|
||||
if bytes >= out_band_size {
|
||||
n := bytes;
|
||||
extra := alignment - (n % alignment);
|
||||
n += extra;
|
||||
if n >= out_band_size {
|
||||
assert(block_allocator.procedure != nil);
|
||||
memory := block_allocator.procedure(block_allocator.data, Allocator_Mode.Alloc,
|
||||
block_size, alignment,
|
||||
@@ -581,7 +582,7 @@ dynamic_pool_alloc :: proc(using pool: ^Dynamic_Pool, bytes: int) -> rawptr {
|
||||
return memory;
|
||||
}
|
||||
|
||||
if bytes_left < bytes {
|
||||
if bytes_left < n {
|
||||
cycle_new_block(pool);
|
||||
if current_block == nil {
|
||||
return nil;
|
||||
@@ -589,8 +590,8 @@ dynamic_pool_alloc :: proc(using pool: ^Dynamic_Pool, bytes: int) -> rawptr {
|
||||
}
|
||||
|
||||
memory := current_pos;
|
||||
current_pos = ptr_offset((^byte)(current_pos), bytes);
|
||||
bytes_left -= bytes;
|
||||
current_pos = ptr_offset((^byte)(current_pos), n);
|
||||
bytes_left -= n;
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,13 +37,13 @@ make_any :: inline proc(data: rawptr, id: typeid) -> any {
|
||||
}
|
||||
|
||||
raw_string_data :: inline proc(s: $T/string) -> ^byte {
|
||||
return (^Raw_String)(&s).data;
|
||||
return (transmute(Raw_String)s).data;
|
||||
}
|
||||
raw_slice_data :: inline proc(a: $T/[]$E) -> ^E {
|
||||
return cast(^E)(^Raw_Slice)(&a).data;
|
||||
return cast(^E)(transmute(Raw_Slice)a).data;
|
||||
}
|
||||
raw_dynamic_array_data :: inline proc(a: $T/[dynamic]$E) -> ^E {
|
||||
return cast(^E)(^Raw_Dynamic_Array)(&a).data;
|
||||
return cast(^E)(transmute(Raw_Dynamic_Array)a).data;
|
||||
}
|
||||
|
||||
raw_data :: proc{raw_string_data, raw_slice_data, raw_dynamic_array_data};
|
||||
|
||||
@@ -501,7 +501,8 @@ append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) {
|
||||
a := (^mem.Raw_Dynamic_Array)(array);
|
||||
data := (^E)(a.data);
|
||||
assert(data != nil);
|
||||
mem.copy(mem.ptr_offset(data, a.len), &arg, size_of(E));
|
||||
val := arg;
|
||||
mem.copy(mem.ptr_offset(data, a.len), &val, size_of(E));
|
||||
a.len += arg_len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,13 @@ import "core:os"
|
||||
import "core:unicode/utf8"
|
||||
|
||||
|
||||
print_u64 :: proc(fd: os.Handle, u: u64) {
|
||||
print_u64 :: proc(fd: os.Handle, x: u64) {
|
||||
digits := "0123456789";
|
||||
|
||||
a: [129]byte;
|
||||
i := len(a);
|
||||
b := u64(10);
|
||||
u := x;
|
||||
for u >= b {
|
||||
i -= 1; a[i] = digits[u % b];
|
||||
u /= b;
|
||||
@@ -20,10 +21,11 @@ print_u64 :: proc(fd: os.Handle, u: u64) {
|
||||
os.write(fd, a[i:]);
|
||||
}
|
||||
|
||||
print_i64 :: proc(fd: os.Handle, u: i64) {
|
||||
print_i64 :: proc(fd: os.Handle, x: i64) {
|
||||
digits := "0123456789";
|
||||
b :: i64(10);
|
||||
|
||||
u := x;
|
||||
neg := u < 0;
|
||||
u = abs(u);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ _f32_info := Float_Info{23, 8, -127};
|
||||
_f64_info := Float_Info{52, 11, -1023};
|
||||
|
||||
|
||||
generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> []byte {
|
||||
generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, precision, bit_size: int) -> []byte {
|
||||
bits: u64;
|
||||
flt: ^Float_Info;
|
||||
switch bit_size {
|
||||
@@ -73,6 +73,7 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
|
||||
assign(d, mant);
|
||||
shift(d, exp - int(flt.mantbits));
|
||||
digs: Decimal_Slice;
|
||||
prec := precision;
|
||||
shortest := prec < 0;
|
||||
if shortest {
|
||||
round_shortest(d, mant, exp, flt);
|
||||
@@ -100,7 +101,7 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
|
||||
|
||||
|
||||
|
||||
format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slice, prec: int, fmt: byte) -> []byte {
|
||||
format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slice, precision: int, fmt: byte) -> []byte {
|
||||
Buffer :: struct {
|
||||
b: []byte,
|
||||
n: int,
|
||||
@@ -112,6 +113,7 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
|
||||
}
|
||||
|
||||
b := Buffer{b = buf};
|
||||
prec := precision;
|
||||
|
||||
switch fmt {
|
||||
case 'f', 'F':
|
||||
@@ -289,7 +291,8 @@ MAX_BASE :: 32;
|
||||
digits := "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
|
||||
is_integer_negative :: proc(u: u64, is_signed: bool, bit_size: int) -> (unsigned: u64, neg: bool) {
|
||||
is_integer_negative :: proc(x: u64, is_signed: bool, bit_size: int) -> (u: u64, neg: bool) {
|
||||
u = x;
|
||||
if is_signed {
|
||||
switch bit_size {
|
||||
case 8:
|
||||
@@ -312,18 +315,17 @@ is_integer_negative :: proc(u: u64, is_signed: bool, bit_size: int) -> (unsigned
|
||||
panic("is_integer_negative: Unknown integer size");
|
||||
}
|
||||
}
|
||||
return u, neg;
|
||||
return;
|
||||
}
|
||||
|
||||
append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flags) -> string {
|
||||
append_bits :: proc(buf: []byte, x: u64, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flags) -> string {
|
||||
if base < 2 || base > MAX_BASE {
|
||||
panic("strconv: illegal base passed to append_bits");
|
||||
}
|
||||
|
||||
neg: bool;
|
||||
a: [129]byte;
|
||||
i := len(a);
|
||||
u, neg = is_integer_negative(u, is_signed, bit_size);
|
||||
u, neg := is_integer_negative(x, is_signed, bit_size);
|
||||
b := u64(base);
|
||||
for u >= b {
|
||||
i-=1; a[i] = digits[u % b];
|
||||
@@ -360,7 +362,8 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i
|
||||
return string(buf[0:len(out)]);
|
||||
}
|
||||
|
||||
is_integer_negative_128 :: proc(u: u128, is_signed: bool, bit_size: int) -> (unsigned: u128, neg: bool) {
|
||||
is_integer_negative_128 :: proc(x: u128, is_signed: bool, bit_size: int) -> (u: u128, neg: bool) {
|
||||
u = x;
|
||||
if is_signed {
|
||||
switch bit_size {
|
||||
case 8:
|
||||
@@ -387,19 +390,18 @@ is_integer_negative_128 :: proc(u: u128, is_signed: bool, bit_size: int) -> (uns
|
||||
panic("is_integer_negative: Unknown integer size");
|
||||
}
|
||||
}
|
||||
return u, neg;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
append_bits_128 :: proc(buf: []byte, u: u128, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flags) -> string {
|
||||
append_bits_128 :: proc(buf: []byte, x: u128, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flags) -> string {
|
||||
if base < 2 || base > MAX_BASE {
|
||||
panic("strconv: illegal base passed to append_bits");
|
||||
}
|
||||
|
||||
neg: bool;
|
||||
a: [140]byte;
|
||||
i := len(a);
|
||||
u, neg = is_integer_negative_128(u, is_signed, bit_size);
|
||||
u, neg := is_integer_negative_128(x, is_signed, bit_size);
|
||||
b := u128(base);
|
||||
for u >= b {
|
||||
i-=1; a[i] = digits[u % b];
|
||||
|
||||
@@ -23,7 +23,8 @@ _digit_value :: proc(r: rune) -> int {
|
||||
return v;
|
||||
}
|
||||
|
||||
parse_i64 :: proc(s: string) -> i64 {
|
||||
parse_i64 :: proc(str: string) -> i64 {
|
||||
s := str;
|
||||
neg := false;
|
||||
if len(s) > 1 {
|
||||
switch s[0] {
|
||||
@@ -66,7 +67,8 @@ parse_i64 :: proc(s: string) -> i64 {
|
||||
return value;
|
||||
}
|
||||
|
||||
parse_u64 :: proc(s: string) -> u64 {
|
||||
parse_u64 :: proc(str: string) -> u64 {
|
||||
s := str;
|
||||
neg := false;
|
||||
if len(s) > 1 && s[0] == '+' {
|
||||
s = s[1:];
|
||||
@@ -209,7 +211,7 @@ append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> str
|
||||
}
|
||||
|
||||
|
||||
quote :: proc(buf: []byte, s: string) -> string {
|
||||
quote :: proc(buf: []byte, str: string) -> string {
|
||||
write_byte :: inline proc(buf: []byte, i: ^int, bytes: ..byte) {
|
||||
if i^ >= len(buf) do return;
|
||||
n := copy(buf[i^:], bytes[:]);
|
||||
@@ -222,6 +224,7 @@ quote :: proc(buf: []byte, s: string) -> string {
|
||||
|
||||
c :: '"';
|
||||
i := 0;
|
||||
s := str;
|
||||
|
||||
write_byte(buf, &i, c);
|
||||
for width := 0; len(s) > 0; s = s[width:] {
|
||||
|
||||
@@ -68,9 +68,9 @@ write_bytes :: proc(b: ^Builder, x: []byte) {
|
||||
@(private, static)
|
||||
DIGITS_LOWER := "0123456789abcdefx";
|
||||
|
||||
write_quoted_string :: proc(b: ^Builder, s: string, quote: byte = '"') {
|
||||
write_quoted_string :: proc(b: ^Builder, str: string, quote: byte = '"') {
|
||||
write_byte(b, quote);
|
||||
for width := 0; len(s) > 0; s = s[width:] {
|
||||
for width, s := 0, str; len(s) > 0; s = s[width:] {
|
||||
r := rune(s[0]);
|
||||
width = 1;
|
||||
if r >= utf8.RUNE_SELF {
|
||||
@@ -166,27 +166,27 @@ write_escaped_rune :: proc(b: ^Builder, r: rune, quote: byte, html_safe := false
|
||||
case '\t': write_string(b, `\t`);
|
||||
case '\v': write_string(b, `\v`);
|
||||
case:
|
||||
switch {
|
||||
case r < ' ':
|
||||
switch c := r; {
|
||||
case c < ' ':
|
||||
write_byte(b, '\\');
|
||||
write_byte(b, 'x');
|
||||
write_byte(b, DIGITS_LOWER[byte(r)>>4]);
|
||||
write_byte(b, DIGITS_LOWER[byte(r)&0xf]);
|
||||
write_byte(b, DIGITS_LOWER[byte(c)>>4]);
|
||||
write_byte(b, DIGITS_LOWER[byte(c)&0xf]);
|
||||
|
||||
case r > utf8.MAX_RUNE:
|
||||
r = 0xfffd;
|
||||
case c > utf8.MAX_RUNE:
|
||||
c = 0xfffd;
|
||||
fallthrough;
|
||||
case r < 0x10000:
|
||||
case c < 0x10000:
|
||||
write_byte(b, '\\');
|
||||
write_byte(b, 'u');
|
||||
for s := 12; s >= 0; s -= 4 {
|
||||
write_byte(b, DIGITS_LOWER[r>>uint(s) & 0xf]);
|
||||
write_byte(b, DIGITS_LOWER[c>>uint(s) & 0xf]);
|
||||
}
|
||||
case:
|
||||
write_byte(b, '\\');
|
||||
write_byte(b, 'U');
|
||||
for s := 28; s >= 0; s -= 4 {
|
||||
write_byte(b, DIGITS_LOWER[r>>uint(s) & 0xf]);
|
||||
write_byte(b, DIGITS_LOWER[c>>uint(s) & 0xf]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ rune_count :: proc(s: string) -> int {
|
||||
}
|
||||
|
||||
|
||||
equal_fold :: proc(s, t: string) -> bool {
|
||||
equal_fold :: proc(u, v: string) -> bool {
|
||||
s, t := u, v;
|
||||
loop: for s != "" && t != "" {
|
||||
sr, tr: rune;
|
||||
if s[0] < utf8.RUNE_SELF {
|
||||
@@ -250,13 +251,14 @@ count :: proc(s, substr: string) -> int {
|
||||
|
||||
// TODO(bill): Use a non-brute for approach
|
||||
n := 0;
|
||||
str := s;
|
||||
for {
|
||||
i := index(s, substr);
|
||||
i := index(str, substr);
|
||||
if i == -1 {
|
||||
return n;
|
||||
}
|
||||
n += 1;
|
||||
s = s[i+len(substr):];
|
||||
str = str[i+len(substr):];
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@@ -289,22 +291,22 @@ replace :: proc(s, old, new: string, n: int, allocator := context.allocator) ->
|
||||
output = s;
|
||||
return;
|
||||
}
|
||||
|
||||
byte_count := n;
|
||||
if m := count(s, old); m == 0 {
|
||||
was_allocation = false;
|
||||
output = s;
|
||||
return;
|
||||
} else if n < 0 || m < n {
|
||||
n = m;
|
||||
byte_count = m;
|
||||
}
|
||||
|
||||
|
||||
t := make([]byte, len(s) + n*(len(new) - len(old)), allocator);
|
||||
t := make([]byte, len(s) + byte_count*(len(new) - len(old)), allocator);
|
||||
was_allocation = true;
|
||||
|
||||
w := 0;
|
||||
start := 0;
|
||||
for i := 0; i < n; i += 1 {
|
||||
for i := 0; i < byte_count; i += 1 {
|
||||
j := start;
|
||||
if len(old) == 0 {
|
||||
if i > 0 {
|
||||
@@ -475,14 +477,16 @@ trim_left :: proc(s: string, cutset: string) -> string {
|
||||
if s == "" || cutset == "" {
|
||||
return s;
|
||||
}
|
||||
return trim_left_proc_with_state(s, is_in_cutset, &cutset);
|
||||
state := cutset;
|
||||
return trim_left_proc_with_state(s, is_in_cutset, &state);
|
||||
}
|
||||
|
||||
trim_right :: proc(s: string, cutset: string) -> string {
|
||||
if s == "" || cutset == "" {
|
||||
return s;
|
||||
}
|
||||
return trim_right_proc_with_state(s, is_in_cutset, &cutset);
|
||||
state := cutset;
|
||||
return trim_right_proc_with_state(s, is_in_cutset, &state);
|
||||
}
|
||||
|
||||
trim :: proc(s: string, cutset: string) -> string {
|
||||
@@ -515,7 +519,8 @@ trim_null :: proc(s: string) -> string {
|
||||
|
||||
// scrub scruvs invalid utf-8 characters and replaces them with the replacement string
|
||||
// Adjacent invalid bytes are only replaced once
|
||||
scrub :: proc(str: string, replacement: string, allocator := context.allocator) -> string {
|
||||
scrub :: proc(s: string, replacement: string, allocator := context.allocator) -> string {
|
||||
str := s;
|
||||
b := make_builder(allocator);;
|
||||
grow_builder(&b, len(str));
|
||||
|
||||
@@ -547,7 +552,8 @@ scrub :: proc(str: string, replacement: string, allocator := context.allocator)
|
||||
}
|
||||
|
||||
|
||||
reverse :: proc(str: string, allocator := context.allocator) -> string {
|
||||
reverse :: proc(s: string, allocator := context.allocator) -> string {
|
||||
str := s;
|
||||
n := len(str);
|
||||
buf := make([]byte, n);
|
||||
i := 0;
|
||||
@@ -560,17 +566,18 @@ reverse :: proc(str: string, allocator := context.allocator) -> string {
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
expand_tabs :: proc(str: string, tab_size: int, allocator := context.allocator) -> string {
|
||||
expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator) -> string {
|
||||
if tab_size <= 0 {
|
||||
panic("tab size must be positive");
|
||||
}
|
||||
|
||||
if str == "" {
|
||||
|
||||
if s == "" {
|
||||
return "";
|
||||
}
|
||||
|
||||
b := make_builder(allocator);
|
||||
|
||||
str := s;
|
||||
column: int;
|
||||
|
||||
for len(str) > 0 {
|
||||
@@ -683,11 +690,12 @@ write_pad_string :: proc(b: ^Builder, pad: string, pad_len, remains: int) {
|
||||
write_string(b, pad);
|
||||
}
|
||||
|
||||
remains = remains % pad_len;
|
||||
n := remains % pad_len;
|
||||
p := pad;
|
||||
|
||||
if remains != 0 do for i := 0; i < remains; i += 1 {
|
||||
r, w := utf8.decode_rune_in_string(pad);
|
||||
for i := 0; i < n; i += 1 {
|
||||
r, w := utf8.decode_rune_in_string(p);
|
||||
write_rune(b, r);
|
||||
pad = pad[w:];
|
||||
p = p[w:];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,6 @@ _open_file_dialog :: proc(title: string, dir: string,
|
||||
// Filters need to be passed as a pair of strings (title, filter)
|
||||
filter_len := u32(len(filters));
|
||||
if filter_len % 2 != 0 do return "", false;
|
||||
default_filter = clamp(default_filter, 1, filter_len / 2);
|
||||
|
||||
filter: string;
|
||||
filter = strings.join(filters, "\u0000", context.temp_allocator);
|
||||
@@ -102,7 +101,7 @@ _open_file_dialog :: proc(title: string, dir: string,
|
||||
title = utf8_to_wstring(title, context.temp_allocator),
|
||||
filter = utf8_to_wstring(filter, context.temp_allocator),
|
||||
initial_dir = utf8_to_wstring(dir, context.temp_allocator),
|
||||
filter_index = u32(default_filter),
|
||||
filter_index = u32(clamp(default_filter, 1, filter_len / 2)),
|
||||
def_ext = utf8_to_wstring(default_ext, context.temp_allocator),
|
||||
flags = u32(flags),
|
||||
};
|
||||
@@ -121,7 +120,7 @@ _open_file_dialog :: proc(title: string, dir: string,
|
||||
return "", false;
|
||||
}
|
||||
|
||||
file_name := ucs2_to_utf8(file_buf[:], allocator);
|
||||
file_name := utf16_to_utf8(file_buf[:], allocator);
|
||||
path = strings.trim_right_null(file_name);
|
||||
return;
|
||||
}
|
||||
@@ -143,7 +142,7 @@ select_file_to_save :: proc(title := SAVE_TITLE, dir := ".",
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Implement convenience function for select_file_to_open with ALLOW_MULTI_SELECT that takes
|
||||
// TODO: Implement convenience function for select_file_to_open with ALLOW_MULTI_SELECT that takes
|
||||
// it output of the form "path\u0000\file1u\0000file2" and turns it into []string with the path + file pre-concatenated for you.
|
||||
|
||||
OFN_ALLOWMULTISELECT :: 0x00000200; // NOTE(Jeroen): Without OFN_EXPLORER it uses the Win3 dialog.
|
||||
@@ -186,4 +185,4 @@ CDERR_LOCKRESFAILURE :: 0x00000008;
|
||||
CDERR_MEMALLOCFAILURE :: 0x00000009;
|
||||
CDERR_MEMLOCKFAILURE :: 0x0000000A;
|
||||
CDERR_NOHOOK :: 0x0000000B;
|
||||
CDERR_REGISTERMSGFAIL :: 0x0000000C;
|
||||
CDERR_REGISTERMSGFAIL :: 0x0000000C;
|
||||
|
||||
@@ -9,6 +9,6 @@ foreign {
|
||||
get_cwd :: proc(allocator := context.temp_allocator) -> string {
|
||||
buffer := make([]u16, MAX_PATH_WIDE, allocator);
|
||||
_get_cwd_wide(Wstring(&buffer[0]), MAX_PATH_WIDE);
|
||||
file := ucs2_to_utf8(buffer[:], allocator);
|
||||
file := utf16_to_utf8(buffer[:], allocator);
|
||||
return strings.trim_right_null(file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,7 +728,7 @@ CP_UTF8 :: 65001; // UTF-8 translation
|
||||
MB_ERR_INVALID_CHARS :: 8;
|
||||
WC_ERR_INVALID_CHARS :: 128;
|
||||
|
||||
utf8_to_ucs2 :: proc(s: string, allocator := context.temp_allocator) -> []u16 {
|
||||
utf8_to_utf16 :: proc(s: string, allocator := context.temp_allocator) -> []u16 {
|
||||
if len(s) < 1 {
|
||||
return nil;
|
||||
}
|
||||
@@ -751,13 +751,13 @@ utf8_to_ucs2 :: proc(s: string, allocator := context.temp_allocator) -> []u16 {
|
||||
return text[:len(text)-1];
|
||||
}
|
||||
utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> Wstring {
|
||||
if res := utf8_to_ucs2(s, allocator); res != nil {
|
||||
if res := utf8_to_utf16(s, allocator); res != nil {
|
||||
return Wstring(&res[0]);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
ucs2_to_utf8 :: proc(s: []u16, allocator := context.temp_allocator) -> string {
|
||||
utf16_to_utf8 :: proc(s: []u16, allocator := context.temp_allocator) -> string {
|
||||
if len(s) < 1 {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -60,7 +60,9 @@ accept_sizes := [256]u8{
|
||||
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
|
||||
};
|
||||
|
||||
encode_rune :: proc(r: rune) -> ([4]u8, int) {
|
||||
encode_rune :: proc(c: rune) -> ([4]u8, int) {
|
||||
r := c;
|
||||
|
||||
buf: [4]u8;
|
||||
i := u32(r);
|
||||
mask :: u8(0x3f);
|
||||
|
||||
@@ -1533,8 +1533,14 @@ void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) {
|
||||
if (ast_node_expect(node, Ast_UnaryExpr)) {
|
||||
ast_node(ue, UnaryExpr, node);
|
||||
gbString str = expr_to_string(ue->expr);
|
||||
error(op, "Cannot take the pointer address of '%s'", str);
|
||||
gb_string_free(str);
|
||||
defer (gb_string_free(str));
|
||||
|
||||
Entity *e = entity_of_ident(o->expr);
|
||||
if (e != nullptr && (e->flags & EntityFlag_Param) != 0) {
|
||||
error(op, "Cannot take the pointer address of '%s' which is a procedure parameter", str);
|
||||
} else {
|
||||
error(op, "Cannot take the pointer address of '%s'", str);
|
||||
}
|
||||
}
|
||||
o->mode = Addressing_Invalid;
|
||||
return;
|
||||
@@ -5909,17 +5915,6 @@ void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) {
|
||||
}
|
||||
}
|
||||
|
||||
void check_set_mode_with_indirection(Operand *o, bool indirection) {
|
||||
if (o->mode != Addressing_Immutable) {
|
||||
if (indirection) {
|
||||
o->mode = Addressing_Variable;
|
||||
} else if (o->mode != Addressing_Variable &&
|
||||
o->mode != Addressing_Constant) {
|
||||
o->mode = Addressing_Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count) {
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
@@ -5927,7 +5922,9 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count)
|
||||
if (o->mode == Addressing_Constant) {
|
||||
*max_count = o->value.value_string.len;
|
||||
}
|
||||
check_set_mode_with_indirection(o, indirection);
|
||||
if (o->mode != Addressing_Immutable && o->mode != Addressing_Constant) {
|
||||
o->mode = Addressing_Variable;
|
||||
}
|
||||
o->type = t_u8;
|
||||
return true;
|
||||
}
|
||||
@@ -5935,20 +5932,29 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count)
|
||||
|
||||
case Type_Array:
|
||||
*max_count = t->Array.count;
|
||||
check_set_mode_with_indirection(o, indirection);
|
||||
if (o->mode != Addressing_Immutable) {
|
||||
if (indirection) {
|
||||
o->mode = Addressing_Variable;
|
||||
} else if (o->mode != Addressing_Variable &&
|
||||
o->mode != Addressing_Constant) {
|
||||
o->mode = Addressing_Value;
|
||||
}
|
||||
}
|
||||
o->type = t->Array.elem;
|
||||
return true;
|
||||
|
||||
case Type_Slice:
|
||||
o->type = t->Slice.elem;
|
||||
if (o->mode != Addressing_Immutable) {
|
||||
if (o->mode != Addressing_Immutable && o->mode != Addressing_Constant) {
|
||||
o->mode = Addressing_Variable;
|
||||
}
|
||||
return true;
|
||||
|
||||
case Type_DynamicArray:
|
||||
o->type = t->DynamicArray.elem;
|
||||
check_set_mode_with_indirection(o, indirection);
|
||||
if (o->mode != Addressing_Immutable && o->mode != Addressing_Constant) {
|
||||
o->mode = Addressing_Variable;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -303,9 +303,13 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs)
|
||||
}
|
||||
}
|
||||
|
||||
Entity *e = entity_of_ident(lhs->expr);
|
||||
|
||||
gbString str = expr_to_string(lhs->expr);
|
||||
if (lhs->mode == Addressing_Immutable) {
|
||||
error(lhs->expr, "Cannot assign to an immutable: '%s'", str);
|
||||
} else if (e != nullptr && e->flags & EntityFlag_Param) {
|
||||
error(lhs->expr, "Cannot assign to '%s' which is a procedure parameter", str);
|
||||
} else {
|
||||
error(lhs->expr, "Cannot assign to '%s'", str);
|
||||
}
|
||||
|
||||
@@ -1519,18 +1519,6 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
||||
}
|
||||
}
|
||||
|
||||
if (p->flags&FieldFlag_in) {
|
||||
if (is_type_param) {
|
||||
error(param, "'in' cannot be applied to a type parameter");
|
||||
p->flags &= ~FieldFlag_in;
|
||||
} else if (is_variadic) {
|
||||
error(param, "'in' cannot be applied to a variadic parameter");
|
||||
p->flags &= ~FieldFlag_in;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_in = (p->flags&FieldFlag_in) != 0;
|
||||
|
||||
for_array(j, p->names) {
|
||||
Ast *name = p->names[j];
|
||||
|
||||
@@ -1670,7 +1658,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
||||
|
||||
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
|
||||
} else {
|
||||
param = alloc_entity_param(scope, name->Ident.token, type, is_using, is_in);
|
||||
param = alloc_entity_param(scope, name->Ident.token, type, is_using, true);
|
||||
param->Variable.param_value = param_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2854,7 +2854,6 @@ enum FieldPrefixKind {
|
||||
FieldPrefix_no_alias,
|
||||
FieldPrefix_c_var_arg,
|
||||
FieldPrefix_auto_cast,
|
||||
FieldPrefix_in,
|
||||
};
|
||||
|
||||
FieldPrefixKind is_token_field_prefix(AstFile *f) {
|
||||
@@ -2865,9 +2864,6 @@ FieldPrefixKind is_token_field_prefix(AstFile *f) {
|
||||
case Token_using:
|
||||
return FieldPrefix_using;
|
||||
|
||||
case Token_in:
|
||||
return FieldPrefix_in;
|
||||
|
||||
case Token_auto_cast:
|
||||
return FieldPrefix_auto_cast;
|
||||
|
||||
@@ -2892,7 +2888,6 @@ u32 parse_field_prefixes(AstFile *f) {
|
||||
i32 using_count = 0;
|
||||
i32 no_alias_count = 0;
|
||||
i32 c_vararg_count = 0;
|
||||
i32 in_count = 0;
|
||||
i32 auto_cast_count = 0;
|
||||
|
||||
for (;;) {
|
||||
@@ -2910,14 +2905,12 @@ u32 parse_field_prefixes(AstFile *f) {
|
||||
case FieldPrefix_using: using_count += 1; advance_token(f); break;
|
||||
case FieldPrefix_no_alias: no_alias_count += 1; advance_token(f); break;
|
||||
case FieldPrefix_c_var_arg: c_vararg_count += 1; advance_token(f); break;
|
||||
case FieldPrefix_in: in_count += 1; advance_token(f); break;
|
||||
case FieldPrefix_auto_cast: auto_cast_count += 1; advance_token(f); break;
|
||||
}
|
||||
}
|
||||
if (using_count > 1) syntax_error(f->curr_token, "Multiple 'using' in this field list");
|
||||
if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple '#no_alias' in this field list");
|
||||
if (c_vararg_count > 1) syntax_error(f->curr_token, "Multiple '#c_vararg' in this field list");
|
||||
if (in_count > 1) syntax_error(f->curr_token, "Multiple 'in' in this field list");
|
||||
if (auto_cast_count > 1) syntax_error(f->curr_token, "Multiple 'auto_cast' in this field list");
|
||||
|
||||
|
||||
@@ -2925,7 +2918,6 @@ u32 parse_field_prefixes(AstFile *f) {
|
||||
if (using_count > 0) field_flags |= FieldFlag_using;
|
||||
if (no_alias_count > 0) field_flags |= FieldFlag_no_alias;
|
||||
if (c_vararg_count > 0) field_flags |= FieldFlag_c_vararg;
|
||||
if (in_count > 0) field_flags |= FieldFlag_in;
|
||||
if (auto_cast_count > 0) field_flags |= FieldFlag_auto_cast;
|
||||
return field_flags;
|
||||
}
|
||||
|
||||
@@ -186,8 +186,6 @@ enum FieldFlag {
|
||||
FieldFlag_c_vararg = 1<<3,
|
||||
FieldFlag_auto_cast = 1<<4,
|
||||
|
||||
FieldFlag_in = 1<<5,
|
||||
|
||||
|
||||
FieldFlag_Results = 1<<16,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user