diff options
| author | Kevin Newton <kddnewton@gmail.com> | 2024-05-08 15:32:24 -0400 |
|---|---|---|
| committer | Kevin Newton <kddnewton@gmail.com> | 2024-05-21 14:27:46 -0400 |
| commit | 89efb94fec9c78caab7ec4079bfe9e3f4e56a9a4 (patch) | |
| tree | 7dd8b635def05ffa9b8bc15d4805c792b00dad22 /lib | |
| parent | 42930d28a48bf7495180e81fd6e5cf742f3f47c7 (diff) | |
[ruby/prism] Reconfigure rationals
This eliminates the subnode on RationalNode and replaces it with two
integer fields, which represent the ratio for the rational. It also
reduces those two integers if they both fit into 32 bits.
Importantly, this PR does not implement bignum reduction. That's something
I'd like to consider for the future, but it's simple enough for now to
leave them unreduced, which makes it more useful than it used to be.
https://github.com/ruby/prism/commit/86e06c7068
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/prism/node_ext.rb | 2 | ||||
| -rw-r--r-- | lib/prism/translation/parser/compiler.rb | 24 |
2 files changed, 6 insertions, 20 deletions
diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb index ceec76b8d6..4761e5b9b2 100644 --- a/lib/prism/node_ext.rb +++ b/lib/prism/node_ext.rb @@ -103,7 +103,7 @@ module Prism class RationalNode < Node # Returns the value of the node as a Ruby Rational. def value - Rational(numeric.is_a?(IntegerNode) ? numeric.value : slice.chomp("r")) + Rational(numerator, denominator) end end diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb index a6c3118efd..c3fa68231c 100644 --- a/lib/prism/translation/parser/compiler.rb +++ b/lib/prism/translation/parser/compiler.rb @@ -881,7 +881,7 @@ module Prism # 1i # ^^ def visit_imaginary_node(node) - visit_numeric(node, builder.complex([imaginary_value(node), srange(node.location)])) + visit_numeric(node, builder.complex([Complex(0, node.numeric.value), srange(node.location)])) end # { foo: } @@ -1514,7 +1514,7 @@ module Prism # 1r # ^^ def visit_rational_node(node) - visit_numeric(node, builder.rational([rational_value(node), srange(node.location)])) + visit_numeric(node, builder.rational([node.value, srange(node.location)])) end # redo @@ -1940,12 +1940,6 @@ module Prism forwarding end - # Because we have mutated the AST to allow for newlines in the middle of - # a rational, we need to manually handle the value here. - def imaginary_value(node) - Complex(0, node.numeric.is_a?(RationalNode) ? rational_value(node.numeric) : node.numeric.value) - end - # Negate the value of a numeric node. This is a special case where you # have a negative sign on one line and then a number on the next line. # In normal Ruby, this will always be a method call. The parser gem, @@ -1955,7 +1949,9 @@ module Prism case receiver.type when :integer_node, :float_node receiver.copy(value: -receiver.value, location: message_loc.join(receiver.location)) - when :rational_node, :imaginary_node + when :rational_node + receiver.copy(numerator: -receiver.numerator, location: message_loc.join(receiver.location)) + when :imaginary_node receiver.copy(numeric: numeric_negate(message_loc, receiver.numeric), location: message_loc.join(receiver.location)) end end @@ -1974,16 +1970,6 @@ module Prism parameters.block.nil? end - # Because we have mutated the AST to allow for newlines in the middle of - # a rational, we need to manually handle the value here. - def rational_value(node) - if node.numeric.is_a?(IntegerNode) - Rational(node.numeric.value) - else - Rational(node.slice.gsub(/\s/, "").chomp("r")) - end - end - # Locations in the parser gem AST are generated using this class. We # store a reference to its constant to make it slightly faster to look # up. |
