diff --git a/lib/virtual/compiler.rb b/lib/virtual/compiler.rb index e5b6132f..f3771eeb 100644 --- a/lib/virtual/compiler.rb +++ b/lib/virtual/compiler.rb @@ -24,7 +24,7 @@ module Virtual begin self.send "compile_#{exp_name}".to_sym , expression, method rescue NoMethodError => e - puts "No compile method found for " + exp_name + puts "No compile method found for " + exp_name + " #{e}" raise e end end diff --git a/lib/virtual/compiler/while_expression.rb b/lib/virtual/compiler/while_expression.rb index 1806f06b..fe530f0d 100644 --- a/lib/virtual/compiler/while_expression.rb +++ b/lib/virtual/compiler/while_expression.rb @@ -3,24 +3,26 @@ module Virtual # while- attr_reader :condition, :body def self.compile_while expression, method - start = Label.new("while_start") - method.add_code start - is = expression.condition.compile(method ) - branch = IsTrueBranch.new "while" - merge = Label.new(branch.name) - branch.other = merge #false jumps to end of while - method.add_code branch - last = is + # this is where the while ends and both branches meet + merge = method.source.new_block("while merge") + # this comes after the current and beofre the merge + start = method.source.new_block("while_start" ) + method.source.current start + + cond = Compiler.compile(expression.condition, method) + + method.source.add_code IsTrueBranch.new(merge) + + last = cond expression.body.each do |part| - last = part.compile(method ) + last = Compiler.compile(part , method) raise part.inspect if last.nil? end - # unconditionally brnach to the start - merge.next = method.current.next - method.current.next = start - # here we add the end of while that the branch jumps to - #but don't link it in (not using add) - method.current = merge + # unconditionally branch to the start + method.source.add_code UnconditionalBranch.new(start) + + # continue execution / compiling at the merge block + method.source.current merge last end end diff --git a/lib/virtual/method_source.rb b/lib/virtual/method_source.rb index 0375a715..5d0a2ddc 100644 --- a/lib/virtual/method_source.rb +++ b/lib/virtual/method_source.rb @@ -60,7 +60,7 @@ module Virtual # the added instruction will become the new insertion point def add_code instruction unless (instruction.is_a?(Instruction) or instruction.is_a?(Register::Instruction)) - raise instruction.inspect + raise instruction.to_s end @current.add_code(instruction) #insert after current self diff --git a/test/virtual/test_methods.rb b/test/virtual/test_methods.rb index 3c6bddff..4d2d7dd1 100644 --- a/test/virtual/test_methods.rb +++ b/test/virtual/test_methods.rb @@ -1,5 +1,4 @@ require_relative "virtual_helper" - module Virtual class TestMethods < MiniTest::Test @@ -34,7 +33,7 @@ def foo(x) x end HERE - @output = nil + @output = [[1,2,3,4],[],[],[]] check end @@ -94,6 +93,16 @@ HERE check end + def test_while + @string_input = <