From dcbc3e17be2b94738a52664cde290ed97061df26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20R=C3=BCger?= Date: Sat, 28 Sep 2019 15:34:09 +0300 Subject: [PATCH] refactor risc_collection move code that operates on compiler to the compiler class this leaves the collection thin, very thin indeed --- lib/mom/mom_collection.rb | 4 +- lib/risc/callable_compiler.rb | 15 ++++++ lib/risc/method_compiler.rb | 9 ++++ lib/risc/risc_collection.rb | 39 ++------------- test/mom/test_method_compiler.rb | 76 ++++++++++++++++++++++------- test/risc/test_method_compiler.rb | 80 +++++++------------------------ 6 files changed, 106 insertions(+), 117 deletions(-) diff --git a/lib/mom/mom_collection.rb b/lib/mom/mom_collection.rb index 81e9aa07..6021aa47 100644 --- a/lib/mom/mom_collection.rb +++ b/lib/mom/mom_collection.rb @@ -24,8 +24,8 @@ module Mom self end - # Return all compilers, namely the MethodCompilers passed in, plus the - # boot_function's compilers (boot_compilers) + # Return all compilers, namely the MethodCompilers instanc, + # plus the init_compilers def compilers init_compilers @method_compilers diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index ad514806..31677f54 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -123,5 +123,20 @@ module Risc def builder( source) Builder.new(self , source) end + + # compile the callable (method or block) to cpu + # return an Assembler that will then translate to binary + def translate_cpu(translator) + risc = @risc_instructions + cpu_instructions = risc.to_cpu(translator) + nekst = risc.next + while(nekst) + cpu = nekst.to_cpu(translator) # returning nil means no replace + cpu_instructions << cpu if cpu + nekst = nekst.next + end + Risc::Assembler.new(@callable , cpu_instructions ) + end + end end diff --git a/lib/risc/method_compiler.rb b/lib/risc/method_compiler.rb index 41b5c8a3..6c7fbaa1 100644 --- a/lib/risc/method_compiler.rb +++ b/lib/risc/method_compiler.rb @@ -30,5 +30,14 @@ module Risc @block_compilers << compiler end + # translate this method, which means the method itself and all blocks inside it + # returns the array (of assemblers) that you pass in as collection + def translate_method( translator , collection) + collection << translate_cpu( translator ) + @block_compilers.each do |block_compiler| + collection << block_compiler.translate_cpu(translator) + end + collection + end end end diff --git a/lib/risc/risc_collection.rb b/lib/risc/risc_collection.rb index 076916df..f0721228 100644 --- a/lib/risc/risc_collection.rb +++ b/lib/risc/risc_collection.rb @@ -40,43 +40,12 @@ module Risc def translate( platform_sym ) platform_sym = platform_sym.to_s.capitalize platform = Risc::Platform.for(platform_sym) - assemblers = translate_methods( platform.translator ) + assemblers = [] + @method_compilers.each_compiler do |compiler| + compiler.translate_method( platform.translator , assemblers) + end Risc::Linker.new(platform , assemblers , constants) end - # go through all methods and translate them to cpu, given the translator - def translate_methods(translator) - collection = [] - method_compilers.each_compiler do |compiler| - #puts "Translate method #{compiler.callable.name}" - translate_method(compiler , translator , collection) - end - collection - end - - # translate one method, which means the method itself and all blocks inside it - # returns an array of assemblers - def translate_method( method_compiler , translator , collection) - collection << translate_cpu( method_compiler , translator ) - method_compiler.block_compilers.each do |block_compiler| - collection << translate_cpu(block_compiler , translator) - end - collection - end - - # compile the callable (method or block) to cpu - # return an Assembler that will then translate to binary - def translate_cpu(compiler , translator) - risc = compiler.risc_instructions - cpu_instructions = risc.to_cpu(translator) - nekst = risc.next - while(nekst) - cpu = nekst.to_cpu(translator) # returning nil means no replace - cpu_instructions << cpu if cpu - nekst = nekst.next - end - Risc::Assembler.new(compiler.callable , cpu_instructions ) - end - end end diff --git a/test/mom/test_method_compiler.rb b/test/mom/test_method_compiler.rb index 2b93c789..264a99a7 100644 --- a/test/mom/test_method_compiler.rb +++ b/test/mom/test_method_compiler.rb @@ -7,30 +7,70 @@ module Mom def setup end - def in_test_vool(body = "@ivar = 5;return") - code = in_Test("def meth; #{body};end") - RubyX::RubyXCompiler.new(RubyX.default_test_options).ruby_to_mom(code) + def in_test_vool(str) + vool = RubyX::RubyXCompiler.new(RubyX.default_test_options).ruby_to_vool(in_Test(str)) + vool.to_parfait + vool.to_mom(nil) + vool + end + def create_method(body = "@ivar = 5;return") + in_test_vool("def meth; #{body};end") + test = Parfait.object_space.get_class_by_name(:Test) + test.get_instance_method(:meth) end - def test_method - in_test_vool() - method = Parfait.object_space.get_class_by_name(:Test).get_instance_method(:meth) + def test_method_has_source + method = create_method + assert_equal Vool::Statements , method.source.class + end + + def test_method_has_no_locals + method = create_method + assert_equal 1 , method.frame_type.instance_length + end + + def test_method_has_no_args + method = create_method + assert_equal 1 , method.args_type.instance_length + end + + def test_creates_method_in_class + method = create_method + assert method , "No method created" assert_equal Parfait::VoolMethod , method.class end - def test_method_mom_col - mom = in_test_vool() - assert_equal Mom::MomCollection , mom.class - assert_equal Mom::MethodCompiler , mom.compilers.class + + def test_creates_method_statement_in_class + clazz = in_test_vool("def meth; @ivar = 5 ;return;end") + assert_equal Vool::Statements , clazz.body.class + assert_equal Vool::MethodExpression , clazz.body.first.class end - def test_compiles_risc - compiler = in_test_vool().compilers.to_risc - assert_equal Risc::MethodCompiler , compiler.class - assert_equal Risc::Label , compiler.risc_instructions.class + + def test_callable_method_instance_type + in_test_vool("def meth; @ivar = 5; @ibar = 4;return;end") + test = Parfait.object_space.get_class_by_name(:Test) + method = test.instance_type.get_method(:meth) + assert_equal 1, method.self_type.variable_index(:ivar) + assert_equal 2, method.self_type.variable_index(:ibar) end - def test_compiles_all_risc - compiler = in_test_vool().compilers.to_risc - assert_equal Risc::LoadConstant , compiler.risc_instructions.next.class - assert_equal 16 , compiler.risc_instructions.length + def test_callable_method_has_one_local + in_test_vool("def meth; local = 5 ; a = 6;return;end") + test = Parfait.object_space.get_class_by_name(:Test) + method = test.get_instance_method(:meth) + assert_equal 3 , method.frame_type.instance_length + assert_equal 1 , method.frame_type.variable_index(:local) + assert_equal 2 , method.frame_type.variable_index(:a) + end + def constant_setup(input) + mom = RubyX::RubyXCompiler.new(RubyX.default_test_options).ruby_to_mom(in_Test(input)) + assert_equal Mom::MomCollection , mom.class + compiler = mom.method_compilers + assert_equal Mom::MethodCompiler , compiler.class + compiler + end + def test_return_label + compiler = constant_setup("def meth; return 'Hi';end") + assert_equal "return_label", compiler.return_label.name end end end diff --git a/test/risc/test_method_compiler.rb b/test/risc/test_method_compiler.rb index 94484a76..0e8ea341 100644 --- a/test/risc/test_method_compiler.rb +++ b/test/risc/test_method_compiler.rb @@ -5,72 +5,28 @@ module Risc include ScopeHelper def setup + code = in_Test("def meth; @ivar = 5;return ;end") + rubyx = RubyX::RubyXCompiler.new(RubyX.default_test_options) + @compiler = rubyx.ruby_to_mom(code).compilers.to_risc end - - def in_test_vool(str) - vool = RubyX::RubyXCompiler.new(RubyX.default_test_options).ruby_to_vool(in_Test(str)) - vool.to_parfait - vool.to_mom(nil) - vool + def test_compiles_risc + assert_equal Risc::MethodCompiler , @compiler.class + assert_equal Risc::Label , @compiler.risc_instructions.class end - def create_method(body = "@ivar = 5;return") - in_test_vool("def meth; #{body};end") - test = Parfait.object_space.get_class_by_name(:Test) - test.get_instance_method(:meth) + def test_compiles_all_risc + assert_equal Risc::LoadConstant , @compiler.risc_instructions.next.class + assert_equal 16 , @compiler.risc_instructions.length end - - def test_method_has_source - method = create_method - assert_equal Vool::Statements , method.source.class + def test_translate_cpu + cpu = @compiler.translate_cpu(Platform.for(:arm).translator) + assert_equal Assembler , cpu.class + assert_equal :meth , cpu.callable.name end - - def test_method_has_no_locals - method = create_method - assert_equal 1 , method.frame_type.instance_length - end - - def test_method_has_no_args - method = create_method - assert_equal 1 , method.args_type.instance_length - end - - def test_creates_method_in_class - method = create_method - assert method , "No method created" - assert_equal Parfait::VoolMethod , method.class - end - - def test_creates_method_statement_in_class - clazz = in_test_vool("def meth; @ivar = 5 ;return;end") - assert_equal Vool::Statements , clazz.body.class - assert_equal Vool::MethodExpression , clazz.body.first.class - end - - def test_callable_method_instance_type - in_test_vool("def meth; @ivar = 5; @ibar = 4;return;end") - test = Parfait.object_space.get_class_by_name(:Test) - method = test.instance_type.get_method(:meth) - assert_equal 1, method.self_type.variable_index(:ivar) - assert_equal 2, method.self_type.variable_index(:ibar) - end - def test_callable_method_has_one_local - in_test_vool("def meth; local = 5 ; a = 6;return;end") - test = Parfait.object_space.get_class_by_name(:Test) - method = test.get_instance_method(:meth) - assert_equal 3 , method.frame_type.instance_length - assert_equal 1 , method.frame_type.variable_index(:local) - assert_equal 2 , method.frame_type.variable_index(:a) - end - def constant_setup(input) - mom = RubyX::RubyXCompiler.new(RubyX.default_test_options).ruby_to_mom(in_Test(input)) - assert_equal Mom::MomCollection , mom.class - compiler = mom.method_compilers - assert_equal Mom::MethodCompiler , compiler.class - compiler - end - def test_return_label - compiler = constant_setup("def meth; return 'Hi';end") - assert_equal "return_label", compiler.return_label.name + def test_translate_method + ass = @compiler.translate_method(Platform.for(:arm).translator , []) + assert_equal Array , ass.class + assert_equal Assembler , ass.first.class + assert_equal :meth , ass.first.callable.name end end end