diff --git a/core/io/io.odin b/core/io/io.odin index ec95c91d3..ba6dde079 100644 --- a/core/io/io.odin +++ b/core/io/io.odin @@ -139,16 +139,24 @@ destroy :: proc(s: Stream) -> Error { return .Empty } -read :: proc(s: Reader, p: []byte) -> (n: int, err: Error) { +read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) { if s.stream_vtable != nil && s.impl_read != nil { - return s->impl_read(p) + n, err = s->impl_read(p) + if n_read != nil { + n_read^ += n + } + return } return 0, .Empty } -write :: proc(s: Writer, p: []byte) -> (n: int, err: Error) { +write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) { if s.stream_vtable != nil && s.impl_write != nil { - return s->impl_write(p) + n, err = s->impl_write(p) + if n_written != nil { + n_written^ += n + } + return } return 0, .Empty } @@ -207,12 +215,16 @@ size :: proc(s: Stream) -> i64 { -read_at :: proc(r: Reader_At, p: []byte, offset: i64) -> (n: int, err: Error) { +read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: int, err: Error) { if r.stream_vtable == nil { return 0, .Empty } if r.impl_read_at != nil { - return r->impl_read_at(p, offset) + n, err = r->impl_read_at(p, offset) + if n_read != nil { + n_read^ += n + } + return } if r.impl_seek == nil || r.impl_read == nil { return 0, .Empty @@ -225,6 +237,9 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64) -> (n: int, err: Error) { } n, err = r->impl_read(p) + if n_read != nil { + n_read^ += n + } _, err1 := r->impl_seek(curr_offset, .Start) if err1 != nil && err == nil { err = err1 @@ -233,12 +248,16 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64) -> (n: int, err: Error) { } -write_at :: proc(w: Writer_At, p: []byte, offset: i64) -> (n: int, err: Error) { +write_at :: proc(w: Writer_At, p: []byte, offset: i64, n_written: ^int = nil) -> (n: int, err: Error) { if w.stream_vtable == nil { return 0, .Empty } if w.impl_write_at != nil { - return w->impl_write_at(p, offset) + n, err = w->impl_write_at(p, offset) + if n_written != nil { + n_written^ += n + } + return } if w.impl_seek == nil || w.impl_write == nil { return 0, .Empty @@ -251,6 +270,9 @@ write_at :: proc(w: Writer_At, p: []byte, offset: i64) -> (n: int, err: Error) { } n, err = w->impl_write(p) + if n_written != nil { + n_written^ += n + } _, err1 := w->impl_seek(curr_offset, .Start) if err1 != nil && err == nil { err = err1 @@ -278,7 +300,7 @@ read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) { } -read_byte :: proc(r: Byte_Reader) -> (byte, Error) { +read_byte :: proc(r: Byte_Reader, n_read: ^int = nil) -> (byte, Error) { if r.stream_vtable == nil { return 0, .Empty } @@ -291,6 +313,9 @@ read_byte :: proc(r: Byte_Reader) -> (byte, Error) { b: [1]byte _, err := r->impl_read(b[:]) + if err == nil && n_read != nil { + n_read^ += 1 + } return b[0], err } @@ -299,16 +324,16 @@ write_byte :: proc{ write_byte_to_writer, } -write_byte_to_byte_writer :: proc(w: Byte_Writer, c: byte) -> Error { - return _write_byte(w, c) +write_byte_to_byte_writer :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> Error { + return _write_byte(w, c, n_written) } -write_byte_to_writer :: proc(w: Writer, c: byte) -> Error { - return _write_byte(auto_cast w, c) +write_byte_to_writer :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error { + return _write_byte(auto_cast w, c, n_written) } @(private) -_write_byte :: proc(w: Byte_Writer, c: byte) -> Error { +_write_byte :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> Error { if w.stream_vtable == nil { return .Empty } @@ -321,15 +346,22 @@ _write_byte :: proc(w: Byte_Writer, c: byte) -> Error { b := [1]byte{c} _, err := w->impl_write(b[:]) + if err == nil && n_written != nil { + n_written^ += 1 + } return err } -read_rune :: proc(br: Rune_Reader) -> (ch: rune, size: int, err: Error) { +read_rune :: proc(br: Rune_Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: Error) { if br.stream_vtable == nil { return 0, 0, .Empty } if br.impl_read_rune != nil { - return br->impl_read_rune() + ch, size, err = br->impl_read_rune() + if n_read != nil { + n_read^ += size + } + return } if br.impl_read == nil { return 0, 0, .Empty @@ -337,6 +369,7 @@ read_rune :: proc(br: Rune_Reader) -> (ch: rune, size: int, err: Error) { b: [utf8.UTF_MAX]byte _, err = br->impl_read(b[:1]) + s0 := b[0] ch = rune(s0) @@ -344,6 +377,9 @@ read_rune :: proc(br: Rune_Reader) -> (ch: rune, size: int, err: Error) { if err != nil { return } + if n_read != nil { + n_read^ += 1 + } if ch < utf8.RUNE_SELF { return } @@ -356,6 +392,9 @@ read_rune :: proc(br: Rune_Reader) -> (ch: rune, size: int, err: Error) { sz := int(x&7) n: int n, err = br->impl_read(b[1:sz]) + if n_read != nil { + n_read^ += n + } if err != nil || n+1 < sz { ch = utf8.RUNE_ERROR return @@ -379,24 +418,31 @@ unread_rune :: proc(s: Rune_Scanner) -> Error { } -write_string :: proc(s: Writer, str: string) -> (n: int, err: Error) { - return write(s, transmute([]byte)str) +write_string :: proc(s: Writer, str: string, n_written: ^int = nil) -> (n: int, err: Error) { + return write(s, transmute([]byte)str, n_written) } -write_rune :: proc(s: Writer, r: rune) -> (size: int, err: Error) { +write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err: Error) { if s.stream_vtable != nil && s.impl_write_rune != nil { - return s->impl_write_rune(r) + size, err = s->impl_write_rune(r) + if n_written != nil { + n_written^ += size + } + return } if r < utf8.RUNE_SELF { err = write_byte(s, byte(r)) if err == nil { size = 1 + if n_written != nil { + n_written^ += size + } } return } buf, w := utf8.encode_rune(r) - return write(s, buf[:w]) + return write(s, buf[:w], n_written) } diff --git a/core/io/util.odin b/core/io/util.odin index 4df0712ba..ff033e3df 100644 --- a/core/io/util.odin +++ b/core/io/util.odin @@ -3,49 +3,49 @@ package io import "core:strconv" import "core:unicode/utf8" -read_ptr :: proc(r: Reader, p: rawptr, byte_size: int) -> (n: int, err: Error) { - return read(r, ([^]byte)(p)[:byte_size]) +read_ptr :: proc(r: Reader, p: rawptr, byte_size: int, n_read: ^int = nil) -> (n: int, err: Error) { + return read(r, ([^]byte)(p)[:byte_size], n_read) } -write_ptr :: proc(w: Writer, p: rawptr, byte_size: int) -> (n: int, err: Error) { - return write(w, ([^]byte)(p)[:byte_size]) +write_ptr :: proc(w: Writer, p: rawptr, byte_size: int, n_written: ^int = nil) -> (n: int, err: Error) { + return write(w, ([^]byte)(p)[:byte_size], n_written) } -read_ptr_at :: proc(r: Reader_At, p: rawptr, byte_size: int, offset: i64) -> (n: int, err: Error) { - return read_at(r, ([^]byte)(p)[:byte_size], offset) +read_ptr_at :: proc(r: Reader_At, p: rawptr, byte_size: int, offset: i64, n_read: ^int = nil) -> (n: int, err: Error) { + return read_at(r, ([^]byte)(p)[:byte_size], offset, n_read) } -write_ptr_at :: proc(w: Writer_At, p: rawptr, byte_size: int, offset: i64) -> (n: int, err: Error) { - return write_at(w, ([^]byte)(p)[:byte_size], offset) +write_ptr_at :: proc(w: Writer_At, p: rawptr, byte_size: int, offset: i64, n_written: ^int = nil) -> (n: int, err: Error) { + return write_at(w, ([^]byte)(p)[:byte_size], offset, n_written) } -write_u64 :: proc(w: Writer, i: u64, base: int = 10) -> (n: int, err: Error) { +write_u64 :: proc(w: Writer, i: u64, base: int = 10, n_written: ^int = nil) -> (n: int, err: Error) { buf: [32]byte s := strconv.append_bits(buf[:], i, base, false, 64, strconv.digits, nil) - return write_string(w, s) + return write_string(w, s, n_written) } -write_i64 :: proc(w: Writer, i: i64, base: int = 10) -> (n: int, err: Error) { +write_i64 :: proc(w: Writer, i: i64, base: int = 10, n_written: ^int = nil) -> (n: int, err: Error) { buf: [32]byte s := strconv.append_bits(buf[:], u64(i), base, true, 64, strconv.digits, nil) - return write_string(w, s) + return write_string(w, s, n_written) } -write_uint :: proc(w: Writer, i: uint, base: int = 10) -> (n: int, err: Error) { - return write_u64(w, u64(i), base) +write_uint :: proc(w: Writer, i: uint, base: int = 10, n_written: ^int = nil) -> (n: int, err: Error) { + return write_u64(w, u64(i), base, n_written) } -write_int :: proc(w: Writer, i: int, base: int = 10) -> (n: int, err: Error) { - return write_i64(w, i64(i), base) +write_int :: proc(w: Writer, i: int, base: int = 10, n_written: ^int = nil) -> (n: int, err: Error) { + return write_i64(w, i64(i), base, n_written) } -write_u128 :: proc(w: Writer, i: u128, base: int = 10) -> (n: int, err: Error) { +write_u128 :: proc(w: Writer, i: u128, base: int = 10, n_written: ^int = nil) -> (n: int, err: Error) { buf: [32]byte s := strconv.append_bits_128(buf[:], i, base, false, 128, strconv.digits, nil) - return write_string(w, s) + return write_string(w, s, n_written) } -write_i128 :: proc(w: Writer, i: i128, base: int = 10) -> (n: int, err: Error) { +write_i128 :: proc(w: Writer, i: i128, base: int = 10, n_written: ^int = nil) -> (n: int, err: Error) { buf: [32]byte s := strconv.append_bits_128(buf[:], u128(i), base, true, 128, strconv.digits, nil) - return write_string(w, s) + return write_string(w, s, n_written) } @@ -54,57 +54,51 @@ write_i128 :: proc(w: Writer, i: i128, base: int = 10) -> (n: int, err: Error) { @(private="file") DIGITS_LOWER := "0123456789abcdefx" -@(private="file") -n_write_byte :: proc(w: Writer, b: byte, bytes_processed: ^int) -> Error { - err := write_byte(w, b) - if err == nil { - bytes_processed^ += 1 - } - return err -} - n_wrapper :: proc(n: int, err: Error, bytes_processed: ^int) -> Error { bytes_processed^ += n return err } -write_encoded_rune :: proc(w: Writer, r: rune, write_quote := true) -> (n: int, err: Error) { +write_encoded_rune :: proc(w: Writer, r: rune, write_quote := true, n_written: ^int = nil) -> (n: int, err: Error) { + defer if n_written != nil { + n_written^ += n + } if write_quote { - n_write_byte(w, '\'', &n) or_return + write_byte(w, '\'', &n) or_return } switch r { - case '\a': n_wrapper(write_string(w, `\a"`), &n) or_return - case '\b': n_wrapper(write_string(w, `\b"`), &n) or_return - case '\e': n_wrapper(write_string(w, `\e"`), &n) or_return - case '\f': n_wrapper(write_string(w, `\f"`), &n) or_return - case '\n': n_wrapper(write_string(w, `\n"`), &n) or_return - case '\r': n_wrapper(write_string(w, `\r"`), &n) or_return - case '\t': n_wrapper(write_string(w, `\t"`), &n) or_return - case '\v': n_wrapper(write_string(w, `\v"`), &n) or_return + case '\a': write_string(w, `\a"`, &n) or_return + case '\b': write_string(w, `\b"`, &n) or_return + case '\e': write_string(w, `\e"`, &n) or_return + case '\f': write_string(w, `\f"`, &n) or_return + case '\n': write_string(w, `\n"`, &n) or_return + case '\r': write_string(w, `\r"`, &n) or_return + case '\t': write_string(w, `\t"`, &n) or_return + case '\v': write_string(w, `\v"`, &n) or_return case: if r < 32 { - n_wrapper(write_string(w, `\x`), &n) or_return + write_string(w, `\x`, &n) or_return buf: [2]byte s := strconv.append_bits(buf[:], u64(r), 16, true, 64, strconv.digits, nil) switch len(s) { - case 0: n_wrapper(write_string(w, "00"), &n) or_return - case 1: n_write_byte(w, '0', &n) or_return - case 2: n_wrapper(write_string(w, s), &n) or_return + case 0: write_string(w, "00", &n) or_return + case 1: write_byte(w, '0', &n) or_return + case 2: write_string(w, s, &n) or_return } } else { - n_wrapper(write_rune(w, r), &n) or_return + write_rune(w, r, &n) or_return } } if write_quote { - n_write_byte(w, '\'', &n) or_return + write_byte(w, '\'', &n) or_return } return } -write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false) -> (n: int, err: Error) { +write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false, n_written: ^int = nil) -> (n: int, err: Error) { is_printable :: proc(r: rune) -> bool { if r <= 0xff { switch r { @@ -118,66 +112,72 @@ write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false) // TODO(bill): A proper unicode library will be needed! return false } + defer if n_written != nil { + n_written^ += n + } if html_safe { switch r { case '<', '>', '&': - n_write_byte(w, '\\', &n) or_return - n_write_byte(w, 'u', &n) or_return + write_byte(w, '\\', &n) or_return + write_byte(w, 'u', &n) or_return for s := 12; s >= 0; s -= 4 { - n_write_byte(w, DIGITS_LOWER[r>>uint(s) & 0xf], &n) or_return + write_byte(w, DIGITS_LOWER[r>>uint(s) & 0xf], &n) or_return } return } } if r == rune(quote) || r == '\\' { - n_write_byte(w, '\\', &n) or_return - n_write_byte(w, byte(r), &n) or_return + write_byte(w, '\\', &n) or_return + write_byte(w, byte(r), &n) or_return return } else if is_printable(r) { - n_wrapper(write_encoded_rune(w, r, false), &n) or_return + write_encoded_rune(w, r, false, &n) or_return return } switch r { - case '\a': n_wrapper(write_string(w, `\a`), &n) or_return - case '\b': n_wrapper(write_string(w, `\b`), &n) or_return - case '\e': n_wrapper(write_string(w, `\e`), &n) or_return - case '\f': n_wrapper(write_string(w, `\f`), &n) or_return - case '\n': n_wrapper(write_string(w, `\n`), &n) or_return - case '\r': n_wrapper(write_string(w, `\r`), &n) or_return - case '\t': n_wrapper(write_string(w, `\t`), &n) or_return - case '\v': n_wrapper(write_string(w, `\v`), &n) or_return + case '\a': write_string(w, `\a`, &n) or_return + case '\b': write_string(w, `\b`, &n) or_return + case '\e': write_string(w, `\e`, &n) or_return + case '\f': write_string(w, `\f`, &n) or_return + case '\n': write_string(w, `\n`, &n) or_return + case '\r': write_string(w, `\r`, &n) or_return + case '\t': write_string(w, `\t`, &n) or_return + case '\v': write_string(w, `\v`, &n) or_return case: switch c := r; { case c < ' ': - n_write_byte(w, '\\', &n) or_return - n_write_byte(w, 'x', &n) or_return - n_write_byte(w, DIGITS_LOWER[byte(c)>>4], &n) or_return - n_write_byte(w, DIGITS_LOWER[byte(c)&0xf], &n) or_return + write_byte(w, '\\', &n) or_return + write_byte(w, 'x', &n) or_return + write_byte(w, DIGITS_LOWER[byte(c)>>4], &n) or_return + write_byte(w, DIGITS_LOWER[byte(c)&0xf], &n) or_return case c > utf8.MAX_RUNE: c = 0xfffd fallthrough case c < 0x10000: - n_write_byte(w, '\\', &n) or_return - n_write_byte(w, 'u', &n) or_return + write_byte(w, '\\', &n) or_return + write_byte(w, 'u', &n) or_return for s := 12; s >= 0; s -= 4 { - n_write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return + write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return } case: - n_write_byte(w, '\\', &n) or_return - n_write_byte(w, 'U', &n) or_return + write_byte(w, '\\', &n) or_return + write_byte(w, 'U', &n) or_return for s := 28; s >= 0; s -= 4 { - n_write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return + write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return } } } return } -write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"') -> (n: int, err: Error) { - n_write_byte(w, quote, &n) or_return +write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written: ^int = nil) -> (n: int, err: Error) { + defer if n_written != nil { + n_written^ += n + } + write_byte(w, quote, &n) or_return for width, s := 0, str; len(s) > 0; s = s[width:] { r := rune(s[0]) width = 1 @@ -185,17 +185,17 @@ write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"') -> (n: in r, width = utf8.decode_rune_in_string(s) } if width == 1 && r == utf8.RUNE_ERROR { - n_write_byte(w, '\\', &n) or_return - n_write_byte(w, 'x', &n) or_return - n_write_byte(w, DIGITS_LOWER[s[0]>>4], &n) or_return - n_write_byte(w, DIGITS_LOWER[s[0]&0xf], &n) or_return + write_byte(w, '\\', &n) or_return + write_byte(w, 'x', &n) or_return + write_byte(w, DIGITS_LOWER[s[0]>>4], &n) or_return + write_byte(w, DIGITS_LOWER[s[0]&0xf], &n) or_return continue } n_wrapper(write_escaped_rune(w, r, quote), &n) or_return } - n_write_byte(w, quote, &n) or_return + write_byte(w, quote, &n) or_return return } diff --git a/core/reflect/types.odin b/core/reflect/types.odin index a43d9deb1..d0a96a088 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -349,244 +349,241 @@ write_type_builder :: proc(buf: ^strings.Builder, ti: ^Type_Info) -> int { n, _ := write_type_writer(strings.to_writer(buf), ti) return n } -write_type_writer :: proc(w: io.Writer, ti: ^Type_Info) -> (n: int, err: io.Error) { +write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) -> (n: int, err: io.Error) { + defer if n_written != nil { + n_written^ += n + } if ti == nil { - return io.write_string(w, "nil") + io.write_string(w, "nil", &n) or_return + return } - - _n1 :: proc(err: io.Error, n: ^int) -> io.Error { - n^ += 1 if err == nil else 0 - return err - } - _n2 :: io.n_wrapper - _n :: proc{_n1, _n2} - + switch info in ti.variant { case Type_Info_Named: - return io.write_string(w, info.name) + io.write_string(w, info.name, &n) or_return case Type_Info_Integer: switch ti.id { - case int: return io.write_string(w, "int") - case uint: return io.write_string(w, "uint") - case uintptr: return io.write_string(w, "uintptr") + case int: io.write_string(w, "int", &n) or_return + case uint: io.write_string(w, "uint", &n) or_return + case uintptr: io.write_string(w, "uintptr", &n) or_return case: - _n(io.write_byte(w, 'i' if info.signed else 'u'), &n) or_return - _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return + io.write_byte(w, 'i' if info.signed else 'u', &n) or_return + io.write_i64(w, i64(8*ti.size), 10, &n) or_return switch info.endianness { case .Platform: // Okay - case .Little: _n(io.write_string(w, "le"), &n) or_return - case .Big: _n(io.write_string(w, "be"), &n) or_return + case .Little: io.write_string(w, "le", &n) or_return + case .Big: io.write_string(w, "be", &n) or_return } } case Type_Info_Rune: - _n(io.write_string(w, "rune"), &n) or_return + io.write_string(w, "rune", &n) or_return case Type_Info_Float: - _n(io.write_byte(w, 'f'), &n) or_return - _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return + io.write_byte(w, 'f', &n) or_return + io.write_i64(w, i64(8*ti.size), 10, &n) or_return switch info.endianness { case .Platform: // Okay - case .Little: _n(io.write_string(w, "le"), &n) or_return - case .Big: _n(io.write_string(w, "be"), &n) or_return + case .Little: io.write_string(w, "le", &n) or_return + case .Big: io.write_string(w, "be", &n) or_return } case Type_Info_Complex: - _n(io.write_string(w, "complex"), &n) or_return - _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return + io.write_string(w, "complex", &n) or_return + io.write_i64(w, i64(8*ti.size), 10, &n) or_return case Type_Info_Quaternion: - _n(io.write_string(w, "quaternion"), &n) or_return - _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return + io.write_string(w, "quaternion", &n) or_return + io.write_i64(w, i64(8*ti.size), 10, &n) or_return case Type_Info_String: if info.is_cstring { - _n(io.write_string(w, "cstring"), &n) or_return + io.write_string(w, "cstring", &n) or_return } else { - _n(io.write_string(w, "string"), &n) or_return + io.write_string(w, "string", &n) or_return } case Type_Info_Boolean: switch ti.id { - case bool: _n(io.write_string(w, "bool"), &n) or_return + case bool: io.write_string(w, "bool", &n) or_return case: - _n(io.write_byte(w, 'b'), &n) or_return - _n(io.write_i64(w, i64(8*ti.size), 10), &n) or_return + io.write_byte(w, 'b', &n) or_return + io.write_i64(w, i64(8*ti.size), 10, &n) or_return } case Type_Info_Any: - _n(io.write_string(w, "any"), &n) or_return + io.write_string(w, "any", &n) or_return case Type_Info_Type_Id: - _n(io.write_string(w, "typeid"), &n) or_return + io.write_string(w, "typeid", &n) or_return case Type_Info_Pointer: if info.elem == nil { - return io.write_string(w, "rawptr") + io.write_string(w, "rawptr", &n) or_return } else { - _n(io.write_string(w, "^"), &n) or_return - return write_type(w, info.elem) + io.write_string(w, "^", &n) or_return + write_type(w, info.elem, &n) or_return } case Type_Info_Multi_Pointer: - _n(io.write_string(w, "[^]"), &n) or_return - return write_type(w, info.elem) + io.write_string(w, "[^]", &n) or_return + write_type(w, info.elem, &n) or_return case Type_Info_Procedure: - _n(io.write_string(w, "proc"), &n) or_return + io.write_string(w, "proc", &n) or_return if info.params == nil { - _n(io.write_string(w, "()"), &n) or_return + io.write_string(w, "()", &n) or_return } else { t := info.params.variant.(Type_Info_Tuple) - _n(io.write_string(w, "("), &n) or_return + io.write_string(w, "(", &n) or_return for t, i in t.types { if i > 0 { - _n(io.write_string(w, ", "), &n) or_return + io.write_string(w, ", ", &n) or_return } - _n(write_type(w, t), &n) or_return + write_type(w, t, &n) or_return } - _n(io.write_string(w, ")"), &n) or_return + io.write_string(w, ")", &n) or_return } if info.results != nil { - _n(io.write_string(w, " -> "), &n) or_return - _n(write_type(w, info.results), &n) or_return + io.write_string(w, " -> ", &n) or_return + write_type(w, info.results, &n) or_return } case Type_Info_Tuple: count := len(info.names) if count != 1 { - _n(io.write_string(w, "("), &n) or_return + io.write_string(w, "(", &n) or_return } for name, i in info.names { - if i > 0 { _n(io.write_string(w, ", "), &n) or_return } + if i > 0 { io.write_string(w, ", ", &n) or_return } t := info.types[i] if len(name) > 0 { - _n(io.write_string(w, name), &n) or_return - _n(io.write_string(w, ": "), &n) or_return + io.write_string(w, name, &n) or_return + io.write_string(w, ": ", &n) or_return } - _n(write_type(w, t), &n) or_return + write_type(w, t, &n) or_return } if count != 1 { - _n(io.write_string(w, ")"), &n) or_return + io.write_string(w, ")", &n) or_return } case Type_Info_Array: - _n(io.write_string(w, "["), &n) or_return - _n(io.write_i64(w, i64(info.count), 10), &n) or_return - _n(io.write_string(w, "]"), &n) or_return - _n(write_type(w, info.elem), &n) or_return + io.write_string(w, "[", &n) or_return + io.write_i64(w, i64(info.count), 10, &n) or_return + io.write_string(w, "]", &n) or_return + write_type(w, info.elem, &n) or_return case Type_Info_Enumerated_Array: - _n(io.write_string(w, "["), &n) or_return - _n(write_type(w, info.index), &n) or_return - _n(io.write_string(w, "]"), &n) or_return - _n(write_type(w, info.elem), &n) or_return + io.write_string(w, "[", &n) or_return + write_type(w, info.index, &n) or_return + io.write_string(w, "]", &n) or_return + write_type(w, info.elem, &n) or_return case Type_Info_Dynamic_Array: - _n(io.write_string(w, "[dynamic]"), &n) or_return - _n(write_type(w, info.elem), &n) or_return + io.write_string(w, "[dynamic]", &n) or_return + write_type(w, info.elem, &n) or_return case Type_Info_Slice: - _n(io.write_string(w, "[]"), &n) or_return - _n(write_type(w, info.elem), &n) or_return + io.write_string(w, "[]", &n) or_return + write_type(w, info.elem, &n) or_return case Type_Info_Map: - _n(io.write_string(w, "map["), &n) or_return - _n(write_type(w, info.key), &n) or_return - _n(io.write_byte(w, ']'), &n) or_return - _n(write_type(w, info.value), &n) or_return + io.write_string(w, "map[", &n) or_return + write_type(w, info.key, &n) or_return + io.write_byte(w, ']', &n) or_return + write_type(w, info.value, &n) or_return case Type_Info_Struct: switch info.soa_kind { case .None: // Ignore case .Fixed: - _n(io.write_string(w, "#soa["), &n) or_return - _n(io.write_i64(w, i64(info.soa_len)), &n) or_return - _n(io.write_byte(w, ']'), &n) or_return - _n(write_type(w, info.soa_base_type), &n) or_return + io.write_string(w, "#soa[", &n) or_return + io.write_i64(w, i64(info.soa_len), 10 &n) or_return + io.write_byte(w, ']', &n) or_return + write_type(w, info.soa_base_type, &n) or_return return case .Slice: - _n(io.write_string(w, "#soa[]"), &n) or_return - _n(write_type(w, info.soa_base_type), &n) or_return + io.write_string(w, "#soa[]", &n) or_return + write_type(w, info.soa_base_type, &n) or_return return case .Dynamic: - _n(io.write_string(w, "#soa[dynamic]"), &n) or_return - _n(write_type(w, info.soa_base_type), &n) or_return + io.write_string(w, "#soa[dynamic]", &n) or_return + write_type(w, info.soa_base_type, &n) or_return return } - _n(io.write_string(w, "struct "), &n) or_return - if info.is_packed { _n(io.write_string(w, "#packed "), &n) or_return } - if info.is_raw_union { _n(io.write_string(w, "#raw_union "), &n) or_return } + io.write_string(w, "struct ", &n) or_return + if info.is_packed { io.write_string(w, "#packed ", &n) or_return } + if info.is_raw_union { io.write_string(w, "#raw_union ", &n) or_return } if info.custom_align { - _n(io.write_string(w, "#align "), &n) or_return - _n(io.write_i64(w, i64(ti.align), 10), &n) or_return - _n(io.write_byte(w, ' '), &n) or_return + io.write_string(w, "#align ", &n) or_return + io.write_i64(w, i64(ti.align), 10, &n) or_return + io.write_byte(w, ' ', &n) or_return } - _n(io.write_byte(w, '{'), &n) or_return + io.write_byte(w, '{', &n) or_return for name, i in info.names { - if i > 0 { _n(io.write_string(w, ", "), &n) or_return } - _n(io.write_string(w, name), &n) or_return - _n(io.write_string(w, ": "), &n) or_return - _n(write_type(w, info.types[i]), &n) or_return + if i > 0 { io.write_string(w, ", ", &n) or_return } + io.write_string(w, name, &n) or_return + io.write_string(w, ": ", &n) or_return + write_type(w, info.types[i], &n) or_return } - _n(io.write_byte(w, '}'), &n) or_return + io.write_byte(w, '}', &n) or_return case Type_Info_Union: - _n(io.write_string(w, "union "), &n) or_return + io.write_string(w, "union ", &n) or_return if info.maybe { - _n(io.write_string(w, "#maybe "), &n) or_return + io.write_string(w, "#maybe ", &n) or_return } if info.custom_align { - _n(io.write_string(w, "#align "), &n) or_return - _n(io.write_i64(w, i64(ti.align), 10), &n) or_return - _n(io.write_byte(w, ' '), &n) or_return + io.write_string(w, "#align ", &n) or_return + io.write_i64(w, i64(ti.align), 10, &n) or_return + io.write_byte(w, ' ', &n) or_return } - _n(io.write_byte(w, '{'), &n) or_return + io.write_byte(w, '{', &n) or_return for variant, i in info.variants { - if i > 0 { _n(io.write_string(w, ", "), &n) or_return } - _n(write_type(w, variant), &n) or_return + if i > 0 { io.write_string(w, ", ", &n) or_return } + write_type(w, variant, &n) or_return } - _n(io.write_byte(w, '}'), &n) or_return + io.write_byte(w, '}', &n) or_return case Type_Info_Enum: - _n(io.write_string(w, "enum "), &n) or_return - _n(write_type(w, info.base), &n) or_return - _n(io.write_string(w, " {"), &n) or_return + io.write_string(w, "enum ", &n) or_return + write_type(w, info.base, &n) or_return + io.write_string(w, " {", &n) or_return for name, i in info.names { - if i > 0 { _n(io.write_string(w, ", "), &n) or_return } - _n(io.write_string(w, name), &n) or_return + if i > 0 { io.write_string(w, ", ", &n) or_return } + io.write_string(w, name, &n) or_return } - _n(io.write_byte(w, '}'), &n) or_return + io.write_byte(w, '}', &n) or_return case Type_Info_Bit_Set: - _n(io.write_string(w, "bit_set["), &n) or_return + io.write_string(w, "bit_set[", &n) or_return switch { case is_enum(info.elem): - _n(write_type(w, info.elem), &n) or_return + write_type(w, info.elem, &n) or_return case is_rune(info.elem): - _n(io.write_encoded_rune(w, rune(info.lower)), &n) or_return - _n(io.write_string(w, ".."), &n) or_return - _n(io.write_encoded_rune(w, rune(info.upper)), &n) or_return + io.write_encoded_rune(w, rune(info.lower), true, &n) or_return + io.write_string(w, "..", &n) or_return + io.write_encoded_rune(w, rune(info.upper), true, &n) or_return case: - _n(io.write_i64(w, info.lower, 10), &n) or_return - _n(io.write_string(w, ".."), &n) or_return - _n(io.write_i64(w, info.upper, 10), &n) or_return + io.write_i64(w, info.lower, 10, &n) or_return + io.write_string(w, "..", &n) or_return + io.write_i64(w, info.upper, 10, &n) or_return } if info.underlying != nil { - _n(io.write_string(w, "; "), &n) or_return - _n(write_type(w, info.underlying), &n) or_return + io.write_string(w, "; ", &n) or_return + write_type(w, info.underlying, &n) or_return } - _n(io.write_byte(w, ']'), &n) or_return + io.write_byte(w, ']', &n) or_return case Type_Info_Simd_Vector: - _n(io.write_string(w, "#simd["), &n) or_return - _n(io.write_i64(w, i64(info.count)), &n) or_return - _n(io.write_byte(w, ']'), &n) or_return - _n(write_type(w, info.elem), &n) or_return + io.write_string(w, "#simd[", &n) or_return + io.write_i64(w, i64(info.count), 10, &n) or_return + io.write_byte(w, ']', &n) or_return + write_type(w, info.elem, &n) or_return case Type_Info_Relative_Pointer: - _n(io.write_string(w, "#relative("), &n) or_return - _n(write_type(w, info.base_integer), &n) or_return - _n(io.write_string(w, ") "), &n) or_return - _n(write_type(w, info.pointer), &n) or_return + io.write_string(w, "#relative(", &n) or_return + write_type(w, info.base_integer, &n) or_return + io.write_string(w, ") ", &n) or_return + write_type(w, info.pointer, &n) or_return case Type_Info_Relative_Slice: - _n(io.write_string(w, "#relative("), &n) or_return - _n(write_type(w, info.base_integer), &n) or_return - _n(io.write_string(w, ") "), &n) or_return - _n(write_type(w, info.slice), &n) or_return + io.write_string(w, "#relative(", &n) or_return + write_type(w, info.base_integer, &n) or_return + io.write_string(w, ") ", &n) or_return + write_type(w, info.slice, &n) or_return } return