From 71ab369c714d2d118ff185f4124ad70b0a927ebd Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Fri, 24 Aug 2018 18:49:21 +0300 Subject: [PATCH] use factory to generte intergers in space start with just integer factory in space change all the hand-out code still #14 --- lib/mom/instruction/basic_values.rb | 2 +- lib/parfait/object.rb | 5 ---- lib/parfait/space.rb | 32 +++++++++++++-------- lib/risc/builder.rb | 6 ++-- lib/risc/parfait_boot.rb | 3 +- test/mom/send/test_setup_simple.rb | 4 +-- test/mom/test_return_sequence.rb | 4 +-- test/parfait/test_integer.rb | 12 -------- test/parfait/test_space.rb | 28 +++++++++++------- test/parfait/type/test_type_api.rb | 2 +- test/risc/interpreter/calling/test_div10.rb | 4 +-- test/risc/interpreter/calling/test_minus.rb | 2 +- test/risc/interpreter/calling/test_plus.rb | 6 ++-- test/risc/test_interpreter.rb | 4 +-- test/risc/test_linker.rb | 2 +- test/risc/test_register_value.rb | 4 +-- 16 files changed, 59 insertions(+), 61 deletions(-) diff --git a/lib/mom/instruction/basic_values.rb b/lib/mom/instruction/basic_values.rb index 0c697207..f3402c4a 100644 --- a/lib/mom/instruction/basic_values.rb +++ b/lib/mom/instruction/basic_values.rb @@ -21,7 +21,7 @@ module Mom @value = value end def to_parfait(compiler) - value = Parfait.object_space.get_integer + value = Parfait.object_space.get_factory_for(:Integer).get_next_object value.set_value(@value) compiler.add_constant(value) value diff --git a/lib/parfait/object.rb b/lib/parfait/object.rb index 9c1b5c78..c98f8493 100644 --- a/lib/parfait/object.rb +++ b/lib/parfait/object.rb @@ -68,11 +68,6 @@ module Parfait type end - # return the metaclass - def meta - MetaClass.new self - end - def get_instance_variables type.names end diff --git a/lib/parfait/space.rb b/lib/parfait/space.rb index 34586b91..85d17680 100644 --- a/lib/parfait/space.rb +++ b/lib/parfait/space.rb @@ -31,8 +31,9 @@ module Parfait class Space < Object - attr :type, :classes , :types , :next_message , :next_integer , :next_address - attr :messages, :integers , :addresses + attr :type, :classes , :types , :factories + attr :next_message , :next_address + attr :messages, :addresses attr :true_object , :false_object , :nil_object def initialize( classes ) @@ -41,7 +42,8 @@ module Parfait classes.each do |name , cl| add_type(cl.instance_type) end - 101.times { self.integers = Integer.new(0,self.integers) } + self.factories = Dictionary.new + factories[ :Integer ] = Factory.new( classes[:Integer].instance_type) 400.times { self.addresses = ReturnAddress.new(0,self.addresses) } message = Message.new(nil) 50.times do @@ -50,7 +52,6 @@ module Parfait message = self.messages end self.next_message = self.messages - self.next_integer = self.integers self.next_address = self.addresses self.true_object = Parfait::TrueClass.new self.false_object = Parfait::FalseClass.new @@ -64,14 +65,16 @@ module Parfait 16 end - # hand out one of the preallocated ints for use as constant - # the same code is hardcoded as risc instructions for "normal" use, to - # avoid the method call at runtime. But at compile time we want to keep - # the number of integers known (fixed). - def get_integer - int = self.next_integer - self.next_integer = next_integer.next_integer - int + # return the factory for the given type + # or more exactly the type that has a class_name "name" + def get_factory_for(name) + factories[name] + end + + # use the factory of given name to generate next_object + # just a shortcut basically + def get_next_for(name) + factories[name].get_next_object end # hand out a return address for use as constant the address is added @@ -81,12 +84,14 @@ module Parfait addr end + # yield each type in the space def each_type types.values.each do |type| yield(type) end end + # add a type, meaning the instance given must be a valid type def add_type( type ) hash = type.hash raise "upps #{hash} #{hash.class}" unless hash.is_a?(Fixnum) @@ -95,6 +100,7 @@ module Parfait types[hash] = type end + # get a type by the type hash (the hash is what uniquely identifies the type) def get_type_for( hash ) types[hash] end @@ -110,11 +116,13 @@ module Parfait methods end + # shortcut to get the main method. main is defined on Space def get_main space = get_class_by_name :Space space.instance_type.get_method :main end + # shortcut to get the __init__ method, which is defined on Object def get_init object = get_class_by_name :Object object.instance_type.get_method :__init__ diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index dc794fcb..7e7ea184 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -131,10 +131,10 @@ module Risc to.set_builder( self ) # esecially div10 comes in without having used builder from.set_builder( self ) # not named regs, different regs ==> silent errors build do - space? << Parfait.object_space - to << space[:next_integer] + factory! << Parfait.object_space.get_factory_for(:Integer) + to << factory[:next_object] integer_2! << to[:next_integer] - space[:next_integer] << integer_2 + factory[:next_object] << integer_2 to[Parfait::Integer.integer_index] << from end end diff --git a/lib/risc/parfait_boot.rb b/lib/risc/parfait_boot.rb index 8d420199..07a681f8 100644 --- a/lib/risc/parfait_boot.rb +++ b/lib/risc/parfait_boot.rb @@ -163,9 +163,8 @@ module Parfait Factory: { for_type: :Type , next_object: :Object , last_object: :Object , reserve: :Object , attribute_name: :Word }, ReturnAddress: {next_integer: :ReturnAddress}, - Space: {classes: :Dictionary , types: :Dictionary , + Space: {classes: :Dictionary , types: :Dictionary , factories: :Dictionary, next_message: :Message , messages: :Message , - next_integer: :Integer, integers: :Integer , next_address: :ReturnAddress ,addresses: :ReturnAddress , true_object: :TrueClass, false_object: :FalseClass , nil_object: :NilClass}, TrueClass: {}, diff --git a/test/mom/send/test_setup_simple.rb b/test/mom/send/test_setup_simple.rb index d44dcda1..3fe97840 100644 --- a/test/mom/send/test_setup_simple.rb +++ b/test/mom/send/test_setup_simple.rb @@ -28,7 +28,7 @@ module Risc end def test_load_first_message #from space (ie r2) sl = @produced.next( 2 ) - assert_slot_to_reg( sl , :r2 , 3 , :r3 ) + assert_slot_to_reg( sl , :r2 , 4 , :r3 ) end def test_get_next_next #reduce onto itself sl = @produced.next( 3 ) @@ -36,7 +36,7 @@ module Risc end def test_store_next_next_in_space sl = @produced.next( 4 ) - assert_reg_to_slot( sl , :r4 , :r2 , 3 ) + assert_reg_to_slot( sl , :r4 , :r2 , 4 ) end def test_store_message_in_current sl = @produced.next( 5 ) diff --git a/test/mom/test_return_sequence.rb b/test/mom/test_return_sequence.rb index 3387d5f3..52da9f25 100644 --- a/test/mom/test_return_sequence.rb +++ b/test/mom/test_return_sequence.rb @@ -36,13 +36,13 @@ module Risc assert_load( instruction(4) , Parfait::Space ) end def test_get_next - assert_slot_to_reg( instruction( 5 ) , :r3 , 3 , :r4 ) + assert_slot_to_reg( instruction( 5 ) , :r3 , 4 , :r4 ) end def test_save_next assert_reg_to_slot( instruction( 6 ) , :r4 , :r0 , 1 ) end def test_save_this - assert_reg_to_slot( instruction( 7 ) , :r0 , :r3 , 3 ) + assert_reg_to_slot( instruction( 7 ) , :r0 , :r3 , 4 ) end def test_save_addr diff --git a/test/parfait/test_integer.rb b/test/parfait/test_integer.rb index e2a61d12..e9ba501f 100644 --- a/test/parfait/test_integer.rb +++ b/test/parfait/test_integer.rb @@ -31,18 +31,6 @@ module Parfait assert_equal 20 , @int.set_internal_word( Integer.integer_index , 20 ) assert_equal 20 , @int.get_internal_word( Integer.integer_index ) end - def test_integer_first - assert Parfait.object_space.next_integer - end - def test_integer_20 - int = Parfait.object_space.next_integer - 20.times do - assert int - assert_equal Parfait::Integer , int.class - assert int.get_internal_word(1) - int = int.next_integer - end - end def test_set @int.set_value(1) assert_equal 1 , @int.value diff --git a/test/parfait/test_space.rb b/test/parfait/test_space.rb index aa2a35c1..89bb0bb4 100644 --- a/test/parfait/test_space.rb +++ b/test/parfait/test_space.rb @@ -11,7 +11,7 @@ module Parfait end def test_space_length - assert_equal 12 , @space.get_type.instance_length , @space.get_type.inspect + assert_equal 11 , @space.get_type.instance_length , @space.get_type.inspect end def test_singletons assert @space.true_object , "No truth" @@ -21,7 +21,6 @@ module Parfait def test_global_space assert_equal Parfait::Space , Parfait.object_space.class end - def test_get_class_by_name assert_equal Parfait::Class , Parfait.object_space.get_class_by_name(:Space).class end @@ -31,10 +30,6 @@ module Parfait def test_get_type_by_class_name_nil assert_nil Parfait.object_space.get_type_by_class_name(:Spac) end - def test_get_integer_instance - int = @space.get_integer - assert_equal Integer , int.class - end def test_classes_class classes.each do |name| assert_equal :Class , @space.classes[name].get_class.name @@ -93,12 +88,26 @@ module Parfait end end end + def test_has_factory + assert_equal Dictionary , @space.factories.class + end + def test_factory_length + assert_equal 1 , @space.factories.length + end + def test_has_integer_factory + ints = @space.get_factory_for(:Integer) + assert_equal Factory , ints.class + assert_equal :Integer , ints.for_type.class_name + end def test_has_integers - assert_equal Parfait::Integer , @space.next_integer.class - assert_equal 0 , @space.next_integer.value + nekst = @space.get_next_for(:Integer) + assert_equal Parfait::Integer , nekst.class + assert_nil nekst.value end def test_has_next_integer - assert_equal Parfait::Integer , @space.next_integer.next_integer.class + nekst = @space.get_next_for(:Integer) + nekst = @space.get_next_for(:Integer) + assert_equal Parfait::Integer , nekst.class end def test_has_addresses assert_equal Parfait::ReturnAddress , @space.next_address.class @@ -116,7 +125,6 @@ module Parfait end assert_equal 400, count end - def test_messages mess = @space.messages all = [] diff --git a/test/parfait/type/test_type_api.rb b/test/parfait/type/test_type_api.rb index 4f6b457b..7bc8c575 100644 --- a/test/parfait/type/test_type_api.rb +++ b/test/parfait/type/test_type_api.rb @@ -27,7 +27,7 @@ module Parfait assert_equal Parfait::Space , space.class type = space.get_type assert_equal Parfait::Type , type.class - assert_equal 12 , type.names.get_length + assert_equal 11 , type.names.get_length assert_equal type.object_class.class , Parfait::Class assert_equal type.object_class.name , :Space end diff --git a/test/risc/interpreter/calling/test_div10.rb b/test/risc/interpreter/calling/test_div10.rb index ee3bbe80..9ba8268c 100644 --- a/test/risc/interpreter/calling/test_div10.rb +++ b/test/risc/interpreter/calling/test_div10.rb @@ -35,11 +35,11 @@ module Risc def test_load_space load_ins = main_ticks 53 - assert_load load_ins, Parfait::Space + assert_load load_ins, Parfait::Factory end def test_load_to to = main_ticks 54 - assert_slot_to_reg to , :r5 , 5 ,:r2 + assert_slot_to_reg to , :r5 , 2 ,:r2 end def test_load_25 load_ins = main_ticks 9 diff --git a/test/risc/interpreter/calling/test_minus.rb b/test/risc/interpreter/calling/test_minus.rb index 001b6e24..a1f6525f 100644 --- a/test/risc/interpreter/calling/test_minus.rb +++ b/test/risc/interpreter/calling/test_minus.rb @@ -45,7 +45,7 @@ module Risc ret = main_ticks(64) assert_equal FunctionReturn , ret.class assert_equal :r1 , ret.register.symbol - assert_equal 27080 , @interpreter.get_register(ret.register) + assert_equal 41992 , @interpreter.get_register(ret.register) end end end diff --git a/test/risc/interpreter/calling/test_plus.rb b/test/risc/interpreter/calling/test_plus.rb index b22b44da..4abc8c68 100644 --- a/test/risc/interpreter/calling/test_plus.rb +++ b/test/risc/interpreter/calling/test_plus.rb @@ -68,11 +68,11 @@ module Risc end def test_load_int_space cons = main_ticks(base + 6) - assert_load( cons , Parfait::Space , :r3) + assert_load( cons , Parfait::Factory , :r3) end def test_load_int_next_space sl = main_ticks(base + 7) - assert_slot_to_reg( sl , :r3 , 5 , :r2) + assert_slot_to_reg( sl , :r3 , 2 , :r2) assert_equal Parfait::Integer , @interpreter.get_register(:r2).class end def test_load_int_next_int @@ -82,7 +82,7 @@ module Risc end def test_load_int_next_int2 sl = main_ticks(base + 9) - assert_reg_to_slot( sl , :r4 , :r3 , 5) + assert_reg_to_slot( sl , :r4 , :r3 , 2) end end end diff --git a/test/risc/test_interpreter.rb b/test/risc/test_interpreter.rb index 6fee456e..266b3778 100644 --- a/test/risc/test_interpreter.rb +++ b/test/risc/test_interpreter.rb @@ -54,7 +54,7 @@ module Risc end def test_pc1 @interpreter.tick - assert_equal 26680 , @interpreter.pc + assert_equal 41592 , @interpreter.pc end def test_tick2 @interpreter.tick @@ -68,7 +68,7 @@ module Risc def test_pc2 @interpreter.tick @interpreter.tick - assert_equal 26684 , @interpreter.pc + assert_equal 41596 , @interpreter.pc end def test_tick_14_jump 14.times {@interpreter.tick} diff --git a/test/risc/test_linker.rb b/test/risc/test_linker.rb index b285fd66..8bbc7e70 100644 --- a/test/risc/test_linker.rb +++ b/test/risc/test_linker.rb @@ -25,7 +25,7 @@ module Risc assert_equal 0 , Position.get(@linker.cpu_init).at end def test_cpu_at - assert_equal "0x76ec" , Position.get(@linker.cpu_init.first).to_s + assert_equal "0xb12c" , Position.get(@linker.cpu_init.first).to_s end def test_cpu_label assert_equal Position , Position.get(@linker.cpu_init.first).class diff --git a/test/risc/test_register_value.rb b/test/risc/test_register_value.rb index abda7e2a..8b8a2ff5 100644 --- a/test/risc/test_register_value.rb +++ b/test/risc/test_register_value.rb @@ -81,7 +81,7 @@ module Risc assert_equal SlotToReg , instr.class assert_equal @r1 , instr.array assert_equal @r0 , instr.register - assert_equal 3 , instr.index + assert_equal 4 , instr.index end def test_reg_to_byte instr = @r1[1] <= @r0 @@ -95,7 +95,7 @@ module Risc assert_equal RegToSlot , instr.class assert_equal @r1 , instr.array assert_equal @r0 , instr.register - assert_equal 3 , instr.index + assert_equal 4 , instr.index end end end