2014-08-13 10:59:51 +02:00
|
|
|
module Virtual
|
|
|
|
# Plock (Proc-Block) is mostly a Block but also somewhat Proc-ish: A Block that carries data.
|
2014-06-17 01:01:00 +02:00
|
|
|
#
|
|
|
|
# Data in a Block is usefull in the same way data in objects is. Plocks being otherwise just code.
|
|
|
|
#
|
2014-08-13 10:59:51 +02:00
|
|
|
# But the concept is not quite straigtforwrd: If one thinks of a Plock embedded in a normal method,
|
2015-05-30 11:20:39 +02:00
|
|
|
# the a data in the Plock would be static data. In OO terms this comes quite close to a Proc,
|
|
|
|
# if the data is the local variables.
|
|
|
|
# Quite possibly they shall be used to implement procs, but that is not the direction now.
|
2014-06-17 01:01:00 +02:00
|
|
|
#
|
2015-05-30 11:20:39 +02:00
|
|
|
# For now we use Plocks behaind the scenes as it were. In the code that you never see,
|
|
|
|
# method invocation mainly.
|
|
|
|
#
|
|
|
|
# In terms of implementation the Plock is a Block with data
|
|
|
|
# (Not too much data, mainly a couple of references).
|
|
|
|
# The block writes it's instructions as normal, but a jump is inserted as the last instruction.
|
|
|
|
# The jump is to the next block, over the data that is inserted after the block code
|
|
|
|
# (and so before the next)
|
2014-06-17 01:01:00 +02:00
|
|
|
#
|
|
|
|
# It follows that Plocks should be linear blocks.
|
|
|
|
class Plock < Block
|
2015-05-30 11:20:39 +02:00
|
|
|
|
2014-08-13 10:59:51 +02:00
|
|
|
def initialize(name , method , next_block )
|
2014-06-17 01:01:00 +02:00
|
|
|
super
|
|
|
|
@data = []
|
|
|
|
@branch_code = RegisterMachine.instance.b next_block
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_next next_b
|
|
|
|
super
|
|
|
|
@branch_code = RegisterMachine.instance.b next_block
|
|
|
|
end
|
|
|
|
|
2014-08-13 10:59:51 +02:00
|
|
|
# Data gets assembled after methods
|
2014-06-17 01:01:00 +02:00
|
|
|
def add_data o
|
|
|
|
return if @objects.include? o
|
2014-08-22 17:00:23 +02:00
|
|
|
raise "must be derived from Code #{o.inspect}" unless o.is_a? Register::Code
|
2014-06-17 01:01:00 +02:00
|
|
|
@data << o # TODO check type , no basic values allowed (must be wrapped)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Code interface follows. Note position is inheitted as is from Code
|
|
|
|
|
|
|
|
# length of the Plock is the length of the block, plus the branch, plus data.
|
2014-09-16 16:16:56 +02:00
|
|
|
def mem_length
|
|
|
|
len = @data.inject(super) {| sum , item | sum + item.mem_length}
|
|
|
|
len + @branch_code.mem_length
|
2014-06-17 01:01:00 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
# again, super + branch plus data
|
|
|
|
def link_at pos , context
|
|
|
|
super(pos , context)
|
|
|
|
@branch_code.link_at pos , context
|
|
|
|
@data.each do |code|
|
|
|
|
code.link_at(pos , context)
|
2014-09-16 16:16:56 +02:00
|
|
|
pos += code.mem_length
|
2014-06-17 01:01:00 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# again, super + branch plus data
|
|
|
|
def assemble(io)
|
|
|
|
super
|
|
|
|
@branch_code.assemble(io)
|
|
|
|
@data.each do |obj|
|
|
|
|
obj.assemble io
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|