2019-10-03 20:07:55 +02:00
|
|
|
module SlotMachine
|
2017-09-11 13:22:33 +02:00
|
|
|
|
|
|
|
# Transering the arguments from the current frame into the next frame
|
|
|
|
#
|
|
|
|
# This could be _done_ at this level, and in fact used to be.
|
2018-03-20 18:01:39 +01:00
|
|
|
# The instruction was introduced to
|
2017-09-11 13:22:33 +02:00
|
|
|
# 1. make optimisations easier
|
|
|
|
# 2. localise the inevitable change
|
|
|
|
#
|
2018-03-20 18:01:39 +01:00
|
|
|
# 1. The optimal risc implementation for this loads old and new frames into registers
|
2017-09-11 13:22:33 +02:00
|
|
|
# and does a whole bunch of transfers
|
|
|
|
# But if we do individual SlotMoves here, each one has to load the frames,
|
|
|
|
# thus making advanced analysis/optimisation neccessary to achieve the same effect.
|
|
|
|
#
|
|
|
|
# 2. Closures will have to have access to variables after the frame goes out of scope
|
2018-03-20 18:01:39 +01:00
|
|
|
# and in fact be able to change the parents variables. The current design does not allow
|
|
|
|
# for this, and so will have to be change in the not so distant future.
|
2017-09-11 13:22:33 +02:00
|
|
|
#
|
|
|
|
class ArgumentTransfer < Instruction
|
|
|
|
|
|
|
|
attr_reader :receiver , :arguments
|
|
|
|
|
2018-03-20 18:01:39 +01:00
|
|
|
# receiver is a slot_definition
|
|
|
|
# arguments is an array of SlotLoads
|
2019-08-10 20:30:00 +02:00
|
|
|
def initialize( source , receiver,arguments )
|
|
|
|
super(source)
|
2017-09-11 13:22:33 +02:00
|
|
|
@receiver , @arguments = receiver , arguments
|
2020-02-17 08:26:50 +01:00
|
|
|
raise "Receiver not Slot #{@receiver}" unless @receiver.is_a?(Slotted)
|
2020-02-27 17:19:27 +01:00
|
|
|
@arguments.each{|a| raise "args not Slotted #{a}" unless a.is_a?(Slotted)}
|
2017-09-11 13:22:33 +02:00
|
|
|
end
|
2018-03-14 15:55:21 +01:00
|
|
|
|
2018-04-17 19:26:15 +02:00
|
|
|
def to_s
|
|
|
|
"ArgumentTransfer " + ([@receiver] + @arguments).join(",")
|
|
|
|
end
|
2018-11-14 11:41:13 +01:00
|
|
|
|
|
|
|
# load receiver and then each arg into the new message
|
|
|
|
# delegates to SlotLoad for receiver and to the actual args.to_risc
|
2018-03-20 18:01:39 +01:00
|
|
|
def to_risc(compiler)
|
2019-08-10 20:30:00 +02:00
|
|
|
transfer = SlotLoad.new(self.source ,[:message , :next_message , :receiver] , @receiver, self).to_risc(compiler)
|
2019-08-22 21:56:44 +02:00
|
|
|
#TODO transfer the Number of arguments to :arguments_given (to be checked on entry)
|
2020-02-27 17:19:27 +01:00
|
|
|
arg_target = [:message , :next_message ]
|
|
|
|
@arguments.each_with_index do |arg , index| # +1 because of type
|
2018-03-20 18:01:39 +01:00
|
|
|
compiler.reset_regs
|
2020-02-27 17:19:27 +01:00
|
|
|
load = SlotMachine::SlotLoad.new(self.source, arg_target + ["arg#{index+1}".to_sym] , arg)
|
|
|
|
load.to_risc(compiler)
|
2018-03-20 18:01:39 +01:00
|
|
|
end
|
2020-02-27 17:19:27 +01:00
|
|
|
compiler.reset_regs
|
2018-03-20 18:01:39 +01:00
|
|
|
transfer
|
2018-03-14 15:55:21 +01:00
|
|
|
end
|
2017-09-11 13:22:33 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end
|