more work on instruction format
This commit is contained in:
parent
db4f074b75
commit
59952f8503
@ -81,6 +81,17 @@ module Vm
|
||||
def self.instance= machine
|
||||
@@instance = machine
|
||||
end
|
||||
def class_for clazz
|
||||
c_name = clazz.name
|
||||
my_module = self.class.name.split("::").first
|
||||
clazz_name = clazz.name.split("::").last
|
||||
if(my_module != Vm )
|
||||
module_class = eval("#{my_module}::#{clazz_name}") rescue nil
|
||||
clazz = module_class if module_class
|
||||
end
|
||||
clazz
|
||||
end
|
||||
|
||||
private
|
||||
#defining the instruction (opcode, symbol) as an given class.
|
||||
# the class is a Vm::Instruction derived base class and to create machine specific function
|
||||
@ -92,7 +103,7 @@ module Vm
|
||||
# This methods picks up that derived class and calls a define_instruction methods that can
|
||||
# be overriden in subclasses
|
||||
def define_instruction_one(inst , clazz , defaults = {} )
|
||||
clazz = class_for(clazz)
|
||||
clazz = self.class_for(clazz)
|
||||
create_method(inst) do |first , options = nil|
|
||||
options = {} if options == nil
|
||||
options.merge defaults
|
||||
@ -103,7 +114,7 @@ module Vm
|
||||
|
||||
# same for two args (left right, from to etc)
|
||||
def define_instruction_two(inst , clazz , defaults = {} )
|
||||
clazz = class_for(clazz)
|
||||
clazz = self.class_for(clazz)
|
||||
create_method(inst) do |left ,right , options = nil|
|
||||
options = {} if options == nil
|
||||
options.merge defaults
|
||||
@ -114,7 +125,7 @@ module Vm
|
||||
|
||||
# same for three args (result = left right,)
|
||||
def define_instruction_three(inst , clazz , defaults = {} )
|
||||
clazz = class_for(clazz)
|
||||
clazz = self.class_for(clazz)
|
||||
create_method(inst) do |result , left ,right , options = nil|
|
||||
options = {} if options == nil
|
||||
options.merge defaults
|
||||
@ -122,16 +133,5 @@ module Vm
|
||||
clazz.new(result, left , right ,options)
|
||||
end
|
||||
end
|
||||
|
||||
def class_for clazz
|
||||
c_name = clazz.name
|
||||
my_module = self.class.name.split("::").first
|
||||
clazz_name = clazz.name.split("::").last
|
||||
if(my_module != Vm )
|
||||
module_class = eval("#{my_module}::#{clazz_name}") rescue nil
|
||||
clazz = module_class if module_class
|
||||
end
|
||||
clazz
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -4,12 +4,13 @@ module Vm
|
||||
|
||||
# Functions are similar to Blocks. Where Blocks can be jumped to, Functions can be called.
|
||||
|
||||
# Functions also have arguments, though they are handled differently (in register allocation)
|
||||
|
||||
# Functions also have arguments and a return. These are Value subclass instances, ie specify
|
||||
# type (by class type) and register by instance
|
||||
|
||||
# Functions have a exactly three blocks, entry, exit and body, which are created for you
|
||||
# with straight branches between them.
|
||||
|
||||
# Also remember that if your den body exists of several blocks, they must be wrapped in a
|
||||
# Also remember that if your body exists of several blocks, they must be wrapped in a
|
||||
# block as the function really only has the one, and blocks only assemble their codes,
|
||||
# not their next links
|
||||
# This comes at zero runtime cost though, as the wrapper is just the sum of it's codes
|
||||
@ -18,10 +19,11 @@ module Vm
|
||||
|
||||
class Function < Code
|
||||
|
||||
def initialize(name , args = [])
|
||||
def initialize(name , args = [] , return_type = nil)
|
||||
super()
|
||||
@name = name
|
||||
@args = args
|
||||
@return_type = return_type
|
||||
@entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry") ,name )
|
||||
@exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit") , name )
|
||||
@body = Block.new("#{name}_body")
|
||||
|
@ -21,57 +21,59 @@ module Vm
|
||||
|
||||
# Instruction derives from Code, for the assembly api
|
||||
|
||||
class Instruction < Code
|
||||
# Make hash attributes to object attributes
|
||||
include Support::HashAttributes
|
||||
|
||||
class Instruction < Code
|
||||
def initialize options
|
||||
@attributes = options
|
||||
end
|
||||
def opcode
|
||||
@attributes[:opcode]
|
||||
end
|
||||
end
|
||||
|
||||
class StackInstruction < Instruction
|
||||
def initialize first , options
|
||||
def initialize first , options = {}
|
||||
@first = first
|
||||
super(options)
|
||||
end
|
||||
end
|
||||
class MemoryInstruction < Instruction
|
||||
def initialize first , options
|
||||
def initialize first , options = {}
|
||||
@first = first
|
||||
super(options)
|
||||
end
|
||||
end
|
||||
class LogicInstruction < Instruction
|
||||
def initialize result , left , right , options
|
||||
def initialize result , left , right , options = {}
|
||||
@result = result
|
||||
@left = left
|
||||
@right = right
|
||||
super(options)
|
||||
end
|
||||
attr_accessor :result
|
||||
end
|
||||
class MathInstruction < Instruction
|
||||
def initialize first , options
|
||||
def initialize first , options = {}
|
||||
@first = first
|
||||
super(options)
|
||||
end
|
||||
end
|
||||
class CompareInstruction < Instruction
|
||||
def initialize left , right , options
|
||||
def initialize left , right , options = {}
|
||||
@left = left
|
||||
@right = right
|
||||
super(options)
|
||||
end
|
||||
end
|
||||
class MoveInstruction < Instruction
|
||||
def initialize to , from , options
|
||||
def initialize to , from , options = {}
|
||||
@to = to
|
||||
@from = from
|
||||
raise inspect unless from
|
||||
super(options)
|
||||
end
|
||||
end
|
||||
class CallInstruction < Instruction
|
||||
def initialize first , options
|
||||
def initialize first , options = {}
|
||||
@first = first
|
||||
super(options)
|
||||
opcode = @attributes[:opcode].to_s
|
||||
|
@ -21,7 +21,15 @@ module Vm
|
||||
# just a base class for data. not sure how this will be usefull (may just have read too much llvm)
|
||||
class Value < Code
|
||||
|
||||
|
||||
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
|
||||
def type
|
||||
self.class
|
||||
end
|
||||
@ -63,6 +71,9 @@ module Vm
|
||||
CMachine.instance.integer_less_or_equal block , self , right
|
||||
end
|
||||
|
||||
def + other
|
||||
class_for(LogicInstruction).new(nil , self , other , :opcode => :add)
|
||||
end
|
||||
def plus block , first , right
|
||||
CMachine.instance.integer_plus block , self , first , right
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user