pretty much redid the variable idea (now slot)
This commit is contained in:
@ -34,7 +34,9 @@ module Virtual
|
||||
@string = str
|
||||
end
|
||||
attr_reader :string
|
||||
|
||||
def type
|
||||
Virtual::Reference
|
||||
end
|
||||
def result= value
|
||||
class_for(MoveInstruction).new(value , self , :opcode => :mov)
|
||||
end
|
||||
|
@ -37,13 +37,6 @@ module Virtual
|
||||
end
|
||||
end
|
||||
|
||||
module Named
|
||||
def initialize name
|
||||
@name = name
|
||||
end
|
||||
attr_reader :name
|
||||
end
|
||||
|
||||
# the first instruction we need is to stop. Off course in a real machine this would be a syscall, but that is just
|
||||
# an implementation (in a programm it would be a function). But in a virtual machine, not only do we need this instruction,
|
||||
# it is indeed the first instruction as just this instruction is the smallest possible programm for the machine.
|
||||
@ -73,13 +66,6 @@ module Virtual
|
||||
class UnconditionalBranch < Branch
|
||||
end
|
||||
|
||||
class MessageGet < Instruction
|
||||
include Named
|
||||
end
|
||||
class FrameGet < Instruction
|
||||
include Named
|
||||
end
|
||||
|
||||
class MessageSend < Instruction
|
||||
def initialize name , args = []
|
||||
@name = name.to_sym
|
||||
@ -88,30 +74,14 @@ module Virtual
|
||||
attr_reader :name , :args
|
||||
end
|
||||
|
||||
class FrameSet < Instruction
|
||||
def initialize name , val
|
||||
@name = name.to_sym
|
||||
@value = val
|
||||
# class for Set instructions, A set is basically a mem move.
|
||||
# to and from are indexes into the known objects(frame,message,self and new_message), or from may be a constant
|
||||
class Set < Instruction
|
||||
def initialize to , from
|
||||
@to = to
|
||||
@from = from
|
||||
end
|
||||
attr_reader :name , :value
|
||||
attr_reader :to , :from
|
||||
end
|
||||
|
||||
class MessageSet < Instruction
|
||||
def initialize name , val
|
||||
@name = name.to_sym
|
||||
@value = val
|
||||
end
|
||||
attr_reader :name , :value
|
||||
end
|
||||
|
||||
class LoadSelf < Instruction
|
||||
def initialize val
|
||||
@value = val
|
||||
end
|
||||
attr_reader :value
|
||||
end
|
||||
|
||||
class ObjectGet < Instruction
|
||||
include Named
|
||||
end
|
||||
end
|
||||
|
@ -44,12 +44,6 @@ module Virtual
|
||||
method.get_var(name)
|
||||
end
|
||||
|
||||
def compile_send method , name , me , with = []
|
||||
method.add_code Virtual::LoadSelf.new(me)
|
||||
method.add_code MessageSend.new(name , with )
|
||||
Return.new( method.return_type )
|
||||
end
|
||||
|
||||
def compile_set method , name , val
|
||||
method.set_var(name,val)
|
||||
if method.has_arg(name)
|
||||
|
@ -32,9 +32,9 @@ module Virtual
|
||||
class MethodDefinition < Virtual::Object
|
||||
#return the main function (the top level) into which code is compiled
|
||||
def MethodDefinition.main
|
||||
MethodDefinition.new(:main , [] , Virtual::SelfReference )
|
||||
MethodDefinition.new(:main , [] )
|
||||
end
|
||||
def initialize name , args , receiver = Virtual::SelfReference.new , return_type = Virtual::Mystery , start = MethodEnter.new()
|
||||
def initialize name , args , receiver = Virtual::Self.new , return_type = Virtual::Mystery , start = MethodEnter.new()
|
||||
@name = name.to_sym
|
||||
@args = args
|
||||
@locals = []
|
||||
|
65
lib/virtual/slot.rb
Normal file
65
lib/virtual/slot.rb
Normal file
@ -0,0 +1,65 @@
|
||||
module Virtual
|
||||
# Slots are named, or rather indexed, storage locations that are typed.
|
||||
# Four of those locations exist and those correspond to subclasses:
|
||||
# - the message that has been received: MessageSlot
|
||||
# - the frame of the method that is executing (local variables): FrameSlot
|
||||
# - self as an object: SelfSlot
|
||||
# - a message that will be sent, NewMessageSlot
|
||||
|
||||
# additionally frame, self and return are slots in Message and NewMessage
|
||||
|
||||
class Slot < Value
|
||||
RETURN = 0
|
||||
SELF = 1
|
||||
|
||||
attr_accessor :index , :type
|
||||
private #abstract base class
|
||||
def initialize index , type
|
||||
@index = index
|
||||
@type = type
|
||||
end
|
||||
end
|
||||
|
||||
class MessageSlot < Slot
|
||||
def initialize index , type = Mystery
|
||||
super
|
||||
end
|
||||
end
|
||||
class FrameSlot < Slot
|
||||
def initialize index , type = Mystery
|
||||
super
|
||||
end
|
||||
end
|
||||
class SelfSlot < Slot
|
||||
def initialize index , type = Mystery
|
||||
super
|
||||
end
|
||||
end
|
||||
class NewMessageSlot < Slot
|
||||
def initialize index , type = Mystery
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
class Return < MessageSlot
|
||||
def initialize type = Mystery
|
||||
super( RETURN , type )
|
||||
end
|
||||
end
|
||||
class NewReturn < NewMessageSlot
|
||||
def initialize type = Mystery
|
||||
super( RETURN , type )
|
||||
end
|
||||
end
|
||||
class Self < MessageSlot
|
||||
def initialize type = Mystery
|
||||
super( SELF , type )
|
||||
end
|
||||
end
|
||||
class NewSelf < NewMessageSlot
|
||||
def initialize type = Mystery
|
||||
super( SELF , type )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -6,58 +6,17 @@ module Virtual
|
||||
class Type
|
||||
def == other
|
||||
return false unless other.class == self.class
|
||||
Sof::Util.attributes(self).each do |a|
|
||||
begin
|
||||
left = send(a)
|
||||
rescue NoMethodError
|
||||
next # not using instance variables that are not defined as attr_readers for equality
|
||||
end
|
||||
begin
|
||||
right = other.send(a)
|
||||
rescue NoMethodError
|
||||
return false
|
||||
end
|
||||
return false unless left.class == right.class
|
||||
return false unless left == right
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
def inspect
|
||||
self.class.name + ".new(" + attributes.collect{|a| send(a).inspect }.join(",")+ ")"
|
||||
end
|
||||
end
|
||||
|
||||
class Integer < Type
|
||||
|
||||
def initialize
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Reference < Type
|
||||
|
||||
def initialize clazz = nil
|
||||
@clazz = clazz
|
||||
end
|
||||
attr_accessor :clazz
|
||||
|
||||
def at_index block , left , right
|
||||
block.ldr( self , left , right )
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
class SelfReference < Reference
|
||||
end
|
||||
|
||||
class Mystery < Type
|
||||
def initialize
|
||||
end
|
||||
def as type
|
||||
type.new
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -27,37 +27,10 @@ module Virtual
|
||||
end
|
||||
return true
|
||||
end
|
||||
private
|
||||
private #can't instantiate, must be constant or variable
|
||||
def initialize
|
||||
end
|
||||
end
|
||||
|
||||
class Variable < Value
|
||||
|
||||
def initialize name , type
|
||||
@name = name.to_sym
|
||||
@type = type
|
||||
end
|
||||
attr_accessor :name , :type
|
||||
end
|
||||
# The subclasses are not strictly speaking neccessary at this def point
|
||||
# i just don't want to destroy the information for later optimizations
|
||||
#
|
||||
# All variables are stored in frames and quite possibly in order arg,local,tmp
|
||||
class Return < Variable
|
||||
def initialize type
|
||||
super(:return , type)
|
||||
end
|
||||
end
|
||||
class Self < Variable
|
||||
def initialize type
|
||||
super(:self , type)
|
||||
end
|
||||
end
|
||||
class Argument < Variable
|
||||
end
|
||||
class Local < Variable
|
||||
end
|
||||
class Temp < Variable
|
||||
end
|
||||
end
|
||||
|
||||
require_relative "slot"
|
Reference in New Issue
Block a user