Skip to content

Commit

Permalink
[GR-45043] Integrate YARP parser [Part 3]
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/3907
  • Loading branch information
andrykonchin committed Oct 12, 2023
2 parents 3875f52 + 71dbf65 commit 3545de8
Show file tree
Hide file tree
Showing 109 changed files with 2,515 additions and 400 deletions.
82 changes: 41 additions & 41 deletions CHANGELOG.md

Large diffs are not rendered by default.

95 changes: 52 additions & 43 deletions spec/ruby/language/case_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -329,49 +329,6 @@ def bar; @calls << :bar; end
100
end.should == 100
end
end

describe "The 'case'-construct with no target expression" do
it "evaluates the body of the first clause when at least one of its condition expressions is true" do
case
when true, false; 'foo'
end.should == 'foo'
end

it "evaluates the body of the first when clause that is not false/nil" do
case
when false; 'foo'
when 2; 'bar'
when 1 == 1; 'baz'
end.should == 'bar'

case
when false; 'foo'
when nil; 'foo'
when 1 == 1; 'bar'
end.should == 'bar'
end

it "evaluates the body of the else clause if all when clauses are false/nil" do
case
when false; 'foo'
when nil; 'foo'
when 1 == 2; 'bar'
else 'baz'
end.should == 'baz'
end

it "evaluates multiple conditional expressions as a boolean disjunction" do
case
when true, false; 'foo'
else 'bar'
end.should == 'foo'

case
when false, true; 'foo'
else 'bar'
end.should == 'foo'
end

it "evaluates true as only 'true' when true is the first clause" do
case 1
Expand Down Expand Up @@ -442,6 +399,49 @@ def ===(o)
:called
end.should == :called
end
end

describe "The 'case'-construct with no target expression" do
it "evaluates the body of the first clause when at least one of its condition expressions is true" do
case
when true, false; 'foo'
end.should == 'foo'
end

it "evaluates the body of the first when clause that is not false/nil" do
case
when false; 'foo'
when 2; 'bar'
when 1 == 1; 'baz'
end.should == 'bar'

case
when false; 'foo'
when nil; 'foo'
when 1 == 1; 'bar'
end.should == 'bar'
end

it "evaluates the body of the else clause if all when clauses are false/nil" do
case
when false; 'foo'
when nil; 'foo'
when 1 == 2; 'bar'
else 'baz'
end.should == 'baz'
end

it "evaluates multiple conditional expressions as a boolean disjunction" do
case
when true, false; 'foo'
else 'bar'
end.should == 'foo'

case
when false, true; 'foo'
else 'bar'
end.should == 'foo'
end

# Homogeneous cases are often optimized to avoid === using a jump table, and should be tested separately.
# See https://github.com/jruby/jruby/issues/6440
Expand All @@ -451,4 +451,13 @@ def ===(o)
when 2; 'bar'
end.should == 'foo'
end

it "expands arrays to lists of values" do
case
when *[false]
"foo"
when *[true]
"bar"
end.should == "bar"
end
end
46 changes: 5 additions & 41 deletions spec/tags/truffle/parsing/parsing_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,7 @@ fails:Parsing a Block (Tail expression / with explicit return inside then branch
fails:Parsing a Block (a block with empty body) case is parsed correctly
fails:Parsing a Block (a block with not empty body) case is parsed correctly
fails:Parsing a Block (a block without parameters) case is parsed correctly
fails:Parsing a Break (break operator within a block) case is parsed correctly
fails:Parsing a case expression (case expression with expression/value to match (case a when ... end)) case is parsed correctly
fails:Parsing a case expression (case expression with expression to match and `else` branch (case a when ... else ... end)) case is parsed correctly
fails:Parsing a case expression (case expression with expression to match and multiple values in a `when` branch (case a when a, b ... end)) case is parsed correctly
fails:Parsing a case expression (case expression without expression to match (case when expr ... end)) case is parsed correctly
fails:Parsing a case expression (case expression without expression to match and with `else` branch (case when expr ... else ... end)) case is parsed correctly
fails:Parsing a case expression (case expression without expression to match and with multiple conditions in a `when` branch (case when a, b ... end)) case is parsed correctly
fails:Parsing a Break (within a block) case is parsed correctly
fails:Parsing a class << (reopen an object singleton class) case is parsed correctly
fails:Parsing a Complex number (Complex literal `bri` (without real part) where b is Float is represented as `Complext.convert(0, Rational.convert(b*100, 100))` where 100 is some power of 10 to convert b to Integer) case is parsed correctly
fails:Parsing a Complex number (Complex literal `bri` (without real part) where b is Integer is represented as `Complext.convert(0, Rational.convert(b, 1))`) case is parsed correctly
Expand Down Expand Up @@ -117,39 +111,12 @@ fails:Parsing a Method call (Arguments/with keyword arguments) case is parsed co
fails:Parsing a Method call (Arguments/with positional argument and splat operator (a, *args)) case is parsed correctly
fails:Parsing a Method call (Arguments/with splat operator (*args)) case is parsed correctly
fails:Parsing a Method call (Arguments/with splat operator and positional arguments (*args, a)) case is parsed correctly
fails:Parsing a Method call (Primitive is replaced with a node implementing this method) case is parsed correctly
fails:Parsing a Method call (Special cases/method #!) case is parsed correctly
fails:Parsing a Method call (Special cases/method #%) case is parsed correctly
fails:Parsing a Method call (Special cases/method #&) case is parsed correctly
fails:Parsing a Method call (Special cases/method #*) case is parsed correctly
fails:Parsing a Method call (Special cases/method #+) case is parsed correctly
fails:Parsing a Method call (Special cases/method #-) case is parsed correctly
fails:Parsing a Method call (Special cases/method #-@) case is parsed correctly
fails:Parsing a Method call (Special cases/method #<) case is parsed correctly
fails:Parsing a Method call (Special cases/method #<<) case is parsed correctly
fails:Parsing a Method call (Special cases/method #<=) case is parsed correctly
fails:Parsing a Method call (Special cases/method #==) case is parsed correctly
fails:Parsing a Method call (Special cases/method #===) case is parsed correctly
fails:Parsing a Method call (Special cases/method #>) case is parsed correctly
fails:Parsing a Method call (Special cases/method #>=) case is parsed correctly
fails:Parsing a Method call (Special cases/method #>>) case is parsed correctly
fails:Parsing a Method call (Special cases/method #[]) case is parsed correctly
fails:Parsing a Method call (Special cases/method #[]=) case is parsed correctly
fails:Parsing a Method call (Special cases/method #at (Array#at)) case is parsed correctly
fails:Parsing a Method call (Special cases/method #bytesize) case is parsed correctly
fails:Parsing a Method call (Special cases/method #dedup called on a String literal) case is parsed correctly
fails:Parsing a Method call (Special cases/method #freeze) case is parsed correctly
fails:Parsing a Method call (Special cases/method #is_a?) case is parsed correctly
fails:Parsing a Method call (Special cases/method #kind_of?) case is parsed correctly
fails:Parsing a Method call (Special cases/method #lambda (Kernel#lambda)) case is parsed correctly
fails:Parsing a Method call (Special cases/method #lambda (not Kernel#lambda)) case is parsed correctly
fails:Parsing a Method call (Special cases/method #nil?) case is parsed correctly
fails:Parsing a Method call (Special cases/method #/) case is parsed correctly
fails:Parsing a Method call (Special cases/method #|) case is parsed correctly
fails:Parsing a Method call (Special cases/method #attr= (property assignment)) case is parsed correctly
fails:Parsing a Method call (Method call with implicit receiver (`foo`)) case is parsed correctly
fails:Parsing a Method call (With safe navigation operator (&.)) case is parsed correctly
fails:Parsing a Method call (Without arguments and parentheses) case is parsed correctly
fails:Parsing a Method call (super / in a method body with explicit arguments) case is parsed correctly
fails:Parsing a Method call (super / in a method body without explicit arguments) case is parsed correctly
fails:Parsing a Method call (super / outside a method body with explicit arguments) case is parsed correctly
fails:Parsing a Method call (super / outside a method body without explicit arguments) case is parsed correctly
fails:Parsing a &&= (Assign an attribute local variable (a.b &&= c)) case is parsed correctly
fails:Parsing a &&= (Assign an referenced element (a[b] &&= c)) case is parsed correctly
fails:Parsing a &&= (Assign an element referenced with multiple indexes (a[b, c, d] &&= e)) case is parsed correctly
Expand All @@ -160,11 +127,8 @@ fails:Parsing a &&= (Variable assignment/global variable ($a &&= b)) case is par
fails:Parsing a &&= (Variable assignment/instance variable (@a &&= b)) case is parsed correctly
fails:Parsing a &&= (Variable assignment/local variable (a &&= b)) case is parsed correctly
fails:Parsing a Flip-flop operator (in a block) case is parsed correctly
fails:Parsing a Flip-flop operator (in a class body) case is parsed correctly
fails:Parsing a Flip-flop operator (in a lambda) case is parsed correctly
fails:Parsing a Flip-flop operator (in a method) case is parsed correctly
fails:Parsing a Flip-flop operator (in a module body) case is parsed correctly
fails:Parsing a Flip-flop operator (Flop-flop operator - a range literal in boolean context) case is parsed correctly
fails:Parsing a Match (=~ operator) case is parsed correctly
fails:Parsing a Match (=~ operator/with Regexp literal as a RHS) case is parsed correctly
fails:Parsing a Match (=~ operator/with Regexp literal as a LHS (without named capture groups)) case is parsed correctly
Expand Down
1 change: 0 additions & 1 deletion spec/truffle/parsing/fixtures/END.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ ast: |
methodName = "at_exit"
notEmptyKeywordsProfile = false
notRuby2KeywordsHashProfile = false
ruby2KeywordsHashProfile = false
children:
arguments = [
BooleanLiteralNode
Expand Down
1 change: 0 additions & 1 deletion spec/truffle/parsing/fixtures/block/name/in_block.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ ast: |
methodName = "proc"
notEmptyKeywordsProfile = false
notRuby2KeywordsHashProfile = false
ruby2KeywordsHashProfile = false
children:
block =
BlockDefinitionNode
Expand Down
1 change: 0 additions & 1 deletion spec/truffle/parsing/fixtures/block/name/in_method.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ ast: |
methodName = "proc"
notEmptyKeywordsProfile = false
notRuby2KeywordsHashProfile = false
ruby2KeywordsHashProfile = false
children:
block =
BlockDefinitionNode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
subject: "Break"
description: "break operator with multiple arguments"
description: "with multiple arguments"
focused_on_node: "org.truffleruby.language.control.BreakNode"
ruby: |
while true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
subject: "Break"
description: "break operator with argument"
description: "with single argument"
focused_on_node: "org.truffleruby.language.control.BreakNode"
ruby: |
while true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
subject: "Break"
description: "break operator with splat operator (break *a)"
description: "with splat operator (break *a)"
focused_on_node: "org.truffleruby.language.control.BreakNode"
ruby: |
while true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
subject: "Break"
description: "with splat operator and following argument (break *a, b)"
notes: >
Arguments are represented with combination of:
- ArrayConcatNode
- SplatCastNodeGen
- ArrayLiteralNode$UninitialisedArrayLiteralNode
nodes
yarp_specific: true # Simplified AST and replaced ArrayAppendOneNodeGen by concatenating with array of one element
focused_on_node: "org.truffleruby.language.control.BreakNode"
ruby: |
while true
break *foo, 42
end
ast: |
BreakNode
attributes:
breakID = org.truffleruby.language.control.BreakID@...
flags = 1
ignoreMarker = true
children:
child =
ArrayConcatNode
attributes:
flags = 0
children:
children = [
SplatCastNodeGen
attributes:
conversionMethod = :to_a
copy = true
flags = 0
nilBehavior = CONVERT
children:
childNode_ =
RubyCallNode
attributes:
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
dispatchConfig = PRIVATE
emptyKeywordsProfile = false
flags = 0
isAttrAssign = false
isSafeNavigation = false
isSplatted = false
isVCall = true
lastArgIsNotHashProfile = false
methodName = "foo"
notEmptyKeywordsProfile = false
notRuby2KeywordsHashProfile = false
children:
receiver =
SelfNode
attributes:
flags = 0
ArrayLiteralNode$UninitialisedArrayLiteralNode
attributes:
flags = 0
language = org.truffleruby.RubyLanguage@...
children:
values = [
IntegerFixnumLiteralNode
attributes:
flags = 0
value = 42
]
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
subject: "Break"
description: "with splat operator and following arguments (break *a, b, ...)"
notes: >
Arguments are represented with combination of:
- ArrayConcatNode
- SplatCastNodeGen
- ArrayLiteralNode$UninitialisedArrayLiteralNode
nodes
yarp_specific: true # Removed excessive SplatCastNodeGen:
# SplatCastNodeGen(UninitialisedArrayLiteralNode) -> UninitialisedArrayLiteralNode
focused_on_node: "org.truffleruby.language.control.BreakNode"
ruby: |
while true
break *foo, 42, 100500
end
ast: |
BreakNode
attributes:
breakID = org.truffleruby.language.control.BreakID@...
flags = 1
ignoreMarker = true
children:
child =
ArrayConcatNode
attributes:
flags = 0
children:
children = [
SplatCastNodeGen
attributes:
conversionMethod = :to_a
copy = true
flags = 0
nilBehavior = CONVERT
children:
childNode_ =
RubyCallNode
attributes:
descriptor = org.truffleruby.language.arguments.EmptyArgumentsDescriptor@...
dispatchConfig = PRIVATE
emptyKeywordsProfile = false
flags = 0
isAttrAssign = false
isSafeNavigation = false
isSplatted = false
isVCall = true
lastArgIsNotHashProfile = false
methodName = "foo"
notEmptyKeywordsProfile = false
notRuby2KeywordsHashProfile = false
children:
receiver =
SelfNode
attributes:
flags = 0
ArrayLiteralNode$UninitialisedArrayLiteralNode
attributes:
flags = 0
language = org.truffleruby.RubyLanguage@...
children:
values = [
IntegerFixnumLiteralNode
attributes:
flags = 0
value = 42
IntegerFixnumLiteralNode
attributes:
flags = 0
value = 100500
]
]
Loading

0 comments on commit 3545de8

Please sign in to comment.