2014-05-05 10:03:43 +02:00
|
|
|
require_relative "code"
|
|
|
|
|
2014-04-28 21:08:09 +02:00
|
|
|
module Vm
|
2014-05-02 07:02:25 +02:00
|
|
|
|
|
|
|
# Values represent the information as it is processed. Different subclasses for different types,
|
|
|
|
# each type with different operations.
|
|
|
|
# The oprerations on values is what makes a machine do things.
|
2014-05-03 14:13:44 +02:00
|
|
|
# For compilation, values are moved to the machines registers and the methods (on values) map
|
|
|
|
# to machine instructions
|
2014-05-02 07:02:25 +02:00
|
|
|
|
|
|
|
# Values are immutable! (that's why they are called values)
|
|
|
|
# Operations on values _always_ produce new values (conceptionally)
|
|
|
|
|
2014-05-03 14:13:44 +02:00
|
|
|
# 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
|
2014-05-02 07:02:25 +02:00
|
|
|
|
|
|
|
# Word Values are what fits in a register. Derived classes
|
|
|
|
# Float, Reference , Integer(s) must fit the same registers
|
|
|
|
|
2014-05-05 10:03:43 +02:00
|
|
|
# just a base class for data. not sure how this will be usefull (may just have read too much llvm)
|
|
|
|
class Value < Code
|
2014-05-10 09:59:56 +02:00
|
|
|
|
2014-05-19 10:28:13 +02:00
|
|
|
def class_for clazz
|
|
|
|
CMachine.instance.class_for(clazz)
|
|
|
|
end
|
|
|
|
# part of the dsl, ie serves to make code like value.is a + b work
|
|
|
|
# ie we save the receier as the result into the instruction and pass that back
|
|
|
|
def is instruction
|
|
|
|
instruction.result = self
|
|
|
|
instruction
|
|
|
|
end
|
2014-05-13 15:24:19 +02:00
|
|
|
def type
|
|
|
|
self.class
|
2014-05-10 09:59:56 +02:00
|
|
|
end
|
2014-05-02 07:02:25 +02:00
|
|
|
end
|
|
|
|
|
2014-05-13 17:21:24 +02:00
|
|
|
# Just a nice way to write branches
|
|
|
|
class Bool < Value
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2014-05-13 15:24:19 +02:00
|
|
|
# This is what it is when we don't know what it is.
|
|
|
|
# Must be promoted to A Word-Value to to anything
|
|
|
|
# remembering that our oo machine is typed, no overloading or stuff
|
2014-05-02 07:02:25 +02:00
|
|
|
class Word < Value
|
2014-05-13 15:24:19 +02:00
|
|
|
|
|
|
|
attr_accessor :register
|
|
|
|
|
2014-05-13 17:21:24 +02:00
|
|
|
def inspect
|
2014-05-20 10:03:18 +02:00
|
|
|
self.class.name + "(r#{register})"
|
|
|
|
end
|
|
|
|
def to_s
|
|
|
|
inspect
|
2014-05-13 17:21:24 +02:00
|
|
|
end
|
2014-05-13 15:24:19 +02:00
|
|
|
def initialize reg
|
2014-05-13 17:21:24 +02:00
|
|
|
@register = reg
|
2014-05-05 08:35:40 +02:00
|
|
|
end
|
2014-05-10 14:24:56 +02:00
|
|
|
def length
|
|
|
|
4
|
|
|
|
end
|
2014-04-28 21:08:09 +02:00
|
|
|
end
|
|
|
|
|
2014-05-02 07:02:25 +02:00
|
|
|
class Unsigned < Word
|
|
|
|
|
2014-05-13 17:21:24 +02:00
|
|
|
def plus block , unsigned
|
|
|
|
CMachine.instance.unsigned_plus self , unsigned
|
2014-05-02 07:02:25 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-05-13 15:24:19 +02:00
|
|
|
class Integer < Word
|
2014-05-02 07:02:25 +02:00
|
|
|
|
2014-05-20 10:14:18 +02:00
|
|
|
# part of the dsl.
|
|
|
|
# Gets called with either fixnum/IntegerConstant or an Instruction (usually logic, iw add...)
|
|
|
|
# For instructions we flip, ie call the assign on the instruction
|
|
|
|
# but for constants we have to create instruction first (mov)
|
|
|
|
def assign other
|
|
|
|
other = Vm::IntegerConstant.new(other) if other.is_a? Fixnum
|
|
|
|
if other.is_a? Vm::IntegerConstant
|
|
|
|
class_for(MoveInstruction).new( self , other , :opcode => :mov)
|
|
|
|
else
|
|
|
|
other.assign(self)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-05-13 17:21:24 +02:00
|
|
|
def less_or_equal block , right
|
|
|
|
CMachine.instance.integer_less_or_equal block , self , right
|
2014-05-06 20:36:28 +02:00
|
|
|
end
|
|
|
|
|
2014-05-19 10:28:13 +02:00
|
|
|
def + other
|
2014-05-20 10:54:59 +02:00
|
|
|
class_for(LogicInstruction).new(nil , self , other , opcode: :add)
|
|
|
|
end
|
|
|
|
def - other
|
|
|
|
class_for(LogicInstruction).new(nil , self , other , opcode: :sub , update_status: 1 )
|
2014-05-19 10:28:13 +02:00
|
|
|
end
|
2014-05-16 09:42:25 +02:00
|
|
|
def plus block , first , right
|
|
|
|
CMachine.instance.integer_plus block , self , first , right
|
2014-05-13 17:21:24 +02:00
|
|
|
end
|
2014-05-16 09:42:25 +02:00
|
|
|
def minus block , first , right
|
|
|
|
CMachine.instance.integer_minus block , self , first , right
|
2014-05-14 10:33:23 +02:00
|
|
|
end
|
2014-05-13 17:21:24 +02:00
|
|
|
|
|
|
|
def load block , right
|
|
|
|
CMachine.instance.integer_load block , self , right
|
2014-05-03 14:13:44 +02:00
|
|
|
end
|
2014-05-14 11:02:54 +02:00
|
|
|
|
|
|
|
def move block , right
|
|
|
|
CMachine.instance.integer_move block , self , right
|
|
|
|
end
|
|
|
|
|
2014-05-02 07:02:25 +02:00
|
|
|
end
|
|
|
|
end
|
2014-05-13 15:24:19 +02:00
|
|
|
require_relative "constants"
|