Skip to content

Commit

Permalink
Improve parser/codegen support for paren expressions (fixes #291)
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 7, 2013
1 parent 0078289 commit 888b783
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 11 deletions.
2 changes: 1 addition & 1 deletion lib/opal/grammar.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/opal/grammar.y
Expand Up @@ -766,7 +766,7 @@ primary:
}
| PAREN_BEG compstmt ')'
{
result = val[1] || s(:nil)
result = s(:paren, val[1] || s(:nil))
}
| primary_value '::' CONSTANT
{
Expand Down
23 changes: 22 additions & 1 deletion lib/opal/parser.rb
Expand Up @@ -915,7 +915,7 @@ def process_arglist(sexp, level)

# s(:splat, sexp)
def process_splat(sexp, level)
if sexp.first == [:nil]
if sexp.first == [:nil] or sexp.first == [:paren, [:nil]]
[f("[]")]
elsif sexp.first.first == :sym
[f("["), process(sexp[0]), f("]")]
Expand Down Expand Up @@ -2248,6 +2248,27 @@ def process_begin(exp, level)
end
end

def process_paren(sexp, level)
if sexp[0][0] == :block
result = []

sexp[0][1..-1].each do |part|
result << f(', ') unless result.empty?
result << process(part, :expr)
end

[f('('), result, f(')')]
else
result = process sexp[0], level

unless level == :stmt
result = [f('('), result, f(')')]
end

result
end
end

def process_next(exp, level)
if in_while?
f("continue;", exp)
Expand Down
14 changes: 14 additions & 0 deletions spec/opal/language/paren_spec.rb
@@ -0,0 +1,14 @@
require 'spec_helper'

describe "Parens" do
it "can be used to group expressions" do
(self.class; self.to_s; 42).should == 42
(3.142).should == 3.142
().should == nil
end

it "generates code that contains the expression in precedence" do
foo = 100
((foo += 42) == 142).should == true
end
end
16 changes: 8 additions & 8 deletions spec/parser/call_spec.rb
Expand Up @@ -83,24 +83,24 @@
describe "Operator precedence" do
it "should be raised with parentheses" do
opal_parse("(1 + 2) + (3 - 4)").should == [:call,
[:call, [:int, 1], :+, [:arglist, [:int, 2]]],
[:paren, [:call, [:int, 1], :+, [:arglist, [:int, 2]]]],
:+,
[:arglist, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]],
[:arglist, [:paren, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]]],
]
opal_parse("(1 + 2) - (3 - 4)").should == [:call,
[:call, [:int, 1], :+, [:arglist, [:int, 2]]],
[:paren, [:call, [:int, 1], :+, [:arglist, [:int, 2]]]],
:-,
[:arglist, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]],
[:arglist, [:paren, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]]],
]
opal_parse("(1 + 2) * (3 - 4)").should == [:call,
[:call, [:int, 1], :+, [:arglist, [:int, 2]]],
[:paren, [:call, [:int, 1], :+, [:arglist, [:int, 2]]]],
:*,
[:arglist, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]],
[:arglist, [:paren, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]]],
]
opal_parse("(1 + 2) / (3 - 4)").should == [:call,
[:call, [:int, 1], :+, [:arglist, [:int, 2]]],
[:paren, [:call, [:int, 1], :+, [:arglist, [:int, 2]]]],
:/,
[:arglist, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]],
[:arglist, [:paren, [:call, [:int, 3], :-, [:arglist, [:int, 4]]]]],
]
end
end
Expand Down

0 comments on commit 888b783

Please sign in to comment.