diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index 0e1b3d5a..dc794fcb 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -2,14 +2,7 @@ module Risc # A Builder is used to generate code, either by using it's api, or dsl # - # There are two subclasses of Builder, depending of what one wants to do with the - # generated code. - # - # CompilerBuilder: The code is added to the method_compiler. - # This is used to generate the builtin methods. - # - # CodeBuilder: The code can be stored up and returned. - # This is used in Mom::to_risc methods + # The code is added to the method_compiler. # class Builder @@ -19,6 +12,7 @@ module Risc # second arg determines weather instructions are added (default true) # call build with a block to build def initialize(compiler, for_source) + raise "no compiler" unless compiler @compiler = compiler @source = for_source @source_used = false @@ -119,16 +113,16 @@ module Risc # space << Parfait.object_space # load constant # message[:receiver] << space #make current message (r0) receiver the space # - # build result is available as built, but also gets added to compiler, if the - # builder is created with default args + # build result is added to compiler directly # def build(&block) instance_eval(&block) - @built end + # add code straight to the compiler def add_code(ins) - raise "Must be implemented in subclass #{self}" + @compiler.add_code(ins) + return ins end # move a machine int from register "from" to a Parfait::Integer in register "to" @@ -146,39 +140,4 @@ module Risc end end - - class CodeBuilder < Builder - - attr_reader :built - def initialize(compiler, for_source) - super - @built = nil - end - - def build(&block) - super - @built - end - - # CodeBuilder stores the code. - # The code can be access through the @built instance, and is returned - # from build method - def add_code(ins) - if(@built) - @built << ins - else - @built = ins - end - end - end - - # A CompilerBuilder adds the generated code to the MethodCompiler. - # - class CompilerBuilder < Builder - # add code straight to the compiler - def add_code(ins) - return @compiler.add_code(ins) - end - end - end diff --git a/lib/risc/builtin/integer.rb b/lib/risc/builtin/integer.rb index 35490429..41e6a020 100644 --- a/lib/risc/builtin/integer.rb +++ b/lib/risc/builtin/integer.rb @@ -13,7 +13,7 @@ module Risc # return new int with result def div4(context) compiler = compiler_for(:Integer,:div4 ,{}) - compiler.compiler_builder(compiler.source).build do + compiler.builder(compiler.source).build do integer! << message[:receiver] integer.reduce_int integer_reg! << 2 @@ -50,7 +50,7 @@ module Risc # - return def comparison( operator ) compiler = compiler_for(:Integer, operator ,{other: :Integer}) - builder = compiler.compiler_builder(compiler.source) + builder = compiler.builder(compiler.source) builder.build do integer! << message[:receiver] integer_reg! << message[:arguments] @@ -87,7 +87,7 @@ module Risc # - returns the new int def operator_method( op_sym ) compiler = compiler_for(:Integer, op_sym ,{other: :Integer}) - builder = compiler.compiler_builder(compiler.source) + builder = compiler.builder(compiler.source) builder.build do integer! << message[:receiver] integer_reg! << message[:arguments] @@ -113,7 +113,7 @@ module Risc def div10( context ) s = "div_10 " compiler = compiler_for(:Integer,:div10 ,{}) - builder = compiler.compiler_builder(compiler.source) + builder = compiler.builder(compiler.source) builder.build do integer_self! << message[:receiver] integer_self.reduce_int diff --git a/lib/risc/builtin/object.rb b/lib/risc/builtin/object.rb index db70ea19..31e1b299 100644 --- a/lib/risc/builtin/object.rb +++ b/lib/risc/builtin/object.rb @@ -8,7 +8,7 @@ module Risc # return is stored in return_value def get_internal_word( context ) compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer}) - compiler.compiler_builder(compiler.source).build do + compiler.builder(compiler.source).build do object! << message[:receiver] integer! << message[:arguments] integer << integer[1] @@ -24,7 +24,7 @@ module Risc # return the value passed in def set_internal_word( context ) compiler = compiler_for(:Object , :set_internal_word , {at: :Integer, :value => :Object} ) - compiler.compiler_builder(compiler.source).build do + compiler.builder(compiler.source).build do object! << message[:receiver] integer! << message[:arguments] object_reg! << integer[ 2] @@ -41,7 +41,7 @@ module Risc # Even if it's just this one, sys_exit (later raise) def _method_missing( context ) compiler = compiler_for(:Object,:method_missing ,{}) - emit_syscall( compiler.compiler_builder(compiler.source) , :exit ) + emit_syscall( compiler.builder(compiler.source) , :exit ) return compiler end @@ -54,7 +54,7 @@ module Risc def __init__( context ) compiler = MethodCompiler.compiler_for_class(:Object,:__init__ , Parfait::NamedList.type_for({}) , Parfait::NamedList.type_for({})) - builder = compiler.compiler_builder(compiler.source) + builder = compiler.builder(compiler.source) builder.build do space! << Parfait.object_space message << space[:next_message] @@ -98,7 +98,7 @@ module Risc # mainly calls exit_sequence def exit( context ) compiler = compiler_for(:Object,:exit ,{}) - builder = compiler.compiler_builder(compiler.source) + builder = compiler.builder(compiler.source) exit_sequence(builder) return compiler end diff --git a/lib/risc/builtin/word.rb b/lib/risc/builtin/word.rb index 8c0eae8a..586df497 100644 --- a/lib/risc/builtin/word.rb +++ b/lib/risc/builtin/word.rb @@ -12,7 +12,7 @@ module Risc # - emit_syscall (which does the return of an integer, see there) def putstring( context) compiler = compiler_for(:Word , :putstring ,{}) - builder = compiler.compiler_builder(compiler.source) + builder = compiler.builder(compiler.source) builder.build do word! << message[:receiver] integer! << word[Parfait::Word.get_length_index] @@ -26,7 +26,7 @@ module Risc # return a word sized new int, in return_value def get_internal_byte( context) compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer}) - compiler.compiler_builder(compiler.source).build do + compiler.builder(compiler.source).build do object! << message[:receiver] integer! << message[:arguments] integer << integer[1] @@ -44,7 +44,7 @@ module Risc # return value def set_internal_byte( context ) compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , :value => :Integer} ) - compiler.compiler_builder(compiler.source).build do + compiler.builder(compiler.source).build do word! << message[:receiver] integer! << message[:arguments] integer << integer[1] diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index b7041ee4..438f4e44 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -13,20 +13,16 @@ module Risc def initialize( callable ) @callable = callable @regs = [] - init_instructions - @current = @risc_instructions @constants = [] @block_compilers = [] - end - attr_reader :risc_instructions , :constants , :block_compilers , :callable - - def init_instructions @risc_instructions = Risc.label(source_name, source_name) - @risc_instructions.append Risc.label( source_name, "return_label") - @risc_instructions.append Mom::ReturnSequence.new.to_risc(self) - @risc_instructions.append Risc.label( source_name, "unreachable") + @current = @risc_instructions + add_code Risc.label( source_name, "return_label") + Mom::ReturnSequence.new.to_risc(self) + add_code Risc.label( source_name, "unreachable") reset_regs end + attr_reader :risc_instructions , :constants , :block_compilers , :callable , :current def return_label @risc_instructions.each do |ins| @@ -42,8 +38,7 @@ module Risc while( instruction ) raise "whats this a #{instruction}" unless instruction.is_a?(Mom::Instruction) #puts "adding mom #{instruction.to_s}:#{instruction.next.to_s}" - risc = instruction.to_risc( self ) - add_code(risc) + instruction.to_risc( self ) reset_regs #puts "adding risc #{risc.to_s}:#{risc.next.to_s}" instruction = instruction.next @@ -135,19 +130,12 @@ module Risc # Build with builder (see there), adding the created instructions def build(source , &block) - code_builder(source).build(&block) + builder(source).build(&block) end - # return a new code builder that uses this compiler - # CodeBuilder returns code after building - def code_builder( source) - CodeBuilder.new(self , source) - end - - # return a CompilerBuilder - # CompilerBuilder adds the generated code to the compiler - def compiler_builder( source) - CompilerBuilder.new(self , source) + # return a Builder, that adds the generated code to this compiler + def builder( source) + Builder.new(self , source) end end end diff --git a/lib/risc/register_value.rb b/lib/risc/register_value.rb index e0dfcd5c..fa4b4983 100644 --- a/lib/risc/register_value.rb +++ b/lib/risc/register_value.rb @@ -45,10 +45,10 @@ module Risc # using the registers type, resolve the slot to an index # Using the index and the register, add a SlotToReg to the instruction - def resolve_and_add(slot , instruction , compiler) + def resolve_and_add(slot , compiler) index = resolve_index( slot ) new_left = get_new_left( slot , compiler ) - instruction << Risc::SlotToReg.new( "SlotLoad #{type}[#{slot}]" , self ,index, new_left) + compiler.add_code Risc::SlotToReg.new( "SlotLoad #{type}[#{slot}]" , self ,index, new_left) new_left end diff --git a/lib/vool/yield_statement.rb b/lib/vool/yield_statement.rb index ae6c6e8b..a218bfc3 100644 --- a/lib/vool/yield_statement.rb +++ b/lib/vool/yield_statement.rb @@ -38,7 +38,7 @@ module Vool runtime_method = Mom::SlotDefinition.new( :message , [ :method] ) check = Mom::NotSameCheck.new(compile_method , runtime_method, ok_label) # TODO? Maybe create mom instructions for this - #builder = compiler.code_builder("yield") + #builder = compiler.builder("yield") #Risc::Builtin::Object.exit_sequence(builder) #check << builder.built check << ok_label diff --git a/test/risc/test_builder.rb b/test/risc/test_builder.rb index ee7cfc34..aa091507 100644 --- a/test/risc/test_builder.rb +++ b/test/risc/test_builder.rb @@ -7,8 +7,12 @@ module Risc Parfait.boot! Risc.boot! init = Parfait.object_space.get_init - @builder = Risc::MethodCompiler.new( init ).code_builder(init) + @builder = Risc::MethodCompiler.new( init ).builder(init) @label = Risc.label("source","name") + @start = @builder.compiler.current + end + def built + @start.next end def test_has_build assert @builder.respond_to?(:build) @@ -36,34 +40,34 @@ module Risc end def test_returns_built r1 = RegisterValue.new(:r1 , :Space) - built = @builder.build{ space! << r1 } + @builder.build{ space! << r1 } assert_equal Transfer , built.class end def test_returns_two r1 = RegisterValue.new(:r1 , :Space) - built = @builder.build{ space! << r1 ; space << r1} + @builder.build{ space! << r1 ; space << r1} assert_equal Transfer , built.next.class end def test_returns_slot r2 = RegisterValue.new(:r2 , :Message).set_builder( @builder ) - built = @builder.build{ r2 << space![:next_message] } + @builder.build{ r2 << space![:next_message] } assert_equal SlotToReg , built.class assert_equal :r1 , built.array.symbol end def test_returns_slot_reverse r2 = RegisterValue.new(:r2 , :Message).set_builder( @builder ) - built = @builder.build{ r2 << space![:next_message] } + @builder.build{ r2 << space![:next_message] } assert_equal SlotToReg , built.class assert_equal :r1 , built.array.symbol end def test_reuses_names r1 = RegisterValue.new(:r1 , :Space) - built = @builder.build{ space! << r1 ; space << r1} + @builder.build{ space! << r1 ; space << r1} assert_equal built.to.symbol , built.next.to.symbol end def test_uses_message_as_message r1 = RegisterValue.new(:r1 , :Space) - built = @builder.build{ message[:receiver] << r1} + @builder.build{ message[:receiver] << r1} assert_equal RegToSlot , built.class assert_equal :r0 , built.array.symbol end diff --git a/test/risc/test_builder1.rb b/test/risc/test_builder1.rb index bd79df69..92d43193 100644 --- a/test/risc/test_builder1.rb +++ b/test/risc/test_builder1.rb @@ -8,7 +8,7 @@ module Risc Risc.boot! @init = Parfait.object_space.get_init @compiler = Risc::MethodCompiler.new( @init ) - @builder = @compiler.compiler_builder(@init) + @builder = @compiler.builder(@init) end def test_inserts_built r1 = RegisterValue.new(:r1 , :Space) diff --git a/test/risc/test_builder2.rb b/test/risc/test_builder2.rb index a1636c1b..28b52e2a 100644 --- a/test/risc/test_builder2.rb +++ b/test/risc/test_builder2.rb @@ -8,7 +8,7 @@ module Risc Risc.boot! @init = Parfait.object_space.get_init @compiler = Risc::MethodCompiler.new( @init ) - @builder = @compiler.compiler_builder(@init) + @builder = @compiler.builder(@init) end def test_list assert_equal :List , @builder.infer_type(:list).class_name