more work on instruction format
This commit is contained in:
parent
db4f074b75
commit
59952f8503
@ -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
|
||||||
|
@ -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")
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user