solves control flow issue when adding blocks

This commit is contained in:
Torsten Ruger 2014-05-22 16:35:59 +03:00
parent 8596fb312d
commit 7c2d149106
2 changed files with 20 additions and 2 deletions

View File

@ -17,13 +17,14 @@ module Ast
ret = into.new_block "#{into.name}_return_#{hash}"
while_block = into.new_block "#{into.name}_while_#{hash}"
cond_val = condition.compile(context , while_block)
while_block.beq ret
while_block.bne ret
last = nil
body.each do |part|
last = part.compile(context , while_block )
puts "compiled in while #{last.inspect}"
end
while_block.b while_block
into.insert_at_end
return last
end
end

View File

@ -26,6 +26,7 @@ module Vm
@name = name.to_sym
@next = next_block
@codes = []
@insert_at_end = false
end
attr_reader :name , :next , :codes , :function
@ -39,7 +40,7 @@ module Vm
end
raise "alarm #{kode}" if kode.is_a? Word
raise "alarm #{kode}" unless kode.is_a? Code
@codes << kode
insert_at.codes << kode
self
end
alias :<< :add_code
@ -54,6 +55,22 @@ module Vm
return new_b
end
# when control structures create new blocks (with new_block) control continues at the end of
# the chain of blocks that was created.
# the code using _this block should be unaware of the complexity of the block and just keep using this
# block as before (ie in a linear way)
# this switches that behaviour on, ie code is hence after inserted at the end of the last block
def insert_at_end
@insert_at_end = true
self
end
# returns the point at which code is added. See insert_at_end for explanation. Usually self, but...
def insert_at
return self unless @insert_at_end
@next ? @next.insert_at : self
end
# to use the assignment syntax (see method_missing) the scope must be set, so variables can be resolved
# The scope you set should be a binding (literally, the kernel.binding)
# The function return the block, so it can be chained into an assignment