Fix div10 without method_missing

but reanimate infer_type to auto create the needed regsiters
also some helpers
This commit is contained in:
Torsten 2020-03-04 12:39:52 +02:00
parent 9a5e0f15cd
commit 9c5d17a3bb
6 changed files with 47 additions and 20 deletions

View File

@ -24,6 +24,20 @@ module Risc
@source_used = false @source_used = false
end end
# especially for the macros (where register allocation is often manual)
# register need to be created. And since the code is "ported" we create
# them with the old names, which used the infer_type to infer the type
#
# Return the RegisterValue with given name and inferred type, compiler set
def register( name )
RegisterValue.new(name , infer_type(name) ).set_compiler(compiler)
end
# create an add a RegisterTransfer instruction with to and from
def transfer(to , from)
add_code Risc.transfer(@source, to , from)
end
# Infer the type from a symbol. In the simplest case the symbol is the class name. # Infer the type from a symbol. In the simplest case the symbol is the class name.
# But in building, sometimes variations are needed, so next_message or caller work # But in building, sometimes variations are needed, so next_message or caller work
# too (and both return "Message") # too (and both return "Message")
@ -90,8 +104,8 @@ module Risc
return ins return ins
end end
def load_object(object) def load_object(object , into = nil)
@compiler.load_object(object) @compiler.load_object(object , into)
end end
# for some methods that return an integer it is beneficial to pre allocate the # for some methods that return an integer it is beneficial to pre allocate the

View File

@ -93,8 +93,9 @@ module Risc
# Load a constant, meaning create a LoadConstant instruction for the constant # Load a constant, meaning create a LoadConstant instruction for the constant
# add the instruction to the code and return the register_value that was created # add the instruction to the code and return the register_value that was created
# for further use # for further use
def load_object( object ) # register may be passed in (epecially in mcro building) as second arg
ins = Risc.load_constant("load to #{object}" , object) def load_object( object , into = nil)
ins = Risc.load_constant("load to #{object}" , object , into)
ins.register.set_compiler(self) ins.register.set_compiler(self)
add_code ins add_code ins
# todo for constants (not objects) # todo for constants (not objects)

View File

@ -32,18 +32,21 @@ module Risc
end end
end end
end end
def self.load_constant( source , constant )
def self.load_constant( source , constant , register = nil)
value = constant value = constant
case constant unless register
when Parfait::Object case constant
type = constant.get_type when Parfait::Object
when Label type = constant.get_type
type = constant.address.get_type when Label
else type = constant.address.get_type
type = constant.ct_type else
value = constant.value type = constant.ct_type
value = constant.value
end
register = RegisterValue.new( "id_#{value.object_id}".to_sym , type )
end end
register = RegisterValue.new( "id_#{value.object_id}".to_sym , type )
LoadConstant.new( source , constant , register ) LoadConstant.new( source , constant , register )
end end
end end

View File

@ -4,13 +4,16 @@ module SlotMachine
s = "div_10 " s = "div_10 "
builder = compiler.builder(compiler.source) builder = compiler.builder(compiler.source)
integer_tmp = builder.allocate_int integer_tmp = builder.allocate_int
integer_1 = builder.register( :integer_1 )
integer_reg = builder.register( :integer_reg )
integer_const = builder.register( :integer_const )
builder.build do builder.build do
integer_self! << message[:receiver] integer_self = message[:receiver].to_reg.reduce_int
integer_self.reduce_int transfer( integer_self , integer_1)
integer_1! << integer_self transfer( integer_self , integer_reg)
integer_reg! << integer_self
load_object( Parfait::Integer.new(1) , integer_const)
integer_const! << 1
integer_1.op :>> , integer_const integer_1.op :>> , integer_const
integer_const << 2 integer_const << 2

View File

@ -10,6 +10,12 @@ module Risc
@compiler = Risc::MethodCompiler.new( method, SlotMachine::Label.new( "source_name", "return_label") ) @compiler = Risc::MethodCompiler.new( method, SlotMachine::Label.new( "source_name", "return_label") )
@builder = @compiler.builder(method) @builder = @compiler.builder(method)
end end
def test_register_creation
assert_equal RegisterValue , @builder.register(:name).class
end
def test_register_creation_compiler
assert @builder.register(:name).compiler
end
def test_list def test_list
assert_equal :List , @builder.infer_type(:list).class_name assert_equal :List , @builder.infer_type(:list).class_name
end end

View File

@ -14,7 +14,7 @@ module SlotMachine
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 70 , @method.to_risc.risc_instructions.length assert_equal 69 , @method.to_risc.risc_instructions.length
end end
end end
end end