diff --git a/lib/ast/function_expression.rb b/lib/ast/function_expression.rb index 3307f29c..880d4262 100644 --- a/lib/ast/function_expression.rb +++ b/lib/ast/function_expression.rb @@ -8,7 +8,7 @@ module Ast end r = receiver ? receiver.compile(method,message) : Virtual::Self.new() new_method = Virtual::CompiledMethod.new(name , args , r ) - new_method.class_name = r.is_a?(BootClass) ? r.name : method.class_name + new_method.class_name = r.is_a?(Virtual::BootClass) ? r.name : method.class_name clazz = Virtual::BootSpace.space.get_or_create_class(new_method.class_name) clazz.add_instance_method new_method diff --git a/lib/register/assembler.rb b/lib/register/assembler.rb index 051f8ad3..10f582ce 100644 --- a/lib/register/assembler.rb +++ b/lib/register/assembler.rb @@ -25,7 +25,7 @@ module Register def assemble_object object slot = get_slot(object) - raise "Object not linked #{object_id}" unless slot + raise "Object not linked #{object_id}=>#{object.class}" unless slot if object.is_a? Instruction object.assemble( @stream , self ) else @@ -34,14 +34,37 @@ module Register end end + def write_ref object + slot = @linker.get_slot(object) + raise "Object not linked #{object.inspect}" unless slot + @stream.write_uint32 slot.position + end + + # assemble the instance variables of the object + def assemble_self( object ) + slot = @linker.get_slot(object) + raise "Object not linked #{object.inspect}" unless slot + layout = slot.layout + @stream.write_uint32( 0 ) #TODO + @stream.write_uint32( slot.position ) #ref + layout.each do |name| + write_ref(name) + end + end + + def assemble_Hash hash + assemble_self( hash ) + hash.each do |key , val| + assemble_object(key) + assemble_object(val) + end + end + def assemble_BootSpace(space) # assemble in the same order as linked - space.classes.values.each do |cl| - assemble_object(cl) - end - space.objects.each do |o| - assemble_object(o) - end + assemble_object(space.classes) + assemble_object(space.objects) + assemble_self(space) end def assemble_BootClass(clazz) diff --git a/lib/register/linker.rb b/lib/register/linker.rb index 8903e3cd..1a4e128a 100644 --- a/lib/register/linker.rb +++ b/lib/register/linker.rb @@ -1,10 +1,11 @@ module Register class LinkSlot - def initialize at + def initialize position @position = position + raise "Nil not is not an allowed position" unless position @length = 0 end - attr_accessor :position , :length + attr_accessor :position , :length , :layout end class Linker def initialize @@ -24,6 +25,7 @@ module Register if object.is_a? Instruction length = 4 else + slot.layout = layout_for(object) clazz = object.class.name.split("::").last length = send("link_#{clazz}".to_sym , object , at) end @@ -31,6 +33,28 @@ module Register length end + def layout_for(object) + case object + when Array , Symbol , String , Virtual::CompiledMethod , Virtual::Block , Virtual::StringConstant + { :names => [] , :types => []} + when Hash + { :names => [:keys,:values] , :types => [Virtual::Reference,Virtual::Reference]} + when Virtual::BootClass + { :names => [:name , :super_class_name , :instance_methods] , :types => [Virtual::Reference,Virtual::Reference,Virtual::Reference]} + when Virtual::BootSpace + { :names => [:classes,:objects] , :types => [Virtual::Reference,Virtual::Reference]} + else + raise "linker encounters unknown class #{object.class}" + end + end + + def link_self(object , at) + slot = @objects[object.object_id] + layout = slot.layout + length = link_object(layout[:names] , at) + length + members( layout[:names].length) # 2 for type and layout + end + def link_Array( array , at) length = 0 array.each do |elem| @@ -40,17 +64,24 @@ module Register members(length) end + def link_Hash( hash , at) + length = link_object(hash.keys , at) + length += link_object(hash.values , at + length) + length += link_self(hash , at + length) + members(length) + end + def link_BootSpace(space , at) - length = members( 2 ) - length += link_Array( space.classes.values , at + length ) - length + link_Array(space.objects , at + length) + length = link_object( space.classes , at + length ) + length += link_object(space.objects , at + length) + length + members( 2 ) end def link_BootClass(clazz , at) - length = members(3) - length += link_object(clazz.name , at + length) + length = link_object(clazz.name , at + length) length += link_object(clazz.super_class_name , at + length) - length + link_Array(clazz.instance_methods , at + length) + length += link_object(clazz.instance_methods , at + length) + length + members(3) end def link_CompiledMethod(method , at) diff --git a/lib/salama.rb b/lib/salama.rb index 9b770557..e2d37f7b 100644 --- a/lib/salama.rb +++ b/lib/salama.rb @@ -7,3 +7,4 @@ require "virtual/machine" require "ast/all" require "sof/all" require "register/register_machine" +require_relative "stream_reader" \ No newline at end of file diff --git a/lib/virtual/boot_class.rb b/lib/virtual/boot_class.rb index ce0fb841..0346e72f 100644 --- a/lib/virtual/boot_class.rb +++ b/lib/virtual/boot_class.rb @@ -1,5 +1,7 @@ -require "virtual/meta_class" +require_relative "meta_class" +module Virtual + # class is mainly a list of methods with a name (for now) # layout of object is seperated into Layout class BootClass < Virtual::ObjectConstant @@ -41,3 +43,5 @@ require "virtual/meta_class" end end + +end \ No newline at end of file diff --git a/lib/virtual/boot_space.rb b/lib/virtual/boot_space.rb index 917225f2..a08db2ed 100644 --- a/lib/virtual/boot_space.rb +++ b/lib/virtual/boot_space.rb @@ -1,4 +1,4 @@ -require "virtual/boot_class" +require_relative "boot_class" require "builtin/object" module Virtual