From 3f8095338508998baccbc740d0b6db12c6d88111 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Thu, 5 Jul 2018 14:02:38 +0300 Subject: [PATCH] passing compiler to to_mom, not method To be able to delegate scope (block/method) things later --- lib/parfait/vool_method.rb | 2 +- lib/vool/assign_statement.rb | 10 +++---- lib/vool/basic_values.rb | 14 +++++----- lib/vool/block_statement.rb | 7 +++-- lib/vool/if_statement.rb | 18 ++++++------ lib/vool/local_assignment.rb | 8 +++--- lib/vool/return_statement.rb | 5 ++-- lib/vool/send_statement.rb | 46 +++++++++++++++---------------- lib/vool/statement.rb | 4 +-- lib/vool/statements.rb | 6 ++-- lib/vool/variables.rb | 6 ++-- lib/vool/while_statement.rb | 8 +++--- lib/vool/yield_statement.rb | 14 +++++----- test/support/compiling.rb | 2 +- test/vool/test_block_statement.rb | 2 +- 15 files changed, 78 insertions(+), 74 deletions(-) diff --git a/lib/parfait/vool_method.rb b/lib/parfait/vool_method.rb index d4a8bee0..703defff 100644 --- a/lib/parfait/vool_method.rb +++ b/lib/parfait/vool_method.rb @@ -30,8 +30,8 @@ module Parfait def compiler_for(for_type) typed_method = create_typed_method(for_type) - head = source.to_mom( typed_method ) compiler = Risc::MethodCompiler.new( typed_method ) + head = source.to_mom( compiler ) compiler.add_mom(head) compiler end diff --git a/lib/vool/assign_statement.rb b/lib/vool/assign_statement.rb index 22278965..df8f8854 100644 --- a/lib/vool/assign_statement.rb +++ b/lib/vool/assign_statement.rb @@ -31,9 +31,9 @@ module Vool statements end - def chain_assign(assign , method) + def chain_assign(assign , compiler) return assign unless @value.is_a?(SendStatement) - @value.to_mom(method) << assign + @value.to_mom(compiler) << assign end def each(&block) @@ -54,10 +54,10 @@ module Vool return IvarAssignment.new(@name , @value) end - def to_mom( method ) + def to_mom( compiler ) to = Mom::SlotDefinition.new(:message ,[ :receiver , @name]) - from = @value.slot_definition(method) - return chain_assign( Mom::SlotLoad.new(to,from) , method) + from = @value.slot_definition(compiler) + return chain_assign( Mom::SlotLoad.new(to,from) , compiler) end end diff --git a/lib/vool/basic_values.rb b/lib/vool/basic_values.rb index 50af9f4f..b7a593fe 100644 --- a/lib/vool/basic_values.rb +++ b/lib/vool/basic_values.rb @@ -10,7 +10,7 @@ module Vool def initialize(value) @value = value end - def slot_definition(method) + def slot_definition(compiler) return Mom::SlotDefinition.new(Mom::IntegerConstant.new(@value) , []) end def ct_type @@ -35,7 +35,7 @@ module Vool def ct_type Parfait.object_space.get_class_by_name(:True).instance_type end - def slot_definition(method) + def slot_definition(compiler) return Mom::SlotDefinition.new(Parfait.object_space.true_object , []) end def to_s(depth = 0) @@ -46,7 +46,7 @@ module Vool def ct_type Parfait.object_space.get_class_by_name(:False).instance_type end - def slot_definition(method) + def slot_definition(compiler) return Mom::SlotDefinition.new(Parfait.object_space.false_object , []) end def to_s(depth = 0) @@ -57,7 +57,7 @@ module Vool def ct_type Parfait.object_space.get_class_by_name(:Nil).instance_type end - def slot_definition(method) + def slot_definition(compiler) return Mom::SlotDefinition.new(Parfait.object_space.nil_object , []) end def to_s(depth = 0) @@ -69,8 +69,8 @@ module Vool def initialize(type = nil) @my_type = type end - def slot_definition(in_method) - @my_type = in_method.for_type + def slot_definition(compiler) + @my_type = compiler.method.for_type Mom::SlotDefinition.new(:message , [:receiver]) end def ct_type @@ -90,7 +90,7 @@ module Vool def initialize(value) @value = value end - def slot_definition(method) + def slot_definition(compiler) return Mom::SlotDefinition.new(Mom::StringConstant.new(@value),[]) end def ct_type diff --git a/lib/vool/block_statement.rb b/lib/vool/block_statement.rb index 4fc78926..dcc031b4 100644 --- a/lib/vool/block_statement.rb +++ b/lib/vool/block_statement.rb @@ -8,8 +8,11 @@ module Vool @clazz = clazz end - def to_mom( _ ) - raise "should not be called (call create_objects)" + def to_mom( compiler ) +# raise "should not be called (call create_objects)" + end + def slot_definition(compiler) + return Mom::SlotDefinition.new(Mom::IntegerConstant.new(1) , []) end def each(&block) diff --git a/lib/vool/if_statement.rb b/lib/vool/if_statement.rb index ea981ea0..dfaad714 100644 --- a/lib/vool/if_statement.rb +++ b/lib/vool/if_statement.rb @@ -20,31 +20,31 @@ module Vool rest end - def to_mom( method ) - if_false ? full_if(method) : simple_if(method) + def to_mom( compiler ) + if_false ? full_if(compiler) : simple_if(compiler) end - def simple_if(method) + def simple_if(compiler) true_label = Mom::Label.new( "true_label_#{object_id.to_s(16)}") merge_label = Mom::Label.new( "merge_label_#{object_id.to_s(16)}") - head = Mom::TruthCheck.new(condition.slot_definition(method) , merge_label) + head = Mom::TruthCheck.new(condition.slot_definition(compiler) , merge_label) head << true_label - head << if_true.to_mom(method) + head << if_true.to_mom(compiler) head << merge_label end - def full_if(method) + def full_if(compiler) true_label = Mom::Label.new( "true_label_#{object_id.to_s(16)}") false_label = Mom::Label.new( "false_label_#{object_id.to_s(16)}") merge_label = Mom::Label.new( "merge_label_#{object_id.to_s(16)}") - head = Mom::TruthCheck.new(condition.slot_definition(method) , false_label) + head = Mom::TruthCheck.new(condition.slot_definition(compiler) , false_label) head << true_label - head << if_true.to_mom(method) + head << if_true.to_mom(compiler) head << Mom::Jump.new(merge_label) head << false_label - head << if_false.to_mom(method) + head << if_false.to_mom(compiler) head << merge_label end diff --git a/lib/vool/local_assignment.rb b/lib/vool/local_assignment.rb index b71f33f5..c65ee822 100644 --- a/lib/vool/local_assignment.rb +++ b/lib/vool/local_assignment.rb @@ -2,15 +2,15 @@ module Vool class LocalAssignment < Assignment - def to_mom( method ) - if method.arguments_type.variable_index(@name) + def to_mom( compiler ) + if compiler.method.arguments_type.variable_index(@name) type = :arguments else type = :frame end to = Mom::SlotDefinition.new(:message ,[ type , @name]) - from = @value.slot_definition(method) - return chain_assign( Mom::SlotLoad.new(to,from) , method) + from = @value.slot_definition(compiler) + return chain_assign( Mom::SlotLoad.new(to,from) , compiler) end end diff --git a/lib/vool/return_statement.rb b/lib/vool/return_statement.rb index 53412be1..ac045f33 100644 --- a/lib/vool/return_statement.rb +++ b/lib/vool/return_statement.rb @@ -24,8 +24,9 @@ module Vool # To return form a method in mom instructions we only need to do two things: # - store the given return value, this is a SlotMove # - activate return sequence (reinstantiate old message and jump to return address) - def to_mom( method ) - ret = Mom::SlotLoad.new( [:message , :return_value] , @return_value.slot_definition(method) ) + def to_mom( compiler ) + ret = Mom::SlotLoad.new( [:message , :return_value] , + @return_value.slot_definition(compiler) ) ret << Mom::ReturnSequence.new end diff --git a/lib/vool/send_statement.rb b/lib/vool/send_statement.rb index 98974d48..5bdd0af3 100644 --- a/lib/vool/send_statement.rb +++ b/lib/vool/send_statement.rb @@ -60,7 +60,7 @@ module Vool @arguments.each do |arg| block.call(arg) end - self.block.each(block) if self.block + self.block.each(&block) if self.block end # lazy init this, to keep the dependency (which goes to parfait and booting) at bay @@ -71,62 +71,62 @@ module Vool # A Send breaks down to 2 steps: # - Setting up the next message, with receiver, arguments, and (importantly) return address # - a CachedCall , or a SimpleCall, depending on wether the receiver type can be determined - def to_mom( in_method ) - @parfait_block = self.block.to_mom(in_method) if self.block - @receiver = SelfExpression.new(in_method.for_type) if @receiver.is_a?(SelfExpression) + def to_mom( compiler ) + @parfait_block = self.block.to_mom(compiler) if self.block + @receiver = SelfExpression.new(compiler.method.for_type) if @receiver.is_a?(SelfExpression) if(@receiver.ct_type) - simple_call(in_method) + simple_call(compiler) else - cached_call(in_method) + cached_call(compiler) end end # When used as right hand side, this tells what data to move to get the result into # a varaible. It is (off course) the return value of the message - def slot_definition(in_method) + def slot_definition(compiler) Mom::SlotDefinition.new(:message ,[ :return_value]) end - def message_setup(in_method,called_method) + def message_setup(compiler,called_method) setup = Mom::MessageSetup.new( called_method ) - mom_receive = @receiver.slot_definition(in_method) + mom_receive = @receiver.slot_definition(compiler) arg_target = [:message , :next_message , :arguments] args = [] @arguments.each_with_index do |arg , index| # +1 because of type - args << Mom::SlotLoad.new( arg_target + [index + 1] , arg.slot_definition(in_method)) + args << Mom::SlotLoad.new( arg_target + [index + 1] , arg.slot_definition(compiler)) end setup << Mom::ArgumentTransfer.new( mom_receive , args ) end - def simple_call(in_method) + def simple_call(compiler) type = @receiver.ct_type called_method = type.resolve_method(@name) raise "No method #{@name} for #{type}" unless called_method - message_setup(in_method,called_method) << Mom::SimpleCall.new(called_method) + message_setup(compiler,called_method) << Mom::SimpleCall.new(called_method) end # this breaks cleanly into two parts: # - check the cached type and if neccessary update # - call the cached method - def cached_call(in_method) - cache_check(in_method) << call_cached_method(in_method) + def cached_call(compiler) + cache_check(compiler) << call_cached_method(compiler) end # check that current type is the cached type # if not, change and find method for the type (simple_call to resolve_method) # conceptually easy in ruby, but we have to compile that "easy" ruby - def cache_check(in_method) + def cache_check(compiler) ok = Mom::Label.new("cache_ok_#{self.object_id}") - check = build_condition(ok, in_method) # if cached_type != current_type - check << Mom::SlotLoad.new([dynamic_call.cache_entry, :cached_type] , receiver_type_definition(in_method)) + check = build_condition(ok, compiler) # if cached_type != current_type + check << Mom::SlotLoad.new([dynamic_call.cache_entry, :cached_type] , receiver_type_definition(compiler)) check << Mom::ResolveMethod.new( @name , dynamic_call.cache_entry ) check << ok end # to call the method (that we know now to be in the cache), we move the method # to reg1, do the setup (very similar to static) and call - def call_cached_method(in_method) - message_setup(in_method,dynamic_call.cache_entry) << dynamic_call + def call_cached_method(compiler) + message_setup(compiler,dynamic_call.cache_entry) << dynamic_call end def to_s(depth = 0) @@ -135,14 +135,14 @@ module Vool end private - def receiver_type_definition(in_method) - defi = @receiver.slot_definition(in_method) + def receiver_type_definition(compiler) + defi = @receiver.slot_definition(compiler) defi.slots << :type defi end - def build_condition(ok_label, in_method) + def build_condition(ok_label, compiler) cached_type = Mom::SlotDefinition.new(dynamic_call.cache_entry , [:cached_type]) - current_type = receiver_type_definition(in_method) + current_type = receiver_type_definition(compiler) Mom::NotSameCheck.new(cached_type , current_type, ok_label) end end diff --git a/lib/vool/statement.rb b/lib/vool/statement.rb index f9e1a866..09d93b48 100644 --- a/lib/vool/statement.rb +++ b/lib/vool/statement.rb @@ -52,13 +52,13 @@ module Vool def normalize raise "should not be normalized #{self}" end - def to_mom(method) + def to_mom(compiler) raise "should not be momed #{self}" end # for loading into a lot, return the "slot_definition" that can be passed to # SlotLoad. - def slot_definition(method) + def slot_definition(compiler) raise "not iplemented in #{self}" end diff --git a/lib/vool/statements.rb b/lib/vool/statements.rb index c3b83f10..72740ed8 100644 --- a/lib/vool/statements.rb +++ b/lib/vool/statements.rb @@ -29,12 +29,12 @@ module Vool end # create mom instructions - def to_mom( method ) + def to_mom( compiler ) raise "Empty list ? #{statements.length}" if empty? stats = @statements.dup - flat = stats.shift.to_mom(method) + flat = stats.shift.to_mom(compiler) while( nekst = stats.shift ) - flat.append nekst.to_mom(method) + flat.append nekst.to_mom(compiler) end flat end diff --git a/lib/vool/variables.rb b/lib/vool/variables.rb index 0027aebf..650d9f42 100644 --- a/lib/vool/variables.rb +++ b/lib/vool/variables.rb @@ -10,8 +10,8 @@ module Vool class LocalVariable < Expression include Named - def slot_definition(method) - if method.arguments_type.variable_index(@name) + def slot_definition(compiler) + if compiler.method.arguments_type.variable_index(@name) type = :arguments else type = :frame @@ -25,7 +25,7 @@ module Vool class InstanceVariable < Expression include Named - def slot_definition(method) + def slot_definition(compiler) Mom::SlotDefinition.new(:message , [ :receiver , @name] ) end # used to collect type information diff --git a/lib/vool/while_statement.rb b/lib/vool/while_statement.rb index 757f3de4..b8e245e0 100644 --- a/lib/vool/while_statement.rb +++ b/lib/vool/while_statement.rb @@ -16,13 +16,13 @@ module Vool WhileStatement.new(cond , @body.normalize , rest) end - def to_mom( method ) + def to_mom( compiler ) merge_label = Mom::Label.new( "merge_label_#{object_id.to_s(16)}") cond_label = Mom::Label.new( "cond_label_#{object_id.to_s(16)}") codes = cond_label - codes << @hoisted.to_mom(method) if @hoisted - codes << Mom::TruthCheck.new(condition.slot_definition(method) , merge_label) - codes << @body.to_mom(method) + codes << @hoisted.to_mom(compiler) if @hoisted + codes << Mom::TruthCheck.new(condition.slot_definition(compiler) , merge_label) + codes << @body.to_mom(compiler) codes << Mom::Jump.new(cond_label) codes << merge_label end diff --git a/lib/vool/yield_statement.rb b/lib/vool/yield_statement.rb index 48ced6ad..c327f9d1 100644 --- a/lib/vool/yield_statement.rb +++ b/lib/vool/yield_statement.rb @@ -46,11 +46,11 @@ module Vool # A Send breaks down to 2 steps: # - Setting up the next message, with receiver, arguments, and (importantly) return address # - a SimpleCall, - def to_mom( in_method ) - @parfait_block = @block.to_mom(in_method) if @block - @receiver = SelfExpression.new(in_method.for_type) if @receiver.is_a?(SelfExpression) + def to_mom( compiler ) + @parfait_block = @block.to_mom(compiler) if @block + @receiver = SelfExpression.new(compiler.for_type) if @receiver.is_a?(SelfExpression) if(@receiver.ct_type) - simple_call(in_method) + simple_call(compiler) else raise "ERROR" end @@ -58,17 +58,17 @@ module Vool # When used as right hand side, this tells what data to move to get the result into # a varaible. It is (off course) the return value of the message - def slot_definition(in_method) + def slot_definition(compiler) Mom::SlotDefinition.new(:message ,[ :return_value]) end def message_setup(in_method,called_method) setup = Mom::MessageSetup.new( called_method ) - mom_receive = @receiver.slot_definition(in_method) + mom_receive = @receiver.slot_definition(compiler) arg_target = [:message , :next_message , :arguments] args = [] @arguments.each_with_index do |arg , index| # +1 because of type - args << Mom::SlotLoad.new( arg_target + [index + 1] , arg.slot_definition(in_method)) + args << Mom::SlotLoad.new( arg_target + [index + 1] , arg.slot_definition(compiler)) end setup << Mom::ArgumentTransfer.new( mom_receive , args ) end diff --git a/test/support/compiling.rb b/test/support/compiling.rb index 09dcbe5e..a7dfccaa 100644 --- a/test/support/compiling.rb +++ b/test/support/compiling.rb @@ -35,7 +35,7 @@ module MomCompile assert_equal Mom::MomCompiler , ret.class compiler = ret.method_compilers.find{|c| c.method.name == :main and c.method.for_type.object_class.name == :Test} assert_equal Risc::MethodCompiler , compiler.class - @method.source.to_mom( compiler.method ) + @method.source.to_mom( compiler ) end def compile_mom(input) diff --git a/test/vool/test_block_statement.rb b/test/vool/test_block_statement.rb index 672e9769..847e69d1 100644 --- a/test/vool/test_block_statement.rb +++ b/test/vool/test_block_statement.rb @@ -11,7 +11,7 @@ module Vool end def test_is_compiler - assert_equal Mom::MomCompiler , @ret.class +# assert_equal Mom::MomCompiler , @ret.class end def est_has_compilers