fix the compile while test

This commit is contained in:
Torsten Ruger 2015-07-18 19:02:54 +03:00
parent 3d8fc8819c
commit a554762da8
4 changed files with 30 additions and 19 deletions

View File

@ -24,7 +24,7 @@ module Virtual
begin begin
self.send "compile_#{exp_name}".to_sym , expression, method self.send "compile_#{exp_name}".to_sym , expression, method
rescue NoMethodError => e rescue NoMethodError => e
puts "No compile method found for " + exp_name puts "No compile method found for " + exp_name + " #{e}"
raise e raise e
end end
end end

View File

@ -3,24 +3,26 @@ module Virtual
# while- attr_reader :condition, :body # while- attr_reader :condition, :body
def self.compile_while expression, method def self.compile_while expression, method
start = Label.new("while_start") # this is where the while ends and both branches meet
method.add_code start merge = method.source.new_block("while merge")
is = expression.condition.compile(method ) # this comes after the current and beofre the merge
branch = IsTrueBranch.new "while" start = method.source.new_block("while_start" )
merge = Label.new(branch.name) method.source.current start
branch.other = merge #false jumps to end of while
method.add_code branch cond = Compiler.compile(expression.condition, method)
last = is
method.source.add_code IsTrueBranch.new(merge)
last = cond
expression.body.each do |part| expression.body.each do |part|
last = part.compile(method ) last = Compiler.compile(part , method)
raise part.inspect if last.nil? raise part.inspect if last.nil?
end end
# unconditionally brnach to the start # unconditionally branch to the start
merge.next = method.current.next method.source.add_code UnconditionalBranch.new(start)
method.current.next = start
# here we add the end of while that the branch jumps to # continue execution / compiling at the merge block
#but don't link it in (not using add) method.source.current merge
method.current = merge
last last
end end
end end

View File

@ -60,7 +60,7 @@ module Virtual
# the added instruction will become the new insertion point # the added instruction will become the new insertion point
def add_code instruction def add_code instruction
unless (instruction.is_a?(Instruction) or instruction.is_a?(Register::Instruction)) unless (instruction.is_a?(Instruction) or instruction.is_a?(Register::Instruction))
raise instruction.inspect raise instruction.to_s
end end
@current.add_code(instruction) #insert after current @current.add_code(instruction) #insert after current
self self

View File

@ -1,5 +1,4 @@
require_relative "virtual_helper" require_relative "virtual_helper"
module Virtual module Virtual
class TestMethods < MiniTest::Test class TestMethods < MiniTest::Test
@ -34,7 +33,7 @@ def foo(x)
x x
end end
HERE HERE
@output = nil @output = [[1,2,3,4],[],[],[]]
check check
end end
@ -94,6 +93,16 @@ HERE
check check
end end
def test_while
@string_input = <<HERE
while(1) do
3
end
HERE
@output = [[MethodEnter],[Set,IsTrueBranch,Set,UnconditionalBranch],[],[MethodReturn]]
check
end
def ttest_function_while def ttest_function_while
@string_input = <<HERE @string_input = <<HERE
def fibonaccit(n) def fibonaccit(n)