Skip to content

Commit af9c6aa

Browse files
nobuEarlopain
authored andcommitted
[Bug #21831] Fix denominator of rational float literal
Denominators can contain underscores in fraction part as well as other numeric literals. [Bug #21831]: https://bugs.ruby-lang.org/issues/21831
1 parent ff334c4 commit af9c6aa

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

src/prism.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4264,9 +4264,13 @@ pm_float_node_rational_create(pm_parser_t *parser, const pm_token_t *token) {
42644264
memcpy(digits + (point - start), point + 1, (unsigned long) (end - point - 1));
42654265
pm_integer_parse(&node->numerator, PM_INTEGER_BASE_DEFAULT, digits, digits + length - 1);
42664266

4267+
size_t fract_length = 0;
4268+
for (const uint8_t *fract = point; fract < end; ++fract) {
4269+
if (*fract != '_') ++fract_length;
4270+
}
42674271
digits[0] = '1';
4268-
if (end - point > 1) memset(digits + 1, '0', (size_t) (end - point - 1));
4269-
pm_integer_parse(&node->denominator, PM_INTEGER_BASE_DEFAULT, digits, digits + (end - point));
4272+
if (fract_length > 1) memset(digits + 1, '0', fract_length - 1);
4273+
pm_integer_parse(&node->denominator, PM_INTEGER_BASE_DEFAULT, digits, digits + fract_length);
42704274
xfree(digits);
42714275

42724276
pm_integers_reduce(&node->numerator, &node->denominator);

test/prism/result/numeric_value_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,27 @@ module Prism
66
class NumericValueTest < TestCase
77
def test_numeric_value
88
assert_equal 123, Prism.parse_statement("123").value
9+
assert_equal 123, Prism.parse_statement("1_23").value
910
assert_equal 3.14, Prism.parse_statement("3.14").value
11+
assert_equal 3.14, Prism.parse_statement("3.1_4").value
1012
assert_equal 42i, Prism.parse_statement("42i").value
13+
assert_equal 42i, Prism.parse_statement("4_2i").value
1114
assert_equal 42.1ri, Prism.parse_statement("42.1ri").value
15+
assert_equal 42.1ri, Prism.parse_statement("42.1_0ri").value
1216
assert_equal 3.14i, Prism.parse_statement("3.14i").value
17+
assert_equal 3.14i, Prism.parse_statement("3.1_4i").value
1318
assert_equal 42r, Prism.parse_statement("42r").value
19+
assert_equal 42r, Prism.parse_statement("4_2r").value
1420
assert_equal 0.5r, Prism.parse_statement("0.5r").value
21+
assert_equal 0.5r, Prism.parse_statement("0.5_0r").value
1522
assert_equal 42ri, Prism.parse_statement("42ri").value
23+
assert_equal 42ri, Prism.parse_statement("4_2ri").value
1624
assert_equal 0.5ri, Prism.parse_statement("0.5ri").value
25+
assert_equal 0.5ri, Prism.parse_statement("0.5_0ri").value
1726
assert_equal 0xFFr, Prism.parse_statement("0xFFr").value
27+
assert_equal 0xFFr, Prism.parse_statement("0xF_Fr").value
1828
assert_equal 0xFFri, Prism.parse_statement("0xFFri").value
29+
assert_equal 0xFFri, Prism.parse_statement("0xF_Fri").value
1930
end
2031
end
2132
end

0 commit comments

Comments
 (0)