From 6958fc31ab92cca5ce6ec5256ff96514a046da64 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sat, 7 Apr 2018 23:07:44 +0300 Subject: [PATCH] rework resolve_method, using builder --- lib/mom/instruction/message_setup.rb | 3 +- lib/mom/instruction/slot_load.rb | 2 +- lib/risc/builder.rb | 2 +- lib/risc/builtin/word.rb | 54 ++++++++++++++-------------- lib/risc/method_compiler.rb | 2 +- lib/risc/risc_value.rb | 4 +-- test/risc/test_risc_value.rb | 2 +- 7 files changed, 33 insertions(+), 36 deletions(-) diff --git a/lib/mom/instruction/message_setup.rb b/lib/mom/instruction/message_setup.rb index 9ef8c6ba..742cd64b 100644 --- a/lib/mom/instruction/message_setup.rb +++ b/lib/mom/instruction/message_setup.rb @@ -27,8 +27,7 @@ module Mom # Move method name, frame and arguemnt types from the method to the next_message # Get the message from Space and link it. def to_risc(compiler) - builder = Risc::Builder.new(compiler) - build_with(builder) + build_with(compiler.builder) end # directly called by to_risc diff --git a/lib/mom/instruction/slot_load.rb b/lib/mom/instruction/slot_load.rb index 43e7512a..048952de 100644 --- a/lib/mom/instruction/slot_load.rb +++ b/lib/mom/instruction/slot_load.rb @@ -1,6 +1,6 @@ module Mom - # SlotLoad is an abstract base class for moving data into a slot + # SlotLoad is for moving data into a slot, either from another slot, or constant # A Slot is basically an instance variable, but it must be of known type # # The value loaded (the right hand side) can be a constant (Mom::Constant) or come from diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index b36ce0ad..452f42b3 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -55,7 +55,7 @@ module Risc return risc end - def add_instruction(ins) + def add(ins) if(@built) @built << ins else diff --git a/lib/risc/builtin/word.rb b/lib/risc/builtin/word.rb index a87eb088..993a8502 100644 --- a/lib/risc/builtin/word.rb +++ b/lib/risc/builtin/word.rb @@ -57,42 +57,40 @@ module Risc def resolve_method( context) compiler = compiler_for(:Word, :resolve_method , {:value => :Type} ) source = "resolve_method " - me = compiler.add_known( :receiver ) - type_arg = compiler.use_reg( :Type ) - method = compiler.use_reg( :TypedMethod ) - method_name = compiler.use_reg( :Word ) - space = compiler.use_reg( :Space ) - methods_index = Risc.resolve_to_index(:Type , :methods) - next_index = Risc.resolve_to_index(:TypedMethod , :next_method) - name_index = Risc.resolve_to_index(:TypedMethod , :name) - binary_index = Risc.resolve_to_index(:TypedMethod , :binary) - nil_index = Risc.resolve_to_index(:Space , :nil_object) + while_start = Risc.label( source , source + "while_start_#{object_id}") exit_label = Risc.label( source , source + "exit_label_#{object_id}") false_label = Risc.label( source , source + "fal_label_#{object_id}") - compiler.add_slot_to_reg(source + "retrieve args" , :message , :arguments , type_arg ) - compiler.add_slot_to_reg(source + "retrieve arg 1", type_arg , 1 + 1, type_arg ) #1 for type - compiler.add_slot_to_reg(source + "get methods from type", type_arg , methods_index, method ) - compiler.add_code while_start - compiler.add_load_constant(source + "load space" , Parfait.object_space , space ) - compiler.add_slot_to_reg(source + "get nil object", space , nil_index, space ) - compiler.add_op(source + "if method is nil", :- , space , method ) - compiler.add_code Risc::IsZero.new(source + "jump if nil" , exit_label) + compiler.build do + word << message[ :receiver ] - compiler.add_slot_to_reg(source + "get name from method" , method , name_index, method_name ) - compiler.add_op(source + " compare name with me", :- , method_name , me ) - compiler.add_code Risc::IsNotZero.new(source + "jump if not same" , false_label) + type << message[:arguments] + type << type[2] + type << type[:type] + typed_method << type[:methods] + add while_start + space << Parfait.object_space + space << space[:nil_object] - compiler.add_slot_to_reg(source + "get binary from method" , method , binary_index, method ) - compiler.add_reg_to_slot(source + "save binary to return", method , :message , :return_value) - compiler.add_mom( Mom::ReturnSequence.new) + add Risc.op(source + "if method is nil", :- , space , typed_method ) + add Risc::IsZero.new(source + "jump if nil" , exit_label) - compiler.add_code false_label - compiler.add_slot_to_reg(source + "get next method" , method , next_index, method ) - compiler.add_code Risc::Branch.new(source + "back to while", while_start) + name << typed_method[:name] + add Risc.op(source + " compare name with me", :- , name , word ) + add Risc::IsNotZero.new(source + "jump if not same" , false_label) - compiler.add_code exit_label + typed_method << typed_method[:binary] + message[:return_value] << typed_method + + add Mom::ReturnSequence.new.to_risc(compiler) + + add false_label + typed_method << typed_method[:next_method] + add Risc::Branch.new(source + "back to while", while_start) + + add exit_label + end Risc::Builtin::Object.emit_syscall( compiler , :exit ) return compiler.method end diff --git a/lib/risc/method_compiler.rb b/lib/risc/method_compiler.rb index 20bc6f02..576286c7 100644 --- a/lib/risc/method_compiler.rb +++ b/lib/risc/method_compiler.rb @@ -173,7 +173,7 @@ module Risc # Build with builder (see there), adding the created instructions def build(&block) - builder.build_and_return(&block) + builder.build(&block) end # return a new builder that uses this compiler diff --git a/lib/risc/risc_value.rb b/lib/risc/risc_value.rb index ed4a8639..8c8c9ba5 100644 --- a/lib/risc/risc_value.rb +++ b/lib/risc/risc_value.rb @@ -73,7 +73,7 @@ module Risc else raise "not implemented" end - builder.add_instruction(ins) if builder + builder.add(ins) if builder return ins end @@ -98,7 +98,7 @@ module Risc def <<( reg ) raise "not reg #{reg}" unless reg.is_a?(RiscValue) reg_to_slot = Risc.reg_to_slot("#{reg.type} -> #{register.type}[#{index}]" , reg , register, index) - builder.add_instruction(reg_to_slot) if builder + builder.add(reg_to_slot) if builder reg_to_slot end diff --git a/test/risc/test_risc_value.rb b/test/risc/test_risc_value.rb index b05814b1..3e64566a 100644 --- a/test/risc/test_risc_value.rb +++ b/test/risc/test_risc_value.rb @@ -2,7 +2,7 @@ require_relative "../helper" class FakeBuilder attr_reader :built - def add_instruction(ins) + def add(ins) @built = ins end end