From 2f07cc34f3f56c72d05c7d822f40fa6c15fd6a08 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sat, 7 Jul 2018 15:50:43 +0300 Subject: [PATCH] add parfait block --- lib/parfait.rb | 1 + lib/parfait/block.rb | 23 ++++++++++++++++++++ lib/parfait/callable_method.rb | 19 ++++++++++++++++ lib/risc/parfait_boot.rb | 4 ++++ test/parfait/helper.rb | 6 ++++++ test/parfait/test_block.rb | 24 +++++++++++++++++++++ test/parfait/test_callable_method.rb | 5 +---- test/parfait/test_space.rb | 2 +- test/risc/interpreter/calling/test_minus.rb | 2 +- test/risc/test_interpreter.rb | 4 ++-- test/risc/test_linker.rb | 2 +- 11 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 lib/parfait/block.rb create mode 100644 test/parfait/test_block.rb diff --git a/lib/parfait.rb b/lib/parfait.rb index 69241e00..b2664718 100644 --- a/lib/parfait.rb +++ b/lib/parfait.rb @@ -11,6 +11,7 @@ require_relative "parfait/list" require_relative "parfait/word" require_relative "parfait/binary_code" require_relative "parfait/callable" +require_relative "parfait/block" require_relative "parfait/callable_method" require_relative "parfait/vool_method" require_relative "parfait/dictionary" diff --git a/lib/parfait/block.rb b/lib/parfait/block.rb new file mode 100644 index 00000000..13412e7e --- /dev/null +++ b/lib/parfait/block.rb @@ -0,0 +1,23 @@ +module Parfait + + # A Block is a callable object, much like a CallableMethod. + # Surprisingly similar in fact, as the block is really only missing the name. + # + # The difference lies mostly in the way they are compiled + # + # Also both have a list of blocks defined in their scope. But this is + # notimplemented for blocks yet + # + class Block < Callable + + def ==(other) + return false unless other.is_a?(Block) + super + end + + def inspect + "#{@self_type.object_class.name}(#{arguments_type.inspect})" + end + + end +end diff --git a/lib/parfait/callable_method.rb b/lib/parfait/callable_method.rb index 7d63f7d0..f1982dbc 100644 --- a/lib/parfait/callable_method.rb +++ b/lib/parfait/callable_method.rb @@ -36,5 +36,24 @@ module Parfait block.call( self ) @next.each_method( &block ) if @next end + + def create_block(args , frame) + bl = Block.new(self_type , args , frame) + block = self.blocks + bl.next = block if(block) + @blocks = bl + end + + def has_block(block) + each_block{ |bl| return true if bl == block} + false + end + def each_block(&bl) + blo = blocks + while( blo ) + yield(blo) + blo = blo.next + end + end end end diff --git a/lib/risc/parfait_boot.rb b/lib/risc/parfait_boot.rb index c4495fd3..084e88cc 100644 --- a/lib/risc/parfait_boot.rb +++ b/lib/risc/parfait_boot.rb @@ -124,6 +124,7 @@ module Parfait Word: :Data8 , List: :Data16 , CallableMethod: :Callable, + Block: :Callable, ReturnAddress: :Integer} end @@ -132,6 +133,9 @@ module Parfait # and all instance variable names. Really have to find a better way def self.type_names {BinaryCode: {next: :BinaryCode} , + Block: {binary: :BinaryCode, next: :CallableMethod, + arguments_type: :Type , self_type: :Type, frame_type: :Type } , + CacheEntry: {cached_type: :Type , cached_method: :CallableMethod } , Callable: {binary: :BinaryCode,next: :Callable , arguments_type: :Type , self_type: :Type, frame_type: :Type } , diff --git a/test/parfait/helper.rb b/test/parfait/helper.rb index fe90ec48..d732fb05 100644 --- a/test/parfait/helper.rb +++ b/test/parfait/helper.rb @@ -7,5 +7,11 @@ module Parfait Parfait.boot! @space = Parfait.object_space end + def make_method + @obj = Parfait.object_space.get_class_by_name(:Object).instance_type + @args = Parfait::Type.for_hash( @obj.object_class , { bar: :Integer , foo: :Type}) + @frame = Parfait::Type.for_hash( @obj.object_class , { local_bar: :Integer , local_foo: :Type}) + @method = Parfait::CallableMethod.new( @obj , :meth , @args , @frame) + end end end diff --git a/test/parfait/test_block.rb b/test/parfait/test_block.rb new file mode 100644 index 00000000..be300d60 --- /dev/null +++ b/test/parfait/test_block.rb @@ -0,0 +1,24 @@ +require_relative "helper" + +module Parfait + class TestBlock < ParfaitTest + + def setup + super + make_method + end + + def test_make_block + assert_equal Block , @method.create_block(@args , @frame ).class + end + + def test_block_type + assert_equal @method.self_type , @method.create_block(@args , @frame ).self_type + end + + def test_block_in_method + assert @method.has_block( @method.create_block(@args , @frame )) + end + + end +end diff --git a/test/parfait/test_callable_method.rb b/test/parfait/test_callable_method.rb index 888a5c3e..efc1bcbf 100644 --- a/test/parfait/test_callable_method.rb +++ b/test/parfait/test_callable_method.rb @@ -5,10 +5,7 @@ module Parfait def setup super - @obj = Parfait.object_space.get_class_by_name(:Object).instance_type - @args = Parfait::Type.for_hash( @obj.object_class , { bar: :Integer , foo: :Type}) - @frame = Parfait::Type.for_hash( @obj.object_class , { local_bar: :Integer , local_foo: :Type}) - @method = Parfait::CallableMethod.new( @obj , :meth , @args , @frame) + make_method end def test_method_name diff --git a/test/parfait/test_space.rb b/test/parfait/test_space.rb index 81cd1dee..5bba5e0a 100644 --- a/test/parfait/test_space.rb +++ b/test/parfait/test_space.rb @@ -4,7 +4,7 @@ module Parfait class TestSpace < ParfaitTest def classes - [:BinaryCode,:CacheEntry,:Callable,:CallableMethod,:Class, + [:BinaryCode,:Block,:CacheEntry,:Callable,:CallableMethod,:Class, :DataObject,:Data4,:Data8,:Data16,:Dictionary,:Integer,:FalseClass, :List,:Message,:NamedList,:NilClass,:Object,:ReturnAddress, :Space,:TrueClass,:Type,:VoolMethod,:Word] diff --git a/test/risc/interpreter/calling/test_minus.rb b/test/risc/interpreter/calling/test_minus.rb index 2d28ca93..3969faf4 100644 --- a/test/risc/interpreter/calling/test_minus.rb +++ b/test/risc/interpreter/calling/test_minus.rb @@ -45,7 +45,7 @@ module Risc ret = main_ticks(63) assert_equal FunctionReturn , ret.class assert_equal :r1 , ret.register.symbol - assert_equal 21476 , @interpreter.get_register(ret.register) + assert_equal 21732 , @interpreter.get_register(ret.register) end def test_sys sys = main_ticks(68) diff --git a/test/risc/test_interpreter.rb b/test/risc/test_interpreter.rb index 3cf24bc5..80be4b81 100644 --- a/test/risc/test_interpreter.rb +++ b/test/risc/test_interpreter.rb @@ -54,7 +54,7 @@ module Risc end def test_pc1 @interpreter.tick - assert_equal 21048 , @interpreter.pc + assert_equal 21304 , @interpreter.pc end def test_tick2 @interpreter.tick @@ -68,7 +68,7 @@ module Risc def test_pc2 @interpreter.tick @interpreter.tick - assert_equal 21052 , @interpreter.pc + assert_equal 21308 , @interpreter.pc end def test_tick_14_jump 14.times {@interpreter.tick} diff --git a/test/risc/test_linker.rb b/test/risc/test_linker.rb index 4abb80f6..7a849226 100644 --- a/test/risc/test_linker.rb +++ b/test/risc/test_linker.rb @@ -25,7 +25,7 @@ module Risc assert_equal 0 , Position.get(@linker.cpu_init).at end def test_cpu_at - assert_equal "0x60ec" , Position.get(@linker.cpu_init.first).to_s + assert_equal "0x61ec" , Position.get(@linker.cpu_init.first).to_s end def test_cpu_label assert_equal Position , Position.get(@linker.cpu_init.first).class