diff --git a/lib/ruby/assignment.rb b/lib/ruby/assignment.rb index a44bc2c5..eb5f4662 100644 --- a/lib/ruby/assignment.rb +++ b/lib/ruby/assignment.rb @@ -13,11 +13,24 @@ module Ruby return self.vool_brother.new(name,@value.to_vool) when SendStatement return normalize_send + when BlockStatement + return normalize_block else raise "unsupported right #{value}" end end + # Ruby BlockStatements have the block and the send. Normalize the send + # and assign it (it is the last in the list) + def normalize_block + statements = value.to_vool + index = statements.length - 1 + snd = statements.statements[index] + raise "Expecting Send #{snd.class}:#{snd}" unless snd.is_a?( Vool::SendStatement) + statements.statements[index] = assignment( snd ) + statements + end + # sends may have complex args that get hoisted in vool:ing them # in which case we have to assign the simplified, otherwise the # plain send diff --git a/test/ruby/test_block_statement1.rb b/test/ruby/test_block_statement1.rb new file mode 100644 index 00000000..f629d853 --- /dev/null +++ b/test/ruby/test_block_statement1.rb @@ -0,0 +1,58 @@ +require_relative "helper" + +module Ruby + class TestBlockReturn < MiniTest::Test + include RubyTests + + def setup() + input = "a = plus_one{return 1 } ; return a " + @lst = compile( input ) + end + def test_scope + assert_equal ScopeStatement , @lst.class + end + def test_assign + assert_equal LocalAssignment , @lst.first.class + end + def test_assign_right + assert_equal BlockStatement , @lst.first.value.class + end + def test_method_name + assert_equal :plus_one , @lst.first.value.send.name + end + def test_ret + assert_equal ReturnStatement , @lst.last.class + end + end + class TestBlockReturnVool < MiniTest::Test + include RubyTests + def setup() + input = "a = plus_one{return 1 } ; return a " + @lst = compile( input ).to_vool + end + def test_scope + assert_equal Vool::ScopeStatement , @lst.class + end + def test_first + assert_equal Vool::Statements , @lst.first.class + end + def test_block_assign + assert_equal Vool::LocalAssignment , @lst.first.first.class + assert @lst.first.first.name.to_s.start_with?("implicit_block") + end + def test_block_assign_right + assert_equal Vool::BlockStatement , @lst.first.first.value.class + end + def test_a_assign + assert_equal Vool::LocalAssignment , @lst.first.last.class + assert_equal :a , @lst.first.last.name + end + def test_a_assign_val + assert_equal Vool::SendStatement , @lst.first.last.value.class + assert_equal :plus_one , @lst.first.last.value.name + end + def test_ret + assert_equal Vool::ReturnStatement , @lst.last.class + end + end +end