diff --git a/lib/vm/values.rb b/lib/vm/values.rb index a04f901b..1c5f89cc 100644 --- a/lib/vm/values.rb +++ b/lib/vm/values.rb @@ -44,103 +44,9 @@ module Vm end 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 - 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 initialize reg - if reg.is_a? RegisterReference - @register = reg - else - @register = RegisterReference.new(reg) - end - end - def length - 4 - end - # aka to string - def to_asm - "#{register_symbol}" - end - end - - class Unsigned < Word - - def plus block , unsigned - RegisterMachine.instance.unsigned_plus self , unsigned - end - end - - class Integer < Word - - 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 at_index block , left , right - block.ldr( self , left , right ) - self - 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 , first , right - block.mov( self , left , shift_lsr: right ) - self - end - def equals block , right - block.cmp( self , right ) - Vm::BranchCondition.new :eq - end - - 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 move block , right - block.mov( self , right ) - self - end - end end -require_relative "constants" \ No newline at end of file +require_relative "values/constants" +require_relative "values/word" +require_relative "values/integer" +require_relative "values/reference" +require_relative "values/mystery" diff --git a/lib/vm/constants.rb b/lib/vm/values/constants.rb similarity index 100% rename from lib/vm/constants.rb rename to lib/vm/values/constants.rb diff --git a/lib/vm/values/integer.rb b/lib/vm/values/integer.rb new file mode 100644 index 00000000..0239d738 --- /dev/null +++ b/lib/vm/values/integer.rb @@ -0,0 +1,64 @@ +module Vm + class Integer < Word + # needs to be here as Word's constructor is private (to make it abstract) + def initilize 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 at_index block , left , right + block.ldr( self , left , right ) + self + 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 , first , right + block.mov( self , left , shift_lsr: right ) + self + end + def equals block , right + block.cmp( self , right ) + Vm::BranchCondition.new :eq + end + + 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 move block , right + block.mov( self , right ) + self + end + end +end \ No newline at end of file diff --git a/lib/vm/values/mystery.rb b/lib/vm/values/mystery.rb new file mode 100644 index 00000000..bb10a2e4 --- /dev/null +++ b/lib/vm/values/mystery.rb @@ -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 diff --git a/lib/vm/values/reference.rb b/lib/vm/values/reference.rb new file mode 100644 index 00000000..11740850 --- /dev/null +++ b/lib/vm/values/reference.rb @@ -0,0 +1,9 @@ +module Vm + class Reference + # needs to be here as Word's constructor is private (to make it abstract) + def initilize reg + super + end + + end +end diff --git a/lib/vm/values/word.rb b/lib/vm/values/word.rb new file mode 100644 index 00000000..18069bf4 --- /dev/null +++ b/lib/vm/values/word.rb @@ -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 \ No newline at end of file