Fix div10 without method_missing
but reanimate infer_type to auto create the needed regsiters also some helpers
This commit is contained in:
parent
9a5e0f15cd
commit
9c5d17a3bb
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user