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
This commit is contained in:
2019-09-29 22:37:28 +03:00
parent 17f87f7464
commit ba83affd8c
11 changed files with 49 additions and 29 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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