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
|
||||
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
|
||||
|
@ -1,20 +1,6 @@
|
||||
module SlotMachine
|
||||
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)
|
||||
super(object , slots )
|
||||
end
|
||||
@ -47,5 +33,14 @@ module SlotMachine
|
||||
return const.register
|
||||
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
|
||||
|
@ -22,10 +22,10 @@ module SlotMachine
|
||||
MessageDefinition.new(slots)
|
||||
when Constant
|
||||
ConstantDefinition.new(object , slots)
|
||||
when Parfait::Object
|
||||
when Parfait::Object , Risc::Label
|
||||
ObjectDefinition.new(object , slots)
|
||||
else
|
||||
SlotDefinition.new(object,slots)
|
||||
raise "not supported type #{object}"
|
||||
end
|
||||
end
|
||||
|
||||
@ -47,47 +47,6 @@ module SlotMachine
|
||||
"[#{names.join(', ')}]"
|
||||
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
|
||||
|
@ -34,6 +34,7 @@ module SlotMachine
|
||||
@left = SlotDefinition.for(@left.shift , @left) if @left.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 "left not SlotMachine, #{@left.to_s}" unless @left.is_a?( SlotDefinition )
|
||||
@original_source = original_source || self
|
||||
end
|
||||
|
||||
@ -46,37 +47,10 @@ module SlotMachine
|
||||
# after loading the right into register
|
||||
def to_risc(compiler)
|
||||
const_reg = @right.to_register(compiler , original_source)
|
||||
left_slots = @left.slots
|
||||
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
|
||||
@left.reduce_and_load(const_reg , compiler , original_source )
|
||||
compiler.reset_regs
|
||||
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
|
||||
|
@ -3,19 +3,22 @@ require_relative "helper"
|
||||
module SlotMachine
|
||||
class TestSlotLoadBasics < MiniTest::Test
|
||||
|
||||
def setup
|
||||
Parfait.boot!({})
|
||||
end
|
||||
def test_ins_ok
|
||||
assert SlotLoad.new("test", [:message, :caller] , [:receiver,:type] )
|
||||
assert SlotLoad.new("test", [:message, :caller] , [:message , :receiver,:type] )
|
||||
end
|
||||
def test_ins_fail1
|
||||
assert_raises {SlotLoad.new( "test",[:message, :caller] , nil )}
|
||||
end
|
||||
def test_fail_on_right
|
||||
@load = SlotLoad.new( "test",[:message, :caller] , [:receiver,:type] )
|
||||
assert_raises {@load.to_risc(Risc::FakeCompiler.new)}
|
||||
def pest_fail_on_right
|
||||
load = SlotLoad.new( "test",[:message, :caller] , [:message ,:receiver,:type] )
|
||||
assert_raises {load.to_risc(Risc::FakeCompiler.new)}
|
||||
end
|
||||
def test_fail_on_left_long
|
||||
@load = SlotLoad.new("test", [:message, :caller , :type] , [:receiver,:type] )
|
||||
assert_raises {@load.to_risc(Risc::FakeCompiler.new)}
|
||||
def pest_fail_on_left_long
|
||||
load = SlotLoad.new("test", [:message, :caller , :type , :type] , [:message,:type] )
|
||||
assert_raises {load.to_risc(Risc::FakeCompiler.new)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user