diff --git a/lib/typed/compiler.rb b/lib/typed/compiler.rb index 34a13ca6..87de0b21 100644 --- a/lib/typed/compiler.rb +++ b/lib/typed/compiler.rb @@ -3,9 +3,10 @@ require_relative "tree" module Typed CompilerModules = [ "assignment" , "basic_values" , "call_site", "class_field" , - "class_statement" , "collections" , "field_def" , "field_access", - "function_statement" , "if_statement" , "name_expression" , - "operator_expression" , "return_statement", "statement_list"] + "class_statement" , "collections" , "field_def" , "field_access", + "function_statement" , "if_statement" , "name_expression" , + "operator_expression" , "return_statement", "statement_list", + "while_statement"] CompilerModules.each do |mod| require_relative "compiler/" + mod @@ -190,5 +191,3 @@ module Typed end end end - -require_relative "compiler/while_statement" diff --git a/lib/typed/compiler/if_statement.rb b/lib/typed/compiler/if_statement.rb index 3c128f93..2217230f 100644 --- a/lib/typed/compiler/if_statement.rb +++ b/lib/typed/compiler/if_statement.rb @@ -7,17 +7,17 @@ module Typed def on_IfStatement( statement ) # branch_type , condition , if_true , if_false = *statement - true_block = compile_condition( statement ) - merge = compile_false( statement ) + true_block = compile_if_condition( statement ) + merge = compile_if_false( statement ) add_code true_block - compile_true(statement) + compile_if_true(statement) add_code merge nil # statements don't return anything end private - def compile_condition( statement ) + def compile_if_condition( statement ) reset_regs process(statement.condition) branch_class = Object.const_get "Register::Is#{statement.branch_type.capitalize}" @@ -25,12 +25,12 @@ module Typed add_code branch_class.new( statement.condition , true_block ) return true_block end - def compile_true( statement ) + def compile_if_true( statement ) reset_regs process(statement.if_true) end - def compile_false( statement ) + def compile_if_false( statement ) reset_regs process(statement.if_false) if statement.if_false.statements merge = Register::Label.new(statement , "if_merge") diff --git a/lib/typed/compiler/while_statement.rb b/lib/typed/compiler/while_statement.rb index 487506ac..44d87b67 100644 --- a/lib/typed/compiler/while_statement.rb +++ b/lib/typed/compiler/while_statement.rb @@ -1,22 +1,17 @@ module Typed - Compiler.class_eval do + module WhileStatement def on_WhileStatement statement - #puts statement.inspect #branch_type , condition , statements = *statement - condition_label = Register::Label.new(statement.condition , "condition_label") - # unconditionally branch to the condition upon entering the loop - add_code Register::Branch.new(statement.condition,condition_label) + condition_label = compile_while_preamble( statement ) #jump there - add_code start = Register::Label.new(statement , "while_start" ) - reset_regs - process(statement.statements) + start = compile_while_body( statement ) # This is where the loop starts, though in subsequent iterations it's in the middle add_code condition_label - reset_regs - process(statement.condition) + + compile_while_condition( statement ) branch_class = Object.const_get "Register::Is#{statement.branch_type.capitalize}" # this is where the while ends and both branches meet @@ -24,5 +19,24 @@ module Typed nil # statements don't return anything end + private + + def compile_while_preamble( statement ) + condition_label = Register::Label.new(statement.condition , "condition_label") + # unconditionally branch to the condition upon entering the loop + add_code Register::Branch.new(statement.condition , condition_label) + condition_label + end + def compile_while_body( statement ) + start = Register::Label.new(statement , "while_start" ) + add_code start + reset_regs + process(statement.statements) + start + end + def compile_while_condition( statement ) + reset_regs + process(statement.condition) + end end end