From d913bb01de4514caedd235d41cbfd92c6a3002cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20R=C3=BCger?= Date: Sun, 15 Sep 2019 15:13:11 +0300 Subject: [PATCH] use method missing in resolve method not just exit try to print name next --- lib/mom/instruction/resolve_method.rb | 5 +-- lib/mom/macro/init.rb | 16 ++++++-- lib/mom/macro/method_missing.rb | 9 +++-- lib/mom/mom_collection.rb | 45 ++++++++++++--------- test/mom/macro/test_method_missing.rb | 2 +- test/mom/test_mom_collection.rb | 11 +++-- test/risc/interpreter/calling/test_minus.rb | 2 +- test/risc/test_collector.rb | 4 +- test/risc/test_interpreter.rb | 9 ++--- test/risc/test_linker.rb | 2 +- test/risc/test_linker1.rb | 2 +- test/rubyx/macro/test_object_missing.rb | 2 +- test/rubyx/test_rubyx_compiler2.rb | 2 +- test/rubyx/test_rubyx_compiler3.rb | 2 +- 14 files changed, 63 insertions(+), 50 deletions(-) diff --git a/lib/mom/instruction/resolve_method.rb b/lib/mom/instruction/resolve_method.rb index 92f9c4ea..9178954e 100644 --- a/lib/mom/instruction/resolve_method.rb +++ b/lib/mom/instruction/resolve_method.rb @@ -62,10 +62,7 @@ module Mom branch while_start_label add_code exit_label - # temporary, need to raise really. - factory! << Parfait.object_space.get_factory_for(:Integer) - integer_tmp! << factory[:reserve] - Mom::Macro.emit_syscall( builder , :died ) #uses integer_tmp + MethodMissing.new(compiler.source_name).to_risc(compiler) add_code ok_label cache_entry[:cached_method] << callable_method diff --git a/lib/mom/macro/init.rb b/lib/mom/macro/init.rb index 0959d36a..7614d45e 100644 --- a/lib/mom/macro/init.rb +++ b/lib/mom/macro/init.rb @@ -1,9 +1,17 @@ module Mom + # Init "method" is the first thing that happens in the machine + # There is an inital jump to it, but that's it, no setup, no nothing + # + # The method is in quotes, because it is not really a method, it does not return!! + # This is common to all double underscore "methods", but __init also does not + # rely on the message. In fact it's job is to set up the first message + # and to call the main (possibly later _init_ , single undescrore) + # class Init < Macro def to_risc(compiler) builder = compiler.builder(compiler.source) main = Parfait.object_space.get_method!(:Space, :main) - + # Set up the first message, but advance one, so main has somewhere to return to builder.build do factory! << Parfait.object_space.get_factory_for(:Message) message << factory[:next_object] @@ -11,14 +19,14 @@ module Mom factory[:next_object] << next_message end builder.reset_names + # Set up the call to main, with space as receiver Mom::MessageSetup.new(main).build_with( builder ) - builder.build do message << message[:next_message] space? << Parfait.object_space message[:receiver] << space end - + # set up return address and jump to main exit_label = Risc.label(compiler.source , "#{compiler.receiver_type.object_class.name}.#{compiler.source.name}" ) ret_tmp = compiler.use_reg(:Label).set_builder(builder) builder.build do @@ -28,7 +36,7 @@ module Mom add_code exit_label end compiler.reset_regs - Macro.exit_sequence(builder) + Macro.exit_sequence(builder) # exit will use mains return_value as exit_code return compiler end end diff --git a/lib/mom/macro/method_missing.rb b/lib/mom/macro/method_missing.rb index 7cab2be7..bf37e4d0 100644 --- a/lib/mom/macro/method_missing.rb +++ b/lib/mom/macro/method_missing.rb @@ -1,9 +1,12 @@ module Mom class MethodMissing < Macro def to_risc(compiler) - builder = compiler.builder(compiler.source) - builder.prepare_int_return # makes integer_tmp variable as return - Macro.emit_syscall( builder , :exit ) + builder = compiler.builder(compiler.source_name) + builder.build do + factory! << Parfait.object_space.get_factory_for(:Integer) + integer_tmp! << factory[:reserve] + Mom::Macro.emit_syscall( builder , :died ) #uses integer_tmp + end return compiler end end diff --git a/lib/mom/mom_collection.rb b/lib/mom/mom_collection.rb index 28e245c8..6ecb155d 100644 --- a/lib/mom/mom_collection.rb +++ b/lib/mom/mom_collection.rb @@ -14,15 +14,18 @@ module Mom @method_compilers = compilers end - # lazily instantiate the compiler for init function + # lazily instantiate the compiler for __init__ function and __method_missing__ def init_compiler - @init_compilers ||= MomCollection.create_init_compiler + @init_compilers ||= [ + MomCollection.create_init_compiler , + MomCollection.create_mm_compiler , + ] end # Return all compilers, namely the MethodCompilers passed in, plus the # boot_function's compilers (boot_compilers) def compilers - @method_compilers << init_compiler + @method_compilers + init_compiler end # Append another MomCompilers method_compilers to this one. @@ -41,23 +44,25 @@ module Mom Risc::RiscCollection.new(riscs) end - # this is the really really first place the machine starts (apart from the jump here) - # 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: - # - load fist message, set up Space as receiver - # - call main, ie set up message for that etc - # - exit (exit_sequence) which passes a machine int out to c - def self.create_init_compiler - compiler = compiler_for(:Object,:__init__ ,{}) - compiler._reset_for_init # no return, just for init - compiler.add_code Init.new("missing") - return compiler - end - def self.compiler_for( clazz_name , method_name , arguments , locals = {}) - frame = Parfait::NamedList.type_for( locals ) - args = Parfait::NamedList.type_for( arguments ) - MethodCompiler.compiler_for_class(clazz_name , method_name , args, frame ) - end + # See Init instruction. We must have an init (ie we need it in code), so it is created in code + def self.create_init_compiler + compiler = compiler_for(:Object,:__init__ ,{}) + compiler._reset_for_init # no return, just for init + compiler.add_code Init.new("missing") + return compiler + end + + def self.create_mm_compiler + compiler = compiler_for(:Object,:__method_missing__ ,{}) + compiler.add_code MethodMissing.new("missing") + return compiler + end + + def self.compiler_for( clazz_name , method_name , arguments , locals = {}) + frame = Parfait::NamedList.type_for( locals ) + args = Parfait::NamedList.type_for( arguments ) + MethodCompiler.compiler_for_class(clazz_name , method_name , args, frame ) + end end end diff --git a/test/mom/macro/test_method_missing.rb b/test/mom/macro/test_method_missing.rb index 7fdcf73f..f96dc2c5 100644 --- a/test/mom/macro/test_method_missing.rb +++ b/test/mom/macro/test_method_missing.rb @@ -14,7 +14,7 @@ module Mom assert_equal Risc::MethodCompiler , @method.to_risc.class end def test_risc_length - assert_equal 42 , @method.to_risc.risc_instructions.length + assert_equal 21 , @method.to_risc.risc_instructions.length end end end diff --git a/test/mom/test_mom_collection.rb b/test/mom/test_mom_collection.rb index 4fc3f894..87b75b3e 100644 --- a/test/mom/test_mom_collection.rb +++ b/test/mom/test_mom_collection.rb @@ -12,13 +12,16 @@ module Mom assert_equal MomCollection , @comp.class end def test_compilers - assert_equal 2 , @comp.compilers.length + assert_equal 3 , @comp.compilers.length + end + def test_init_compilers + assert_equal Array , @comp.init_compiler.class end def test_init_compiler - assert_equal Mom::MethodCompiler , @comp.init_compiler.class + assert_equal Mom::MethodCompiler , @comp.init_compiler.first.class end def test_compilers_bare - assert_equal 1 , MomCollection.new.compilers.length + assert_equal 2 , MomCollection.new.compilers.length end def test_append_class assert_equal MomCollection, (@comp.append @comp).class @@ -42,7 +45,7 @@ module Mom end def test_has_risc_compiler assert_equal Risc::MethodCompiler, compiler.class - assert_equal 2, @collection.method_compilers.length + assert_equal 3, @collection.method_compilers.length end def test_has_risc_instructions assert_equal Risc::Label, compiler.risc_instructions.class diff --git a/test/risc/interpreter/calling/test_minus.rb b/test/risc/interpreter/calling/test_minus.rb index feefa2e4..bfd2a8b5 100644 --- a/test/risc/interpreter/calling/test_minus.rb +++ b/test/risc/interpreter/calling/test_minus.rb @@ -38,7 +38,7 @@ module Risc ret = main_ticks(49) assert_equal FunctionReturn , ret.class assert_equal :r3 , ret.register.symbol - assert_equal 38140 , @interpreter.get_register(ret.register) + assert_equal 38236 , @interpreter.get_register(ret.register) end end end diff --git a/test/risc/test_collector.rb b/test/risc/test_collector.rb index 3eea1aeb..1ff40ecb 100644 --- a/test/risc/test_collector.rb +++ b/test/risc/test_collector.rb @@ -38,7 +38,7 @@ module Risc end def len - 1476 + 1479 end def test_collect_all_types @@ -70,7 +70,7 @@ module Risc end def len - 2956 + 2959 end end end diff --git a/test/risc/test_interpreter.rb b/test/risc/test_interpreter.rb index be21cef0..c39f363d 100644 --- a/test/risc/test_interpreter.rb +++ b/test/risc/test_interpreter.rb @@ -52,14 +52,11 @@ module Risc @interpreter.tick assert_equal 2 , @interpreter.clock end - def test_pc1 + def test_pc @interpreter.tick - assert_equal 37704 , @interpreter.pc - end - def test_pc2 + assert_equal t = 37800 , @interpreter.pc @interpreter.tick - @interpreter.tick - assert_equal 37708 , @interpreter.pc + assert_equal t + 4 , @interpreter.pc end def test_tick2 @interpreter.tick diff --git a/test/risc/test_linker.rb b/test/risc/test_linker.rb index 56357a33..758c7826 100644 --- a/test/risc/test_linker.rb +++ b/test/risc/test_linker.rb @@ -24,7 +24,7 @@ module Risc assert_equal 0 , Position.get(@linker.cpu_init).at end def test_cpu_at - assert_equal "0x93bc" , Position.get(@linker.cpu_init.first).to_s + assert_equal "0x941c" , 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_linker1.rb b/test/risc/test_linker1.rb index 1a457483..13529621 100644 --- a/test/risc/test_linker1.rb +++ b/test/risc/test_linker1.rb @@ -16,7 +16,7 @@ module Risc assert_equal 1 , mains.length end def test_assembler_num - assert_equal 2 , @linker.assemblers.length + assert_equal 3 , @linker.assemblers.length end end end diff --git a/test/rubyx/macro/test_object_missing.rb b/test/rubyx/macro/test_object_missing.rb index 64cd01b3..ebc46e26 100644 --- a/test/rubyx/macro/test_object_missing.rb +++ b/test/rubyx/macro/test_object_missing.rb @@ -28,7 +28,7 @@ GET assert_equal Mom::MethodMissing , compiler.mom_instructions.next.class end def test_risc - assert_equal 42 , compiler.to_risc.risc_instructions.length + assert_equal 21 , compiler.to_risc.risc_instructions.length end end end diff --git a/test/rubyx/test_rubyx_compiler2.rb b/test/rubyx/test_rubyx_compiler2.rb index 2d69c1d3..5d4dc671 100644 --- a/test/rubyx/test_rubyx_compiler2.rb +++ b/test/rubyx/test_rubyx_compiler2.rb @@ -23,7 +23,7 @@ module RubyX end def test_asm_len linker = @collection.translate(:interpreter) - assert_equal 2 , linker.assemblers.length + assert_equal 3 , linker.assemblers.length end end class TestRubyXCompilerParfait < MiniTest::Test diff --git a/test/rubyx/test_rubyx_compiler3.rb b/test/rubyx/test_rubyx_compiler3.rb index cb489e16..c6812095 100644 --- a/test/rubyx/test_rubyx_compiler3.rb +++ b/test/rubyx/test_rubyx_compiler3.rb @@ -36,7 +36,7 @@ module RubyX assert_equal 2 , compiler.vool.length linker = compiler.to_binary(:interpreter) assert_equal Risc::Linker , linker.class - assert_equal 3 , linker.assemblers.length + assert_equal 4 , linker.assemblers.length end end end