first steps to defining specialised slot classes

getting rid of the mess in SlotDefinition (wip)
This commit is contained in:
2020-02-10 18:12:39 +07:00
parent df4fd409c1
commit 24d7fe25da
35 changed files with 104 additions and 62 deletions

View File

@ -0,0 +1,29 @@
module SlotMachine
class MessageDefinition < SlotDefinition
def initialize(slots)
super(:message , slots)
end
def known_name
known_object
end
# load the slots into a register
# the code is added to compiler
# the register returned
def to_register(compiler, source)
type = :Message
right = compiler.use_reg( type )
slots = @slots.dup
left = Risc.message_reg
left = left.resolve_and_add( slots.shift , compiler)
reg = compiler.current.register
while( !slots.empty? )
left = left.resolve_and_add( slots.shift , compiler)
end
return reg
end
end
end

View File

@ -1,7 +1,7 @@
module SlotMachine
# A SlotDefinition defines a slot. A bit like a variable name but for objects.
#
# PS: for the interested: A "developement" of Smalltalk was the
# PS: for the interested: A "development" of Smalltalk was the
# prototype based language (read: JavaScript equivalent)
# called Self https://en.wikipedia.org/wiki/Self_(programming_language)
#
@ -15,6 +15,16 @@ module SlotMachine
# Instructions. Or in the case of constants to ConstantLoad
#
class SlotDefinition
# get the right definition, depending on the object
def self.for(object , slots)
case object
when :message
MessageDefinition.new(slots)
else
SlotDefinition.new(object,slots)
end
end
attr_reader :known_object , :slots
# is an array of symbols, that specifies the first the object, and then the Slot.
# The first element is either a known type name (Capitalized symbol of the class name) ,
@ -39,8 +49,6 @@ module SlotMachine
known_object.class.short_name
when Risc::Label
known_object.to_s
when Symbol
known_object
else
"unknown"
end
@ -69,14 +77,12 @@ module SlotMachine
end
raise "Can't have slots into Constants #{slots}" if slots.length > 1
when Parfait::Object , Risc::Label
const = const = Risc.load_constant(source, known_object , right)
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
when Symbol
return sym_to_risc(compiler , source)
else
raise "We have a #{self} #{known_object}"
end
@ -92,19 +98,5 @@ module SlotMachine
return const.register
end
# resolve the slots one by one to slot_to_reg instructions using the
# type information inferred from their names / type hierachy
def sym_to_risc(compiler , source)
slots = @slots.dup
raise "Not Message #{@known_object}" unless @known_object == :message
left = Risc.message_reg
left = left.resolve_and_add( slots.shift , compiler)
reg = compiler.current.register
while( !slots.empty? )
left = left.resolve_and_add( slots.shift , compiler)
end
return reg
end
end
end

View File

@ -31,8 +31,8 @@ module SlotMachine
def initialize(source , left , right, original_source = nil)
super(source)
@left , @right = left , right
@left = SlotDefinition.new(@left.shift , @left) if @left.is_a? Array
@right = SlotDefinition.new(@right.shift , @right) if @right.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
raise "right not SlotMachine, #{@right.to_s}" unless @right.is_a?( SlotDefinition )
@original_source = original_source || self
end
@ -81,3 +81,4 @@ module SlotMachine
end
require_relative "slot_definition"
require_relative "message_definition"