rename typed_method to callable_method
seems to make the essence clearer also extracted base class
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
# we resolve the method at runtime, and then cache it. Aaron has shown that over 99%
|
||||
# of call sites are type stable, so one cache entry at the moment
|
||||
#
|
||||
# A cache entry stores the type of the object and the TypedMethod that is to be called
|
||||
# A cache entry stores the type of the object and the CallableMethod that is to be called
|
||||
# This is used in DynamicCall, see there
|
||||
#
|
||||
module Parfait
|
||||
|
@ -8,11 +8,12 @@ module Parfait
|
||||
# - frame_type: A type object describing the local variables that the method has
|
||||
# - binary: The binary (jumpable) code that instructions get assembled into
|
||||
# - blocks: linked list of blocks inside this method/block
|
||||
# - next: next block/method at same level
|
||||
#
|
||||
class Callable < Object
|
||||
|
||||
attr_reader :self_type , :arguments_type , :frame_type , :binary , :blocks
|
||||
|
||||
attr_reader :self_type , :arguments_type , :frame_type , :binary
|
||||
attr_reader :blocks, :next
|
||||
def initialize( self_type , arguments_type , frame_type)
|
||||
super()
|
||||
raise "No class #{self}" unless self_type
|
||||
@ -53,5 +54,10 @@ module Parfait
|
||||
bin = bin.next
|
||||
end
|
||||
end
|
||||
|
||||
def set_next( method )
|
||||
@next = method
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
40
lib/parfait/callable_method.rb
Normal file
40
lib/parfait/callable_method.rb
Normal file
@ -0,0 +1,40 @@
|
||||
# A CallableMethod is static object that primarily holds the executable code.
|
||||
# It is callable through it's binary code
|
||||
# Additionally to the base class it has a name
|
||||
#
|
||||
# It's relation to the method a ruby programmer knows (called VoolMethod) is many to one,
|
||||
# meaning one VoolMethod (untyped) has many CallableMethod implementations.
|
||||
# The VoolMethod only holds vool code, no binary.
|
||||
|
||||
|
||||
module Parfait
|
||||
|
||||
class CallableMethod < Callable
|
||||
|
||||
attr_reader :name
|
||||
|
||||
def initialize( self_type , name , arguments_type , frame_type)
|
||||
@name = name
|
||||
super(self_type , arguments_type , frame_type)
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
return false unless other.is_a?(CallableMethod)
|
||||
return false if @name != other.name
|
||||
super
|
||||
end
|
||||
|
||||
def rxf_reference_name
|
||||
"Method: " + @name.to_s
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#{@self_type.object_class.name}:#{name}(#{arguments_type.inspect})"
|
||||
end
|
||||
|
||||
def each_method( &block )
|
||||
block.call( self )
|
||||
@next.each_method( &block ) if @next
|
||||
end
|
||||
end
|
||||
end
|
@ -12,7 +12,7 @@
|
||||
# An Object carries the data for the instance variables it has.
|
||||
# The Type lists the names of the instance variables
|
||||
# The Class keeps a list of instance methods, these have a name and (vool) code
|
||||
# Each type in turn has a list of TypedMethods that hold binary code
|
||||
# Each type in turn has a list of CallableMethods that hold binary code
|
||||
|
||||
module Parfait
|
||||
class Class < Object
|
||||
|
@ -87,12 +87,12 @@ module Parfait
|
||||
found.init(arguments , frame)
|
||||
return found
|
||||
else
|
||||
add_method TypedMethod.new( self , method_name , arguments , frame )
|
||||
add_method CallableMethod.new( self , method_name , arguments , frame )
|
||||
end
|
||||
end
|
||||
|
||||
def add_method( method )
|
||||
raise "not a method #{method.class} #{method.inspect}" unless method.is_a? TypedMethod
|
||||
raise "not a method #{method.class} #{method.inspect}" unless method.is_a? CallableMethod
|
||||
raise "syserr #{method.name.class}" unless method.name.is_a? Symbol
|
||||
if self.is_a?(Class) and (method.self_type != self)
|
||||
raise "Adding to wrong class, should be #{method.for_class}"
|
||||
@ -109,16 +109,16 @@ module Parfait
|
||||
def remove_method( method_name )
|
||||
raise "No such method #{method_name} in #{self.name}" unless @methods
|
||||
if( @methods.name == method_name)
|
||||
@methods = @methods.next_method
|
||||
@methods = @methods.next
|
||||
return true
|
||||
end
|
||||
method = @methods
|
||||
while(method && method.next_method)
|
||||
if( method.next_method.name == method_name)
|
||||
method.set_next( method.next_method.next_method )
|
||||
while(method && method.next)
|
||||
if( method.next.name == method_name)
|
||||
method.set_next( method.next.next )
|
||||
return true
|
||||
else
|
||||
method = method.next_method
|
||||
method = method.next
|
||||
end
|
||||
end
|
||||
raise "No such method #{method_name} in #{self.name}"
|
||||
@ -144,6 +144,7 @@ module Parfait
|
||||
return method if method
|
||||
sup = object_class.super_class
|
||||
return nil unless sup
|
||||
return nil if object_class.name == :Object
|
||||
sup.instance_type.resolve_method(fname)
|
||||
end
|
||||
|
||||
|
@ -1,53 +0,0 @@
|
||||
require_relative "callable"
|
||||
# A TypedMethod is static object that primarily holds the executable code.
|
||||
# It is called typed, because all arguments and variables it uses are "typed",
|
||||
# that is to say the names are known and form a type (not that the types of the
|
||||
# variables are known). The object's type is known too, which means all instances
|
||||
# variable names are known (not their respective type).
|
||||
|
||||
# It's relation to the method a ruby programmer knows (called VoolMethod) is many to one,
|
||||
# meaning one VoolMethod (untyped) has many TypedMethod implementations.
|
||||
# The VoolMethod only holds vool code, no binary.
|
||||
|
||||
# The Typed method has the following instance variables
|
||||
# - name : This is the same as the ruby method name it implements
|
||||
# - binary: The binary (jumpable) code that the instructions get assembled into
|
||||
# - arguments_type: A type object describing the arguments (name+types) to be passed
|
||||
# - frame_type: A type object describing the local variables that the method has
|
||||
# - self_type: The Type the Method is for
|
||||
|
||||
|
||||
module Parfait
|
||||
|
||||
class TypedMethod < Callable
|
||||
|
||||
attr_reader :name , :next_method
|
||||
|
||||
def initialize( self_type , name , arguments_type , frame_type)
|
||||
@name = name
|
||||
super(self_type , arguments_type , frame_type)
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
return false unless other.is_a?(TypedMethod)
|
||||
return false if @name != other.name
|
||||
super
|
||||
end
|
||||
|
||||
def rxf_reference_name
|
||||
"Method: " + @name.to_s
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#{@self_type.object_class.name}:#{name}(#{arguments_type.inspect})"
|
||||
end
|
||||
|
||||
def each_method( &block )
|
||||
block.call( self )
|
||||
next_method.each_method( &block ) if next_method
|
||||
end
|
||||
def set_next( method )
|
||||
@next_method = method
|
||||
end
|
||||
end
|
||||
end
|
@ -5,7 +5,7 @@ module Parfait
|
||||
# Type objects are already created for args and locals, but the main attribute
|
||||
# is the source, which is a Vool::Statement
|
||||
#
|
||||
# Classes store VoolMethods, while Types store TypedMethod
|
||||
# Classes store VoolMethods, while Types store CallableMethod
|
||||
# A Type referes to a Class , but a Class (interface) is implemented by many types
|
||||
# as it changes during the course of it's life. Types do not change. Objects have
|
||||
# type, and so only indirectly a class.
|
||||
@ -23,14 +23,14 @@ module Parfait
|
||||
raise "Empty bod" if(source.is_a?(Vool::Statements) and source.empty?)
|
||||
end
|
||||
|
||||
def create_typed_method( type )
|
||||
def create_callable_method( type )
|
||||
raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type
|
||||
type.create_method( @name , @args_type , @frame_type)
|
||||
end
|
||||
|
||||
def compiler_for(self_type)
|
||||
typed_method = create_typed_method(self_type)
|
||||
compiler = Risc::MethodCompiler.new( typed_method )
|
||||
callable_method = create_callable_method(self_type)
|
||||
compiler = Risc::MethodCompiler.new( callable_method )
|
||||
head = source.to_mom( compiler )
|
||||
compiler.add_mom(head)
|
||||
compiler
|
||||
|
Reference in New Issue
Block a user