more work on instruction format

This commit is contained in:
Torsten Ruger 2014-05-19 11:28:13 +03:00
parent db4f074b75
commit 59952f8503
4 changed files with 45 additions and 30 deletions

View File

@ -81,6 +81,17 @@ module Vm
def self.instance= machine def self.instance= machine
@@instance = machine @@instance = machine
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
private private
#defining the instruction (opcode, symbol) as an given class. #defining the instruction (opcode, symbol) as an given class.
# the class is a Vm::Instruction derived base class and to create machine specific function # 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 # This methods picks up that derived class and calls a define_instruction methods that can
# be overriden in subclasses # be overriden in subclasses
def define_instruction_one(inst , clazz , defaults = {} ) def define_instruction_one(inst , clazz , defaults = {} )
clazz = class_for(clazz) clazz = self.class_for(clazz)
create_method(inst) do |first , options = nil| create_method(inst) do |first , options = nil|
options = {} if options == nil options = {} if options == nil
options.merge defaults options.merge defaults
@ -103,7 +114,7 @@ module Vm
# same for two args (left right, from to etc) # same for two args (left right, from to etc)
def define_instruction_two(inst , clazz , defaults = {} ) def define_instruction_two(inst , clazz , defaults = {} )
clazz = class_for(clazz) clazz = self.class_for(clazz)
create_method(inst) do |left ,right , options = nil| create_method(inst) do |left ,right , options = nil|
options = {} if options == nil options = {} if options == nil
options.merge defaults options.merge defaults
@ -114,7 +125,7 @@ module Vm
# same for three args (result = left right,) # same for three args (result = left right,)
def define_instruction_three(inst , clazz , defaults = {} ) 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| create_method(inst) do |result , left ,right , options = nil|
options = {} if options == nil options = {} if options == nil
options.merge defaults options.merge defaults
@ -122,16 +133,5 @@ module Vm
clazz.new(result, left , right ,options) clazz.new(result, left , right ,options)
end end
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
end end

View File

@ -4,12 +4,13 @@ module Vm
# Functions are similar to Blocks. Where Blocks can be jumped to, Functions can be called. # 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 # Functions have a exactly three blocks, entry, exit and body, which are created for you
# with straight branches between them. # 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, # block as the function really only has the one, and blocks only assemble their codes,
# not their next links # not their next links
# This comes at zero runtime cost though, as the wrapper is just the sum of it's codes # 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 class Function < Code
def initialize(name , args = []) def initialize(name , args = [] , return_type = nil)
super() super()
@name = name @name = name
@args = args @args = args
@return_type = return_type
@entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry") ,name ) @entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry") ,name )
@exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit") , name ) @exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit") , name )
@body = Block.new("#{name}_body") @body = Block.new("#{name}_body")

View File

@ -22,56 +22,58 @@ module Vm
# Instruction derives from Code, for the assembly api # Instruction derives from Code, for the assembly api
class Instruction < Code class Instruction < Code
# Make hash attributes to object attributes
include Support::HashAttributes
def initialize options def initialize options
@attributes = options @attributes = options
end end
def opcode
@attributes[:opcode]
end
end end
class StackInstruction < Instruction class StackInstruction < Instruction
def initialize first , options def initialize first , options = {}
@first = first @first = first
super(options) super(options)
end end
end end
class MemoryInstruction < Instruction class MemoryInstruction < Instruction
def initialize first , options def initialize first , options = {}
@first = first @first = first
super(options) super(options)
end end
end end
class LogicInstruction < Instruction class LogicInstruction < Instruction
def initialize result , left , right , options def initialize result , left , right , options = {}
@result = result @result = result
@left = left @left = left
@right = right @right = right
super(options) super(options)
end end
attr_accessor :result
end end
class MathInstruction < Instruction class MathInstruction < Instruction
def initialize first , options def initialize first , options = {}
@first = first @first = first
super(options) super(options)
end end
end end
class CompareInstruction < Instruction class CompareInstruction < Instruction
def initialize left , right , options def initialize left , right , options = {}
@left = left @left = left
@right = right @right = right
super(options) super(options)
end end
end end
class MoveInstruction < Instruction class MoveInstruction < Instruction
def initialize to , from , options def initialize to , from , options = {}
@to = to @to = to
@from = from @from = from
raise inspect unless from
super(options) super(options)
end end
end end
class CallInstruction < Instruction class CallInstruction < Instruction
def initialize first , options def initialize first , options = {}
@first = first @first = first
super(options) super(options)
opcode = @attributes[:opcode].to_s opcode = @attributes[:opcode].to_s

View File

@ -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) # just a base class for data. not sure how this will be usefull (may just have read too much llvm)
class Value < Code 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 def type
self.class self.class
end end
@ -63,6 +71,9 @@ module Vm
CMachine.instance.integer_less_or_equal block , self , right CMachine.instance.integer_less_or_equal block , self , right
end end
def + other
class_for(LogicInstruction).new(nil , self , other , :opcode => :add)
end
def plus block , first , right def plus block , first , right
CMachine.instance.integer_plus block , self , first , right CMachine.instance.integer_plus block , self , first , right
end end