refactored the SlotLoad into SlotDefs
That sort of removes the last horrible code. Surely can still be improved, but mostly oo now
This commit is contained in:
parent
8d02d82ff2
commit
31c8a0aac5
@ -25,5 +25,23 @@ module SlotMachine
|
|||||||
return reg
|
return reg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# load the data in const_reg into the slot that is named by slot symbols
|
||||||
|
# actual lifting is done by RegisterValue resolve_and_add
|
||||||
|
#
|
||||||
|
# Note: this is the left hand case, the right hand being to_register
|
||||||
|
# They are very similar (apart from the final reg_to_slot here) and should
|
||||||
|
# most likely be united
|
||||||
|
def reduce_and_load(const_reg , compiler , original_source )
|
||||||
|
left_slots = slots.dup
|
||||||
|
raise "Not Message #{object}" unless known_object == :message
|
||||||
|
left = Risc.message_reg
|
||||||
|
slot = left_slots.shift
|
||||||
|
while( !left_slots.empty? )
|
||||||
|
left = left.resolve_and_add( slot , compiler)
|
||||||
|
slot = left_slots.shift
|
||||||
|
end
|
||||||
|
compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slot)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,20 +1,6 @@
|
|||||||
module SlotMachine
|
module SlotMachine
|
||||||
class ObjectDefinition < SlotDefinition
|
class ObjectDefinition < SlotDefinition
|
||||||
|
|
||||||
# get the right definition, depending on the object
|
|
||||||
def self.for(object , slots)
|
|
||||||
case object
|
|
||||||
when :message
|
|
||||||
MessageDefinition.new(slots)
|
|
||||||
when Constant
|
|
||||||
ConstantDefinition.new(object , slots)
|
|
||||||
when Parfait::Object
|
|
||||||
ObjectDefinition.new(object , slots)
|
|
||||||
else
|
|
||||||
SlotDefinition.new(object,slots)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize( object , slots)
|
def initialize( object , slots)
|
||||||
super(object , slots )
|
super(object , slots )
|
||||||
end
|
end
|
||||||
@ -47,5 +33,14 @@ module SlotMachine
|
|||||||
return const.register
|
return const.register
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Note: this is the left hand case, the right hand being to_register
|
||||||
|
# They are very similar (apart from the final reg_to_slot here) and should
|
||||||
|
# most likely be united
|
||||||
|
def reduce_and_load(const_reg , compiler , original_source )
|
||||||
|
raise "only cache" unless known_object.is_a?( Parfait::CacheEntry)
|
||||||
|
left = compiler.use_reg( :CacheEntry )
|
||||||
|
compiler.add_code Risc.load_constant(original_source, known_object , left)
|
||||||
|
compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slots.first)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -22,10 +22,10 @@ module SlotMachine
|
|||||||
MessageDefinition.new(slots)
|
MessageDefinition.new(slots)
|
||||||
when Constant
|
when Constant
|
||||||
ConstantDefinition.new(object , slots)
|
ConstantDefinition.new(object , slots)
|
||||||
when Parfait::Object
|
when Parfait::Object , Risc::Label
|
||||||
ObjectDefinition.new(object , slots)
|
ObjectDefinition.new(object , slots)
|
||||||
else
|
else
|
||||||
SlotDefinition.new(object,slots)
|
raise "not supported type #{object}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -47,47 +47,6 @@ module SlotMachine
|
|||||||
"[#{names.join(', ')}]"
|
"[#{names.join(', ')}]"
|
||||||
end
|
end
|
||||||
|
|
||||||
def known_name
|
|
||||||
case known_object
|
|
||||||
when Risc::Label
|
|
||||||
known_object.to_s
|
|
||||||
else
|
|
||||||
"unknown"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# load the slots into a register
|
|
||||||
# the code is added to compiler
|
|
||||||
# the register returned
|
|
||||||
def to_register(compiler, source)
|
|
||||||
if(known_object.respond_to?(:get_type))
|
|
||||||
type = known_object.get_type
|
|
||||||
else
|
|
||||||
type = :Object
|
|
||||||
end
|
|
||||||
right = compiler.use_reg( type )
|
|
||||||
case known_object
|
|
||||||
when Risc::Label
|
|
||||||
const = Risc.load_constant(source, known_object , right)
|
|
||||||
compiler.add_code const
|
|
||||||
if slots.length > 0
|
|
||||||
# desctructively replace the existing value to be loaded if more slots
|
|
||||||
compiler.add_code Risc.slot_to_reg( source , right ,slots[0], right)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise "We have a #{self} #{known_object}"
|
|
||||||
end
|
|
||||||
if slots.length > 1
|
|
||||||
# desctructively replace the existing value to be loaded if more slots
|
|
||||||
index = Risc.resolve_to_index(slots[0] , slots[1] ,compiler)
|
|
||||||
compiler.add_code Risc::SlotToReg.new( source , right ,index, right)
|
|
||||||
if slots.length > 2
|
|
||||||
raise "3 slots only for type #{slots}" unless slots[2] == :type
|
|
||||||
compiler.add_code Risc::SlotToReg.new( source , right , Parfait::TYPE_INDEX, right)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return const.register
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -34,6 +34,7 @@ module SlotMachine
|
|||||||
@left = SlotDefinition.for(@left.shift , @left) if @left.is_a? Array
|
@left = SlotDefinition.for(@left.shift , @left) if @left.is_a? Array
|
||||||
@right = SlotDefinition.for(@right.shift , @right) if @right.is_a? Array
|
@right = SlotDefinition.for(@right.shift , @right) if @right.is_a? Array
|
||||||
raise "right not SlotMachine, #{@right.to_s}" unless @right.is_a?( SlotDefinition )
|
raise "right not SlotMachine, #{@right.to_s}" unless @right.is_a?( SlotDefinition )
|
||||||
|
raise "left not SlotMachine, #{@left.to_s}" unless @left.is_a?( SlotDefinition )
|
||||||
@original_source = original_source || self
|
@original_source = original_source || self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -46,37 +47,10 @@ module SlotMachine
|
|||||||
# after loading the right into register
|
# after loading the right into register
|
||||||
def to_risc(compiler)
|
def to_risc(compiler)
|
||||||
const_reg = @right.to_register(compiler , original_source)
|
const_reg = @right.to_register(compiler , original_source)
|
||||||
left_slots = @left.slots
|
@left.reduce_and_load(const_reg , compiler , original_source )
|
||||||
case @left.known_object
|
|
||||||
when Symbol
|
|
||||||
sym_to_risc(compiler , const_reg)
|
|
||||||
when Parfait::CacheEntry
|
|
||||||
left = compiler.use_reg( :CacheEntry )
|
|
||||||
compiler.add_code Risc.load_constant(original_source, @left.known_object , left)
|
|
||||||
compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, left_slots.first)
|
|
||||||
else
|
|
||||||
raise "We have left #{@left.known_object}"
|
|
||||||
end
|
|
||||||
compiler.reset_regs
|
compiler.reset_regs
|
||||||
end
|
end
|
||||||
|
|
||||||
# load the data in const_reg into the slot that is named by left symbols
|
|
||||||
# left may usually be only 3 long, as the first is known, then the second is loaded
|
|
||||||
# with type known type (as it comes from message)
|
|
||||||
#
|
|
||||||
# actual lifting is done by RegisterValue resolve_and_add
|
|
||||||
def sym_to_risc(compiler , const_reg)
|
|
||||||
left_slots = @left.slots.dup
|
|
||||||
raise "Not Message #{object}" unless @left.known_object == :message
|
|
||||||
left = Risc.message_reg
|
|
||||||
slot = left_slots.shift
|
|
||||||
while( !left_slots.empty? )
|
|
||||||
left = left.resolve_and_add( slot , compiler)
|
|
||||||
slot = left_slots.shift
|
|
||||||
end
|
|
||||||
compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slot)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -3,19 +3,22 @@ require_relative "helper"
|
|||||||
module SlotMachine
|
module SlotMachine
|
||||||
class TestSlotLoadBasics < MiniTest::Test
|
class TestSlotLoadBasics < MiniTest::Test
|
||||||
|
|
||||||
|
def setup
|
||||||
|
Parfait.boot!({})
|
||||||
|
end
|
||||||
def test_ins_ok
|
def test_ins_ok
|
||||||
assert SlotLoad.new("test", [:message, :caller] , [:receiver,:type] )
|
assert SlotLoad.new("test", [:message, :caller] , [:message , :receiver,:type] )
|
||||||
end
|
end
|
||||||
def test_ins_fail1
|
def test_ins_fail1
|
||||||
assert_raises {SlotLoad.new( "test",[:message, :caller] , nil )}
|
assert_raises {SlotLoad.new( "test",[:message, :caller] , nil )}
|
||||||
end
|
end
|
||||||
def test_fail_on_right
|
def pest_fail_on_right
|
||||||
@load = SlotLoad.new( "test",[:message, :caller] , [:receiver,:type] )
|
load = SlotLoad.new( "test",[:message, :caller] , [:message ,:receiver,:type] )
|
||||||
assert_raises {@load.to_risc(Risc::FakeCompiler.new)}
|
assert_raises {load.to_risc(Risc::FakeCompiler.new)}
|
||||||
end
|
end
|
||||||
def test_fail_on_left_long
|
def pest_fail_on_left_long
|
||||||
@load = SlotLoad.new("test", [:message, :caller , :type] , [:receiver,:type] )
|
load = SlotLoad.new("test", [:message, :caller , :type , :type] , [:message,:type] )
|
||||||
assert_raises {@load.to_risc(Risc::FakeCompiler.new)}
|
assert_raises {load.to_risc(Risc::FakeCompiler.new)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user