2019-10-03 20:07:55 +02:00
|
|
|
module SlotMachine
|
2018-07-24 10:35:49 +02:00
|
|
|
|
|
|
|
# A BlockYield calls an argument block. All we need to know is the index
|
|
|
|
# of the argument, and the rest is almost as simple as a SimpleCall
|
|
|
|
|
|
|
|
class BlockYield < Instruction
|
|
|
|
attr :arg_index
|
|
|
|
|
2019-10-03 23:36:49 +02:00
|
|
|
# pass in the source (sol statement) and the index.
|
2019-08-10 20:59:31 +02:00
|
|
|
# The index is the argument index of the block that we call
|
|
|
|
def initialize(source , index)
|
|
|
|
super(source)
|
2018-07-24 10:35:49 +02:00
|
|
|
@arg_index = index
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s
|
|
|
|
"BlockYield[#{arg_index}] "
|
|
|
|
end
|
|
|
|
|
2019-08-10 20:59:31 +02:00
|
|
|
# almost as simple as a SimpleCall, use a dynamic_jump to get there
|
2018-07-24 10:35:49 +02:00
|
|
|
def to_risc(compiler)
|
2018-08-16 07:58:49 +02:00
|
|
|
return_label = Risc.label("block_yield", "continue_#{object_id}")
|
|
|
|
index = arg_index
|
2020-03-03 15:22:50 +01:00
|
|
|
return_address = compiler.load_object return_label
|
|
|
|
compiler.build(to_s) do
|
|
|
|
message[:next_message][:return_address] << return_address
|
2018-08-16 07:58:49 +02:00
|
|
|
|
2020-03-03 15:22:50 +01:00
|
|
|
block_reg = message["arg#{index}".to_sym].to_reg
|
2018-08-16 07:58:49 +02:00
|
|
|
|
|
|
|
message << message[:next_message]
|
|
|
|
add_code Risc::DynamicJump.new("block_yield", block_reg )
|
|
|
|
add_code return_label
|
|
|
|
end
|
2018-07-24 10:35:49 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|