diff --git a/lib/ruby/assignment.rb b/lib/ruby/assignment.rb index bde8a60d..ba116eaa 100644 --- a/lib/ruby/assignment.rb +++ b/lib/ruby/assignment.rb @@ -11,26 +11,13 @@ module Ruby case value when Variable , Constant return self.vool_brother.new(name,@value.to_vool) - when SendStatement , YieldStatement + when SendStatement , YieldStatement , RubyBlockStatement return normalize_send - when RubyBlockStatement - 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/lib/ruby/call_statement.rb b/lib/ruby/call_statement.rb index d94118ac..cfe187ff 100644 --- a/lib/ruby/call_statement.rb +++ b/lib/ruby/call_statement.rb @@ -39,9 +39,7 @@ module Ruby # rather than using a stack to do that at runtime def normalize_arg(arg , statements) vool_arg = arg.to_vool - if arg.is_a?(Variable) || arg.is_a?(Constant) - return vool_arg - end + return vool_arg if vool_arg.is_a?(Vool::Expression) if( vool_arg.is_a?(Vool::Statements)) while(vool_arg.length > 1) statements << vool_arg.shift diff --git a/lib/ruby/ruby_block_statement.rb b/lib/ruby/ruby_block_statement.rb index 64e31b67..69f9edf9 100644 --- a/lib/ruby/ruby_block_statement.rb +++ b/lib/ruby/ruby_block_statement.rb @@ -13,24 +13,17 @@ module Ruby raise "no bod" unless @body end - # In Vool we "hoist" the block definition through a local assignment, much - # as we would other complex args (bit like in the Normalizer) - # The block is then passed as a normal variable to the send. In other words, the - # BlockStatement resolves to a list of Statements, the last of which is the send + # This resolves to a Vool SendStatement, in fact that is mostly what it is. + # + # The implicitly passed block (in ruby) gets converted to the constant it is, and + # is passed as the last argument. # def to_vool - block_name = "implicit_block_#{object_id}".to_sym - block = Vool::LambdaExpression.new( @args.dup , @body.to_vool) - assign = Vool::LocalAssignment.new( block_name , block) - sendd = @send.to_vool - if(sendd.is_a?(Vool::Statements)) - ret = sendd - sendd = sendd.last - else - ret = Vool::Statements.new([sendd]) - end - sendd.arguments << LocalVariable.new(block_name).to_vool - ret.prepend(assign) + #block_name = "implicit_block_#{object_id}".to_sym + lambda = Vool::LambdaExpression.new( @args.dup , @body.to_vool) + ret = @send.to_vool + sendd = ret.is_a?(Vool::Statements) ? ret.last : ret + sendd.arguments << lambda ret end diff --git a/lib/ruby/ruby_compiler.rb b/lib/ruby/ruby_compiler.rb index 230dd5bb..fc3fd8ee 100644 --- a/lib/ruby/ruby_compiler.rb +++ b/lib/ruby/ruby_compiler.rb @@ -76,7 +76,6 @@ module Ruby end def on_block(block_node) - puts block_node.to_s sendd = process(block_node.children[0]) args = process(block_node.children[1]) body = process(block_node.children[2]) diff --git a/test/ruby/test_ruby_block_statement.rb b/test/ruby/test_ruby_block_statement.rb index ae96c0ac..a983f7f1 100644 --- a/test/ruby/test_ruby_block_statement.rb +++ b/test/ruby/test_ruby_block_statement.rb @@ -33,24 +33,17 @@ module Ruby @lst = compile( input ).to_vool end def test_block - assert_equal Vool::Statements , @lst.class + assert_equal Vool::SendStatement , @lst.class end - def test_first - assert_equal Vool::LocalAssignment , @lst.first.class - assert @lst.first.name.to_s.start_with?("implicit_block_") - assert_equal Vool::LambdaExpression , @lst.first.value.class - end - def test_last_send - assert_equal 2 , @lst.length - assert_equal Vool::SendStatement , @lst.last.class - assert_equal :plus_one , @lst.last.name + def test_send_name + assert_equal :plus_one , @lst.name end def test_send_block_arg - assert_equal 1 , @lst.last.arguments.length - assert @lst.last.arguments.first.name.to_s.start_with?("implicit_block_") + assert_equal 1 , @lst.arguments.length + assert_equal Vool::LambdaExpression , @lst.arguments.first.class end def test_block_args - assert_equal [:arg1] , @lst.first.value.args + assert_equal [:arg1] , @lst.arguments.first.args end end end diff --git a/test/ruby/test_ruby_block_statement1.rb b/test/ruby/test_ruby_block_statement1.rb index fa967e60..fdeb7aa8 100644 --- a/test/ruby/test_ruby_block_statement1.rb +++ b/test/ruby/test_ruby_block_statement1.rb @@ -33,26 +33,19 @@ module Ruby def test_scope assert_equal Vool::ScopeStatement , @lst.class end - def test_first - assert_equal Vool::Statements , @lst.first.class + def test_assign + assert_equal Vool::LocalAssignment , @lst.first.class + assert_equal :a , @lst.first.name end - def test_block_assign - assert_equal Vool::LocalAssignment , @lst.first.first.class - assert @lst.first.first.name.to_s.start_with?("implicit_block") + def test_send + assert_equal Vool::SendStatement , @lst.first.value.class + assert_equal :plus_one , @lst.first.value.name end - def test_block_assign_right - assert_equal Vool::LambdaExpression , @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 + def test_block_arg + assert_equal Vool::LambdaExpression , @lst.first.value.arguments.first.class end def test_ret - assert_equal Vool::ReturnStatement , @lst.last.class + assert_equal Vool::ReturnStatement , @lst[1].class end end end diff --git a/test/ruby/test_send_statement1.rb b/test/ruby/test_send_statement1.rb index 8cb65c44..480845be 100644 --- a/test/ruby/test_send_statement1.rb +++ b/test/ruby/test_send_statement1.rb @@ -39,13 +39,14 @@ module Ruby end class TestSendSuperVool < MiniTest::Test include RubyTests - def test_super0_receiver - lst = compile( "super").to_vool - assert_equal Vool::SuperExpression , lst.receiver.class - end def test_super0 lst = compile( "super").to_vool - assert_equal Vool::SendStatement , lst.class + assert_equal Vool::Statements , lst.class + assert_equal Vool::SendStatement , lst.last.class + end + def test_super0_receiver + lst = compile( "super").to_vool + assert_equal Vool::SuperExpression , lst.first.value.class end end class TestSendSuperArgsVool < MiniTest::Test @@ -54,13 +55,14 @@ module Ruby @lst = compile( "super(1)").to_vool end def test_super_class - assert_equal Vool::SendStatement , @lst.class + assert_equal Vool::Statements , @lst.class + assert_equal Vool::SendStatement , @lst.last.class end def test_super_receiver - assert_equal Vool::SuperExpression , @lst.receiver.class + assert_equal Vool::SuperExpression , @lst.first.value.class end - def test_super_name #is nil - assert_nil @lst.name + def test_super_name + assert @lst.first.name.to_s.start_with?("tmp") end end class TestSendReceiverTypeVool < MiniTest::Test