diff --git a/stdlib/internal/builtin.codon b/stdlib/internal/builtin.codon index eea6672d..124615ab 100644 --- a/stdlib/internal/builtin.codon +++ b/stdlib/internal/builtin.codon @@ -445,9 +445,24 @@ class int: elif (n >= 3 and s.ptr[0] == byte(48) and (s.ptr[1] == C_LOWER or s.ptr[1] == C_UPPER)): # '0b' etc. - if not check_digit(s.ptr[3], base): + if not check_digit(s.ptr[2], base): parse_error(s0, base0) s = str(s.ptr + 2, n - 2) + + n = len(s) + underscore_count = 0 + for i in range(n): + if s.ptr[i] == byte(95): # '_' + underscore_count += 1 + + if underscore_count: + p = Ptr[byte](n - underscore_count) + j = 0 + for i in range(n): + if s.ptr[i] != byte(95): # '_' + p[j] = s.ptr[i] + j += 1 + s = str(p, n - underscore_count) end = cobj() result = _C.seq_int_from_str(s, __ptr__(end), i32(base)) diff --git a/test/core/bltin.codon b/test/core/bltin.codon index a848159c..29b2c6da 100644 --- a/test/core/bltin.codon +++ b/test/core/bltin.codon @@ -897,6 +897,56 @@ def test_num_from_str(): except ValueError as e: assert str(e) == "could not convert string to float: ''" + # new tests for PR #786 + + assert int("0b0", 0) == 0 + assert int("0b1", 0) == 1 + assert int("0b1101", 0) == 13 + assert int("+0b1101", 0) == 13 + assert int("-0b1101", 0) == -13 + + assert int("7", 0) == 7 + assert int("42", 0) == 42 + assert int("12345", 0) == 12345 + assert int("+67890", 0) == 67890 + assert int("-24680", 0) == -24680 + + assert int("0o7", 0) == 7 + assert int("0o123", 0) == 83 + assert int("0o707", 0) == 455 + assert int("+0o710", 0) == 456 + assert int("-0o765", 0) == -501 + + assert int("0xA", 0) == 10 + assert int("0xABCD", 0) == 43981 + assert int("0xFFF", 0) == 4095 + assert int("+0x1234", 0) == 4660 + assert int("-0xFF", 0) == -255 + + assert int("1_0", 2) == 2 + assert int("10_01", 2) == 9 + assert int("101_101", 2) == 45 + assert int("0b1_101", 0) == 13 + assert int("-0b101_011", 0) == -43 + + assert int("1_2", 8) == 10 + assert int("12_3", 8) == 83 + assert int("7_07", 8) == 455 + assert int("0o1_23", 0) == 83 + assert int("-0o7_10", 0) == -456 + + assert int("1_A", 16) == 26 + assert int("AB_CD", 16) == 43981 + assert int("F_FF", 16) == 4095 + assert int("0x1_A", 0) == 26 + assert int("-0xF_F", 0) == -255 + + assert int("1_2") == 12 + assert int("12_34") == 1234 + assert int("123_456") == 123456 + assert int("+1_000_001") == 1000001 + assert int("-9_87_65") == -98765 + @test def test_files(open_fn, append_allowed: bool = True): path = 'build/testfile.txt'