Makes slots linked list
slots used to ba an array of symbols Now we have an object for each slot, that holds the name and the next_slot relatively easy change, though quite broad
This commit is contained in:
parent
93103d551f
commit
c1679bd6ff
@ -18,11 +18,13 @@ module SlotMachine
|
|||||||
|
|
||||||
attr_reader :name , :next_slot
|
attr_reader :name , :next_slot
|
||||||
|
|
||||||
|
# initialize with just the name of the slot. Add more to the chain with set_next
|
||||||
def initialize( name )
|
def initialize( name )
|
||||||
raise "No name" unless name
|
raise "No name" unless name
|
||||||
@name = name
|
@name = name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#set the next_slot , but always at the end of the chain
|
||||||
def set_next(slot)
|
def set_next(slot)
|
||||||
if(@next_slot)
|
if(@next_slot)
|
||||||
@next_slot.set_next(slot)
|
@next_slot.set_next(slot)
|
||||||
@ -31,12 +33,18 @@ module SlotMachine
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# return the length of chain, ie 1 plus however many more next_slots there are
|
||||||
|
def length
|
||||||
|
return 1 unless @next_slot
|
||||||
|
1 + @next_slot.length
|
||||||
|
end
|
||||||
|
|
||||||
|
# name of all the slots, with dot syntax
|
||||||
def to_s
|
def to_s
|
||||||
names = name.to_s
|
names = name.to_s
|
||||||
names += ".#{@next_slot}" if @next_slot
|
names += ".#{@next_slot}" if @next_slot
|
||||||
names
|
names
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,27 +11,41 @@ module SlotMachine
|
|||||||
when Parfait::Object , Risc::Label
|
when Parfait::Object , Risc::Label
|
||||||
SlottedObject.new(object , slots)
|
SlottedObject.new(object , slots)
|
||||||
else
|
else
|
||||||
raise "not supported type #{object}"
|
raise "not supported type #{object}:#{object.class}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# The first in a possible chain of slots, that name instance variables in the
|
# The first in a possible chain of slots, that name instance variables in the
|
||||||
# previous object
|
# previous object
|
||||||
attr_reader :slot
|
attr_reader :slots
|
||||||
|
|
||||||
def initialize( slots )
|
def initialize( slots )
|
||||||
raise "No slots #{object}" unless slots
|
raise "No slots #{object}" unless slots
|
||||||
slots = [slots] unless slots.is_a?(Array)
|
slots = [slots] unless slots.is_a?(Array)
|
||||||
first = slots.shift
|
first = slots.shift
|
||||||
@slot = Slot.new(first)
|
return unless first
|
||||||
|
@slots = Slot.new(first)
|
||||||
until(slots.empty?)
|
until(slots.empty?)
|
||||||
@slot.set_next( Slot.new( slots.shift ))
|
@slots.set_next( Slot.new( slots.shift ))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def slots_length
|
||||||
|
return 0 unless @slots
|
||||||
|
1 + @slots.length
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_next(slot)
|
||||||
|
if(@slots)
|
||||||
|
@slots.set_next(slot)
|
||||||
|
else
|
||||||
|
@slots = slot
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
names = known_name.to_s
|
names = known_name.to_s
|
||||||
names += ".#{@slot}" if @slot
|
names += ".#{@slots}" if @slots
|
||||||
names
|
names
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
module SlotMachine
|
module SlotMachine
|
||||||
class SlottedConstant < Slotted
|
class SlottedConstant < Slotted
|
||||||
|
|
||||||
|
|
||||||
attr_reader :known_object
|
attr_reader :known_object
|
||||||
|
|
||||||
def initialize( object , slots)
|
def initialize( object , slots)
|
||||||
@ -27,11 +26,11 @@ module SlotMachine
|
|||||||
parfait = known_object.to_parfait(compiler)
|
parfait = known_object.to_parfait(compiler)
|
||||||
const = Risc.load_constant(source, parfait , right)
|
const = Risc.load_constant(source, parfait , right)
|
||||||
compiler.add_code const
|
compiler.add_code const
|
||||||
if slots.length == 1
|
if slots_length == 2
|
||||||
raise "only type allowed for constants, not #{slots[0]}" unless slots[0] == :type
|
raise "only type allowed for constants, not #{slots}" unless slots.name == :type
|
||||||
compiler.add_code Risc::SlotToReg.new( source , right , Parfait::TYPE_INDEX, right)
|
compiler.add_code Risc::SlotToReg.new( source , right , Parfait::TYPE_INDEX, right)
|
||||||
end
|
end
|
||||||
raise "Can't have slots into Constants #{slots}" if slots.length > 1
|
raise "Can't have slots into Constants #{slots}" if slots_length > 2
|
||||||
return const.register
|
return const.register
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
module SlotMachine
|
module SlotMachine
|
||||||
class SlottedMessage < Slotted
|
class SlottedMessage < Slotted
|
||||||
|
|
||||||
|
|
||||||
def known_name
|
def known_name
|
||||||
:message
|
:message
|
||||||
end
|
end
|
||||||
@ -13,13 +12,13 @@ module SlotMachine
|
|||||||
def to_register(compiler, source)
|
def to_register(compiler, source)
|
||||||
type = :Message
|
type = :Message
|
||||||
right = compiler.use_reg( type )
|
right = compiler.use_reg( type )
|
||||||
slots = @slot
|
slots = @slots
|
||||||
left = Risc.message_reg
|
left = Risc.message_reg
|
||||||
left = left.resolve_and_add( slots.name , compiler)
|
left = left.resolve_and_add( slots.name , compiler)
|
||||||
reg = compiler.current.register
|
reg = compiler.current.register
|
||||||
slots = slots.next_slot
|
slots = slots.next_slot
|
||||||
while( slots )
|
while( slots )
|
||||||
left = left.resolve_and_add( slots , compiler)
|
left = left.resolve_and_add( slots.name , compiler)
|
||||||
slots = slots.next_slot
|
slots = slots.next_slot
|
||||||
end
|
end
|
||||||
return reg
|
return reg
|
||||||
@ -32,15 +31,14 @@ module SlotMachine
|
|||||||
# They are very similar (apart from the final reg_to_slot here) and should
|
# They are very similar (apart from the final reg_to_slot here) and should
|
||||||
# most likely be united
|
# most likely be united
|
||||||
def reduce_and_load(const_reg , compiler , original_source )
|
def reduce_and_load(const_reg , compiler , original_source )
|
||||||
left_slots = slots.dup
|
|
||||||
raise "Not Message #{object}" unless known_object == :message
|
raise "Not Message #{object}" unless known_object == :message
|
||||||
left = Risc.message_reg
|
left = Risc.message_reg
|
||||||
slot = left_slots.shift
|
slot = slots
|
||||||
while( !left_slots.empty? )
|
while( slot.next_slot )
|
||||||
left = left.resolve_and_add( slot , compiler)
|
left = left.resolve_and_add( slot.name , compiler)
|
||||||
slot = left_slots.shift
|
slot = slot.next_slot
|
||||||
end
|
end
|
||||||
compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slot)
|
compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slot.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -21,16 +21,16 @@ module SlotMachine
|
|||||||
right = compiler.use_reg( type )
|
right = compiler.use_reg( type )
|
||||||
const = Risc.load_constant(source, known_object , right)
|
const = Risc.load_constant(source, known_object , right)
|
||||||
compiler.add_code const
|
compiler.add_code const
|
||||||
if slots.length > 0
|
if slots_length > 1
|
||||||
# desctructively replace the existing value to be loaded if more slots
|
# desctructively replace the existing value to be loaded if more slots
|
||||||
compiler.add_code Risc.slot_to_reg( source , right ,slots[0], right)
|
compiler.add_code Risc.slot_to_reg( source , right ,slots.name, right)
|
||||||
end
|
end
|
||||||
if slots.length > 1
|
if slots_length > 2
|
||||||
# desctructively replace the existing value to be loaded if more slots
|
# desctructively replace the existing value to be loaded if more slots
|
||||||
index = Risc.resolve_to_index(slots[0] , slots[1] ,compiler)
|
index = Risc.resolve_to_index(slots.name , slots.next_slot.name ,compiler)
|
||||||
compiler.add_code Risc::SlotToReg.new( source , right ,index, right)
|
compiler.add_code Risc::SlotToReg.new( source , right ,index, right)
|
||||||
if slots.length > 2
|
if slots_length > 3
|
||||||
raise "3 slots only for type #{slots}" unless slots[2] == :type
|
raise "3 slots only for type #{slots}" unless slots.next_slot.next_slot.name == :type
|
||||||
compiler.add_code Risc::SlotToReg.new( source , right , Parfait::TYPE_INDEX, right)
|
compiler.add_code Risc::SlotToReg.new( source , right , Parfait::TYPE_INDEX, right)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -44,7 +44,7 @@ module SlotMachine
|
|||||||
raise "only cache" unless known_object.is_a?( Parfait::CacheEntry)
|
raise "only cache" unless known_object.is_a?( Parfait::CacheEntry)
|
||||||
left = compiler.use_reg( :CacheEntry )
|
left = compiler.use_reg( :CacheEntry )
|
||||||
compiler.add_code Risc.load_constant(original_source, known_object , left)
|
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)
|
compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slots.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -33,7 +33,7 @@ module Sol
|
|||||||
# Derived classes do not implement to_slot, only slot_position
|
# Derived classes do not implement to_slot, only slot_position
|
||||||
def to_slot(compiler)
|
def to_slot(compiler)
|
||||||
to = SlotMachine::Slotted.for(:message , self.slot_position(compiler))
|
to = SlotMachine::Slotted.for(:message , self.slot_position(compiler))
|
||||||
from = @value.to_slot_definition(compiler)
|
from = @value.to_slotted(compiler)
|
||||||
assign = SlotMachine::SlotLoad.new(self,to,from)
|
assign = SlotMachine::SlotLoad.new(self,to,from)
|
||||||
return assign unless @value.is_a?(CallStatement)
|
return assign unless @value.is_a?(CallStatement)
|
||||||
@value.to_slot(compiler) << assign
|
@value.to_slot(compiler) << assign
|
||||||
|
@ -9,7 +9,7 @@ module Sol
|
|||||||
def initialize(value)
|
def initialize(value)
|
||||||
@value = value
|
@value = value
|
||||||
end
|
end
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
return SlotMachine::Slotted.for(SlotMachine::IntegerConstant.new(@value) , [])
|
return SlotMachine::Slotted.for(SlotMachine::IntegerConstant.new(@value) , [])
|
||||||
end
|
end
|
||||||
def ct_type
|
def ct_type
|
||||||
@ -37,7 +37,7 @@ module Sol
|
|||||||
def ct_type
|
def ct_type
|
||||||
Parfait.object_space.get_type_by_class_name(:True)
|
Parfait.object_space.get_type_by_class_name(:True)
|
||||||
end
|
end
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
return SlotMachine::Slotted.for(Parfait.object_space.true_object , [])
|
return SlotMachine::Slotted.for(Parfait.object_space.true_object , [])
|
||||||
end
|
end
|
||||||
def to_s(depth = 0)
|
def to_s(depth = 0)
|
||||||
@ -49,7 +49,7 @@ module Sol
|
|||||||
def ct_type
|
def ct_type
|
||||||
Parfait.object_space.get_type_by_class_name(:False)
|
Parfait.object_space.get_type_by_class_name(:False)
|
||||||
end
|
end
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
return SlotMachine::Slotted.for(Parfait.object_space.false_object , [])
|
return SlotMachine::Slotted.for(Parfait.object_space.false_object , [])
|
||||||
end
|
end
|
||||||
def to_s(depth = 0)
|
def to_s(depth = 0)
|
||||||
@ -61,7 +61,7 @@ module Sol
|
|||||||
def ct_type
|
def ct_type
|
||||||
Parfait.object_space.get_type_by_class_name(:Nil)
|
Parfait.object_space.get_type_by_class_name(:Nil)
|
||||||
end
|
end
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
return SlotMachine::Slotted.for(Parfait.object_space.nil_object , [])
|
return SlotMachine::Slotted.for(Parfait.object_space.nil_object , [])
|
||||||
end
|
end
|
||||||
def to_s(depth = 0)
|
def to_s(depth = 0)
|
||||||
@ -75,7 +75,7 @@ module Sol
|
|||||||
def initialize(type = nil)
|
def initialize(type = nil)
|
||||||
@my_type = type
|
@my_type = type
|
||||||
end
|
end
|
||||||
def to_slot_definition(compiler)
|
def to_slotted(compiler)
|
||||||
@my_type = compiler.receiver_type
|
@my_type = compiler.receiver_type
|
||||||
SlotMachine::Slotted.for(:message , [:receiver])
|
SlotMachine::Slotted.for(:message , [:receiver])
|
||||||
end
|
end
|
||||||
@ -91,7 +91,7 @@ module Sol
|
|||||||
def initialize(value)
|
def initialize(value)
|
||||||
@value = value
|
@value = value
|
||||||
end
|
end
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
return SlotMachine::Slotted.for(SlotMachine::StringConstant.new(@value),[])
|
return SlotMachine::Slotted.for(SlotMachine::StringConstant.new(@value),[])
|
||||||
end
|
end
|
||||||
def ct_type
|
def ct_type
|
||||||
|
@ -10,7 +10,7 @@ module Sol
|
|||||||
|
|
||||||
# When used as right hand side, this tells what data to move to get the result into
|
# When used as right hand side, this tells what data to move to get the result into
|
||||||
# a varaible. It is (off course) the return value of the message
|
# a varaible. It is (off course) the return value of the message
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
SlotMachine::Slotted.for(:message ,[ :return_value])
|
SlotMachine::Slotted.for(:message ,[ :return_value])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ module Sol
|
|||||||
|
|
||||||
# create the slot lazily, so to_slot gets called first
|
# create the slot lazily, so to_slot gets called first
|
||||||
def check_slot(compiler , false_label)
|
def check_slot(compiler , false_label)
|
||||||
SlotMachine::TruthCheck.new(@condition.to_slot_definition(compiler) , false_label)
|
SlotMachine::TruthCheck.new(@condition.to_slotted(compiler) , false_label)
|
||||||
end
|
end
|
||||||
|
|
||||||
def each(&block)
|
def each(&block)
|
||||||
|
@ -13,7 +13,7 @@ module Sol
|
|||||||
#
|
#
|
||||||
# This means we do the compiler here (rather than to_slot, which is in
|
# This means we do the compiler here (rather than to_slot, which is in
|
||||||
# fact never called)
|
# fact never called)
|
||||||
def to_slot_definition(compiler)
|
def to_slotted(compiler)
|
||||||
compile(compiler) unless @parfait_block
|
compile(compiler) unless @parfait_block
|
||||||
return SlotMachine::Slotted.for(SlotMachine::LambdaConstant.new(parfait_block(compiler)) , [])
|
return SlotMachine::Slotted.for(SlotMachine::LambdaConstant.new(parfait_block(compiler)) , [])
|
||||||
end
|
end
|
||||||
|
@ -14,7 +14,7 @@ module Sol
|
|||||||
|
|
||||||
# When used as right hand side, this tells what data to move to get the result into
|
# When used as right hand side, this tells what data to move to get the result into
|
||||||
# a varaible. It is (off course) the return value of the message
|
# a varaible. It is (off course) the return value of the message
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
SlotMachine::Slotted.for(:message ,[ :return_value])
|
SlotMachine::Slotted.for(:message ,[ :return_value])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ module Sol
|
|||||||
|
|
||||||
def slot_load(compiler)
|
def slot_load(compiler)
|
||||||
SlotMachine::SlotLoad.new( self , [:message , :return_value] ,
|
SlotMachine::SlotLoad.new( self , [:message , :return_value] ,
|
||||||
@return_value.to_slot_definition(compiler) )
|
@return_value.to_slotted(compiler) )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -67,11 +67,11 @@ module Sol
|
|||||||
|
|
||||||
def message_setup(compiler,called_method)
|
def message_setup(compiler,called_method)
|
||||||
setup = SlotMachine::MessageSetup.new( called_method )
|
setup = SlotMachine::MessageSetup.new( called_method )
|
||||||
slot_receive = @receiver.to_slot_definition(compiler)
|
slot_receive = @receiver.to_slotted(compiler)
|
||||||
arg_target = [:message , :next_message ]
|
arg_target = [:message , :next_message ]
|
||||||
args = []
|
args = []
|
||||||
@arguments.each_with_index do |arg , index| # +1 because of type
|
@arguments.each_with_index do |arg , index| # +1 because of type
|
||||||
args << SlotMachine::SlotLoad.new(self, arg_target + ["arg#{index+1}".to_sym] , arg.to_slot_definition(compiler))
|
args << SlotMachine::SlotLoad.new(self, arg_target + ["arg#{index+1}".to_sym] , arg.to_slotted(compiler))
|
||||||
end
|
end
|
||||||
setup << SlotMachine::ArgumentTransfer.new(self, slot_receive , args )
|
setup << SlotMachine::ArgumentTransfer.new(self, slot_receive , args )
|
||||||
end
|
end
|
||||||
@ -111,10 +111,11 @@ module Sol
|
|||||||
|
|
||||||
private
|
private
|
||||||
def receiver_type_definition(compiler)
|
def receiver_type_definition(compiler)
|
||||||
defi = @receiver.to_slot_definition(compiler)
|
defi = @receiver.to_slotted(compiler)
|
||||||
defi.slots << :type
|
defi.set_next( SlotMachine::Slot.new(:type) )
|
||||||
defi
|
defi
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_condition(ok_label, compiler)
|
def build_condition(ok_label, compiler)
|
||||||
cached_type = SlotMachine::Slotted.for(dynamic_call.cache_entry , [:cached_type])
|
cached_type = SlotMachine::Slotted.for(dynamic_call.cache_entry , [:cached_type])
|
||||||
current_type = receiver_type_definition(compiler)
|
current_type = receiver_type_definition(compiler)
|
||||||
|
@ -10,7 +10,7 @@ module Sol
|
|||||||
|
|
||||||
class LocalVariable < Expression
|
class LocalVariable < Expression
|
||||||
include Named
|
include Named
|
||||||
def to_slot_definition(compiler)
|
def to_slotted(compiler)
|
||||||
slot_def = compiler.slot_type_for(@name)
|
slot_def = compiler.slot_type_for(@name)
|
||||||
SlotMachine::Slotted.for(:message , slot_def)
|
SlotMachine::Slotted.for(:message , slot_def)
|
||||||
end
|
end
|
||||||
@ -24,7 +24,7 @@ module Sol
|
|||||||
|
|
||||||
class InstanceVariable < Expression
|
class InstanceVariable < Expression
|
||||||
include Named
|
include Named
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
SlotMachine::Slotted.for(:message , [ :receiver , @name] )
|
SlotMachine::Slotted.for(:message , [ :receiver , @name] )
|
||||||
end
|
end
|
||||||
# used to collect type information
|
# used to collect type information
|
||||||
@ -51,7 +51,7 @@ module Sol
|
|||||||
def ct_type
|
def ct_type
|
||||||
get_named_class.single_class.instance_type
|
get_named_class.single_class.instance_type
|
||||||
end
|
end
|
||||||
def to_slot_definition(_)
|
def to_slotted(_)
|
||||||
return SlotMachine::Slotted.for( get_named_class, [])
|
return SlotMachine::Slotted.for( get_named_class, [])
|
||||||
end
|
end
|
||||||
def get_named_class
|
def get_named_class
|
||||||
|
@ -15,7 +15,7 @@ module Sol
|
|||||||
codes = cond_label
|
codes = cond_label
|
||||||
codes << @hoisted.to_slot(compiler) if @hoisted
|
codes << @hoisted.to_slot(compiler) if @hoisted
|
||||||
codes << @condition.to_slot(compiler) if @condition.is_a?(SendStatement)
|
codes << @condition.to_slot(compiler) if @condition.is_a?(SendStatement)
|
||||||
codes << SlotMachine::TruthCheck.new(condition.to_slot_definition(compiler) , merge_label)
|
codes << SlotMachine::TruthCheck.new(condition.to_slotted(compiler) , merge_label)
|
||||||
codes << @body.to_slot(compiler)
|
codes << @body.to_slot(compiler)
|
||||||
codes << SlotMachine::Jump.new(cond_label)
|
codes << SlotMachine::Jump.new(cond_label)
|
||||||
codes << merge_label
|
codes << merge_label
|
||||||
|
@ -49,11 +49,11 @@ module Sol
|
|||||||
def yield_arg_block(compiler)
|
def yield_arg_block(compiler)
|
||||||
arg_index = compiler.get_method.arguments_type.get_length - 1
|
arg_index = compiler.get_method.arguments_type.get_length - 1
|
||||||
setup = SlotMachine::MessageSetup.new( arg_index )
|
setup = SlotMachine::MessageSetup.new( arg_index )
|
||||||
slot_receive = @receiver.to_slot_definition(compiler)
|
slot_receive = @receiver.to_slotted(compiler)
|
||||||
arg_target = [:message , :next_message ]
|
arg_target = [:message , :next_message ]
|
||||||
args = []
|
args = []
|
||||||
@arguments.each_with_index do |arg , index| # +1 because of type
|
@arguments.each_with_index do |arg , index| # +1 because of type
|
||||||
args << SlotMachine::SlotLoad.new(self, arg_target + ["arg#{index+1}".to_sym] , arg.to_slot_definition(compiler))
|
args << SlotMachine::SlotLoad.new(self, arg_target + ["arg#{index+1}".to_sym] , arg.to_slotted(compiler))
|
||||||
end
|
end
|
||||||
setup << SlotMachine::ArgumentTransfer.new( self , slot_receive , args )
|
setup << SlotMachine::ArgumentTransfer.new( self , slot_receive , args )
|
||||||
setup << SlotMachine::BlockYield.new( self , arg_index )
|
setup << SlotMachine::BlockYield.new( self , arg_index )
|
||||||
|
Loading…
Reference in New Issue
Block a user