diff --git a/Gemfile.lock b/Gemfile.lock index ca7933b2..09511a91 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: git://github.com/salama/salama-arm.git - revision: c278f7eec20e9d62a55394bb7691e976980cbbe9 + revision: 3fcf596a028d48ab5fa2f31babafbc5f97a6edab specs: salama-arm (0.3.0) diff --git a/README.md b/README.md index f5866bf3..4b15bb6c 100644 --- a/README.md +++ b/README.md @@ -80,13 +80,13 @@ it's main purpose is to have an oo system language to compile to. I spent some time on the parse testing framework, so it is safe to fiddle and add. In fact it is very modular and easy to add to. -### Virtual: Compile the Ast +### Register: Compile the Ast Since we now have an Abstact syntax tree, it needs to be compiled to a virtual machine Instruction format. For the parsed subset that's almost done. It took me a while to come up with a decent but simple machine model. I had tried to map straight to hardware -but failed. The current Virtual directory represent a machine with basic oo features. +but failed. The current Register directory represent a machine with basic oo features. ### Parfait - the runtime diff --git a/lib/interpreter/interpreter.rb b/lib/interpreter/interpreter.rb index 083719ba..11950f42 100644 --- a/lib/interpreter/interpreter.rb +++ b/lib/interpreter/interpreter.rb @@ -106,7 +106,7 @@ module Interpreter def object_for reg id = get_register(reg) - object = Virtual.machine.objects[id] + object = Register.machine.objects[id] object.nil? ? id : object end diff --git a/lib/parfait/meta_class.rb b/lib/parfait/meta_class.rb index d5814ca9..b5db999f 100644 --- a/lib/parfait/meta_class.rb +++ b/lib/parfait/meta_class.rb @@ -24,7 +24,7 @@ module Parfait # in a non-booting version this should map to _add_singleton_method # def add_function function - # raise "not a function #{function}" unless function.is_a? Virtual::Function + # raise "not a function #{function}" unless function.is_a? Register::Function # raise "syserr " unless function.name.is_a? Symbol # self.functions << function # end diff --git a/lib/parfait/method.rb b/lib/parfait/method.rb index f41bff72..7fada0b9 100644 --- a/lib/parfait/method.rb +++ b/lib/parfait/method.rb @@ -13,7 +13,7 @@ module Parfait # known local variable names # executable code - # ps, the compiler injects its own info, see Virtual::MethodSource + # ps, the compiler injects its own info, see Register::MethodSource class Method < Object diff --git a/lib/parfait/variable.rb b/lib/parfait/variable.rb index da847b5e..5ee7e486 100644 --- a/lib/parfait/variable.rb +++ b/lib/parfait/variable.rb @@ -2,7 +2,7 @@ module Parfait class Variable < Object def initialize type , name , value = nil - raise "not type #{type}" unless Virtual.machine.space.get_class_by_name(type) + raise "not type #{type}" unless Register.machine.space.get_class_by_name(type) self.type , self.name , self.value = type , name , value self.value = 0 if self.type == :Integer and value == nil raise "must give name for variable" unless name diff --git a/lib/parfait/word.rb b/lib/parfait/word.rb index d0a9726c..f18785fb 100644 --- a/lib/parfait/word.rb +++ b/lib/parfait/word.rb @@ -16,7 +16,7 @@ module Parfait class Word < Object # initialize with length. For now we try to keep all non-parfait (including String) out # String will contain spaces for non-zero length - # Virtual provides methods to create Parfait objects from ruby + # Register provides methods to create Parfait objects from ruby def initialize len super() raise "Must init with int, not #{len.class}" unless len.kind_of? Fixnum diff --git a/lib/phisol/compiler/call_site.rb b/lib/phisol/compiler/call_site.rb index a143d4f4..75afdad3 100644 --- a/lib/phisol/compiler/call_site.rb +++ b/lib/phisol/compiler/call_site.rb @@ -34,10 +34,10 @@ module Phisol end # now we have to resolve the method name (+ receiver) into a callable method - clazz = Virtual.machine.space.get_class_by_name(me.type) + clazz = Register.machine.space.get_class_by_name(me.type) raise "No such class #{me.type}" unless clazz method = clazz.get_instance_method(name) - #puts Virtual.machine.space.get_class_by_name(:Integer).method_names.to_a + #puts Register.machine.space.get_class_by_name(:Integer).method_names.to_a raise "Method not implemented #{me.type}.#{name}" unless method Register.issue_call( @method , method ) ret = use_reg( method.source.return_type ) diff --git a/lib/phisol/compiler/function_definition.rb b/lib/phisol/compiler/function_definition.rb index 7360a62c..5db7622a 100644 --- a/lib/phisol/compiler/function_definition.rb +++ b/lib/phisol/compiler/function_definition.rb @@ -19,7 +19,7 @@ module Phisol if( r != :self) raise "unimplemented case in function #{r}" else - r = Virtual::Self.new() + r = Register::Self.new() class_name = method.for_class.name end end @@ -34,7 +34,7 @@ module Phisol #TODO check args / type compatibility @method.source.init @method else - @method = Virtual::MethodSource.create_method(class_name, return_type, name , args ) + @method = Register::MethodSource.create_method(class_name, return_type, name , args ) @method.for_class.add_instance_method @method end @method.source.receiver = r diff --git a/lib/register.rb b/lib/register.rb new file mode 100644 index 00000000..ff66e621 --- /dev/null +++ b/lib/register.rb @@ -0,0 +1,20 @@ +require "parfait" +require "register/machine" +#if we are in the ruby run-time / generating an executable +require "register/positioned" +require "register/padding" +require "register/parfait_adapter" + +require "phisol/compiler" +require "register/method_source" + + +class Fixnum + def fits_u8? + self >= 0 and self <= 255 + end +end + +require "register/instruction" +require "register/register_value" +require "register/assembler" diff --git a/lib/register/assembler.rb b/lib/register/assembler.rb index b9e6e245..d5cf6422 100644 --- a/lib/register/assembler.rb +++ b/lib/register/assembler.rb @@ -238,5 +238,5 @@ module Register end end - Sof::Volotile.add(Register::Assembler , [:objects]) + Sof::Volotile.add(Assembler , [:objects]) end diff --git a/lib/virtual/block.rb b/lib/register/block.rb similarity index 99% rename from lib/virtual/block.rb rename to lib/register/block.rb index ec8718c3..472feb9a 100644 --- a/lib/virtual/block.rb +++ b/lib/register/block.rb @@ -1,4 +1,4 @@ -module Virtual +module Register # Think flowcharts: blocks are the boxes. The smallest unit of linear code diff --git a/lib/virtual/boot.rb b/lib/register/boot.rb similarity index 95% rename from lib/virtual/boot.rb rename to lib/register/boot.rb index bae4a017..d81e9250 100644 --- a/lib/virtual/boot.rb +++ b/lib/register/boot.rb @@ -1,4 +1,4 @@ -module Virtual +module Register # Booting is a complicated, so it is extracted into this file, even it has only one entry point @@ -147,19 +147,19 @@ module Virtual # TODO go through the virtual parfait layer and adjust function names to what they really are obj = @space.get_class_by_name(:Object) [:main , :_get_instance_variable , :_set_instance_variable].each do |f| - obj.add_instance_method Register::Builtin::Object.send(f , nil) + obj.add_instance_method Builtin::Object.send(f , nil) end obj = @space.get_class_by_name(:Kernel) # create __init__ main first, __init__ calls it [:exit,:__send , :__init__ ].each do |f| - obj.add_instance_method Register::Builtin::Kernel.send(f , nil) + obj.add_instance_method Builtin::Kernel.send(f , nil) end - @space.get_class_by_name(:Word).add_instance_method Register::Builtin::Word.send(:putstring , nil) + @space.get_class_by_name(:Word).add_instance_method Builtin::Word.send(:putstring , nil) obj = @space.get_class_by_name(:Integer) [:putint,:fibo , :plus].each do |f| - obj.add_instance_method Register::Builtin::Integer.send(f , nil) + obj.add_instance_method Builtin::Integer.send(f , nil) end end end diff --git a/lib/register/builtin/README.md b/lib/register/builtin/README.md index 95e2b8f4..b28691bc 100644 --- a/lib/register/builtin/README.md +++ b/lib/register/builtin/README.md @@ -4,9 +4,9 @@ The Builtin module contains functions that can not be coded in ruby. It is the other side of the parfait coin, part of the runtime. The functions are organized by their respective class and get loaded in boot_classes! , -right at the start. (see virtual/boot.rb) +right at the start. (see register/boot.rb) -These functions return their code, ie a Parfait::Method with a Virtual::MethodSource object, +These functions return their code, ie a Parfait::Method with a MethodSource object, which can then be called by ruby code as if it were a "normal" function. A normal ruby function is one that is parsed and transformed to code. But not all functionality can diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index ab6cfc93..07f50be0 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -5,7 +5,7 @@ module Register module ClassMethods include AST::Sexp def plus c - plus_function = Virtual::MethodSource.create_method(:Integer,:Integer,:plus , [:Integer] ) + plus_function = MethodSource.create_method(:Integer,:Integer,:plus , [:Integer] ) plus_function.source.set_return_type :Integer plus_function.source.receiver = :Integer @@ -15,7 +15,7 @@ module Register me = Register.tmp_reg :Integer plus_function.source.add_code Register.get_slot(plus_function , :message , :receiver , me ) - add = Register::OperatorInstruction.new( plus_function, :add , me , tmp ) + add = OperatorInstruction.new( plus_function, :add , me , tmp ) plus_function.source.add_code add plus_function.source.add_code Register.set_slot(plus_function , me , :message , :return_value ) return plus_function @@ -28,14 +28,14 @@ module Register # As we write before we recurse (save a push) we write the number backwards # arguments: string address , integer # def utoa context - # utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ :Integer ] ) + # utoa_function = MethodSource.create_method(:Integer ,:utoa , [ :Integer ] ) # function.source.return_type = :Integer # function.source.receiver = :Integer # return utoa_function # # str_addr = utoa_function.receiver # # number = utoa_function.args.first # # remainder = utoa_function.new_local - # # Virtual::RegisterMachine.instance.div10( utoa_function , number , remainder ) + # # RegisterMachine.instance.div10( utoa_function , number , remainder ) # # # make char out of digit (by using ascii encoding) 48 == "0" # # utoa_function.instance_eval do # # add( remainder , remainder , 48) @@ -48,7 +48,7 @@ module Register # end def putint context - putint_function = Virtual::MethodSource.create_method(:Integer,:Integer,:putint , [] ) + putint_function = MethodSource.create_method(:Integer,:Integer,:putint , [] ) putint_function.source.set_return_type :Integer putint_function.source.receiver = :Integer return putint_function @@ -68,7 +68,7 @@ module Register # add( int , buffer , nil ) # string to write to # mov( moved_int , buffer.length ) # end - # Virtual::RegisterMachine.instance.write_stdout(putint_function) + # RegisterMachine.instance.write_stdout(putint_function) # putint_function end @@ -77,7 +77,7 @@ module Register # a hand coded version of the fibonachi numbers # not my hand off course, found in the net http://www.peter-cockerell.net/aalp/html/ch-5.html def fibo context - fibo_function = Virtual::MethodSource.create_method(:Integer,:Integer,:fibo , [] ) + fibo_function = MethodSource.create_method(:Integer,:Integer,:fibo , [] ) fibo_function.source.set_return_type :Integer fibo_function.source.receiver = :Integer return fibo_function diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index 8e74fd1b..6bc79e50 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -6,7 +6,7 @@ module Register # it isn't really a function, ie it is jumped to (not called), exits and may not return # so it is responsible for initial setup def __init__ context - function = Virtual::MethodSource.create_method(:Kernel,:Integer,:__init__ , []) + function = MethodSource.create_method(:Kernel,:Integer,:__init__ , []) function.source.set_return_type :Integer # no method enter or return (automatically added), remove function.source.blocks.first.codes.pop # no Method enter @@ -21,20 +21,20 @@ module Register # And store the space as the new self (so the call can move it back as self) function.source.add_code Register.set_slot( function, space_reg , :new_message , :receiver) # now we are set up to issue a call to the main - Register.issue_call( function , Virtual.machine.space.get_main) + Register.issue_call( function , Register.machine.space.get_main) emit_syscall( function , :exit ) return function end def exit context - function = Virtual::MethodSource.create_method(:Kernel,:Integer,:exit , []) + function = MethodSource.create_method(:Kernel,:Integer,:exit , []) function.source.set_return_type :Integer return function - ret = Virtual::RegisterMachine.instance.exit(function) + ret = RegisterMachine.instance.exit(function) function.set_return ret function end def __send context - function = Virtual::MethodSource.create_method(:Kernel,:Integer ,:__send , [] ) + function = MethodSource.create_method(:Kernel,:Integer ,:__send , [] ) function.source.set_return_type :Integer return function end diff --git a/lib/register/builtin/object.rb b/lib/register/builtin/object.rb index 27509de8..ae3f1c9f 100644 --- a/lib/register/builtin/object.rb +++ b/lib/register/builtin/object.rb @@ -6,7 +6,7 @@ module Register # main entry point, ie __init__ calls this # defined here as empty, to be redefined def main context - function = Virtual::MethodSource.create_method(:Object, :Integer , :main , []) + function = MethodSource.create_method(:Object, :Integer , :main , []) return function end @@ -18,13 +18,13 @@ module Register # The at_index is just "below" the api, something we need but don't want to expose, # so we can't code the above in ruby def _get_instance_variable context , name = :Integer - get_function = Virtual::MethodSource.create_method(:Object,:Integer, :_get_instance_variable , [ ] ) + get_function = MethodSource.create_method(:Object,:Integer, :_get_instance_variable , [ ] ) return get_function # me = get_function.receiver # var_name = get_function.args.first # return_to = get_function.return_type # - # index_function = ::Virtual.machine.space.get_class_by_name(:Object).resolve_method(:index_of) + # index_function = ::Register.machine.space.get_class_by_name(:Object).resolve_method(:index_of) # # get_function.push( [me] ) # # index = get_function.call( index_function ) # @@ -39,7 +39,7 @@ module Register end def _set_instance_variable(context , name = :Integer , value = :Integer ) - set_function = Virtual::MethodSource.create_method(:Object,:Integer,:_set_instance_variable ,[] ) + set_function = MethodSource.create_method(:Object,:Integer,:_set_instance_variable ,[] ) return set_function # receiver set_function # me = set_function.receiver diff --git a/lib/register/builtin/word.rb b/lib/register/builtin/word.rb index b5a378e4..635c1590 100644 --- a/lib/register/builtin/word.rb +++ b/lib/register/builtin/word.rb @@ -3,7 +3,7 @@ module Register module Word module ClassMethods def putstring context - function = Virtual::MethodSource.create_method(:Word,:Integer , :putstring , [] ) + function = MethodSource.create_method(:Word,:Integer , :putstring , [] ) function.source.add_code Register.get_slot( function , :message , :receiver , :new_message ) Kernel.emit_syscall( function , :putstring ) function diff --git a/lib/virtual/collector.rb b/lib/register/collector.rb similarity index 98% rename from lib/virtual/collector.rb rename to lib/register/collector.rb index 845e03fa..1d13e689 100644 --- a/lib/virtual/collector.rb +++ b/lib/register/collector.rb @@ -1,4 +1,4 @@ -module Virtual +module Register # collect anything that is in the space but and reachable from init module Collector diff --git a/lib/register/instructions/get_slot.rb b/lib/register/instructions/get_slot.rb index 9bb04956..2abc0a4b 100644 --- a/lib/register/instructions/get_slot.rb +++ b/lib/register/instructions/get_slot.rb @@ -24,8 +24,8 @@ module Register @index = index @register = register raise "not integer #{index}" unless index.is_a? Numeric - raise "Not register #{register}" unless Register::RegisterValue.look_like_reg(register) - raise "Not register #{array}" unless Register::RegisterValue.look_like_reg(array) + raise "Not register #{register}" unless RegisterValue.look_like_reg(register) + raise "Not register #{array}" unless RegisterValue.look_like_reg(array) end attr_accessor :array , :index , :register diff --git a/lib/register/instructions/set_slot.rb b/lib/register/instructions/set_slot.rb index 68168d44..223b94f9 100644 --- a/lib/register/instructions/set_slot.rb +++ b/lib/register/instructions/set_slot.rb @@ -23,8 +23,8 @@ module Register @array = array @index = index raise "not integer #{index}" unless index.is_a? Numeric - raise "Not register #{register}" unless Register::RegisterValue.look_like_reg(register) - raise "Not register #{array}" unless Register::RegisterValue.look_like_reg(array) + raise "Not register #{register}" unless RegisterValue.look_like_reg(register) + raise "Not register #{array}" unless RegisterValue.look_like_reg(array) end attr_accessor :register , :array , :index def to_s diff --git a/lib/virtual/machine.rb b/lib/register/machine.rb similarity index 96% rename from lib/virtual/machine.rb rename to lib/register/machine.rb index cfb8d559..fcd66962 100644 --- a/lib/virtual/machine.rb +++ b/lib/register/machine.rb @@ -1,7 +1,7 @@ require 'parslet/convenience' require_relative "collector" -module Virtual - # The Virtual Machine is a object based virtual machine in which ruby is implemented. +module Register + # The Register Machine is a object based virtual machine in which ruby is implemented. # # It is minimal and realistic and low level # - minimal means that if one thing can be implemented by another, it is left out. This is quite @@ -118,7 +118,7 @@ module Virtual def boot boot_parfait! @init = Block.new("init", :__init__ ) - branch = Register::Branch.new( "__init__" , self.space.get_init.source.blocks.first ) + branch = Branch.new( "__init__" , self.space.get_init.source.blocks.first ) @init.add_code branch @booted = true self diff --git a/lib/virtual/method_source.rb b/lib/register/method_source.rb similarity index 90% rename from lib/virtual/method_source.rb rename to lib/register/method_source.rb index 83f3a012..65b5afb0 100644 --- a/lib/virtual/method_source.rb +++ b/lib/register/method_source.rb @@ -1,6 +1,6 @@ require_relative "block" -module Virtual +module Register # the static info of a method (with its compiled code, argument names etc ) is part of the # runtime, ie found in Parfait::Method @@ -35,17 +35,17 @@ module Virtual def self.create_method( class_name , return_type , method_name , args) raise "create_method #{class_name}.#{class_name.class}" unless class_name.is_a? Symbol raise "create_method #{method_name}.#{method_name.class}" unless method_name.is_a? Symbol - clazz = Virtual.machine.space.get_class_by_name class_name + clazz = Register.machine.space.get_class_by_name class_name raise "No such class #{class_name}" unless clazz arguments = [] args.each_with_index do | arg , index | unless arg.is_a? Parfait::Variable - raise "not type #{arg}:#{arg.class}" unless Virtual.machine.space.get_class_by_name arg + raise "not type #{arg}:#{arg.class}" unless Register.machine.space.get_class_by_name arg arg = Parfait::Variable.new arg , "arg#{index}".to_sym end arguments << arg end - method = clazz.create_instance_method( method_name , Virtual.new_list(arguments)) + method = clazz.create_instance_method( method_name , Register.new_list(arguments)) method.source = MethodSource.new(method , return_type) method end @@ -63,11 +63,11 @@ module Virtual @current = enter ret = new_block("return") # move the current message to new_message - ret.add_code Register::RegisterTransfer.new(self, Register.message_reg , Register.new_message_reg ) + ret.add_code RegisterTransfer.new(self, Register.message_reg , Register.new_message_reg ) # and restore the message from saved value in new_message ret.add_code Register.get_slot(self,:new_message , :caller , :message ) #load the return address into pc, affecting return. (other cpus have commands for this, but not arm) - ret.add_code Register::FunctionReturn.new( self , Register.new_message_reg , Register.resolve_index(:message , :return_address) ) + ret.add_code FunctionReturn.new( self , Register.new_message_reg , Register.resolve_index(:message , :return_address) ) @constants = [] end attr_reader :blocks , :constants , :return_type @@ -75,13 +75,13 @@ module Virtual def set_return_type type return if type.nil? - raise "not type #{type}" unless Virtual.machine.space.get_class_by_name type + raise "not type #{type}" unless Register.machine.space.get_class_by_name type @return_type = type end # add an instruction after the current (insertion point) # the added instruction will become the new insertion point def add_code instruction - unless instruction.is_a?(Register::Instruction) + unless instruction.is_a?(Instruction) raise instruction.to_s end @current.add_code(instruction) #insert after current @@ -93,7 +93,7 @@ module Virtual def locals_at l_block used =[] # call assigns the return register, but as it is in l_block, it is not asked. - assigned = [ Register::RegisterValue.new(Virtual::RegisterMachine.instance.return_register) ] + assigned = [ RegisterValue.new(RegisterMachine.instance.return_register) ] l_block.reachable.each do |b| b.uses.each {|u| (used << u) unless assigned.include?(u) diff --git a/lib/virtual/minimizer.rb b/lib/register/minimizer.rb similarity index 88% rename from lib/virtual/minimizer.rb rename to lib/register/minimizer.rb index 6ce4be37..e60ae6c7 100644 --- a/lib/virtual/minimizer.rb +++ b/lib/register/minimizer.rb @@ -1,4 +1,4 @@ -module Virtual +module Register # Remove all functions that are not called # Not called is approximated by the fact that the method name doesn't show up @@ -11,7 +11,7 @@ module Virtual @gonners << f end end - keep Virtual.machine.space.get_init + keep Register.machine.space.get_init remove_remaining end @@ -25,7 +25,7 @@ module Virtual @gonners.delete function function.source.blocks.each do |block| block.codes.each do |code| - keep code.method if code.is_a? Register::FunctionCall + keep code.method if code.is_a? FunctionCall end end end diff --git a/lib/virtual/padding.rb b/lib/register/padding.rb similarity index 100% rename from lib/virtual/padding.rb rename to lib/register/padding.rb diff --git a/lib/virtual/parfait_adapter.rb b/lib/register/parfait_adapter.rb similarity index 96% rename from lib/virtual/parfait_adapter.rb rename to lib/register/parfait_adapter.rb index 18da98a5..a9380e4a 100644 --- a/lib/virtual/parfait_adapter.rb +++ b/lib/register/parfait_adapter.rb @@ -4,7 +4,7 @@ # To stay sane, we use the same classes that we use later, but "adapt" them to work in ruby # This affects mainly memory layout -module Virtual +module Register def self.new_list array list = Parfait::List.new list.set_length array.length @@ -24,7 +24,7 @@ class Symbol true end def get_layout - l = Virtual.machine.space.classes[:Word].object_layout + l = Register.machine.space.classes[:Word].object_layout #puts "LL #{l.class}" l end @@ -42,7 +42,7 @@ class Symbol pos = cache_positions[self] if pos == nil str = "position accessed but not set, " - str += "Machine has object=#{Virtual.machine.objects.has_key?(self.object_id)} " + str += "Machine has object=#{Register.machine.objects.has_key?(self.object_id)} " raise str + " for Symbol:#{self}" end pos diff --git a/lib/virtual/positioned.rb b/lib/register/positioned.rb similarity index 83% rename from lib/virtual/positioned.rb rename to lib/register/positioned.rb index a100edc1..5238f2ae 100644 --- a/lib/virtual/positioned.rb +++ b/lib/register/positioned.rb @@ -3,7 +3,7 @@ module Positioned def position if @position.nil? - str = "IN machine #{Virtual.machine.objects.has_key?(self.object_id)}, at #{self.object_id.to_s(16)}\n" + str = "IN machine #{Register.machine.objects.has_key?(self.object_id)}, at #{self.object_id.to_s(16)}\n" raise str + "position not set for #{self.class} len #{word_length} for #{self.inspect[0...100]}" end @position diff --git a/lib/register/register.rb b/lib/register/register.rb deleted file mode 100644 index b6cb805f..00000000 --- a/lib/register/register.rb +++ /dev/null @@ -1,7 +0,0 @@ -require_relative "instruction" -require_relative "register_value" -require_relative "assembler" - -# So the memory model of the machine allows for indexed access into an "object" . -# A fixed number of objects exist (ie garbage collection is reclaming, not destroying and -# recreating) although there may be a way to increase that number. diff --git a/lib/salama.rb b/lib/salama.rb index 190e1011..70a1b4c6 100644 --- a/lib/salama.rb +++ b/lib/salama.rb @@ -10,7 +10,6 @@ end require 'parser/transform' require "salama-object-file" -require "virtual" -require "register/register" +require "register" require "register/builtin/object" require "arm/arm_machine" diff --git a/lib/virtual.rb b/lib/virtual.rb deleted file mode 100644 index 4a0f7acd..00000000 --- a/lib/virtual.rb +++ /dev/null @@ -1,16 +0,0 @@ -require "parfait" -require "virtual/machine" -#if we are in the ruby run-time / generating an executable -require "virtual/positioned" -require "virtual/padding" -require "virtual/parfait_adapter" - -require "phisol/compiler" -require "virtual/method_source" - - -class Fixnum - def fits_u8? - self >= 0 and self <= 255 - end -end diff --git a/lib/virtual/README.md b/lib/virtual/README.md deleted file mode 100644 index 882ebaa9..00000000 --- a/lib/virtual/README.md +++ /dev/null @@ -1,62 +0,0 @@ -### Virtual OO Machine - -This is really an OV (object value) not object oriented machine. - -Integers and References are Values. We make them look like objects, sure, but they are not. -Symbols have similar properties and those are: - -- equality means identity -- no change over lifetime - -It's like with Atoms: they used to be the smallest possible physical unit. Now we have electrons, -proton and neutrons. And so objects are made up of Values (not objects), integers, floats , -references and possibly more. - -Values have type in the same way objects have a class. We keep track of the type of a value at runtime, -also in an similar way that objects have their classes at runtime. - -### Layers - -*Ast* instances get created by the [salama-reader](https://github.com/salama/salama-reader) gem from -source. Here we add compile functions to ast classes and compile the AST layer into -Virtual::Objects and Parfait::Values - -The main objects are Space (lots of objects), Parfait::Class , -Method and MethodSource (with Blocks and Instruction). - -**Virtual** Instructions get further transformed into **register** instructions. -This is done by an abstractly defined Register Machine with basic Intructions. -A concrete implementation (like Arm) derives and creates derived Instructions. - -The transformation is implemented as **passes** to make it easier to understand what is going on. -Also this makes it easier to add functionality and optimisations from external (to the gem) sources. - -The final transformation assigns Positions to all boot objects (Linker) and assembles them into a -binary representation. The data- part is then a representation of classes in the **parfait** runtime. -And the instrucions make up the funtions. - -### Accessible Objects - -Object oriented systems have data hiding. So we have access to the inner state of only four objects: - -- Self -- Message (arguments, method name, self) -- Frame (local and tmp variables) -- NewMessage ( to build the next message sent) - -A single instructions (Set) allows movement of data between these. -There are compare, branch and call intructions too. - -### Micro - -The micro-kernel idea is well stated by: If you can leave it out, do. - - -As such we are aiming for integer and reference (type) support, and a minimal class system -(object/class/aray/hash/string). It is possible to add types to the system in a similar way as we add classes, -and also implement very machine dependent functionality which nevertheless is fully wrapped as OO. - -**Parfait** is that part of the runtime that can be coded in ruby. -It is parsed, like any other code and always included in the resulting binary. -**Builtin** is the part of the runtime that can not be coded in ruby (but is still needed). -This is coded by construction MethodSource in code and necessarily machine dependant. diff --git a/stash/constants.rb b/stash/constants.rb index f7f398fe..61369b14 100644 --- a/stash/constants.rb +++ b/stash/constants.rb @@ -1,6 +1,6 @@ -module Virtual +module Register - class Constant < ::Virtual::Object + class Constant < ::Register::Object end class TrueConstant < Constant end diff --git a/stash/message.rb b/stash/message.rb index 9ee002d6..627c1642 100644 --- a/stash/message.rb +++ b/stash/message.rb @@ -1,4 +1,4 @@ -module Virtual +module Register # So when an object calls a method, or sends a message, this is what it sends: a Message # A message contains the sender, return and exceptional return addresses,the arguments, diff --git a/stash/plock.rb b/stash/plock.rb index a7e2e177..80865ed6 100644 --- a/stash/plock.rb +++ b/stash/plock.rb @@ -1,4 +1,4 @@ -module Virtual +module Register # Plock (Proc-Block) is mostly a Block but also somewhat Proc-ish: A Block that carries data. # # Data in a Block is usefull in the same way data in objects is. Plocks being otherwise just code. diff --git a/stash/slot.rb b/stash/slot.rb index 27ee108a..9cbc5f0c 100644 --- a/stash/slot.rb +++ b/stash/slot.rb @@ -1,4 +1,4 @@ -module Virtual +module Register # A slot is a slot in an object. It is the storage location for a value. # (Remember, values are typed) # From a memory perspective a slot is an index into an array (the object) diff --git a/test/compiler/expressions/compiler_helper.rb b/test/compiler/expressions/compiler_helper.rb index ff4a4b95..9a2df2a0 100644 --- a/test/compiler/expressions/compiler_helper.rb +++ b/test/compiler/expressions/compiler_helper.rb @@ -3,7 +3,7 @@ require 'parslet/convenience' Phisol::Compiler.class_eval do def set_main main - @clazz = Virtual.machine.space.get_class_by_name :Object + @clazz = Register.machine.space.get_class_by_name :Object @method = main end end @@ -11,10 +11,10 @@ end module CompilerHelper def set_main compiler - compiler.set_main Virtual.machine.space.get_main + compiler.set_main Register.machine.space.get_main end def check - machine = Virtual.machine + machine = Register.machine machine.boot unless machine.booted parser = Parser::Salama.new parser = parser.send @root diff --git a/test/compiler/expressions/test_call.rb b/test/compiler/expressions/test_call.rb index c86b18aa..cde6cfe7 100644 --- a/test/compiler/expressions/test_call.rb +++ b/test/compiler/expressions/test_call.rb @@ -1,11 +1,11 @@ require_relative "compiler_helper" -module Virtual +module Register class TestCall < MiniTest::Test include CompilerHelper def setup - Virtual.machine.boot + Register.machine.boot @root = :call_site @output = Register::RegisterValue end @@ -31,7 +31,7 @@ module Virtual end def test_call_main_op - Virtual.machine.space.get_main.ensure_local(:bar , :Integer) + Register.machine.space.get_main.ensure_local(:bar , :Integer) @string_input = 'main( bar )' check end diff --git a/test/compiler/expressions/test_field_access.rb b/test/compiler/expressions/test_field_access.rb index d86d3b30..1236d691 100644 --- a/test/compiler/expressions/test_field_access.rb +++ b/test/compiler/expressions/test_field_access.rb @@ -1,11 +1,11 @@ require_relative "compiler_helper" -module Virtual +module Register class TestFields < MiniTest::Test include CompilerHelper def setup - Virtual.machine.boot + Register.machine.boot end def test_field_not_defined @@ -17,7 +17,7 @@ HERE end def test_field - Virtual.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro) + Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro) @root = :field_access @string_input = <