authorgravatar for 57862114+momumi@users.noreply.github.commomumi <57862114+momumi@users.noreply.github.com> 2020-03-22 13:45:31+10:00
committergravatar for 57862114+momumi@users.noreply.github.commomumi <57862114+momumi@users.noreply.github.com> 2020-03-22 13:59:14+10:00
log8de45e51438d7f593825ae2134ab7dfc46f3bab2
treeebf5cb2d0f7a6e43241e9755f0f84a33e9b29ffb
parent29324e6f393011ee010b80f2c88d946f082bef22

update parsing of int literals in self-hosted

* update std.math.big.Int.setString() to ignore underscores and make it case insensitive * fix issue in ir.zig with leading zeroes in integer literals

2 files changed, 28 insertions(+), 4 deletions(-)

lib/std/math/big/int.zig+23-2
...@@ -373,6 +373,7 @@ pub const Int = struct {...@@ -373,6 +373,7 @@ pub const Int = struct {
373 const d = switch (ch) {373 const d = switch (ch) {
374 '0'...'9' => ch - '0',374 '0'...'9' => ch - '0',
375 'a'...'f' => (ch - 'a') + 0xa,375 'a'...'f' => (ch - 'a') + 0xa,
376 'A'...'F' => (ch - 'A') + 0xa,
376 else => return error.InvalidCharForDigit,377 else => return error.InvalidCharForDigit,
377 };378 };
378379
...@@ -393,8 +394,9 @@ pub const Int = struct {...@@ -393,8 +394,9 @@ pub const Int = struct {
393394
394 /// Set self from the string representation `value`.395 /// Set self from the string representation `value`.
395 ///396 ///
396 /// value must contain only digits <= `base`. Base prefixes are not allowed (e.g. 0x43 should397 /// `value` must contain only digits <= `base` and is case insensitive. Base prefixes are
397 /// simply be 43).398 /// not allowed (e.g. 0x43 should simply be 43). Underscores in the input string are
399 /// ignored and can be used as digit separators.
398 ///400 ///
399 /// Returns an error if memory could not be allocated or `value` has invalid digits for the401 /// Returns an error if memory could not be allocated or `value` has invalid digits for the
400 /// requested base.402 /// requested base.
...@@ -415,6 +417,9 @@ pub const Int = struct {...@@ -415,6 +417,9 @@ pub const Int = struct {
415 try self.set(0);417 try self.set(0);
416418
417 for (value[i..]) |ch| {419 for (value[i..]) |ch| {
420 if (ch == '_') {
421 continue;
422 }
418 const d = try charToDigit(ch, base);423 const d = try charToDigit(ch, base);
419424
420 const ap_d = Int.initFixed(([_]Limb{d})[0..]);425 const ap_d = Int.initFixed(([_]Limb{d})[0..]);
...@@ -1582,6 +1587,22 @@ test "big.int string negative" {...@@ -1582,6 +1587,22 @@ test "big.int string negative" {
1582 testing.expect((try a.to(i32)) == -1023);1587 testing.expect((try a.to(i32)) == -1023);
1583}1588}
15841589
1590test "big.int string set number with underscores" {
1591 var a = try Int.init(testing.allocator);
1592 defer a.deinit();
1593
1594 try a.setString(10, "__1_2_0_3_1_7_2_4_1_2_0_____9_1__2__4_7_8_1_2_4_1_2_9_0_8_4_7_1_2_4___");
1595 testing.expect((try a.to(u128)) == 120317241209124781241290847124);
1596}
1597
1598test "big.int string set case insensitive number" {
1599 var a = try Int.init(testing.allocator);
1600 defer a.deinit();
1601
1602 try a.setString(16, "aB_cD_eF");
1603 testing.expect((try a.to(u32)) == 0xabcdef);
1604}
1605
1585test "big.int string set bad char error" {1606test "big.int string set bad char error" {
1586 var a = try Int.init(testing.allocator);1607 var a = try Int.init(testing.allocator);
1587 defer a.deinit();1608 defer a.deinit();
src-self-hosted/ir.zig+5-2
...@@ -1311,13 +1311,16 @@ pub const Builder = struct {...@@ -1311,13 +1311,16 @@ pub const Builder = struct {
1311 var base: u8 = undefined;1311 var base: u8 = undefined;
1312 var rest: []const u8 = undefined;1312 var rest: []const u8 = undefined;
1313 if (int_token.len >= 3 and int_token[0] == '0') {1313 if (int_token.len >= 3 and int_token[0] == '0') {
1314 rest = int_token[2..];
1314 base = switch (int_token[1]) {1315 base = switch (int_token[1]) {
1315 'b' => 2,1316 'b' => 2,
1316 'o' => 8,1317 'o' => 8,
1317 'x' => 16,1318 'x' => 16,
1318 else => unreachable,1319 else => {
1320 base = 10;
1321 rest = int_token;
1322 },
1319 };1323 };
1320 rest = int_token[2..];
1321 } else {1324 } else {
1322 base = 10;1325 base = 10;
1323 rest = int_token;1326 rest = int_token;