diff --git a/lib/vool/statements/normalizer.rb b/lib/vool/statements/normalizer.rb index 2d059daa..54043537 100644 --- a/lib/vool/statements/normalizer.rb +++ b/lib/vool/statements/normalizer.rb @@ -10,7 +10,7 @@ module Vool if( condition.is_a?(ScopeStatement) and condition.single?) condition = condition.first end - return [condition] if condition.is_a?(Named) + return [condition] if condition.respond_to?(:slot_definition) condition = condition.normalize local = "tmp_#{object_id}" assign = Statements.new [LocalAssignment.new( local , condition)] diff --git a/lib/vool/statements/return_statement.rb b/lib/vool/statements/return_statement.rb index d96f2d0d..424c2982 100644 --- a/lib/vool/statements/return_statement.rb +++ b/lib/vool/statements/return_statement.rb @@ -1,24 +1,32 @@ module Vool class ReturnStatement < Statement + include Normalizer + attr_reader :return_value def initialize(value) @return_value = value end - def collect(arr) - @return_value.collect(arr) - super + def normalize + val , rest = *normalize_name(@return_value) + me = ReturnStatement.new(val) + return me unless rest + rest << me + rest end - # To return form a method in mom instructions we need to do two things: - # - store the given return value, this is a SlotMove / SlotConstant + def each(&block) + block.call(@return_value) + end + + # Since the return is normalized to only allow simple values it is simple. + # To return form a method in mom instructions we only need to do two things: + # - store the given return value, this is a SlotMove # - activate return sequence (reinstantiate old message and jump to return address) def to_mom( method ) - statements = @return_value.to_mom(method) - statements << @return_value.slot_class.new( [:message , :return_value] , @return_value.slot_definition ) - statements << Mom::ReturnSequence.new - return statements + ret = Mom::SlotLoad.new( [:message , :return_value] , @return_value.slot_definition(method) ) + ret << Mom::ReturnSequence.new end end diff --git a/test/vool/to_mom/test_return.rb b/test/vool/to_mom/test_return.rb index 4ad36863..b1d5f172 100644 --- a/test/vool/to_mom/test_return.rb +++ b/test/vool/to_mom/test_return.rb @@ -3,51 +3,52 @@ require_relative "helper" module Vool class TestReturnMom < MiniTest::Test include MomCompile + include Mom def setup Risc.machine.boot - @stats = compile_first_method( "return 5").first + @inst = compile_first_method( "return 5") end - def test_compiles_not_array - assert Array != @stats.class , @stats - end def test_class_compiles - assert_equal Mom::SlotLoad , @stats.first.class , @stats + assert_equal SlotLoad , @inst.class , @inst end def test_slot_is_set - assert @stats.first.left + assert @inst.left end def test_two_instructions_are_returned - assert_equal 2 , @stats.length + assert_equal 2 , @inst.length end def test_second_is_return - assert_equal Mom::ReturnSequence, @stats.last.class + assert_equal ReturnSequence, @inst.last.class end def test_slot_starts_at_message - assert_equal :message , @stats.first.left.known_object + assert_equal :message , @inst.left.known_object end def test_slot_gets_return - assert_equal :return_value , @stats.first.left.slots[0] + assert_equal :return_value , @inst.left.slots[0] end def test_slot_assigns_something - assert @stats.first.right + assert @inst.right end def test_slot_assigns_int - assert_equal Mom::IntegerConstant , @stats.first.right.class + assert_equal Mom::IntegerConstant , @inst.right.class + end + def test_array + check_array [SlotLoad,ReturnSequence] , @ins end end class TestReturnSendMom < MiniTest::Test include MomCompile + include Mom def setup Risc.machine.boot - @stats = compile_first_method( "return 5.mod4").first + @ins = compile_first_method( "return 5.mod4") end - def test_two_instructions_are_returned -#need to implement send first -# assert_equal 2 , @stats.length + def test_array + check_array [SlotLoad,ReturnSequence] , @ins end end end diff --git a/test/vool/vool_compiler/test_if_statement.rb b/test/vool/vool_compiler/test_if_statement.rb index fdcfe2ea..33a76599 100644 --- a/test/vool/vool_compiler/test_if_statement.rb +++ b/test/vool/vool_compiler/test_if_statement.rb @@ -9,9 +9,8 @@ module Vool "if(10 < 12) ; a = true ; end" end def test_if_basic_hoist - lst = compile_main( basic_if ) - assert_equal Statements , lst.class - assert_equal IfStatement , lst.statements[1].class + lst = RubyCompiler.compile( basic_if ) + assert_equal IfStatement , lst.class end def pest_if_basic_cond lst = RubyCompiler.compile( basic_if )