2017-12-10 19:47:26 +01:00
|
|
|
module Parfait
|
2016-12-20 19:02:20 +01:00
|
|
|
|
2019-10-03 23:36:49 +02:00
|
|
|
# This represents the method at source code level (sis sol)
|
2017-12-10 19:47:26 +01:00
|
|
|
#
|
|
|
|
# Type objects are already created for args and locals, but the main attribute
|
2019-10-03 23:36:49 +02:00
|
|
|
# is the source, which is a Sol::Statement
|
2017-12-10 19:47:26 +01:00
|
|
|
#
|
2019-10-03 23:36:49 +02:00
|
|
|
# Classes store SolMethods, while Types store Risc::CallableMethod
|
2017-12-10 19:47:26 +01:00
|
|
|
# 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.
|
|
|
|
#
|
2019-10-03 23:36:49 +02:00
|
|
|
class SolMethod < Object
|
2016-12-20 19:02:20 +01:00
|
|
|
|
2019-09-09 23:18:20 +02:00
|
|
|
attr_reader :name , :args_type , :frame_type
|
2018-08-12 13:48:20 +02:00
|
|
|
attr_reader :source
|
2019-07-22 14:21:16 +02:00
|
|
|
|
2018-03-14 15:54:47 +01:00
|
|
|
def initialize(name , args_type , frame_type , source )
|
2019-09-09 19:26:54 +02:00
|
|
|
@name = name
|
|
|
|
@args_type = args_type
|
|
|
|
@frame_type = frame_type
|
2018-08-12 13:48:20 +02:00
|
|
|
@source = source
|
2019-09-30 16:09:13 +02:00
|
|
|
#raise source.to_s if name == :type_length
|
2017-01-16 16:44:34 +01:00
|
|
|
raise "Name must be symbol" unless name.is_a?(Symbol)
|
|
|
|
raise "args_type must be type" unless args_type.is_a?(Parfait::Type)
|
2018-03-14 15:54:47 +01:00
|
|
|
raise "frame_type must be type" unless frame_type.is_a?(Parfait::Type)
|
2019-10-03 23:36:49 +02:00
|
|
|
raise "source must be sol not#{source.class}" unless source.is_a?(Sol::Statement)
|
|
|
|
raise "Empty bod" if(@source.is_a?(Sol::Statements) and @source.empty?)
|
2016-12-20 19:02:20 +01:00
|
|
|
end
|
|
|
|
|
2019-09-10 11:33:57 +02:00
|
|
|
def create_callable_method_for( type )
|
2017-01-15 11:10:37 +01:00
|
|
|
raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type
|
2019-09-29 21:37:28 +02:00
|
|
|
#puts "Create #{name} for #{type.object_class.name}.#{type.hash}"
|
2019-09-09 19:26:54 +02:00
|
|
|
type.create_method( @name , @args_type , @frame_type)
|
2017-01-15 11:10:37 +01:00
|
|
|
end
|
|
|
|
|
2018-07-06 19:01:17 +02:00
|
|
|
def compiler_for(self_type)
|
2019-09-29 21:37:28 +02:00
|
|
|
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
|
2019-10-03 19:55:41 +02:00
|
|
|
compiler = SlotMachine::MethodCompiler.new( callable_method )
|
|
|
|
head = @source.to_slot( compiler )
|
2019-08-07 11:06:06 +02:00
|
|
|
compiler.add_code(head)
|
2018-07-01 10:57:17 +02:00
|
|
|
compiler
|
2018-06-27 16:09:50 +02:00
|
|
|
end
|
2019-09-29 11:06:37 +02:00
|
|
|
def to_s
|
2019-09-29 21:37:28 +02:00
|
|
|
"def #{name}(#{args_type.names})\n #{source}\nend"
|
2019-09-29 11:06:37 +02:00
|
|
|
end
|
2016-12-20 19:02:20 +01:00
|
|
|
end
|
|
|
|
end
|