fix all tests and a little cleaning
This commit is contained in:
parent
2c26415de7
commit
0dbaebf647
@ -132,8 +132,8 @@ module Arm
|
||||
|
||||
def syscall block , num
|
||||
# This is very arm specific, syscall number is passed in r7, other arguments like a c call ie 0 and up
|
||||
sys = Vm::Integer.new( Vm::RegisterUse.new(:r7) )
|
||||
ret = Vm::Integer.new( Vm::RegisterUse.new(RETURN_REG) )
|
||||
sys = Vm::Integer.new( Vm::RegisterReference.new(:r7) )
|
||||
ret = Vm::Integer.new( Vm::RegisterReference.new(RETURN_REG) )
|
||||
block.do_add mov( sys , num )
|
||||
block.do_add swi( 0 )
|
||||
#todo should write type into r1 according to syscall
|
||||
|
@ -6,7 +6,7 @@ module Ast
|
||||
locals = {}
|
||||
params.each_with_index do |param , index|
|
||||
arg = param.name
|
||||
register = Vm::RegisterUse.new(Vm::RegisterMachine.instance.receiver_register).next_reg_use(index + 1)
|
||||
register = Vm::RegisterReference.new(Vm::RegisterMachine.instance.receiver_register).next_reg_use(index + 1)
|
||||
arg_value = Vm::Integer.new(register)
|
||||
locals[arg] = arg_value
|
||||
args << arg_value
|
||||
|
@ -40,7 +40,7 @@ module Vm
|
||||
|
||||
@args = Array.new(args.length)
|
||||
args.each_with_index do |arg , i|
|
||||
shouldda = RegisterUse.new(RegisterMachine.instance.receiver_register).next_reg_use(i + 1)
|
||||
shouldda = RegisterReference.new(RegisterMachine.instance.receiver_register).next_reg_use(i + 1)
|
||||
if arg.is_a?(Value)
|
||||
@args[i] = arg
|
||||
raise "arg #{i} in non std register #{arg.used_register}, expecting #{shouldda}" unless shouldda == arg.used_register
|
||||
@ -88,7 +88,7 @@ module Vm
|
||||
def locals_at l_block
|
||||
used =[]
|
||||
# call assigns the return register, but as it is in l_block, it is not asked.
|
||||
assigned = [ RegisterUse.new(Vm::RegisterMachine.instance.return_register) ]
|
||||
assigned = [ RegisterReference.new(Vm::RegisterMachine.instance.return_register) ]
|
||||
l_block.reachable.each do |b|
|
||||
b.uses.each {|u|
|
||||
(used << u) unless assigned.include?(u)
|
||||
|
@ -36,7 +36,7 @@ module Vm
|
||||
atts.delete(:condition_code) if atts[:condition_code] == :al
|
||||
atts.empty? ? "" : ", #{atts}"
|
||||
end
|
||||
# returns an array of registers (RegisterUses) that this instruction uses.
|
||||
# returns an array of registers (RegisterReferences) that this instruction uses.
|
||||
# ie for r1 = r2 + r3
|
||||
# which in assembler is add r1 , r2 , r3
|
||||
# it would return [r2,r3]
|
||||
@ -44,7 +44,7 @@ module Vm
|
||||
def uses
|
||||
raise "abstract called for #{self.class}"
|
||||
end
|
||||
# returns an array of registers (RegisterUses) that this instruction assigns to.
|
||||
# returns an array of registers (RegisterReferences) that this instruction assigns to.
|
||||
# ie for r1 = r2 + r3
|
||||
# which in assembler is add r1 , r2 , r3
|
||||
# it would return [r1]
|
||||
@ -191,7 +191,7 @@ module Vm
|
||||
end
|
||||
def assigns
|
||||
if opcode == :call
|
||||
[RegisterUse.new(RegisterMachine.instance.return_register)]
|
||||
[RegisterReference.new(RegisterMachine.instance.return_register)]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
33
lib/vm/register_reference.rb
Normal file
33
lib/vm/register_reference.rb
Normal file
@ -0,0 +1,33 @@
|
||||
module Vm
|
||||
|
||||
# RegisterReference is not the name for a register, "only" for a certain use of it.
|
||||
# In a way it is like a variable name, a storage location. The location is a register off course,
|
||||
# but which register can be changed, and _all_ instructions sharing the RegisterReference then use that register
|
||||
# In other words a simple level of indirection, or change from value to reference sematics.
|
||||
|
||||
class RegisterReference
|
||||
attr_accessor :symbol
|
||||
def initialize r
|
||||
if( r.is_a? Fixnum)
|
||||
r = "r#{r}".to_sym
|
||||
end
|
||||
raise "wrong type for register init #{r}" unless r.is_a? Symbol
|
||||
raise "double r #{r}" if r == :rr1
|
||||
@symbol = r
|
||||
end
|
||||
|
||||
def == other
|
||||
return false if other.nil?
|
||||
return false if other.class != RegisterReference
|
||||
symbol == other.symbol
|
||||
end
|
||||
|
||||
#helper method to calculate with register symbols
|
||||
def next_reg_use by = 1
|
||||
int = @symbol[1,3].to_i
|
||||
sym = "r#{int + by}".to_sym
|
||||
RegisterReference.new( sym )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -1,4 +1,5 @@
|
||||
require_relative "code"
|
||||
require_relative "register_reference"
|
||||
|
||||
module Vm
|
||||
|
||||
@ -7,12 +8,7 @@ module Vm
|
||||
# The oprerations on values is what makes a machine do things. Operations are captured as
|
||||
# subclasses of Instruction and saved to Blocks
|
||||
|
||||
# Values are immutable! (that's why they are called values)
|
||||
# Operations on values _always_ produce new values (conceptionally)
|
||||
|
||||
# Values are a way to reason about (create/validate) instructions.
|
||||
# In fact a linked lists of values is created by invoking instructions
|
||||
# the linked list goes from value to instruction to value, backwards
|
||||
|
||||
# Word Values are what fits in a register. Derived classes
|
||||
# Float, Reference , Integer(s) must fit the same registers
|
||||
@ -48,35 +44,6 @@ module Vm
|
||||
end
|
||||
end
|
||||
|
||||
# RegisterUSe is _not_ the name for a register, "only" for a certain use of it.
|
||||
# In a way it is like a variable name, a storage location. The location is a register off course,
|
||||
# but which register can be changed, and _all_ instructions sharing the RegisterUse then use that register
|
||||
# In other words a simple level of indirection, or change from value to reference sematics.
|
||||
class RegisterUse
|
||||
attr_accessor :symbol
|
||||
def initialize r
|
||||
if( r.is_a? Fixnum)
|
||||
r = "r#{r}".to_sym
|
||||
end
|
||||
raise "wrong type for register init #{r}" unless r.is_a? Symbol
|
||||
raise "double r #{r}" if r == :rr1
|
||||
@symbol = r
|
||||
end
|
||||
|
||||
def == other
|
||||
return false if other.nil?
|
||||
return false if other.class != RegisterUse
|
||||
symbol == other.symbol
|
||||
end
|
||||
|
||||
#helper method to calculate with register symbols
|
||||
def next_reg_use by = 1
|
||||
int = @symbol[1,3].to_i
|
||||
sym = "r#{int + by}".to_sym
|
||||
RegisterUse.new( sym )
|
||||
end
|
||||
end
|
||||
|
||||
# This is what it is when we don't know what it is. #TODO, better if it were explicitly a different type, not the base
|
||||
# Must be promoted to A Word-Value to to anything makes is_a chaecking easier
|
||||
# remembering that our oo machine is typed, no overloading or stuff
|
||||
@ -94,10 +61,10 @@ module Vm
|
||||
inspect
|
||||
end
|
||||
def initialize reg
|
||||
if reg.is_a? RegisterUse
|
||||
if reg.is_a? RegisterReference
|
||||
@used_register = reg
|
||||
else
|
||||
@used_register = RegisterUse.new(reg)
|
||||
@used_register = RegisterReference.new(reg)
|
||||
end
|
||||
end
|
||||
def length
|
||||
|
@ -15,7 +15,7 @@ end
|
||||
|
||||
itest(20)
|
||||
HERE
|
||||
@should = [0x0,0x40,0x2d,0xe9,0xc,0x0,0x53,0xe3,0x3,0x0,0x0,0xba,0x44,0x20,0x8f,0xe2,0x8,0x30,0xa0,0xe3,0x4,0x0,0x0,0xeb,0x2,0x0,0x0,0xea,0x3c,0x20,0x8f,0xe2,0x8,0x30,0xa0,0xe3,0x0,0x0,0x0,0xeb,0x0,0x80,0xbd,0xe8]
|
||||
@should = [0x0,0x40,0x2d,0xe9,0xc,0x0,0x53,0xe3,0x3,0x0,0x0,0xba,0x34,0x20,0x8f,0xe2,0x8,0x30,0xa0,0xe3,0xd4,0xff,0xff,0xeb,0x2,0x0,0x0,0xea,0x2c,0x20,0x8f,0xe2,0x8,0x30,0xa0,0xe3,0xd0,0xff,0xff,0xeb,0x0,0x80,0xbd,0xe8]
|
||||
@output = "else "
|
||||
@target = [:Object , :itest]
|
||||
parse
|
||||
|
@ -7,7 +7,7 @@ class TestPutint < MiniTest::Test
|
||||
@string_input = <<HERE
|
||||
42.putint()
|
||||
HERE
|
||||
@should = [0x0,0x40,0x2d,0xe9,0x2,0x30,0xa0,0xe1,0x34,0x20,0x8f,0xe2,0x9,0x20,0x82,0xe2,0xe9,0xff,0xff,0xeb,0x28,0x20,0x8f,0xe2,0xc,0x30,0xa0,0xe3,0x1,0x0,0xa0,0xe3,0x2,0x10,0xa0,0xe1,0x3,0x20,0xa0,0xe1,0x4,0x70,0xa0,0xe3,0x0,0x0,0x0,0xef,0x0,0x80,0xbd,0xe8]
|
||||
@should = [0x0,0x40,0x2d,0xe9,0x2,0x30,0xa0,0xe1,0x78,0x20,0x8f,0xe2,0x9,0x20,0x82,0xe2,0xe2,0xff,0xff,0xeb,0x6c,0x20,0x8f,0xe2,0xc,0x30,0xa0,0xe3,0x1,0x0,0xa0,0xe3,0x2,0x10,0xa0,0xe1,0x3,0x20,0xa0,0xe1,0x4,0x70,0xa0,0xe3,0x0,0x0,0x0,0xef,0x0,0x80,0xbd,0xe8]
|
||||
@output = " 42 "
|
||||
@target = [:Object , :putint]
|
||||
parse
|
||||
|
@ -20,7 +20,7 @@ end # r0 <- r5
|
||||
|
||||
fibonaccit( 10 )
|
||||
HERE
|
||||
@should = [0x0,0x40,0x2d,0xe9,0x0,0x40,0xa0,0xe3,0x1,0x50,0xa0,0xe3,0x1,0x0,0x53,0xe3,0x4,0x0,0x0,0xda,0x4,0x60,0xa0,0xe1,0x5,0x40,0xa0,0xe1,0x5,0x50,0x86,0xe0,0x1,0x30,0x43,0xe2,0xf8,0xff,0xff,0xea,0x20,0x0,0x2d,0xe9,0x5,0x20,0xa0,0xe1,0x13,0x0,0x0,0xeb,0x20,0x0,0xbd,0xe8,0x5,0x0,0xa0,0xe1,0x0,0x80,0xbd,0xe8]
|
||||
@should = [0x0,0x40,0x2d,0xe9,0x0,0x40,0xa0,0xe3,0x1,0x50,0xa0,0xe3,0x1,0x0,0x53,0xe3,0x4,0x0,0x0,0xda,0x4,0x60,0xa0,0xe1,0x5,0x40,0xa0,0xe1,0x5,0x50,0x86,0xe0,0x1,0x30,0x43,0xe2,0xf8,0xff,0xff,0xea,0x20,0x0,0x2d,0xe9,0x5,0x20,0xa0,0xe1,0xd4,0xff,0xff,0xeb,0x20,0x0,0xbd,0xe8,0x5,0x0,0xa0,0xe1,0x0,0x80,0xbd,0xe8]
|
||||
@output = " 55 "
|
||||
@target = [:Object , :fibonaccit]
|
||||
parse
|
||||
|
Loading…
Reference in New Issue
Block a user