that fixes the while. To work. Actually work. Fibonacci and all :-)

This commit is contained in:
Torsten Ruger 2014-05-23 20:27:14 +03:00
parent 7b6d6b9024
commit 2c90006697
2 changed files with 17 additions and 18 deletions

View File

@ -14,8 +14,8 @@ module Ast
[:condition, :body]
end
def compile context , into
while_block = into.new_block "#{into.name}_while_#{hash}"
ret = while_block.new_block "#{into.name}_return_#{hash}"
while_block = into.new_block "#{into.name}_while"
ret = while_block.new_block "#{into.name}_return"
cond_val = condition.compile(context , while_block)
puts "compiled while condition #{cond_val.inspect}"
while_block.b ret , condition_code: cond_val.not_operator
@ -26,7 +26,7 @@ module Ast
end
while_block.b while_block
puts "compile while end"
into.insert_at_end
into.insert_at ret
return last
end
end

View File

@ -26,7 +26,7 @@ module Vm
@name = name.to_sym
@next = next_block
@codes = []
@insert_at_end = false
@insert_at = self
end
attr_reader :name , :next , :codes , :function
@ -40,7 +40,7 @@ module Vm
end
raise "alarm #{kode}" if kode.is_a? Word
raise "alarm #{kode}" unless kode.is_a? Code
insert_at.codes << kode
@insert_at.codes << kode
self
end
alias :<< :add_code
@ -55,22 +55,21 @@ 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
# when control structures create new blocks (with new_block) control continues at some new block the
# the control structure creates.
# Example: while, needs 2 extra blocks
# 1 condition code, must be its own blockas we jump back to it
# - the body, can actually be after the condition as we don't need to jump there
# 2 after while block. Condition jumps here
# After block 2, the function is linear again and the calling code does not need to know what happened
# But subsequent statements are still using the original block (self) to add code to
# So the while expression creates the extra blocks, adds them and the code and then "moves" the insertion point along
def insert_at block
@insert_at = block
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