From b4419fc43843d51e2d0ee756d1274460adc66708 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Mon, 25 Aug 2014 17:03:39 +0300 Subject: [PATCH] start on linking and assembly (again, hurra) --- lib/register/assembler.rb | 65 ++++++++++++++++++++++++++++++++ lib/register/register_machine.rb | 1 + lib/virtual/boot_space.rb | 4 +- test/virtual/hello.rb | 2 + 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 lib/register/assembler.rb diff --git a/lib/register/assembler.rb b/lib/register/assembler.rb new file mode 100644 index 00000000..c91acaae --- /dev/null +++ b/lib/register/assembler.rb @@ -0,0 +1,65 @@ +module Register + class LinkSlot + def initialize at + @position = position + end + attr_accessor :position + end + class Assembler + + def initialize space + @space = space + @objects = {} + end + + def link at = 0 + link_object @space , at + end + + def link_object object , at + slot = @objects[object.object_id] + unless slot + slot = LinkSlot.new at + @objects[object.object_id] = slot + end + return if object.is_a? Instruction + clazz = object.class.name.split("::").last + send("link_#{clazz}".to_sym , object , at) + end + + def link_BootSpace space , at + space.classes.values.each do |cl| + link_object cl , at + end + end + + def link_BootClass clazz , at + link_object clazz.name , at + link_object clazz.super_class_name , at + clazz.instance_methods.each do |meth| + link_object meth , at + end + end + def link_MethodDefinition method , at + link_object method.name ,at + method.blocks.each do |block| + link_object block , at + end + end + def link_Block block , at + block.codes.each do |code| + link_object code , at + end + end + def link_MethodEnter str , at + end + def link_MethodReturn str , at + end + def link_FunctionCall str , at + end + def link_String str , at + end + def link_Symbol sym , at + end + end +end diff --git a/lib/register/register_machine.rb b/lib/register/register_machine.rb index 19d8b40b..f9c0c18b 100644 --- a/lib/register/register_machine.rb +++ b/lib/register/register_machine.rb @@ -150,3 +150,4 @@ require_relative "get_implementation" require_relative "set_implementation" require_relative "call_implementation" require "arm/arm_machine" +require_relative "assembler" \ No newline at end of file diff --git a/lib/virtual/boot_space.rb b/lib/virtual/boot_space.rb index 403c7088..8a599866 100644 --- a/lib/virtual/boot_space.rb +++ b/lib/virtual/boot_space.rb @@ -21,7 +21,7 @@ module Virtual @main = Virtual::MethodDefinition.new("main" , [] ) #global objects (data) @objects = [] - boot_classes + boot_classes! # boot is a verb here @passes = [ Virtual::SendImplementation ] end attr_reader :main , :classes , :objects @@ -65,7 +65,7 @@ module Virtual # minimal means only that which can not be coded in ruby # MethodDefinitions are grabbed from respective modules by sending the method name. This should return the # implementation of the method (ie a method object), not actually try to implement it (as that's impossible in ruby) - def boot_classes + def boot_classes! # very fiddly chicken 'n egg problem. Functions need to be in the right order, and in fact we have to define some # dummies, just for the other to compile obj = get_or_create_class :Object diff --git a/test/virtual/hello.rb b/test/virtual/hello.rb index f416784d..a4ef4ad7 100644 --- a/test/virtual/hello.rb +++ b/test/virtual/hello.rb @@ -8,6 +8,8 @@ class HelloTest < MiniTest::Test expressions = machine.compile_main @string_input puts "" Virtual::BootSpace.space.run_passes + ass = Register::Assembler.new(Virtual::BootSpace.space) + ass.link puts Sof::Writer.write(expressions) # puts Sof::Writer.write(Virtual::BootSpace.space) end