return works
This commit is contained in:
parent
259b248588
commit
d01bdf5dc5
@ -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)]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user