authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-04-20 16:53:59-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-20 17:08:05-04:00
logb4aec0e31db2c9ea7bc2c892f0e557a0de8f4735
treec0c804d4b2165d255dec74e297edddbf9fdf3b40
parent6b944492b5f35ce61591e1231dc6c8d44ccf17e3

stage2: make std.fmt.parseInt ignore `_`


2 files changed, 12 insertions(+), 0 deletions(-)

lib/std/fmt.zig+11
...@@ -1358,6 +1358,7 @@ pub fn Formatter(comptime format_fn: anytype) type {...@@ -1358,6 +1358,7 @@ pub fn Formatter(comptime format_fn: anytype) type {
1358/// * A prefix of "0x" implies radix=16,1358/// * A prefix of "0x" implies radix=16,
1359/// * Otherwise radix=10 is assumed.1359/// * Otherwise radix=10 is assumed.
1360///1360///
1361/// Ignores '_' character in `buf`.
1361/// See also `parseUnsigned`.1362/// See also `parseUnsigned`.
1362pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) ParseIntError!T {1363pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) ParseIntError!T {
1363 if (buf.len == 0) return error.InvalidCharacter;1364 if (buf.len == 0) return error.InvalidCharacter;
...@@ -1394,12 +1395,18 @@ test "parseInt" {...@@ -1394,12 +1395,18 @@ test "parseInt" {
13941395
1395 // autodectect the radix1396 // autodectect the radix
1396 std.testing.expect((try parseInt(i32, "111", 0)) == 111);1397 std.testing.expect((try parseInt(i32, "111", 0)) == 111);
1398 std.testing.expect((try parseInt(i32, "1_1_1", 0)) == 111);
1399 std.testing.expect((try parseInt(i32, "1_1_1", 0)) == 111);
1397 std.testing.expect((try parseInt(i32, "+0b111", 0)) == 7);1400 std.testing.expect((try parseInt(i32, "+0b111", 0)) == 7);
1401 std.testing.expect((try parseInt(i32, "+0b1_11", 0)) == 7);
1398 std.testing.expect((try parseInt(i32, "+0o111", 0)) == 73);1402 std.testing.expect((try parseInt(i32, "+0o111", 0)) == 73);
1403 std.testing.expect((try parseInt(i32, "+0o11_1", 0)) == 73);
1399 std.testing.expect((try parseInt(i32, "+0x111", 0)) == 273);1404 std.testing.expect((try parseInt(i32, "+0x111", 0)) == 273);
1400 std.testing.expect((try parseInt(i32, "-0b111", 0)) == -7);1405 std.testing.expect((try parseInt(i32, "-0b111", 0)) == -7);
1406 std.testing.expect((try parseInt(i32, "-0b11_1", 0)) == -7);
1401 std.testing.expect((try parseInt(i32, "-0o111", 0)) == -73);1407 std.testing.expect((try parseInt(i32, "-0o111", 0)) == -73);
1402 std.testing.expect((try parseInt(i32, "-0x111", 0)) == -273);1408 std.testing.expect((try parseInt(i32, "-0x111", 0)) == -273);
1409 std.testing.expect((try parseInt(i32, "-0x1_11", 0)) == -273);
14031410
1404 // bare binary/octal/decimal prefix is invalid1411 // bare binary/octal/decimal prefix is invalid
1405 std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0b", 0));1412 std.testing.expectError(error.InvalidCharacter, parseInt(u32, "0b", 0));
...@@ -1448,6 +1455,7 @@ fn parseWithSign(...@@ -1448,6 +1455,7 @@ fn parseWithSign(
1448 var x: T = 0;1455 var x: T = 0;
14491456
1450 for (buf_start) |c| {1457 for (buf_start) |c| {
1458 if (c == '_') continue;
1451 const digit = try charToDigit(c, buf_radix);1459 const digit = try charToDigit(c, buf_radix);
14521460
1453 if (x != 0) x = try math.mul(T, x, try math.cast(T, buf_radix));1461 if (x != 0) x = try math.mul(T, x, try math.cast(T, buf_radix));
...@@ -1466,6 +1474,7 @@ fn parseWithSign(...@@ -1466,6 +1474,7 @@ fn parseWithSign(
1466/// * A prefix of "0x" implies radix=16,1474/// * A prefix of "0x" implies radix=16,
1467/// * Otherwise radix=10 is assumed.1475/// * Otherwise radix=10 is assumed.
1468///1476///
1477/// Ignores '_' character in `buf`.
1469/// See also `parseInt`.1478/// See also `parseInt`.
1470pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseIntError!T {1479pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseIntError!T {
1471 return parseWithSign(T, buf, radix, .Pos);1480 return parseWithSign(T, buf, radix, .Pos);
...@@ -1474,9 +1483,11 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseIntError...@@ -1474,9 +1483,11 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseIntError
1474test "parseUnsigned" {1483test "parseUnsigned" {
1475 std.testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124);1484 std.testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124);
1476 std.testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535);1485 std.testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535);
1486 std.testing.expect((try parseUnsigned(u16, "65_535", 10)) == 65535);
1477 std.testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));1487 std.testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));
14781488
1479 std.testing.expect((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);1489 std.testing.expect((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);
1490 std.testing.expect((try parseUnsigned(u64, "0f_fff_fff_fff_fff_fff", 16)) == 0xffffffffffffffff);
1480 std.testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16));1491 std.testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16));
14811492
1482 std.testing.expect((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);1493 std.testing.expect((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);
src/AstGen.zig+1
...@@ -5111,6 +5111,7 @@ fn integerLiteral(...@@ -5111,6 +5111,7 @@ fn integerLiteral(
5111 };5111 };
5112 return rvalue(gz, scope, rl, result, node);5112 return rvalue(gz, scope, rl, result, node);
5113 } else |err| {5113 } else |err| {
5114 assert(err != error.InvalidCharacter);
5114 return gz.astgen.failNode(node, "TODO implement int literals that don't fit in a u64", .{});5115 return gz.astgen.failNode(node, "TODO implement int literals that don't fit in a u64", .{});
5115 }5116 }
5116}5117}