Skip to content
Browse files

Set the scope of masgn locals early. Fixes #502.

  • Loading branch information...
1 parent c49837f commit 8b273e8af9df5cac16631fd977cfbad4ce9d20f8 Evan Phoenix committed Sep 28, 2010
Showing with 131 additions and 1 deletion.
  1. +28 −1 lib/compiler/ast/variables.rb
  2. +103 −0 spec/compiler/masgn_spec.rb
View
29 lib/compiler/ast/variables.rb
@@ -465,7 +465,9 @@ def initialize(line, name, value)
def bytecode(g)
pos(g)
- g.state.scope.assign_local_reference self
+ unless @variable
+ g.state.scope.assign_local_reference self
+ end
if @value
@value.bytecode(g)
@@ -541,11 +543,36 @@ def iter_arguments
@iter_arguments = true
end
+ def declare_local_scope(g)
+ # Fix the scope for locals introduced by the left. We
+ # do this before running the code for the right so that
+ # right side sees the proper scoping of the locals on the left.
+
+ if @left
+ @left.body.each do |var|
+ case var
+ when LocalVariable
+ g.state.scope.assign_local_reference var
+ when MultipleAssignment
+ var.declare_local_scope(g)
+ end
+ end
+ end
+
+ if @splat and @splat.kind_of?(SplatAssignment)
+ if @splat.value.kind_of?(LocalVariable)
+ g.state.scope.assign_local_reference @splat.value
+ end
+ end
+ end
+
def bytecode(g, array_on_stack=false)
unless array_on_stack
g.cast_array unless @right or (@splat and not @left)
end
+ declare_local_scope(g)
+
if @fixed
pad_short(g) if @left and !@splat
@right.body.each { |x| x.bytecode(g) }
View
103 spec/compiler/masgn_spec.rb
@@ -1277,4 +1277,107 @@
g.push :true
end
end
+
+ relates "a, b = nil, lambda { a = 7 }" do
+ compile do |g|
+ g.push :nil
+
+ g.push :self
+ g.in_block_send :lambda, :none do |d|
+ d.push 7
+ d.set_local_depth 1, 0
+ end
+
+ g.rotate 2
+
+ g.set_local 0
+ g.pop
+
+ g.set_local 1
+ g.pop
+
+ g.push :true
+ end
+ end
+
+ relates "a, *b = lambda { b = 8 }, nil" do
+ compile do |g|
+ g.push :self
+ g.in_block_send :lambda, :none do |d|
+ d.push 8
+ d.set_local_depth 1, 1
+ end
+
+ g.push :nil
+ g.make_array 1
+
+ g.rotate 2
+
+ g.set_local 0
+ g.pop
+
+ g.cast_array
+ g.set_local 1
+ g.pop
+
+ g.push :true
+ end
+ end
+
+ relates "*a = lambda { a = 8 }" do
+ compile do |g|
+ g.push :self
+ g.in_block_send :lambda, :none do |d|
+ d.push 8
+ d.set_local_depth 1, 0
+ end
+
+ g.make_array 1
+
+ g.set_local 0
+ g.pop
+
+ g.push :true
+ end
+ end
+
+ relates "a, (b, *c), d = lambda { b = d }, [], nil" do
+ compile do |g|
+ g.push :self
+ g.in_block_send :lambda, :none do |d|
+ d.push_local_depth 1, 3
+ d.set_local_depth 1, 1
+ end
+
+ g.make_array 0
+ g.push :nil
+
+ g.rotate 3
+
+ g.set_local 0
+ g.pop
+
+ g.cast_array
+ g.shift_array
+ g.set_local 1
+ g.pop
+ g.dup
+ g.push_cpath_top
+ g.find_const :Array
+ g.swap
+ g.kind_of
+
+ is_array = g.new_label
+ g.git is_array
+ g.make_array 1
+ is_array.set!
+
+ g.set_local 2
+ g.pop
+ g.set_local 3
+ g.pop
+
+ g.push :true
+ end
+ end
end

0 comments on commit 8b273e8

Please sign in to comment.
Something went wrong with that request. Please try again.