| ... | @@ -117,7 +117,7 @@ pub fn formatType( | ... | @@ -117,7 +117,7 @@ pub fn formatType( |
| 117 | return output(context, @errorName(value)); | 117 | return output(context, @errorName(value)); |
| 118 | } | 118 | } |
| 119 | switch (@typeInfo(T)) { | 119 | switch (@typeInfo(T)) { |
| 120 | builtin.TypeId.Int, builtin.TypeId.Float => { | 120 | builtin.TypeId.ComptimeInt, builtin.TypeId.Int, builtin.TypeId.Float => { |
| 121 | return formatValue(value, fmt, context, Errors, output); | 121 | return formatValue(value, fmt, context, Errors, output); |
| 122 | }, | 122 | }, |
| 123 | builtin.TypeId.Void => { | 123 | builtin.TypeId.Void => { |
| ... | @@ -268,11 +268,15 @@ fn formatValue( | ... | @@ -268,11 +268,15 @@ fn formatValue( |
| 268 | } | 268 | } |
| 269 | } | 269 | } |
| 270 | | 270 | |
| 271 | comptime var T = @typeOf(value); | 271 | const T = @typeOf(value); |
| 272 | switch (@typeId(T)) { | 272 | switch (@typeId(T)) { |
| 273 | builtin.TypeId.Float => return formatFloatValue(value, fmt, context, Errors, output), | 273 | builtin.TypeId.Float => return formatFloatValue(value, fmt, context, Errors, output), |
| 274 | builtin.TypeId.Int => return formatIntValue(value, fmt, context, Errors, output), | 274 | builtin.TypeId.Int => return formatIntValue(value, fmt, context, Errors, output), |
| 275 | else => unreachable, | 275 | builtin.TypeId.ComptimeInt => { |
| | 276 | const Int = math.IntFittingRange(value, value); |
| | 277 | return formatIntValue(Int(value), fmt, context, Errors, output); |
| | 278 | }, |
| | 279 | else => comptime unreachable, |
| 276 | } | 280 | } |
| 277 | } | 281 | } |
| 278 | | 282 | |
| ... | @@ -289,9 +293,10 @@ pub fn formatIntValue( | ... | @@ -289,9 +293,10 @@ pub fn formatIntValue( |
| 289 | if (fmt.len > 0) { | 293 | if (fmt.len > 0) { |
| 290 | switch (fmt[0]) { | 294 | switch (fmt[0]) { |
| 291 | 'c' => { | 295 | 'c' => { |
| 292 | if (@typeOf(value) == u8) { | 296 | if (@typeOf(value).bit_count <= 8) { |
| 293 | if (fmt.len > 1) @compileError("Unknown format character: " ++ []u8{fmt[1]}); | 297 | if (fmt.len > 1) |
| 294 | return formatAsciiChar(value, context, Errors, output); | 298 | @compileError("Unknown format character: " ++ []u8{fmt[1]}); |
| | 299 | return formatAsciiChar(u8(value), context, Errors, output); |
| 295 | } | 300 | } |
| 296 | }, | 301 | }, |
| 297 | 'b' => { | 302 | 'b' => { |
| ... | @@ -964,6 +969,25 @@ test "fmt.format" { | ... | @@ -964,6 +969,25 @@ test "fmt.format" { |
| 964 | const value: u8 = 0b1100; | 969 | const value: u8 = 0b1100; |
| 965 | try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", value); | 970 | try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", value); |
| 966 | } | 971 | } |
| | 972 | { |
| | 973 | var buf1: [32]u8 = undefined; |
| | 974 | var context = BufPrintContext{ .remaining = buf1[0..] }; |
| | 975 | try formatType(1234, "", &context, error{BufferTooSmall}, bufPrintWrite); |
| | 976 | var res = buf1[0 .. buf1.len - context.remaining.len]; |
| | 977 | assert(mem.eql(u8, res, "1234")); |
| | 978 | |
| | 979 | context = BufPrintContext{ .remaining = buf1[0..] }; |
| | 980 | try formatType('a', "c", &context, error{BufferTooSmall}, bufPrintWrite); |
| | 981 | res = buf1[0 .. buf1.len - context.remaining.len]; |
| | 982 | debug.warn("{}\n", res); |
| | 983 | assert(mem.eql(u8, res, "a")); |
| | 984 | |
| | 985 | context = BufPrintContext{ .remaining = buf1[0..] }; |
| | 986 | try formatType(0b1100, "b", &context, error{BufferTooSmall}, bufPrintWrite); |
| | 987 | res = buf1[0 .. buf1.len - context.remaining.len]; |
| | 988 | debug.warn("{}\n", res); |
| | 989 | assert(mem.eql(u8, res, "1100")); |
| | 990 | } |
| 967 | { | 991 | { |
| 968 | const value: [3]u8 = "abc"; | 992 | const value: [3]u8 = "abc"; |
| 969 | try testFmt("array: abc\n", "array: {}\n", value); | 993 | try testFmt("array: abc\n", "array: {}\n", value); |
| ... | @@ -985,6 +1009,10 @@ test "fmt.format" { | ... | @@ -985,6 +1009,10 @@ test "fmt.format" { |
| 985 | try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", value); | 1009 | try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", value); |
| 986 | try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", value); | 1010 | try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", value); |
| 987 | } | 1011 | } |
| | 1012 | { |
| | 1013 | const value = @intToPtr(fn () void, 0xdeadbeef); |
| | 1014 | try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value); |
| | 1015 | } |
| 988 | try testFmt("buf: Test \n", "buf: {s5}\n", "Test"); | 1016 | try testFmt("buf: Test \n", "buf: {s5}\n", "Test"); |
| 989 | try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", "Test"); | 1017 | try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", "Test"); |
| 990 | try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C"); | 1018 | try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C"); |