From 59952f85036915ca1c8f50a796a0ce19b63a5e1c Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Mon, 19 May 2014 11:28:13 +0300 Subject: [PATCH] more work on instruction format --- lib/vm/c_machine.rb | 28 ++++++++++++++-------------- lib/vm/function.rb | 10 ++++++---- lib/vm/instruction.rb | 24 +++++++++++++----------- lib/vm/values.rb | 13 ++++++++++++- 4 files changed, 45 insertions(+), 30 deletions(-) diff --git a/lib/vm/c_machine.rb b/lib/vm/c_machine.rb index 7c2e4bd9..fbea9a35 100644 --- a/lib/vm/c_machine.rb +++ b/lib/vm/c_machine.rb @@ -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 diff --git a/lib/vm/function.rb b/lib/vm/function.rb index 90e9b711..17ad6ff7 100644 --- a/lib/vm/function.rb +++ b/lib/vm/function.rb @@ -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") diff --git a/lib/vm/instruction.rb b/lib/vm/instruction.rb index 7ad49ada..fd6db839 100644 --- a/lib/vm/instruction.rb +++ b/lib/vm/instruction.rb @@ -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 diff --git a/lib/vm/values.rb b/lib/vm/values.rb index d342fba2..8e4d6e20 100644 --- a/lib/vm/values.rb +++ b/lib/vm/values.rb @@ -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