diff --git a/lib/arm/compare_instruction.rb b/lib/arm/compare_instruction.rb index 543592d4..f05302e8 100644 --- a/lib/arm/compare_instruction.rb +++ b/lib/arm/compare_instruction.rb @@ -88,7 +88,7 @@ module Arm io.write_uint32 val end def shift val , by - raise "Not integer #{val}:#{val.class}" unless val.is_a? Fixnum + raise "Not integer #{val}:#{val.class} #{inspect}" unless val.is_a? Fixnum val << by end end diff --git a/lib/core/kernel.rb b/lib/core/kernel.rb index 65bbd423..1da415f2 100644 --- a/lib/core/kernel.rb +++ b/lib/core/kernel.rb @@ -80,30 +80,31 @@ module Core # not my hand off course, found in the net from a basic introduction def fibo context fibo_function = Vm::Function.new(:fibo , [Vm::Integer , Vm::Integer] , Vm::Integer ) - result , int = fibo_function.args - i = Vm::Integer.new(2) + result = fibo_function.args[0] + int = fibo_function.args[1] + count = Vm::Integer.new(2) loop_block = Vm::Block.new("loop") f1 = Vm::Integer.new(3) f2 = Vm::Integer.new(4) - fibo_function.body.instance_eval do - cmp( int , 1) - mov( result, int , condition_code: :le) - mov( :pc , :lr , condition_code: :le) - push [ i , f1 , f2 , :lr] - mov( f1 , 1) - mov(f2 , 0) - sub( i , int , 2) - add_code loop_block - end + b = fibo_function.body.scope binding + + b.a int == 1 + b.mov( result, int , condition_code: :le) + b.mov( :pc , :lr , condition_code: :le) + b.push [ count , f1 , f2 , :lr] + b.f1 = 1 + b.f2 = 0 + b.count = int - 2 - loop_block.instance_eval do - add( f1 , f1 , f2) - sub( f2 , f1 , f2) - sub( i , i , 1 , update_status: 1) - bpl( loop_block ) - mov( result , f1 ) - pop [ i , f1 , f2 , :pc] - end + b.add_code loop_block + l = loop_block.scope binding + + l.f1 = f1 + f2 + l.f2 = f1 - f2 + l.count = (count - 1).set_update_status + l.bpl( loop_block ) + l.result = f1 + l.pop [ count , f1 , f2 , :pc] fibo_function end diff --git a/lib/support/hash_attributes.rb b/lib/support/hash_attributes.rb index 92dfb0cf..0114d1ac 100644 --- a/lib/support/hash_attributes.rb +++ b/lib/support/hash_attributes.rb @@ -23,4 +23,15 @@ module Support end end end -end \ No newline at end of file +end + +class Binding + #these are defined in 2.1 and thus the definitions should be conditional. TODO + def local_variable_defined? sym + vars = eval("local_variables") + vars.include? sym + end + def local_variable_get sym + eval(sym.to_s) + end +end diff --git a/lib/vm/code.rb b/lib/vm/code.rb index 8864c2c6..fb97f5b4 100644 --- a/lib/vm/code.rb +++ b/lib/vm/code.rb @@ -11,6 +11,10 @@ module Vm # The first setting the position, the second assembling class Code + def class_for clazz + CMachine.instance.class_for(clazz) + end + # set the position to zero, will have to reset later def initialize @position = 0 diff --git a/lib/vm/instruction.rb b/lib/vm/instruction.rb index 47f73f80..8890d1e8 100644 --- a/lib/vm/instruction.rb +++ b/lib/vm/instruction.rb @@ -28,6 +28,18 @@ module Vm def opcode @attributes[:opcode] end + + def method_missing name , *args , &block + return super unless (args.length <= 1) or block_given? + set , attribute = name.to_s.split("set_") + if set == "" + @attributes[attribute.to_sym] = args[0] || 1 + return self + else + return super + end + return @attributes[name.to_sym] + end end class StackInstruction < Instruction