2019-10-06 18:49:53 +02:00
|
|
|
|
|
|
|
module SlotLanguage
|
2020-02-12 09:41:16 +01:00
|
|
|
# MacroMaker instances represent Macros at the Slot level
|
|
|
|
#
|
|
|
|
# Macros are like SlotInstruction instances in that they transform to Risc
|
|
|
|
# But all SlotInstructions form a whole that lets us reduce Sol to Slot to risc.
|
|
|
|
# Each Macro on the other hand represents a functionality (kind of method)
|
|
|
|
# that can not be coded in sol. It transforms to a sequence of risc Instructions
|
|
|
|
# that can not be coded any other way. They are not Methods, as they have no
|
|
|
|
# scope, hence the name Macro.
|
|
|
|
#
|
|
|
|
# This MacroMaker is an attempt to code these kind of sequences in SlotLanguage
|
|
|
|
# The SlotCompiler is used to transform a file of SlotLanguage code into and
|
|
|
|
# array of SlotLanguage constructs, which in turn can be transformed into
|
|
|
|
# SlotInstructions.
|
|
|
|
# To start with we work backwards from existing large SlotInstructions, to
|
|
|
|
# get a list of constructs that will transform to the same SlotInstructions
|
|
|
|
# that transform to the same risc as the current large instruction (+ some redundandency)
|
2019-10-06 18:49:53 +02:00
|
|
|
class MacroMaker
|
2020-02-12 09:41:16 +01:00
|
|
|
# an array of Makers
|
2019-10-06 18:49:53 +02:00
|
|
|
attr_reader :source
|
|
|
|
|
2020-02-12 09:41:16 +01:00
|
|
|
# load slot code from a file, in a subdir code/ + filename
|
|
|
|
# use load_string to compile the content
|
2019-10-06 18:49:53 +02:00
|
|
|
def self.load_file(relative_name)
|
|
|
|
path = File.expand_path( "../code/#{relative_name}" , __FILE__)
|
|
|
|
load_string( File.read(path))
|
|
|
|
end
|
2020-02-12 09:41:16 +01:00
|
|
|
|
|
|
|
# compile the given SlotLanguage source
|
|
|
|
# the compiler returns an array of Makers which a new MacroMaker
|
|
|
|
# instance stores
|
|
|
|
# return the MacroMaker that represents the source
|
2019-10-06 18:49:53 +02:00
|
|
|
def self.load_string(source_code)
|
|
|
|
MacroMaker.new( SlotCompiler.compile(source_code) )
|
|
|
|
end
|
|
|
|
|
2020-02-12 09:41:16 +01:00
|
|
|
# must initialize with an array of Makers, which is stored
|
2019-10-06 18:49:53 +02:00
|
|
|
def initialize( source )
|
|
|
|
@source = source
|
|
|
|
raise "undefined source #{source}" unless source.is_a?(Array)
|
|
|
|
end
|
|
|
|
|
2020-02-12 09:41:16 +01:00
|
|
|
# Basically calls to_slot on each Element of the source array
|
|
|
|
#
|
|
|
|
# Thus transforming an array of Makers into a linked list of
|
|
|
|
# SlotInstructions.
|
|
|
|
# Return the head of the linked list.
|
2019-10-06 18:49:53 +02:00
|
|
|
def to_slot(compiler)
|
2019-10-07 19:14:40 +02:00
|
|
|
chain = do_link( @source.first , compiler)
|
|
|
|
rest = @source.dup
|
|
|
|
rest.shift
|
|
|
|
rest.each do |link|
|
|
|
|
chain << do_link(link , compiler)
|
|
|
|
end
|
|
|
|
chain
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def do_link(link,compiler)
|
|
|
|
return link if link.is_a?(SlotMachine::Instruction)
|
|
|
|
link.to_slot(compiler)
|
2019-10-06 18:49:53 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|