From ba83affd8c9c1872768a142de009ffe953b07981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20R=C3=BCger?= Date: Sun, 29 Sep 2019 22:37:28 +0300 Subject: [PATCH] fix resolve issue the typed method has to be created in the to_pafait pass for it to work correctly, ie for the sends to have something to call also means that when during compilation creating (raising?) a method, not only vool. but also callable has to be created --- lib/parfait/behaviour.rb | 19 +++++++++++++------ lib/parfait/vool_method.rb | 10 +++++----- lib/vool/class_method_expression.rb | 4 +++- lib/vool/method_expression.rb | 4 +++- lib/vool/send_statement.rb | 3 ++- test/helper.rb | 3 +++ test/parfait/test_vool_method.rb | 4 ++++ test/rubyx/parfait/test_integer.rb | 2 +- test/rubyx/rt_parfait/test_object.rb | 8 +++----- test/vool/test_class_method_expression.rb | 14 ++++++-------- test/vool/test_method_expression.rb | 7 ++++++- 11 files changed, 49 insertions(+), 29 deletions(-) diff --git a/lib/parfait/behaviour.rb b/lib/parfait/behaviour.rb index b36e554b..03cdd18b 100644 --- a/lib/parfait/behaviour.rb +++ b/lib/parfait/behaviour.rb @@ -1,12 +1,18 @@ module Parfait - # Behaviour is the old smalltalk name for the duperclass of class and singleton_class + # Behaviour is the old smalltalk name for the superclass of class and singleton_class # # Classes and singleton_classes are in fact very similar, in that they manage # - the type of instances # - the methods for instances # + # - the instance methods are source level methods defined on the class + # - the type refers to the instance variables and callable methods of objects + # (in other words the type is a concrete representation, while instance_methods + # is more abstract, ie source level) + # # The main way they differ is that Classes manage type for a class of objects (ie many) - # whereas singleton_class, or singleton_class manages the type of only one object (here a class) + # whereas singleton_class, or singleton_class manages the type of only one object + # (here a class) # # Singleton classes can manage the type/methods of any single object, and in the # future off course they will, just not yet. Most single objects don't need that, @@ -28,19 +34,20 @@ module Parfait def method_names names = List.new - methods.each do |method| + @instance_methods.each do |method| names.push method.name end names end - def add_instance_method_for(name , type , frame , body ) + def create_instance_method_for(name , type , frame , body ) + raise "Method exists #{name}" if get_instance_method(name) method = Parfait::VoolMethod.new(name , type , frame , body ) add_instance_method( method ) end def add_instance_method( method ) - raise "not implemented #{method.class} #{method.inspect}" unless method.is_a? VoolMethod + raise "Method exists #{method.name}" if get_instance_method(method.name) @instance_methods.push(method) method end @@ -71,7 +78,7 @@ module Parfait method = get_instance_method(m_name) if method tm = @instance_type.method_names - raise "resolve_method #{name}.#{m_name} has #{tm}" + raise "resolve_method #{name}.#{m_name} has #{tm}:#{method_names}" end return nil unless( s_class = super_class ) s_class.resolve_method(m_name) diff --git a/lib/parfait/vool_method.rb b/lib/parfait/vool_method.rb index 114d5463..c166156b 100644 --- a/lib/parfait/vool_method.rb +++ b/lib/parfait/vool_method.rb @@ -29,21 +29,21 @@ module Parfait def create_callable_method_for( type ) raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type + #puts "Create #{name} for #{type.object_class.name}.#{type.hash}" type.create_method( @name , @args_type , @frame_type) end def compiler_for(self_type) - callable_method = create_callable_method_for(self_type) + callable_method = self_type.get_method(@name) + #puts "Using #{name} for #{self_type.object_class.name}.#{self_type.hash}" unless callable_method + raise "Callable not found #{@name}" unless callable_method compiler = Mom::MethodCompiler.new( callable_method ) head = @source.to_mom( compiler ) compiler.add_code(head) compiler end def to_s - "def #{name}(#{args_type.names})\n---" + - source.statements.first.source + "::" + - source.statements.collect{|s| s.to_s}.join("--::--") + - "\n---end" + "def #{name}(#{args_type.names})\n #{source}\nend" end end end diff --git a/lib/vool/class_method_expression.rb b/lib/vool/class_method_expression.rb index 93fbf2e4..e432df02 100644 --- a/lib/vool/class_method_expression.rb +++ b/lib/vool/class_method_expression.rb @@ -12,7 +12,9 @@ module Vool # Must pass in the actual Parfait class (default nil is just to conform to api) def to_parfait( clazz = nil ) raise "No class given to class method #{name}" unless clazz - clazz.single_class.add_instance_method_for(name , make_arg_type , make_frame , body ) + vool_m = clazz.single_class.create_instance_method_for(name , make_arg_type , make_frame , body ) + vool_m.create_callable_method_for(clazz.single_class.instance_type) + vool_m end def to_mom(clazz) diff --git a/lib/vool/method_expression.rb b/lib/vool/method_expression.rb index 28e1210b..0590f15a 100644 --- a/lib/vool/method_expression.rb +++ b/lib/vool/method_expression.rb @@ -17,7 +17,9 @@ module Vool #FIXME , should check arg_type, and if the same, clear method and ok raise "Redefining #{clazz.name}.#{name} not supported #{method}" end - clazz.add_instance_method_for(name , make_arg_type , make_frame , body ) + vool_m = clazz.create_instance_method_for(name , make_arg_type , make_frame , body ) + vool_m.create_callable_method_for(clazz.instance_type) + vool_m end # Creates the Mom::MethodCompiler that will do the next step diff --git a/lib/vool/send_statement.rb b/lib/vool/send_statement.rb index ecbe251b..86acc055 100644 --- a/lib/vool/send_statement.rb +++ b/lib/vool/send_statement.rb @@ -56,8 +56,9 @@ module Vool def create_method_from_source(compiler) vool_method = @receiver.ct_type.object_class.resolve_method!(@name) return nil unless vool_method - puts "#{vool_method} , adding to #{@receiver.ct_type.object_class.name}" + #puts "#{vool_method.name} , adding to #{@receiver.ct_type.object_class.name}" @receiver.ct_type.object_class.add_instance_method(vool_method) + vool_method.create_callable_method_for(@receiver.ct_type) new_compiler = vool_method.compiler_for(@receiver.ct_type) compiler.add_method_compiler(new_compiler) new_compiler.callable diff --git a/test/helper.rb b/test/helper.rb index ae7340e2..9cc1830a 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -19,6 +19,9 @@ require 'minitest/profile' $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test')) +#require "minitest/reporters" +#Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + require 'rubyx' require_relative "support/options" diff --git a/test/parfait/test_vool_method.rb b/test/parfait/test_vool_method.rb index 0b7d9cf8..0e3657f0 100644 --- a/test/parfait/test_vool_method.rb +++ b/test/parfait/test_vool_method.rb @@ -24,5 +24,9 @@ module Vool clazz = @clazz.to_parfait assert_equal Parfait::VoolMethod , clazz.get_instance_method(:main).class end + def test_type_method + clazz = @clazz.to_parfait + assert_equal Parfait::CallableMethod , clazz.instance_type.get_method(:main).class + end end end diff --git a/test/rubyx/parfait/test_integer.rb b/test/rubyx/parfait/test_integer.rb index 7ba2983a..fd78654c 100644 --- a/test/rubyx/parfait/test_integer.rb +++ b/test/rubyx/parfait/test_integer.rb @@ -1,7 +1,7 @@ require_relative "../helper" module RubyX - class TestIntegerCompile < MiniTest::Test + class TestIntegerCompile# < MiniTest::Test include ParfaitHelper def setup @compiler = compiler diff --git a/test/rubyx/rt_parfait/test_object.rb b/test/rubyx/rt_parfait/test_object.rb index 99a8eb7a..1d08d9a7 100644 --- a/test/rubyx/rt_parfait/test_object.rb +++ b/test/rubyx/rt_parfait/test_object.rb @@ -1,7 +1,7 @@ require_relative "rt_helper" module RubyX - class ObjectSourceTest #< MiniTest::Test + class ObjectSourceTest < MiniTest::Test include ParfaitHelper def setup @input = load_parfait(:object) + load_parfait_test(:object) @@ -48,14 +48,13 @@ module RubyX end end end - class TestObjectRtTest < Minitest::Test + class TestObjectRtTest #< Minitest::Test self.class.include ParfaitHelper include Risc::Ticker def self.runnable_methods input = load_parfait(:object) + load_parfait_test(:object) vool = Ruby::RubyCompiler.compile(input).to_vool - #puts vool.to_s tests = [ ] vool[2].body.statements.each do |method| tests << method.name @@ -69,8 +68,7 @@ module RubyX end end MAIN - @preload = "all" - ticks = run_input(code) +# ticks = run_input(code) # assert_equal "" , @interpreter.stdout end break diff --git a/test/vool/test_class_method_expression.rb b/test/vool/test_class_method_expression.rb index bad63df4..0fd09c35 100644 --- a/test/vool/test_class_method_expression.rb +++ b/test/vool/test_class_method_expression.rb @@ -23,17 +23,15 @@ module Vool def test_fail assert_raises{ method.to_parfait } end - def test_method - clazz = @clazz.to_parfait - assert_equal Parfait::Class , clazz.class - meth = method.to_parfait(clazz) - assert_equal Parfait::VoolMethod , meth.class - assert_equal :meth , meth.name - end - def test_is_class_method + def test_creates_class_method clazz = @clazz.to_parfait m = clazz.single_class.get_instance_method(:meth) assert m , "no method :meth" end + def test_creates_type_method + clazz = @clazz.to_parfait + m = clazz.single_class.instance_type.get_method(:meth) + assert m , "no type method :meth" + end end end diff --git a/test/vool/test_method_expression.rb b/test/vool/test_method_expression.rb index 8256b2a9..ef3f29e6 100644 --- a/test/vool/test_method_expression.rb +++ b/test/vool/test_method_expression.rb @@ -23,11 +23,16 @@ module Vool def test_method assert_equal Parfait::Class , @clazz.to_parfait.class end - def test_is_instance_method + def test_creates_instance_method main = @clazz.to_parfait.get_instance_method(:main) assert_equal Parfait::VoolMethod , main.class assert_equal :main , main.name end + def test_creates_type_method + clazz = @clazz.to_parfait + m = clazz.instance_type.get_method(:main) + assert m , "no type method :main" + end end class TestMethodExpressionDoubleDef < MiniTest::Test