diff --git a/lib/arm/arm_machine.rb b/lib/arm/arm_machine.rb index 92e47464..0eba5447 100644 --- a/lib/arm/arm_machine.rb +++ b/lib/arm/arm_machine.rb @@ -12,7 +12,11 @@ module Arm def integer_less_or_equal block , left , right block << cmp( left , right ) - Vm::Bool.new + Vm::BranchCondition.new :le + end + def integer_greater_than block , left , right + block << cmp( left , right ) + Vm::BranchCondition.new :gt end def integer_plus block , result , left , right diff --git a/lib/ast/call_site_expression.rb b/lib/ast/call_site_expression.rb index 61c06987..71a19e2f 100644 --- a/lib/ast/call_site_expression.rb +++ b/lib/ast/call_site_expression.rb @@ -20,13 +20,13 @@ module Ast def save_locals context , into into.instance_eval do - push [:r1 , :r2 , :r3] + push [:r0,:r1 , :r2 , :r3] end end def restore_locals context , into into.instance_eval do - pop [:r1, :r2 , :r3] + pop [:r0,:r1, :r2 , :r3] end end diff --git a/lib/ast/function_expression.rb b/lib/ast/function_expression.rb index 539690c2..d103b2bf 100644 --- a/lib/ast/function_expression.rb +++ b/lib/ast/function_expression.rb @@ -38,7 +38,7 @@ module Ast body.each do |b| compiled = b.compile(context , into) function.return_type = compiled - puts "compiled in function #{compiled.class}" + puts "compiled in function #{compiled.inspect}" raise "alarm #{compiled} \n #{b}" unless compiled.is_a? Vm::Word end context.locals = parent_locals diff --git a/lib/ast/operator_expressions.rb b/lib/ast/operator_expressions.rb index 537efb71..b235e035 100644 --- a/lib/ast/operator_expressions.rb +++ b/lib/ast/operator_expressions.rb @@ -36,7 +36,7 @@ module Ast case operator when ">" - code = l_val.less_or_equal into , r_val + code = l_val.greater_than into , r_val when "+" res = context.function.new_local into.res = l_val + r_val diff --git a/lib/ast/while_expression.rb b/lib/ast/while_expression.rb index d8bdd0ed..d8eb98a1 100644 --- a/lib/ast/while_expression.rb +++ b/lib/ast/while_expression.rb @@ -14,16 +14,18 @@ module Ast [:condition, :body] end def compile context , into - ret = into.new_block "#{into.name}_return_#{hash}" while_block = into.new_block "#{into.name}_while_#{hash}" + ret = while_block.new_block "#{into.name}_return_#{hash}" cond_val = condition.compile(context , while_block) - while_block.bne ret + puts "compiled while condition #{cond_val.inspect}" + while_block.b ret , condition_code: cond_val.not_operator last = nil body.each do |part| last = part.compile(context , while_block ) puts "compiled in while #{last.inspect}" end while_block.b while_block + puts "compile while end" into.insert_at_end return last end diff --git a/lib/vm/values.rb b/lib/vm/values.rb index 80b35b0a..b019d77c 100644 --- a/lib/vm/values.rb +++ b/lib/vm/values.rb @@ -25,8 +25,23 @@ module Vm end # Just a nice way to write branches - class Bool < Value + class BranchCondition < Value + def initialize operator + @operator = operator + end + attr_accessor :operator + #needed to check the opposite, ie not true + def not_operator + case @operator + when :le + :gt + when :gt + :le + else + raise "no implemented #{@operator}" + end + end end # This is what it is when we don't know what it is. @@ -77,6 +92,9 @@ module Vm def less_or_equal block , right RegisterMachine.instance.integer_less_or_equal block , self , right end + def greater_than block , right + RegisterMachine.instance.integer_greater_than block , self , right + end def == other code = class_for(CompareInstruction).new(self , other , opcode: :cmp) end