diff --git a/lib/arm/arm_machine.rb b/lib/arm/arm_machine.rb index 9f54c7c6..46f4022a 100644 --- a/lib/arm/arm_machine.rb +++ b/lib/arm/arm_machine.rb @@ -82,7 +82,7 @@ module Arm add( number , number , number , shift_lsr: 8) add( number , number , number , shift_lsr: 16) mov( number , number , shift_lsr: 3) - tmp = Vm::Integer.new( remainder.register + 1) + tmp = function.new_local add( tmp , number , number , shift_lsl: 2) sub( remainder , remainder , tmp , shift_lsl: 1 , update_status: 1) add( number , number, 1 , condition_code: :pl ) diff --git a/lib/ast/operator_expressions.rb b/lib/ast/operator_expressions.rb index ec185e25..a3cac1b7 100644 --- a/lib/ast/operator_expressions.rb +++ b/lib/ast/operator_expressions.rb @@ -25,8 +25,7 @@ module Ast if( l_val ) #variable existed, move data there l_val = l_val.move( into , r_val) else - next_register = context.function.next_register - l_val = Vm::Integer.new(next_register).load( into , r_val ) + l_val = context.function.new_local.load( into , r_val ) end context.locals[left.name] = l_val return l_val @@ -38,12 +37,12 @@ module Ast when ">" code = l_val.less_or_equal into , r_val when "+" - res = Vm::Integer.new(context.function.next_register) + res = context.function.new_local into.add_code res.is l_val + r_val # code = res.plus into , l_val , r_val code = res when "-" - res = Vm::Integer.new(context.function.next_register) + res = context.function.new_local code = res.minus into , l_val , r_val else raise "unimplemented operator #{operator} #{self}" diff --git a/lib/core/kernel.rb b/lib/core/kernel.rb index 1da415f2..2a5971d3 100644 --- a/lib/core/kernel.rb +++ b/lib/core/kernel.rb @@ -83,7 +83,7 @@ module Core result = fibo_function.args[0] int = fibo_function.args[1] count = Vm::Integer.new(2) - loop_block = Vm::Block.new("loop") + loop_block = Vm::Block.new("loop", nil) f1 = Vm::Integer.new(3) f2 = Vm::Integer.new(4) b = fibo_function.body.scope binding diff --git a/lib/vm/block.rb b/lib/vm/block.rb index f4d2bf75..01f20460 100644 --- a/lib/vm/block.rb +++ b/lib/vm/block.rb @@ -20,14 +20,15 @@ module Vm class Block < Code - def initialize(name) + def initialize(name , function) super() + @function = function @name = name.to_sym @next = nil @codes = [] end - attr_reader :name , :next , :codes + attr_reader :name , :next , :codes , :function def length @codes.inject(0) {| sum , item | sum + item.length} diff --git a/lib/vm/function.rb b/lib/vm/function.rb index d0d02078..4214d590 100644 --- a/lib/vm/function.rb +++ b/lib/vm/function.rb @@ -37,15 +37,10 @@ module Vm else @return_type = @return_type.new(0) end - @entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry") ,name ) - @exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit") , name ) - @body = Block.new("#{name}_body") - @reg_count = 0 - branch_body - @entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry") ,name ) - @exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit") , name ) - @body = Block.new("#{name}_body") - @reg_count = 0 + @entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry" , self) ,name ) + @exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit", self) , name ) + @body = Block.new("#{name}_body", self) + @locals = [] branch_body end attr_reader :args , :entry , :exit , :body , :name @@ -55,10 +50,11 @@ module Vm @args.length end - def next_register - next_free = @reg_count - @reg_count += 1 - next_free + args.length + def new_local type = Vm::Integer + register = args.length + @locals.length + l = type.new(register) + @locals << l + l end def link_at address , context diff --git a/lib/vm/program.rb b/lib/vm/program.rb index a217d305..6403207c 100644 --- a/lib/vm/program.rb +++ b/lib/vm/program.rb @@ -23,7 +23,7 @@ module Vm # Initialize with a string for cpu. Naming conventions are: for Machine XXX there exists a module XXX # with a XXXMachine in it that derives from Vm::CMachine def initialize machine = nil - super("start") + super("start" , nil) machine = RbConfig::CONFIG["host_cpu"] unless machine machine = "intel" if machine == "x86_64" machine = machine.capitalize @@ -33,10 +33,10 @@ module Vm @objects = [] # global functions @functions = [] - @entry = Core::Kernel::main_start Vm::Block.new("main_entry") + @entry = Core::Kernel::main_start Vm::Block.new("main_entry",nil) #main gets executed between entry and exit - @main = Block.new("main") - @exit = Core::Kernel::main_exit Vm::Block.new("main_exit") + @main = Block.new("main",nil) + @exit = Core::Kernel::main_exit Vm::Block.new("main_exit",nil) end attr_reader :context , :main , :functions , :entry , :exit diff --git a/test/arm/test_small_program.rb b/test/arm/test_small_program.rb index 723251c1..1f78a4ea 100644 --- a/test/arm/test_small_program.rb +++ b/test/arm/test_small_program.rb @@ -13,7 +13,7 @@ class TestSmallProg < MiniTest::Test end def test_loop - s = Vm::Block.new("start").scope binding + s = Vm::Block.new("start",nil).scope binding m = @program.main.scope binding r0 = Vm::Integer.new(0) m.r0 = 5 #1