copies of the old code to start the new layer

This commit is contained in:
Torsten Ruger
2014-06-25 02:47:59 +03:00
parent 9b39a3a816
commit e41bb8027d
16 changed files with 553 additions and 0 deletions

62
lib/neumann/constants.rb Normal file
View File

@ -0,0 +1,62 @@
module Vm
# constants are the stuff that you embedd in the program as numbers or strings.
# Another way to think about them is as Operands, they have no seperate "identity"
# and usually end up embedded in the instructions. ie your basic foo + 4 will encode
# the 4 in the instruction opcode. The 4 is not accessible anywhere else.
# When it should be usable in other forms, the constant must become a Value first
class Constant < Code
end
# another abstract "marker" class (so we can check for it)
# derived classes are Boot/Meta Clas and StringConstant
class ObjectConstant < Constant
end
class IntegerConstant < Constant
def initialize int
@integer = int
end
attr_reader :integer
def value
@integer
end
def to_asm
@integer.to_s
end
end
# The name really says it all.
# The only interesting thing is storage.
# Currently string are stored "inline" , ie in the code segment.
# Mainly because that works an i aint no elf expert.
class StringConstant < ObjectConstant
attr_reader :string
# currently aligned to 4 (ie padded with 0) and off course 0 at the end
def initialize str
str = str.to_s if str.is_a? Symbol
length = str.length
# rounding up to the next 4 (always adding one for zero pad)
pad = ((length / 4 ) + 1 ) * 4 - length
raise "#{pad} #{self}" unless pad >= 1
@string = str + " " * pad
end
def result= value
class_for(MoveInstruction).new(value , self , :opcode => :mov)
end
# the strings length plus padding
def length
string.length
end
# just writing the string
def assemble(io)
io << string
end
end
end

51
lib/neumann/integer.rb Normal file
View File

@ -0,0 +1,51 @@
module Vm
class Integer < Word
# needs to be here as Word's constructor is private (to make it abstract)
def initialize reg
super
end
def less_or_equal block , right
block.cmp( self , right )
Vm::BranchCondition.new :le
end
def greater_or_equal block , right
block.cmp( self , right )
Vm::BranchCondition.new :ge
end
def greater_than block , right
block.cmp( self , right )
Vm::BranchCondition.new :gt
end
def less_than block , right
block.cmp( self , right )
Vm::BranchCondition.new :lt
end
def plus block , first , right
block.add( self , left , right )
self
end
def minus block , left , right
block.sub( self , left , right )
self
end
def left_shift block , left , right
block.mov( self , left , shift_lsr: right )
self
end
def equals block , right
block.cmp( self , right )
Vm::BranchCondition.new :eq
end
def is_true? function
function.cmp( self , 0 )
Vm::BranchCondition.new :ne
end
def move block , right
block.mov( self , right )
self
end
end
end

8
lib/neumann/mystery.rb Normal file
View File

@ -0,0 +1,8 @@
module Vm
class Mystery < Word
# needs to be here as Word's constructor is private (to make it abstract)
def initilize reg
super
end
end
end

30
lib/neumann/reference.rb Normal file
View File

@ -0,0 +1,30 @@
module Vm
class Reference < Word
# needs to be here as Word's constructor is private (to make it abstract)
def initialize reg , clazz = nil
super(reg)
@clazz = clazz
end
attr_accessor :clazz
def load block , right
if(right.is_a? IntegerConstant)
block.mov( self , right ) #move the value
elsif right.is_a? StringConstant
block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative
block.mov( Integer.new(self.register.next_reg_use) , right.length ) #and the length HACK TODO
elsif right.is_a?(Boot::BootClass) or right.is_a?(Boot::MetaClass)
block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative
else
raise "unknown #{right.inspect}"
end
self
end
def at_index block , left , right
block.ldr( self , left , right )
self
end
end
end

36
lib/neumann/word.rb Normal file
View File

@ -0,0 +1,36 @@
module Vm
# Word is an abstract base class for the obvious values, ie those that fit into a register
# Marked as abstract by private constructor
#
# Integer and (Object) References are the main derived classes, but float will come and ...
# The Mystery Value has unknown type and has only casting methods. So it must be cast to be useful.
# Types are stored at runtime when needed in TYPE_REGISTER (r1 on arm), which is mostly before calls,
# so that the called function can do casts / branching correctly
class Word < Value
attr_accessor :register
def register_symbol
@register.symbol
end
def inspect
"#{self.class.name} (#{register_symbol})"
end
def to_s
inspect
end
def length
4
end
# aka to string
def to_asm
"#{register_symbol}"
end
private
def initialize reg
if reg.is_a? RegisterReference
@register = reg
else
@register = RegisterReference.new(reg)
end
end
end
end