Convert SimpleCall to new regs

Also fix bug in RegsiterValue/Slot with chain, where logic was dodgy and compiler not set
This commit is contained in:
Torsten 2020-03-01 23:38:23 +02:00
parent 4b303977a7
commit ff49ff50c0
8 changed files with 54 additions and 23 deletions

View File

@ -94,8 +94,7 @@ module Risc
# add the instruction to the code and return the register_value that was created
# for further use
def load_object( object )
raise "must be Parfait, not #{object.class}" unless object.is_a?(Parfait::Object)
ins = Risc.load_constant("load to #{object.type}" , object)
ins = Risc.load_constant("load to #{object}" , object)
ins.register.set_compiler(self)
add_code ins
# todo for constants (not objects)

View File

@ -33,9 +33,12 @@ module Risc
end
end
def self.load_constant( source , constant )
if(constant.is_a?(Parfait::Object))
value = constant
case constant
when Parfait::Object
type = constant.get_type
value = constant
when Label
type = constant.address.get_type
else
type = constant.ct_type
value = constant.value

View File

@ -40,15 +40,16 @@ module Risc
# Example: message[:caller][:next_message]
# message[:caller] returns a RegisterSlot, which would be self for this example
# to evaluate self[:next_message] we reduce self to a register with to_reg
def [](index)
def []( index )
reg = to_reg("reduce #{@register.symbol}[@index]")
reg[index]
end
# push the given register into the slot that self represents
# ie create a slot_to_reg instruction and add to the compiler
# the register represents and "array", and the content of the
# given register from, is pushed to the memory at register[index]
def to_mem(source , from )
def to_mem( source , from )
reg_to_slot = Risc.reg_to_slot(source , from , register, index)
compiler.add_code(reg_to_slot) if compiler
reg_to_slot.register
@ -57,9 +58,12 @@ module Risc
# load the conntent of the slot that self descibes into a a new register.
# the register is created, and the slot_to_reg instruction added to the
# compiler. the return is a bit like @register[@index]
def to_reg(source )
def to_reg( source )
slot_to_reg = Risc.slot_to_reg(source , register, index)
compiler.add_code(slot_to_reg) if compiler
if compiler
compiler.add_code(slot_to_reg)
slot_to_reg.register.set_compiler(compiler)
end
slot_to_reg.register
end

View File

@ -143,8 +143,8 @@ module Risc
when RegisterValue
ins = Risc.transfer("#{right.type} to #{self.type}" , right , self)
when RegisterSlot
raise "logic error, after creating the reg, need to transfer"
ins = Risc::SlotToReg.new("#{right.register.type}[#{right.index}] -> #{self.type}" , right.register , right.index , self)
index = right.register.resolve_index(right.index)
ins = SlotToReg.new("#{right.register.type}[#{right.index}] -> #{self.type}" , right.register , index , self)
else
raise "not implemented for #{right.class}:#{right}"
end

View File

@ -26,12 +26,11 @@ module SlotMachine
def to_risc(compiler)
method = @method
return_label = Risc.label(self,"continue_#{object_id}")
compiler.build("SimpleCall") do
return_address! << return_label
next_message! << message[:next_message]
next_message[:return_address] << return_address
return_address = compiler.load_object( return_label )
compiler.build(self.to_s) do
message[:next_message][:return_address] << return_address
message << message[:next_message]
add_code Risc::FunctionCall.new("SimpleCall", method )
add_code Risc.function_call(self.to_s, method )
add_code return_label
end
end

View File

@ -72,4 +72,27 @@ module Risc
assert_equal :message , inst.array.symbol
end
end
class TestRegisterSlot4 < MiniTest::Test
def setup
Parfait.boot!(Parfait.default_test_options)
@compiler = Risc.test_compiler
@r0 = RegisterValue.new(:message , :Message).set_compiler(@compiler)
@r0[:next_message][:return_address] << @r0
end
def test_instructions
assert_equal SlotToReg , @compiler.risc_instructions.next(1).class
assert_equal RegToSlot , @compiler.risc_instructions.next(2).class
assert_equal NilClass , @compiler.risc_instructions.next(3).class
end
def test_slot_to
slot = @compiler.risc_instructions.next(1)
assert_slot_to_reg slot , :message, 1, :"message.next_message"
assert slot.register.compiler
end
def test_reg_to
reg = @compiler.risc_instructions.next(2)
assert_reg_to_slot reg , :message, :"message.next_message" , 4
assert reg.register.compiler
end
end
end

View File

@ -64,12 +64,12 @@ module Risc
assert_equal @r0 , instr.register
assert_equal 1 , instr.index
end
def est_slot_to_reg
def test_slot_to_reg
instr = @r0 << @r2[:next_object]
assert_equal SlotToReg , instr.class
assert_equal @r0 , instr.register
assert_equal :message , instr.register.symbol
assert_equal 2 , instr.index
assert_equal @r1 , instr.array
assert instr.array.is_object?
end
def test_reg_to_byte
instr = @r1[1] <= @r0

View File

@ -7,27 +7,30 @@ module SlotMachine
def instruction
SimpleCall.new( make_method )
end
def test_len
def est_len
assert_equal 7 , all.length , all_str
end
def test_1_load_return_label
assert_load risc(1) , Risc::Label , :r1
assert_load risc(1) , Risc::Label
assert_label risc(1).constant , "continue_"
end
def test_2_load_next_message
assert_slot_to_reg risc(2) ,:r0 , 1 , :r2
assert_slot_to_reg risc(2) ,:message , 1 , :"message.next_message"
end
def test_3_store_return_address
assert_reg_to_slot risc(3) , :r1 , :r2 , 4
assert risc(3).register.is_object?
assert_equal 4, risc(3).index
assert_equal :"message.next_message", risc(3).array.symbol
end
def test_4_swap_messages
assert_slot_to_reg risc(4) ,:r0 , 1 , :r0
assert_slot_to_reg risc(4) ,:message , 1 , :message
end
def test_5_call
assert_equal Risc::FunctionCall , risc(5).class
assert_equal :meth , risc(5).method.name
end
def test_6_label
assert_equal Risc::Label , risc(6).class
assert_label risc(6) , "continue_"
end
end