Skip to content

Commit

Permalink
Fix dereferencing on local variables to ignore whitespace
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Dec 7, 2013
1 parent 4133522 commit 4cd3580
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 10 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -57,6 +57,9 @@

* Support single character strings (using ? prefix) with escaped characters.

* Fix lexer to detect dereferencing on local variables even when whitespace
is present (`a = 0; a [0]` parses as a deference on a).

## 0.5.5 2013-11-25

* Fix regression: add `%i[foo bar]` style words back to lexer
Expand Down
3 changes: 2 additions & 1 deletion lib/opal/parser.rb
Expand Up @@ -9,9 +9,10 @@ class Parser < Racc::Parser
attr_reader :lexer, :file, :scope

def parse(source, file = '(string)')
@lexer = Lexer.new(source, file)
@file = file
@scopes = []
@lexer = Lexer.new(source, file)
@lexer.parser = self

self.parse_to_sexp
end
Expand Down
30 changes: 21 additions & 9 deletions lib/opal/parser/lexer.rb
Expand Up @@ -29,6 +29,7 @@ class Lexer
attr_accessor :strterm
attr_accessor :scanner
attr_accessor :yylval
attr_accessor :parser

def initialize(source, file)
@lex_state = :expr_beg
Expand All @@ -44,6 +45,10 @@ def initialize(source, file)
@scanner_stack = [@scanner]
end

def has_local?(local)
parser.scope.has_local?(local.to_sym)
end

def cond_push(n)
@cond = (@cond << 1) | (n & 1)
end
Expand Down Expand Up @@ -483,6 +488,8 @@ def heredoc_identifier
end

def process_identifier(matched, cmd_start)
last_state = @lex_state

if scanner.peek(2) != '::' && scan(/:/)
@lex_state = :expr_beg
self.yylval = matched
Expand Down Expand Up @@ -571,6 +578,10 @@ def process_identifier(matched, cmd_start)
@lex_state = :expr_end
end

if ![:expr_dot, :expr_fname].include?(last_state) and has_local?(matched)
@lex_state = :expr_end
end

return matched =~ /^[A-Z]/ ? :tCONSTANT : :tIDENTIFIER
end

Expand Down Expand Up @@ -888,18 +899,19 @@ def yylex
else
raise "Unexpected '[' token"
end
elsif beg? || @space_seen
@lex_state = :expr_beg
cond_push 0
cmdarg_push 0
return :tLBRACK
elsif beg?
result = :tLBRACK
elsif arg? && @space_seen
result = :tLBRACK
else
@lex_state = :expr_beg
cond_push 0
cmdarg_push 0
return :tLBRACK2
result = :tLBRACK2
end

@lex_state = :expr_beg
cond_push 0
cmdarg_push 0
return result

elsif scan(/\]/)
cond_lexpop
cmdarg_lexpop
Expand Down
7 changes: 7 additions & 0 deletions spec/cli/lexer_spec.rb
Expand Up @@ -100,4 +100,11 @@
expect(parser.lexer.eof_content).to eq("")
end
end

describe "variable dereferencing ([])" do
it "handles referencing correctly on local variables in scope" do
expect_parsed("x = 0; x [0]").to eq([:block, [:lasgn, :x, [:int, 0]],
[:call, [:lvar, :x], :[], [:arglist, [:int, 0]]]])
end
end
end

0 comments on commit 4cd3580

Please sign in to comment.