mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-22 04:20:35 +00:00
Begin work on %w - 'w'rite as valid Odin literals
This commit is contained in:
@@ -972,7 +972,7 @@ fmt_bad_verb :: proc(fi: ^Info, verb: rune) {
|
||||
//
|
||||
fmt_bool :: proc(fi: ^Info, b: bool, verb: rune) {
|
||||
switch verb {
|
||||
case 't', 'v':
|
||||
case 't', 'v', 'w':
|
||||
fmt_string(fi, b ? "true" : "false", 's')
|
||||
case:
|
||||
fmt_bad_verb(fi, verb)
|
||||
@@ -1209,7 +1209,7 @@ fmt_rune :: proc(fi: ^Info, r: rune, verb: rune) {
|
||||
switch verb {
|
||||
case 'c', 'r', 'v':
|
||||
io.write_rune(fi.writer, r, &fi.n)
|
||||
case 'q':
|
||||
case 'q', 'w':
|
||||
fi.n += io.write_quoted_rune(fi.writer, r)
|
||||
case:
|
||||
fmt_int(fi, u64(r), false, 32, verb)
|
||||
@@ -1226,7 +1226,8 @@ fmt_rune :: proc(fi: ^Info, r: rune, verb: rune) {
|
||||
//
|
||||
fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) {
|
||||
switch verb {
|
||||
case 'v': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'v', 'w':
|
||||
_fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'b': _fmt_int(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'o': _fmt_int(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'i', 'd': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||
@@ -1261,7 +1262,8 @@ fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) {
|
||||
//
|
||||
fmt_int_128 :: proc(fi: ^Info, u: u128, is_signed: bool, bit_size: int, verb: rune) {
|
||||
switch verb {
|
||||
case 'v': _fmt_int_128(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'v', 'w':
|
||||
_fmt_int_128(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'b': _fmt_int_128(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'o': _fmt_int_128(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER)
|
||||
case 'i', 'd': _fmt_int_128(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||
@@ -1351,7 +1353,7 @@ _fmt_float_as :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune, float_fmt: b
|
||||
//
|
||||
fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
|
||||
switch verb {
|
||||
case 'g', 'G', 'v':
|
||||
case 'g', 'G', 'v', 'w':
|
||||
_fmt_float_as(fi, v, bit_size, verb, 'g', -1)
|
||||
case 'f', 'F':
|
||||
_fmt_float_as(fi, v, bit_size, verb, 'f', 3)
|
||||
@@ -1424,7 +1426,7 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) {
|
||||
io.write_string(fi.writer, s, &fi.n)
|
||||
}
|
||||
|
||||
case 'q': // quoted string
|
||||
case 'q', 'w': // quoted string
|
||||
io.write_quoted_string(fi.writer, s, '"', &fi.n)
|
||||
|
||||
case 'x', 'X':
|
||||
@@ -1467,7 +1469,7 @@ fmt_cstring :: proc(fi: ^Info, s: cstring, verb: rune) {
|
||||
fmt_pointer :: proc(fi: ^Info, p: rawptr, verb: rune) {
|
||||
u := u64(uintptr(p))
|
||||
switch verb {
|
||||
case 'p', 'v':
|
||||
case 'p', 'v', 'w':
|
||||
if !fi.hash && verb == 'v' {
|
||||
io.write_string(fi.writer, "0x", &fi.n)
|
||||
}
|
||||
@@ -1535,7 +1537,7 @@ string_to_enum_value :: proc($T: typeid, s: string) -> (T, bool) {
|
||||
// Inputs:
|
||||
// - fi: Pointer to the Info struct containing format settings.
|
||||
// - v: The enum value to format.
|
||||
// - verb: The format specifier character (e.g. 'i','d','f','s','v','q').
|
||||
// - verb: The format specifier character (e.g. 'i','d','f','s','v','q','w').
|
||||
//
|
||||
fmt_enum :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
if v.id == nil || v.data == nil {
|
||||
@@ -1559,6 +1561,15 @@ fmt_enum :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, 'i')
|
||||
io.write_string(fi.writer, ")", &fi.n)
|
||||
}
|
||||
case 'w':
|
||||
if str, ok := enum_value_to_string(v); ok {
|
||||
io.write_byte(fi.writer, '.', &fi.n)
|
||||
io.write_string(fi.writer, str, &fi.n)
|
||||
} else {
|
||||
io.write_string(fi.writer, "%!(BAD ENUM VALUE=", &fi.n)
|
||||
fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, 'i')
|
||||
io.write_string(fi.writer, ")", &fi.n)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1747,8 +1758,8 @@ fmt_write_indent :: proc(fi: ^Info) {
|
||||
// - verb: The formatting verb to be used for the array elements.
|
||||
//
|
||||
fmt_write_array :: proc(fi: ^Info, array_data: rawptr, count: int, elem_size: int, elem_id: typeid, verb: rune) {
|
||||
io.write_byte(fi.writer, '[', &fi.n)
|
||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
||||
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||
defer io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||
|
||||
if count <= 0 {
|
||||
return
|
||||
@@ -1821,6 +1832,13 @@ handle_tag :: proc(data: rawptr, info: reflect.Type_Info_Struct, idx: int, verb:
|
||||
r, w := utf8.decode_rune_in_string(value)
|
||||
value = value[w:]
|
||||
if value == "" || value[0] == ',' {
|
||||
if verb^ == 'w' {
|
||||
// TODO(bill): is this a good idea overriding that field tags if 'w' is used?
|
||||
switch r {
|
||||
case 's': r = 'q'
|
||||
case: r = 'w'
|
||||
}
|
||||
}
|
||||
verb^ = r
|
||||
if len(value) > 0 && value[0] == ',' {
|
||||
field_name := value[1:]
|
||||
@@ -1832,7 +1850,7 @@ handle_tag :: proc(data: rawptr, info: reflect.Type_Info_Struct, idx: int, verb:
|
||||
switch r {
|
||||
case 's', 'q':
|
||||
handle_optional_len(data, info, field_name, optional_len)
|
||||
case 'v':
|
||||
case 'v', 'w':
|
||||
#partial switch reflect.type_kind(info.types[idx].id) {
|
||||
case .String, .Multi_Pointer, .Array, .Slice, .Dynamic_Array:
|
||||
handle_optional_len(data, info, field_name, optional_len)
|
||||
@@ -1854,7 +1872,7 @@ handle_tag :: proc(data: rawptr, info: reflect.Type_Info_Struct, idx: int, verb:
|
||||
// - type_name: The name of the type being formatted
|
||||
//
|
||||
fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_Struct, type_name: string) {
|
||||
if the_verb != 'v' {
|
||||
if the_verb != 'v' && the_verb != 'w' {
|
||||
fmt_bad_verb(fi, the_verb)
|
||||
return
|
||||
}
|
||||
@@ -1871,7 +1889,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
|
||||
is_soa := info.soa_kind != .None
|
||||
|
||||
io.write_string(fi.writer, type_name, &fi.n)
|
||||
io.write_byte(fi.writer, '[' if is_soa else '{', &fi.n)
|
||||
io.write_byte(fi.writer, '[' if is_soa && the_verb == 'v' else '{', &fi.n)
|
||||
fi.record_level += 1
|
||||
defer fi.record_level -= 1
|
||||
|
||||
@@ -1889,7 +1907,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
|
||||
if hash {
|
||||
for _ in 0..<indent { io.write_byte(fi.writer, '\t', &fi.n) }
|
||||
}
|
||||
io.write_byte(fi.writer, ']' if is_soa else '}', &fi.n)
|
||||
io.write_byte(fi.writer, ']' if is_soa && the_verb == 'v' else '}', &fi.n)
|
||||
}
|
||||
|
||||
if is_soa {
|
||||
@@ -1972,7 +1990,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
|
||||
for name, i in info.names {
|
||||
optional_len: int = -1
|
||||
use_nul_termination: bool = false
|
||||
verb := 'v'
|
||||
verb := the_verb if the_verb == 'w' else 'v'
|
||||
if handle_tag(v.data, info, i, &verb, &optional_len, &use_nul_termination) {
|
||||
continue
|
||||
}
|
||||
@@ -2051,7 +2069,7 @@ fmt_array_nul_terminated :: proc(fi: ^Info, data: rawptr, max_n: int, elem_size:
|
||||
// - n: The number of elements in the array.
|
||||
// - elem_size: The size of each element in the array.
|
||||
// - elem: Pointer to the type information of the array element.
|
||||
// - verb: The formatting verb (e.g. 's','q','p').
|
||||
// - verb: The formatting verb (e.g. 's','q','p','w').
|
||||
//
|
||||
fmt_array :: proc(fi: ^Info, data: rawptr, n: int, elem_size: int, elem: ^reflect.Type_Info, verb: rune) {
|
||||
if data == nil && n > 0 {
|
||||
@@ -2130,141 +2148,143 @@ fmt_named :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Named)
|
||||
}
|
||||
|
||||
// Built-in Custom Formatters for core library types
|
||||
switch a in v {
|
||||
case runtime.Source_Code_Location:
|
||||
io.write_string(fi.writer, a.file_path, &fi.n)
|
||||
if verb != 'w' {
|
||||
switch a in v {
|
||||
case runtime.Source_Code_Location:
|
||||
io.write_string(fi.writer, a.file_path, &fi.n)
|
||||
|
||||
when ODIN_ERROR_POS_STYLE == .Default {
|
||||
io.write_byte(fi.writer, '(', &fi.n)
|
||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ')', &fi.n)
|
||||
} else when ODIN_ERROR_POS_STYLE == .Unix {
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
} else {
|
||||
#panic("Unhandled ODIN_ERROR_POS_STYLE")
|
||||
}
|
||||
return
|
||||
|
||||
case time.Duration:
|
||||
ffrac :: proc(buf: []byte, v: u64, prec: int) -> (nw: int, nv: u64) {
|
||||
v := v
|
||||
w := len(buf)
|
||||
print := false
|
||||
for _ in 0..<prec {
|
||||
digit := v % 10
|
||||
print = print || digit != 0
|
||||
if print {
|
||||
w -= 1
|
||||
buf[w] = byte(digit) + '0'
|
||||
}
|
||||
v /= 10
|
||||
}
|
||||
if print {
|
||||
w -= 1
|
||||
buf[w] = '.'
|
||||
}
|
||||
return w, v
|
||||
}
|
||||
fint :: proc(buf: []byte, v: u64) -> int {
|
||||
v := v
|
||||
w := len(buf)
|
||||
if v == 0 {
|
||||
w -= 1
|
||||
buf[w] = '0'
|
||||
when ODIN_ERROR_POS_STYLE == .Default {
|
||||
io.write_byte(fi.writer, '(', &fi.n)
|
||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ')', &fi.n)
|
||||
} else when ODIN_ERROR_POS_STYLE == .Unix {
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
} else {
|
||||
for v > 0 {
|
||||
w -= 1
|
||||
buf[w] = byte(v%10) + '0'
|
||||
#panic("Unhandled ODIN_ERROR_POS_STYLE")
|
||||
}
|
||||
return
|
||||
|
||||
case time.Duration:
|
||||
ffrac :: proc(buf: []byte, v: u64, prec: int) -> (nw: int, nv: u64) {
|
||||
v := v
|
||||
w := len(buf)
|
||||
print := false
|
||||
for _ in 0..<prec {
|
||||
digit := v % 10
|
||||
print = print || digit != 0
|
||||
if print {
|
||||
w -= 1
|
||||
buf[w] = byte(digit) + '0'
|
||||
}
|
||||
v /= 10
|
||||
}
|
||||
if print {
|
||||
w -= 1
|
||||
buf[w] = '.'
|
||||
}
|
||||
return w, v
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
buf: [32]byte
|
||||
w := len(buf)
|
||||
u := u64(a)
|
||||
neg := a < 0
|
||||
if neg {
|
||||
u = -u
|
||||
}
|
||||
|
||||
if u < u64(time.Second) {
|
||||
prec: int
|
||||
w -= 1
|
||||
buf[w] = 's'
|
||||
w -= 1
|
||||
switch {
|
||||
case u == 0:
|
||||
io.write_string(fi.writer, "0s", &fi.n)
|
||||
return
|
||||
case u < u64(time.Microsecond):
|
||||
prec = 0
|
||||
buf[w] = 'n'
|
||||
case u < u64(time.Millisecond):
|
||||
prec = 3
|
||||
// U+00B5 'µ' micro sign == 0xC2 0xB5
|
||||
w -= 1 // Need room for two bytes
|
||||
copy(buf[w:], "µ")
|
||||
case:
|
||||
prec = 6
|
||||
buf[w] = 'm'
|
||||
fint :: proc(buf: []byte, v: u64) -> int {
|
||||
v := v
|
||||
w := len(buf)
|
||||
if v == 0 {
|
||||
w -= 1
|
||||
buf[w] = '0'
|
||||
} else {
|
||||
for v > 0 {
|
||||
w -= 1
|
||||
buf[w] = byte(v%10) + '0'
|
||||
v /= 10
|
||||
}
|
||||
}
|
||||
return w
|
||||
}
|
||||
w, u = ffrac(buf[:w], u, prec)
|
||||
w = fint(buf[:w], u)
|
||||
} else {
|
||||
w -= 1
|
||||
buf[w] = 's'
|
||||
w, u = ffrac(buf[:w], u, 9)
|
||||
w = fint(buf[:w], u%60)
|
||||
u /= 60
|
||||
if u > 0 {
|
||||
|
||||
buf: [32]byte
|
||||
w := len(buf)
|
||||
u := u64(a)
|
||||
neg := a < 0
|
||||
if neg {
|
||||
u = -u
|
||||
}
|
||||
|
||||
if u < u64(time.Second) {
|
||||
prec: int
|
||||
w -= 1
|
||||
buf[w] = 'm'
|
||||
buf[w] = 's'
|
||||
w -= 1
|
||||
switch {
|
||||
case u == 0:
|
||||
io.write_string(fi.writer, "0s", &fi.n)
|
||||
return
|
||||
case u < u64(time.Microsecond):
|
||||
prec = 0
|
||||
buf[w] = 'n'
|
||||
case u < u64(time.Millisecond):
|
||||
prec = 3
|
||||
// U+00B5 'µ' micro sign == 0xC2 0xB5
|
||||
w -= 1 // Need room for two bytes
|
||||
copy(buf[w:], "µ")
|
||||
case:
|
||||
prec = 6
|
||||
buf[w] = 'm'
|
||||
}
|
||||
w, u = ffrac(buf[:w], u, prec)
|
||||
w = fint(buf[:w], u)
|
||||
} else {
|
||||
w -= 1
|
||||
buf[w] = 's'
|
||||
w, u = ffrac(buf[:w], u, 9)
|
||||
w = fint(buf[:w], u%60)
|
||||
u /= 60
|
||||
if u > 0 {
|
||||
w -= 1
|
||||
buf[w] = 'h'
|
||||
w = fint(buf[:w], u)
|
||||
buf[w] = 'm'
|
||||
w = fint(buf[:w], u%60)
|
||||
u /= 60
|
||||
if u > 0 {
|
||||
w -= 1
|
||||
buf[w] = 'h'
|
||||
w = fint(buf[:w], u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if neg {
|
||||
w -= 1
|
||||
buf[w] = '-'
|
||||
}
|
||||
io.write_string(fi.writer, string(buf[w:]), &fi.n)
|
||||
return
|
||||
|
||||
case time.Time:
|
||||
t := a
|
||||
y, mon, d := time.date(t)
|
||||
h, min, s := time.clock(t)
|
||||
ns := (t._nsec - (t._nsec/1e9 + time.UNIX_TO_ABSOLUTE)*1e9) % 1e9
|
||||
write_padded_number(fi, i64(y), 4)
|
||||
io.write_byte(fi.writer, '-', &fi.n)
|
||||
write_padded_number(fi, i64(mon), 2)
|
||||
io.write_byte(fi.writer, '-', &fi.n)
|
||||
write_padded_number(fi, i64(d), 2)
|
||||
io.write_byte(fi.writer, ' ', &fi.n)
|
||||
|
||||
write_padded_number(fi, i64(h), 2)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
write_padded_number(fi, i64(min), 2)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
write_padded_number(fi, i64(s), 2)
|
||||
io.write_byte(fi.writer, '.', &fi.n)
|
||||
write_padded_number(fi, (ns), 9)
|
||||
io.write_string(fi.writer, " +0000 UTC", &fi.n)
|
||||
return
|
||||
}
|
||||
|
||||
if neg {
|
||||
w -= 1
|
||||
buf[w] = '-'
|
||||
}
|
||||
io.write_string(fi.writer, string(buf[w:]), &fi.n)
|
||||
return
|
||||
|
||||
case time.Time:
|
||||
t := a
|
||||
y, mon, d := time.date(t)
|
||||
h, min, s := time.clock(t)
|
||||
ns := (t._nsec - (t._nsec/1e9 + time.UNIX_TO_ABSOLUTE)*1e9) % 1e9
|
||||
write_padded_number(fi, i64(y), 4)
|
||||
io.write_byte(fi.writer, '-', &fi.n)
|
||||
write_padded_number(fi, i64(mon), 2)
|
||||
io.write_byte(fi.writer, '-', &fi.n)
|
||||
write_padded_number(fi, i64(d), 2)
|
||||
io.write_byte(fi.writer, ' ', &fi.n)
|
||||
|
||||
write_padded_number(fi, i64(h), 2)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
write_padded_number(fi, i64(min), 2)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
write_padded_number(fi, i64(s), 2)
|
||||
io.write_byte(fi.writer, '.', &fi.n)
|
||||
write_padded_number(fi, (ns), 9)
|
||||
io.write_string(fi.writer, " +0000 UTC", &fi.n)
|
||||
return
|
||||
}
|
||||
|
||||
#partial switch b in info.base.variant {
|
||||
@@ -2275,6 +2295,23 @@ fmt_named :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Named)
|
||||
case runtime.Type_Info_Bit_Set:
|
||||
fmt_bit_set(fi, v, verb = verb)
|
||||
case:
|
||||
if verb == 'w' {
|
||||
#partial switch b in info.base.variant {
|
||||
case runtime.Type_Info_Array,
|
||||
runtime.Type_Info_Enumerated_Array,
|
||||
runtime.Type_Info_Dynamic_Array,
|
||||
runtime.Type_Info_Slice,
|
||||
runtime.Type_Info_Struct,
|
||||
runtime.Type_Info_Union,
|
||||
runtime.Type_Info_Enum,
|
||||
runtime.Type_Info_Map,
|
||||
runtime.Type_Info_Bit_Set,
|
||||
runtime.Type_Info_Simd_Vector,
|
||||
runtime.Type_Info_Matrix,
|
||||
runtime.Type_Info_Bit_Field:
|
||||
io.write_string(fi.writer, info.name, &fi.n)
|
||||
}
|
||||
}
|
||||
fmt_value(fi, any{v.data, info.base.id}, verb)
|
||||
}
|
||||
}
|
||||
@@ -2341,8 +2378,13 @@ fmt_union :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Union,
|
||||
// - info: A runtime.Type_Info_Matrix struct containing matrix type information.
|
||||
//
|
||||
fmt_matrix :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Matrix) {
|
||||
io.write_string(fi.writer, "matrix[", &fi.n)
|
||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
||||
if verb == 'w' {
|
||||
io.write_byte(fi.writer, '{', &fi.n)
|
||||
} else {
|
||||
io.write_string(fi.writer, "matrix", &fi.n)
|
||||
io.write_byte(fi.writer, '[', &fi.n)
|
||||
}
|
||||
defer io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||
|
||||
fi.indent += 1
|
||||
|
||||
@@ -2413,8 +2455,8 @@ fmt_bit_field :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Bit
|
||||
return false
|
||||
}
|
||||
|
||||
io.write_string(fi.writer, type_name if len(type_name) != 0 else "bit_field", &fi.n)
|
||||
io.write_string(fi.writer, "{", &fi.n)
|
||||
io.write_string(fi.writer, type_name if len(type_name) != 0 || verb == 'w' else "bit_field", &fi.n)
|
||||
io.write_byte(fi.writer, '{', &fi.n)
|
||||
|
||||
hash := fi.hash; defer fi.hash = hash
|
||||
indent := fi.indent; defer fi.indent -= 1
|
||||
@@ -2631,11 +2673,12 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
defer fi.record_level -= 1
|
||||
|
||||
if fi.hash {
|
||||
io.write_string(fi.writer, "[\n", &fi.n)
|
||||
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||
io.write_byte(fi.writer, '\n', &fi.n)
|
||||
defer {
|
||||
io.write_byte(fi.writer, '\n', &fi.n)
|
||||
fmt_write_indent(fi)
|
||||
io.write_byte(fi.writer, ']', &fi.n)
|
||||
io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||
}
|
||||
indent := fi.indent
|
||||
fi.indent += 1
|
||||
@@ -2659,8 +2702,8 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
io.write_string(fi.writer, ",\n", &fi.n)
|
||||
}
|
||||
} else {
|
||||
io.write_byte(fi.writer, '[', &fi.n)
|
||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
||||
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||
io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||
for i in 0..<info.count {
|
||||
if i > 0 { io.write_string(fi.writer, ", ", &fi.n) }
|
||||
|
||||
@@ -2725,38 +2768,42 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
|
||||
|
||||
case runtime.Type_Info_Map:
|
||||
if verb != 'v' {
|
||||
switch verb {
|
||||
case:
|
||||
fmt_bad_verb(fi, verb)
|
||||
return
|
||||
}
|
||||
|
||||
io.write_string(fi.writer, "map[", &fi.n)
|
||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
||||
fi.record_level += 1
|
||||
defer fi.record_level -= 1
|
||||
|
||||
m := (^mem.Raw_Map)(v.data)
|
||||
if m != nil {
|
||||
if info.map_info == nil {
|
||||
return
|
||||
case 'v', 'w':
|
||||
if verb == 'v' {
|
||||
io.write_string(fi.writer, "map", &fi.n)
|
||||
}
|
||||
map_cap := uintptr(runtime.map_cap(m^))
|
||||
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(m^, info.map_info)
|
||||
j := 0
|
||||
for bucket_index in 0..<map_cap {
|
||||
runtime.map_hash_is_valid(hs[bucket_index]) or_continue
|
||||
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||
defer io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||
|
||||
if j > 0 {
|
||||
io.write_string(fi.writer, ", ", &fi.n)
|
||||
fi.record_level += 1
|
||||
defer fi.record_level -= 1
|
||||
|
||||
m := (^mem.Raw_Map)(v.data)
|
||||
if m != nil {
|
||||
if info.map_info == nil {
|
||||
return
|
||||
}
|
||||
j += 1
|
||||
map_cap := uintptr(runtime.map_cap(m^))
|
||||
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(m^, info.map_info)
|
||||
j := 0
|
||||
for bucket_index in 0..<map_cap {
|
||||
runtime.map_hash_is_valid(hs[bucket_index]) or_continue
|
||||
|
||||
key := runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index)
|
||||
value := runtime.map_cell_index_dynamic(vs, info.map_info.vs, bucket_index)
|
||||
if j > 0 {
|
||||
io.write_string(fi.writer, ", ", &fi.n)
|
||||
}
|
||||
j += 1
|
||||
|
||||
fmt_arg(&Info{writer = fi.writer}, any{rawptr(key), info.key.id}, 'v')
|
||||
io.write_string(fi.writer, "=", &fi.n)
|
||||
fmt_arg(fi, any{rawptr(value), info.value.id}, 'v')
|
||||
key := runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index)
|
||||
value := runtime.map_cell_index_dynamic(vs, info.map_info.vs, bucket_index)
|
||||
|
||||
fmt_arg(&Info{writer = fi.writer}, any{rawptr(key), info.key.id}, verb)
|
||||
io.write_string(fi.writer, "=", &fi.n)
|
||||
fmt_arg(fi, any{rawptr(value), info.value.id}, verb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2811,11 +2858,11 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
// - fi: A pointer to an Info struct containing formatting information.
|
||||
// - c: The complex128 value to be formatted.
|
||||
// - bits: The number of bits in the complex number (32 or 64).
|
||||
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H').
|
||||
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H', 'w').
|
||||
//
|
||||
fmt_complex :: proc(fi: ^Info, c: complex128, bits: int, verb: rune) {
|
||||
switch verb {
|
||||
case 'f', 'F', 'v', 'h', 'H':
|
||||
case 'f', 'F', 'v', 'h', 'H', 'w':
|
||||
r, i := real(c), imag(c)
|
||||
fmt_float(fi, r, bits/2, verb)
|
||||
if !fi.plus && i >= 0 {
|
||||
@@ -2835,11 +2882,11 @@ fmt_complex :: proc(fi: ^Info, c: complex128, bits: int, verb: rune) {
|
||||
// - fi: A pointer to an Info struct containing formatting information.
|
||||
// - q: The quaternion256 value to be formatted.
|
||||
// - bits: The number of bits in the quaternion number (64, 128, or 256).
|
||||
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H').
|
||||
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H', 'w').
|
||||
//
|
||||
fmt_quaternion :: proc(fi: ^Info, q: quaternion256, bits: int, verb: rune) {
|
||||
switch verb {
|
||||
case 'f', 'F', 'v', 'h', 'H':
|
||||
case 'f', 'F', 'v', 'h', 'H', 'w':
|
||||
r, i, j, k := real(q), imag(q), jmag(q), kmag(q)
|
||||
|
||||
fmt_float(fi, r, bits/4, verb)
|
||||
|
||||
Reference in New Issue
Block a user