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

View File

@ -26,7 +26,7 @@ module Vm
@name = name.to_sym @name = name.to_sym
@next = next_block @next = next_block
@codes = [] @codes = []
@insert_at_end = false @insert_at = self
end end
attr_reader :name , :next , :codes , :function attr_reader :name , :next , :codes , :function
@ -40,7 +40,7 @@ module Vm
end end
raise "alarm #{kode}" if kode.is_a? Word raise "alarm #{kode}" if kode.is_a? Word
raise "alarm #{kode}" unless kode.is_a? Code raise "alarm #{kode}" unless kode.is_a? Code
insert_at.codes << kode @insert_at.codes << kode
self self
end end
alias :<< :add_code alias :<< :add_code
@ -55,20 +55,19 @@ module Vm
return new_b return new_b
end end
# when control structures create new blocks (with new_block) control continues at the end of # when control structures create new blocks (with new_block) control continues at some new block the
# the chain of blocks that was created. # the control structure creates.
# the code using _this block should be unaware of the complexity of the block and just keep using this # Example: while, needs 2 extra blocks
# block as before (ie in a linear way) # 1 condition code, must be its own blockas we jump back to it
# this switches that behaviour on, ie code is hence after inserted at the end of the last block # - the body, can actually be after the condition as we don't need to jump there
def insert_at_end # 2 after while block. Condition jumps here
@insert_at_end = true # After block 2, the function is linear again and the calling code does not need to know what happened
self
end
# returns the point at which code is added. See insert_at_end for explanation. Usually self, but... # But subsequent statements are still using the original block (self) to add code to
def insert_at # So the while expression creates the extra blocks, adds them and the code and then "moves" the insertion point along
return self unless @insert_at_end def insert_at block
@next ? @next.insert_at : self @insert_at = block
self
end end
# to use the assignment syntax (see method_missing) the scope must be set, so variables can be resolved # to use the assignment syntax (see method_missing) the scope must be set, so variables can be resolved