fix comparison test and helpers

moving to passing the instruction number, not the instruction
so in the error message we can say where the error is
(otherwise minitest is good enough to supress the trace of asserts calling asserts)
This commit is contained in:
Torsten 2020-03-06 21:26:23 +02:00
parent 3575aada17
commit 1760b5b203
4 changed files with 132 additions and 102 deletions

View File

@ -13,8 +13,8 @@ module SlotMachine
def to_risc(compiler) def to_risc(compiler)
builder = compiler.builder(compiler.source) builder = compiler.builder(compiler.source)
operator = @operator # make accessible in block operator = @operator # make accessible in block
false_label = Risc.label("false" , "false") false_label = Risc.label("false" , "false_label_#{object_id}")
merge_label = Risc.label("merge" , "merge") merge_label = Risc.label("merge" , "merge_label_#{object_id}")
result = Risc::RegisterValue.new(:result , :Object) result = Risc::RegisterValue.new(:result , :Object)
builder.build do builder.build do
left = message[:receiver].to_reg.reduce_int left = message[:receiver].to_reg.reduce_int
@ -26,7 +26,7 @@ module SlotMachine
left.op :- , right left.op :- , right
end end
if_minus false_label if_minus false_label
if_zero( false_label ) if operator.to_s.length == 1 if_not_zero( false_label ) if operator.to_s.length == 1
add_code Risc::LoadConstant.new(to_s , Parfait.object_space.true_object, result) add_code Risc::LoadConstant.new(to_s , Parfait.object_space.true_object, result)
branch merge_label branch merge_label
add_code false_label add_code false_label

View File

@ -19,42 +19,41 @@ module SlotMachine
end end
def assert_return(at) def assert_return(at)
assert_label risc(at) , "return_label" assert_label at , "return_label"
assert_slot_to_reg risc(at + 1) , :r0 , 5 , :r1 assert_slot_to_reg at + 1 , :message , 6 , "message.caller"
assert_slot_to_reg risc(at + 2) , :r0 , 6 , :r2 assert_slot_to_reg at + 2 , "message.caller" , 5 , "message.caller.return_value"
assert_reg_to_slot risc(at + 3) ,:r1 , :r2 , 5 assert_reg_to_slot at + 3 ,"message.caller.return_value" , "message.caller" , 5
assert_slot_to_reg risc(at + 4) , :r0 , 4 , :r3 assert_slot_to_reg at + 4 , :message , 4 , "message.return_address"
assert_slot_to_reg risc(at + 5) , :r3 , 2 , :r3 assert_slot_to_reg at + 5 , :message , 6 , :message
assert_slot_to_reg risc(at + 6) , :r0 , 6 , :r0 assert_equal Risc::FunctionReturn , risc(at + 6).class
assert_equal Risc::FunctionReturn , risc(at + 7).class assert_label at + 7 , "unreachable"
assert_label risc(at + 8) , "unreachable"
end end
def assert_allocate def assert_allocate
assert_load risc(1) , Parfait::Factory assert_load 1 , Parfait::Factory
assert_slot_to_reg risc(2) , :r2 , 2 , :r1 assert_slot_to_reg 2 , :r2 , 2 , :r1
assert_load risc(3) , Parfait::NilClass assert_load 3 , Parfait::NilClass
assert_operator risc(4) , :- , :r3 , :r1 assert_operator 4 , :- , :r3 , :r1
assert_equal Risc::IsNotZero , risc(5).class assert_not_zero 5 , :label
assert risc(5).label.name.to_s.start_with?("cont_label") assert risc(5).label.name.to_s.start_with?("cont_label")
assert_slot_to_reg risc(6) , :r2 , 3 , :r4 assert_slot_to_reg 6 , :r2 , 3 , :r4
assert_reg_to_slot risc(7) ,:r4 , :r2 , 2 assert_reg_to_slot 7 ,:r4 , :r2 , 2
assert_load risc(8) , Parfait::CallableMethod assert_load 8 , Parfait::CallableMethod
assert_slot_to_reg risc(9) , :r0 , 1 , :r6 assert_slot_to_reg 9 , :r0 , 1 , :r6
assert_reg_to_slot risc(10) , :r5 , :r6 , 7 assert_reg_to_slot 10 , :r5 , :r6 , 7
assert_load risc(11) , Parfait::Factory assert_load 11 , Parfait::Factory
assert_reg_to_slot risc(12) , :r7 , :r0 , 2 assert_reg_to_slot 12 , :r7 , :r0 , 2
assert_load risc(13) , Risc::Label assert_load 13 , Risc::Label
assert_slot_to_reg risc(14) , :r0 , 1 , :r9 assert_slot_to_reg 14 , :r0 , 1 , :r9
assert_slot_to_reg risc(14),:r0,1,:r9 assert_slot_to_reg 14 ,:r0,1,:r9
assert_reg_to_slot risc(15),:r8,:r9,4 assert_reg_to_slot 15 ,:r8,:r9,4
assert_slot_to_reg risc(16),:r0 , 1 , :r0 assert_slot_to_reg 16 ,:r0 , 1 , :r0
assert_equal Risc::FunctionCall, risc(17).class assert_equal Risc::FunctionCall, risc(17).class
assert_equal :main, risc(17).method.name assert_equal :main, risc(17).method.name
assert_label risc(18) , "continue_" assert_label 18 , "continue_"
assert_slot_to_reg risc(19) , :r2 , 2 , :r1 assert_slot_to_reg 19 , :r2 , 2 , :r1
assert_label risc(20) ,"cont_label_" assert_label 20 ,"cont_label_"
assert_slot_to_reg risc(21) , :r1 , 1 , :r4 assert_slot_to_reg 21 , :r1 , 1 , :r4
assert_reg_to_slot risc(22) , :r4 , :r2 , 2 assert_reg_to_slot 22 , :r4 , :r2 , 2
end end
end end
end end

View File

@ -20,35 +20,35 @@ module SlotMachine
end end
class TestIntComp2Risc < BootTest class TestIntComp2Risc < BootTest
def setup def setup
@method = get_compiler("Integer",:ge) @method = get_compiler("Integer",:gt)
end end
def test_slot_length def test_slot_length
assert_equal :>= , @method.callable.name assert_equal :> , @method.callable.name
assert_equal 7 , @method.slot_instructions.length assert_equal 7 , @method.slot_instructions.length
end end
def test_compile def test_compile
assert_equal Risc::MethodCompiler , @method.to_risc.class assert_equal Risc::MethodCompiler , @method.to_risc.class
end end
def test_risc_length def test_risc_length
assert_equal 24 , @method.to_risc.risc_instructions.length assert_equal 25 , @method.to_risc.risc_instructions.length
end end
def test_all def test_all
assert_slot_to_reg risc(1),:r0 , 2 , :r1 assert_slot_to_reg 1 , :message , 2 , "message.receiver"
assert_slot_to_reg risc(2),:r1 , 2 , :r1 assert_slot_to_reg 2 , "message.receiver" , 2 , "message.receiver"
assert_slot_to_reg risc(3),:r0 , 9 , :r2 assert_slot_to_reg 3 ,:message , 9 , "message.arg1"
assert_slot_to_reg risc(4),:r2 , 2 , :r2 assert_slot_to_reg 4 , "message.arg1" , 2 , "message.arg1"
assert_operator risc(5) , :- , :r1 , :r2 assert_operator 5 , :- , "message.receiver" , "message.arg1"
assert_minus risc(6) , "false_label_" assert_minus 6 , "false_label_"
assert_zero risc(7) , "false_label_" assert_zero 7 , "false_label_"
assert_load risc(8) , Parfait::TrueClass assert_load 8 , Parfait::TrueClass , :result
assert_branch risc(9) , "merge_label_" assert_branch 9 , "merge_label_"
assert_label risc(10) , "false_label_" assert_label 10 , "false_label_"
assert_load risc(11) , Parfait::FalseClass assert_load 11 , Parfait::FalseClass , :result
assert_label risc(12) , "merge_label_" assert_label 12 , "merge_label_"
assert_reg_to_slot risc(13) , :r3 , :r0 , 5 assert_reg_to_slot 13 , :result , :message , 5
assert_slot_to_reg risc(14),:r0 , 5 , :r2 assert_slot_to_reg 14 ,:message , 5 , "message.return_value"
assert_reg_to_slot risc(15) , :r2 , :r0 , 5 assert_reg_to_slot 15 , "message.return_value" , :message , 5
assert_branch risc(16) , "return_label" assert_branch 16 , "return_label"
end end
def test_return def test_return
assert_return(17) assert_return(17)

View File

@ -3,91 +3,122 @@ module Minitest
def assert_tos string , object def assert_tos string , object
assert_equal string , object.to_s.gsub("\n",";").gsub(/\s+/," ").gsub("; ",";") assert_equal string , object.to_s.gsub("\n",";").gsub(/\s+/," ").gsub("; ",";")
end end
def assert_register( kind , pattern , register) def assert_register( kind , pattern , register , at = 0)
return unless register return unless register
if(pattern.is_a?(Symbol)) if(pattern.is_a?(Symbol))
assert_equal( pattern , register.symbol , "wrong #{kind} register:#{register}") assert_equal( pattern , register.symbol , "wrong #{kind} register:#{register} , at:#{at}")
else else
is_parts = pattern.split(".") is_parts = pattern.split(".")
reg_parts = register.symbol.to_s.split(".") reg_parts = register.symbol.to_s.split(".")
assert_equal reg_parts.length , is_parts.length , "wrong dot length for #{pattern}" assert_equal reg_parts.length , is_parts.length , "wrong dot length for #{pattern} , at:#{at}"
is_parts.each_with_index do |part , index| is_parts.each_with_index do |part , index|
assert reg_parts[index].start_with?(part) , "wrong #{kind}, at:#{part} register:#{register}" assert reg_parts[index].start_with?(part) , "wrong #{kind}, part:#{part} register:#{register}, at:#{at}"
end end
end end
end end
def assert_slot_to_reg( slot , array = nil, index = nil , register = nil) def assert_slot_to_reg( slot_i , array = nil, index = nil , register = nil)
assert_equal Risc::SlotToReg , slot.class assert_equal Integer , slot_i.class , "assert_slot_to_reg #{slot_i}"
assert_register( :source , array , slot.array) slot = risc(slot_i)
assert_register( :destination , register , slot.register ) assert_equal Risc::SlotToReg , slot.class , "Class at #{slot_i}"
assert_index( :source , slot , index) assert_register( :source , array , slot.array , slot_i)
assert_register( :destination , register , slot.register , slot_i )
assert_index( :source , slot_i , index)
end end
def assert_reg_to_slot( slot , register = nil, array = nil, index = nil ) def assert_reg_to_slot( slot_i , register = nil, array = nil, index = nil )
assert_equal Risc::RegToSlot , slot.class assert_equal Integer , slot_i.class, "assert_reg_to_slot #{slot_i}"
assert_register( :source , register , slot.register ) slot = risc(slot_i)
assert_register( :destination , array , slot.array) assert_equal Risc::RegToSlot , slot.class, "Class at #{slot_i}"
assert_index( :destination , slot , index) assert_register( :source , register , slot.register , slot_i)
assert_register( :destination , array , slot.array , slot_i)
assert_index( :destination , slot_i , index )
end end
def assert_index(kind , slot , index) def assert_index(kind , slot_i , index)
return unless index return unless index
assert_equal Integer , slot_i.class , "assert_index #{slot_i}"
slot = risc(slot_i)
if(slot.index.is_a?(Risc::RegisterValue)) if(slot.index.is_a?(Risc::RegisterValue))
assert_equal( Symbol , index.class, "wrong #{kind} index class") assert_equal( Symbol , index.class, "wrong #{kind} index class, at:#{slot_i}")
assert_equal( index , slot.index.symbol, "wrong #{kind} index") assert_equal( index , slot.index.symbol, "wrong #{kind} index, at#{slot_i}")
else else
assert_equal( index , slot.index, "wrong #{kind} index") assert_equal( index , slot.index, "wrong #{kind} index, at:#{slot_i}")
end end
end end
def assert_load(load , clazz = nil , register = nil) def assert_load(load_i , clazz = nil , register = nil)
assert_equal Integer , load_i.class, "assert_load #{load_i}"
load = risc(load_i)
assert_equal Risc::LoadConstant , load.class assert_equal Risc::LoadConstant , load.class
assert_equal( clazz , load.constant.class) if clazz assert_equal( clazz , load.constant.class) if clazz
if register if register
assert_register(:source , register , load.register) assert_register(:source , register , load.register)
else else
raise "rewrite" raise "add register at:#{load_i}, as third operand at #{load_i}"
end end
end end
def assert_transfer( transfer , from , to) def assert_transfer( transfer_i , from , to)
assert_equal Risc::Transfer , transfer.class assert_equal Integer , transfer_i.class, "assert_transfer #{transfer_i}"
assert_register( :source , from , transfer.from ) transfer = risc(transfer_i)
assert_register( :destination , to , transfer.to ) assert_equal Risc::Transfer , transfer.class, "Class at #{transfer_i}"
assert_register( :source , from , transfer.from , transfer_i)
assert_register( :destination , to , transfer.to , transfer_i)
end end
def assert_label( label , name ) def assert_label( label_i , name , at = nil)
assert_equal Risc::Label , label.class if(at)
if(name[-1] == "_") label = label_i
assert label.name.start_with?(name) , "Label does not start with #{name}:#{label.name}" label_i = at
else else
assert_equal name , label.name assert_equal Integer , label_i.class, "assert_label #{label_i}"
label = risc(label_i)
end
assert_equal Risc::Label , label.class, "Class at:#{label_i}"
if(name[-1] == "_")
assert label.name.start_with?(name) , "Label at:#{label_i} does not start with #{name}:#{label.name}"
else
assert_equal name , label.name , "Label at:#{label_i}"
end end
end end
def assert_branch( branch , label_name ) def assert_branch( branch_i , label_name )
assert_equal Risc::Branch , branch.class assert_equal Integer , branch_i.class, "assert_branch #{branch_i}"
assert_label branch.label , label_name branch = risc(branch_i)
assert_equal Risc::Branch , branch.class , "Class at:#{branch_i}"
assert_label branch.label , label_name , "Label at #{branch_i}"
end end
def assert_operator ins , op , left , right def assert_operator ins_i , op , left , right
assert_equal Risc::OperatorInstruction , ins.class assert_equal Integer , ins_i.class, "assert_operator #{ins_i}"
ins = risc(ins_i)
assert_equal Risc::OperatorInstruction , ins.class , "Class at:#{ins_i}"
assert_equal op , ins.operator assert_equal op , ins.operator
assert_register :left , left , ins.left assert_register :left , left , ins.left , ins_i
assert_register :right , right , ins.right assert_register :right , right , ins.right, ins_i
end end
def assert_zero ins , label def assert_zero ins_i , label
assert_equal Risc::IsNotZero , ins.class assert_equal Integer , ins_i.class, "assert_zero #{ins_i}"
assert_label ins.label , label ins = risc(ins_i)
assert_equal Risc::IsNotZero , ins.class , "Class at:#{ins_i}"
assert_label ins.label , label , "Label at:#{ins_i}"
end end
def assert_not_zero ins , label def assert_not_zero ins_i , label
assert_equal Risc::IsZero , ins.class assert_equal Integer , ins_i.class, "assert_not_zero #{ins_i}"
assert_label ins.label , label ins = risc(ins_i)
assert_equal Risc::IsZero , ins.class, "Class at:#{ins_i}"
assert_label ins.label , label, "Label at:#{ins_i}"
end end
def assert_syscall ins , name def assert_syscall ins , name
assert_equal Risc::Syscall , ins.class assert_equal Integer , ins_i.class, "assert_syscall #{ins_i}"
ins = risc(ins_i)
assert_equal Risc::Syscall , ins.class, "Class at:#{ins_i}"
assert_equal ins.name , name assert_equal ins.name , name
end end
def assert_minus ins , label def assert_minus ins_i , label
assert_equal Risc::IsMinus , ins.class assert_equal Integer , ins_i.class, "assert_minus #{ins_i}"
assert_label ins.label , label ins = risc(ins_i)
assert_equal Risc::IsMinus , ins.class, "Class at:#{ins_i}"
assert_label ins.label , label, ins_i
end end
def assert_data(ins , data) def assert_data(ins_i , data)
assert_equal Risc::LoadData , ins.class assert_equal Integer , ins_i.class, "assert_data #{ins_i}"
assert_equal data , ins.constant ins = risc(ins_i)
assert_equal Risc::LoadData , ins.class, "Class at:#{ins_i}"
assert_equal data , ins.constant , "Data at:#{ins_i}"
end end
end end
end end