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:
parent
17f87f7464
commit
ba83affd8c
@ -1,12 +1,18 @@
|
|||||||
module Parfait
|
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
|
# Classes and singleton_classes are in fact very similar, in that they manage
|
||||||
# - the type of instances
|
# - the type of instances
|
||||||
# - the methods for 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)
|
# 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
|
# 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,
|
# future off course they will, just not yet. Most single objects don't need that,
|
||||||
@ -28,19 +34,20 @@ module Parfait
|
|||||||
|
|
||||||
def method_names
|
def method_names
|
||||||
names = List.new
|
names = List.new
|
||||||
methods.each do |method|
|
@instance_methods.each do |method|
|
||||||
names.push method.name
|
names.push method.name
|
||||||
end
|
end
|
||||||
names
|
names
|
||||||
end
|
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 )
|
method = Parfait::VoolMethod.new(name , type , frame , body )
|
||||||
add_instance_method( method )
|
add_instance_method( method )
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_instance_method( method )
|
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)
|
@instance_methods.push(method)
|
||||||
method
|
method
|
||||||
end
|
end
|
||||||
@ -71,7 +78,7 @@ module Parfait
|
|||||||
method = get_instance_method(m_name)
|
method = get_instance_method(m_name)
|
||||||
if method
|
if method
|
||||||
tm = @instance_type.method_names
|
tm = @instance_type.method_names
|
||||||
raise "resolve_method #{name}.#{m_name} has #{tm}"
|
raise "resolve_method #{name}.#{m_name} has #{tm}:#{method_names}"
|
||||||
end
|
end
|
||||||
return nil unless( s_class = super_class )
|
return nil unless( s_class = super_class )
|
||||||
s_class.resolve_method(m_name)
|
s_class.resolve_method(m_name)
|
||||||
|
@ -29,21 +29,21 @@ module Parfait
|
|||||||
|
|
||||||
def create_callable_method_for( type )
|
def create_callable_method_for( type )
|
||||||
raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::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)
|
type.create_method( @name , @args_type , @frame_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def compiler_for(self_type)
|
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 )
|
compiler = Mom::MethodCompiler.new( callable_method )
|
||||||
head = @source.to_mom( compiler )
|
head = @source.to_mom( compiler )
|
||||||
compiler.add_code(head)
|
compiler.add_code(head)
|
||||||
compiler
|
compiler
|
||||||
end
|
end
|
||||||
def to_s
|
def to_s
|
||||||
"def #{name}(#{args_type.names})\n---" +
|
"def #{name}(#{args_type.names})\n #{source}\nend"
|
||||||
source.statements.first.source + "::" +
|
|
||||||
source.statements.collect{|s| s.to_s}.join("--::--") +
|
|
||||||
"\n---end"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,7 +12,9 @@ module Vool
|
|||||||
# Must pass in the actual Parfait class (default nil is just to conform to api)
|
# Must pass in the actual Parfait class (default nil is just to conform to api)
|
||||||
def to_parfait( clazz = nil )
|
def to_parfait( clazz = nil )
|
||||||
raise "No class given to class method #{name}" unless clazz
|
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
|
end
|
||||||
|
|
||||||
def to_mom(clazz)
|
def to_mom(clazz)
|
||||||
|
@ -17,7 +17,9 @@ module Vool
|
|||||||
#FIXME , should check arg_type, and if the same, clear method and ok
|
#FIXME , should check arg_type, and if the same, clear method and ok
|
||||||
raise "Redefining #{clazz.name}.#{name} not supported #{method}"
|
raise "Redefining #{clazz.name}.#{name} not supported #{method}"
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
# Creates the Mom::MethodCompiler that will do the next step
|
# Creates the Mom::MethodCompiler that will do the next step
|
||||||
|
@ -56,8 +56,9 @@ module Vool
|
|||||||
def create_method_from_source(compiler)
|
def create_method_from_source(compiler)
|
||||||
vool_method = @receiver.ct_type.object_class.resolve_method!(@name)
|
vool_method = @receiver.ct_type.object_class.resolve_method!(@name)
|
||||||
return nil unless vool_method
|
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)
|
@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)
|
new_compiler = vool_method.compiler_for(@receiver.ct_type)
|
||||||
compiler.add_method_compiler(new_compiler)
|
compiler.add_method_compiler(new_compiler)
|
||||||
new_compiler.callable
|
new_compiler.callable
|
||||||
|
@ -19,6 +19,9 @@ require 'minitest/profile'
|
|||||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
||||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
|
||||||
|
|
||||||
|
#require "minitest/reporters"
|
||||||
|
#Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
||||||
|
|
||||||
require 'rubyx'
|
require 'rubyx'
|
||||||
|
|
||||||
require_relative "support/options"
|
require_relative "support/options"
|
||||||
|
@ -24,5 +24,9 @@ module Vool
|
|||||||
clazz = @clazz.to_parfait
|
clazz = @clazz.to_parfait
|
||||||
assert_equal Parfait::VoolMethod , clazz.get_instance_method(:main).class
|
assert_equal Parfait::VoolMethod , clazz.get_instance_method(:main).class
|
||||||
end
|
end
|
||||||
|
def test_type_method
|
||||||
|
clazz = @clazz.to_parfait
|
||||||
|
assert_equal Parfait::CallableMethod , clazz.instance_type.get_method(:main).class
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require_relative "../helper"
|
require_relative "../helper"
|
||||||
|
|
||||||
module RubyX
|
module RubyX
|
||||||
class TestIntegerCompile < MiniTest::Test
|
class TestIntegerCompile# < MiniTest::Test
|
||||||
include ParfaitHelper
|
include ParfaitHelper
|
||||||
def setup
|
def setup
|
||||||
@compiler = compiler
|
@compiler = compiler
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require_relative "rt_helper"
|
require_relative "rt_helper"
|
||||||
|
|
||||||
module RubyX
|
module RubyX
|
||||||
class ObjectSourceTest #< MiniTest::Test
|
class ObjectSourceTest < MiniTest::Test
|
||||||
include ParfaitHelper
|
include ParfaitHelper
|
||||||
def setup
|
def setup
|
||||||
@input = load_parfait(:object) + load_parfait_test(:object)
|
@input = load_parfait(:object) + load_parfait_test(:object)
|
||||||
@ -48,14 +48,13 @@ module RubyX
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
class TestObjectRtTest < Minitest::Test
|
class TestObjectRtTest #< Minitest::Test
|
||||||
self.class.include ParfaitHelper
|
self.class.include ParfaitHelper
|
||||||
include Risc::Ticker
|
include Risc::Ticker
|
||||||
|
|
||||||
def self.runnable_methods
|
def self.runnable_methods
|
||||||
input = load_parfait(:object) + load_parfait_test(:object)
|
input = load_parfait(:object) + load_parfait_test(:object)
|
||||||
vool = Ruby::RubyCompiler.compile(input).to_vool
|
vool = Ruby::RubyCompiler.compile(input).to_vool
|
||||||
#puts vool.to_s
|
|
||||||
tests = [ ]
|
tests = [ ]
|
||||||
vool[2].body.statements.each do |method|
|
vool[2].body.statements.each do |method|
|
||||||
tests << method.name
|
tests << method.name
|
||||||
@ -69,8 +68,7 @@ module RubyX
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
MAIN
|
MAIN
|
||||||
@preload = "all"
|
# ticks = run_input(code)
|
||||||
ticks = run_input(code)
|
|
||||||
# assert_equal "" , @interpreter.stdout
|
# assert_equal "" , @interpreter.stdout
|
||||||
end
|
end
|
||||||
break
|
break
|
||||||
|
@ -23,17 +23,15 @@ module Vool
|
|||||||
def test_fail
|
def test_fail
|
||||||
assert_raises{ method.to_parfait }
|
assert_raises{ method.to_parfait }
|
||||||
end
|
end
|
||||||
def test_method
|
def test_creates_class_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
|
|
||||||
clazz = @clazz.to_parfait
|
clazz = @clazz.to_parfait
|
||||||
m = clazz.single_class.get_instance_method(:meth)
|
m = clazz.single_class.get_instance_method(:meth)
|
||||||
assert m , "no method :meth"
|
assert m , "no method :meth"
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
@ -23,11 +23,16 @@ module Vool
|
|||||||
def test_method
|
def test_method
|
||||||
assert_equal Parfait::Class , @clazz.to_parfait.class
|
assert_equal Parfait::Class , @clazz.to_parfait.class
|
||||||
end
|
end
|
||||||
def test_is_instance_method
|
def test_creates_instance_method
|
||||||
main = @clazz.to_parfait.get_instance_method(:main)
|
main = @clazz.to_parfait.get_instance_method(:main)
|
||||||
assert_equal Parfait::VoolMethod , main.class
|
assert_equal Parfait::VoolMethod , main.class
|
||||||
assert_equal :main , main.name
|
assert_equal :main , main.name
|
||||||
end
|
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
|
end
|
||||||
class TestMethodExpressionDoubleDef < MiniTest::Test
|
class TestMethodExpressionDoubleDef < MiniTest::Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user