summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-05-08 15:32:24 -0400
committerKevin Newton <kddnewton@gmail.com>2024-05-21 14:27:46 -0400
commit89efb94fec9c78caab7ec4079bfe9e3f4e56a9a4 (patch)
tree7dd8b635def05ffa9b8bc15d4805c792b00dad22 /lib
parent42930d28a48bf7495180e81fd6e5cf742f3f47c7 (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.rb2
-rw-r--r--lib/prism/translation/parser/compiler.rb24
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.