Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-45043] Integrate YARP parser [Part 3] #3292

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading