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?)
|
if( condition.is_a?(ScopeStatement) and condition.single?)
|
||||||
condition = condition.first
|
condition = condition.first
|
||||||
end
|
end
|
||||||
return [condition] if condition.is_a?(Named)
|
return [condition] if condition.respond_to?(:slot_definition)
|
||||||
condition = condition.normalize
|
condition = condition.normalize
|
||||||
local = "tmp_#{object_id}"
|
local = "tmp_#{object_id}"
|
||||||
assign = Statements.new [LocalAssignment.new( local , condition)]
|
assign = Statements.new [LocalAssignment.new( local , condition)]
|
||||||
|
@ -1,24 +1,32 @@
|
|||||||
module Vool
|
module Vool
|
||||||
class ReturnStatement < Statement
|
class ReturnStatement < Statement
|
||||||
|
include Normalizer
|
||||||
|
|
||||||
attr_reader :return_value
|
attr_reader :return_value
|
||||||
|
|
||||||
def initialize(value)
|
def initialize(value)
|
||||||
@return_value = value
|
@return_value = value
|
||||||
end
|
end
|
||||||
|
|
||||||
def collect(arr)
|
def normalize
|
||||||
@return_value.collect(arr)
|
val , rest = *normalize_name(@return_value)
|
||||||
super
|
me = ReturnStatement.new(val)
|
||||||
|
return me unless rest
|
||||||
|
rest << me
|
||||||
|
rest
|
||||||
end
|
end
|
||||||
|
|
||||||
# To return form a method in mom instructions we need to do two things:
|
def each(&block)
|
||||||
# - store the given return value, this is a SlotMove / SlotConstant
|
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)
|
# - activate return sequence (reinstantiate old message and jump to return address)
|
||||||
def to_mom( method )
|
def to_mom( method )
|
||||||
statements = @return_value.to_mom(method)
|
ret = Mom::SlotLoad.new( [:message , :return_value] , @return_value.slot_definition(method) )
|
||||||
statements << @return_value.slot_class.new( [:message , :return_value] , @return_value.slot_definition )
|
ret << Mom::ReturnSequence.new
|
||||||
statements << Mom::ReturnSequence.new
|
|
||||||
return statements
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -3,51 +3,52 @@ require_relative "helper"
|
|||||||
module Vool
|
module Vool
|
||||||
class TestReturnMom < MiniTest::Test
|
class TestReturnMom < MiniTest::Test
|
||||||
include MomCompile
|
include MomCompile
|
||||||
|
include Mom
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Risc.machine.boot
|
Risc.machine.boot
|
||||||
@stats = compile_first_method( "return 5").first
|
@inst = compile_first_method( "return 5")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compiles_not_array
|
|
||||||
assert Array != @stats.class , @stats
|
|
||||||
end
|
|
||||||
def test_class_compiles
|
def test_class_compiles
|
||||||
assert_equal Mom::SlotLoad , @stats.first.class , @stats
|
assert_equal SlotLoad , @inst.class , @inst
|
||||||
end
|
end
|
||||||
def test_slot_is_set
|
def test_slot_is_set
|
||||||
assert @stats.first.left
|
assert @inst.left
|
||||||
end
|
end
|
||||||
def test_two_instructions_are_returned
|
def test_two_instructions_are_returned
|
||||||
assert_equal 2 , @stats.length
|
assert_equal 2 , @inst.length
|
||||||
end
|
end
|
||||||
def test_second_is_return
|
def test_second_is_return
|
||||||
assert_equal Mom::ReturnSequence, @stats.last.class
|
assert_equal ReturnSequence, @inst.last.class
|
||||||
end
|
end
|
||||||
def test_slot_starts_at_message
|
def test_slot_starts_at_message
|
||||||
assert_equal :message , @stats.first.left.known_object
|
assert_equal :message , @inst.left.known_object
|
||||||
end
|
end
|
||||||
def test_slot_gets_return
|
def test_slot_gets_return
|
||||||
assert_equal :return_value , @stats.first.left.slots[0]
|
assert_equal :return_value , @inst.left.slots[0]
|
||||||
end
|
end
|
||||||
def test_slot_assigns_something
|
def test_slot_assigns_something
|
||||||
assert @stats.first.right
|
assert @inst.right
|
||||||
end
|
end
|
||||||
def test_slot_assigns_int
|
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
|
||||||
end
|
end
|
||||||
class TestReturnSendMom < MiniTest::Test
|
class TestReturnSendMom < MiniTest::Test
|
||||||
include MomCompile
|
include MomCompile
|
||||||
|
include Mom
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Risc.machine.boot
|
Risc.machine.boot
|
||||||
@stats = compile_first_method( "return 5.mod4").first
|
@ins = compile_first_method( "return 5.mod4")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_two_instructions_are_returned
|
def test_array
|
||||||
#need to implement send first
|
check_array [SlotLoad,ReturnSequence] , @ins
|
||||||
# assert_equal 2 , @stats.length
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -9,9 +9,8 @@ module Vool
|
|||||||
"if(10 < 12) ; a = true ; end"
|
"if(10 < 12) ; a = true ; end"
|
||||||
end
|
end
|
||||||
def test_if_basic_hoist
|
def test_if_basic_hoist
|
||||||
lst = compile_main( basic_if )
|
lst = RubyCompiler.compile( basic_if )
|
||||||
assert_equal Statements , lst.class
|
assert_equal IfStatement , lst.class
|
||||||
assert_equal IfStatement , lst.statements[1].class
|
|
||||||
end
|
end
|
||||||
def pest_if_basic_cond
|
def pest_if_basic_cond
|
||||||
lst = RubyCompiler.compile( basic_if )
|
lst = RubyCompiler.compile( basic_if )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user