2015-05-20 15:43:26 +02:00
|
|
|
# A Method (at runtime , sis in Parfait) is static object that primarily holds the executable
|
|
|
|
# code.
|
|
|
|
|
|
|
|
# For reflection also holds arguments and such
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
module Parfait
|
|
|
|
|
|
|
|
# static description of a method
|
|
|
|
# name
|
|
|
|
# arg_names
|
|
|
|
# known local variable names
|
|
|
|
# temp variables (numbered)
|
|
|
|
# executable code
|
|
|
|
|
|
|
|
# ps, the compiler injects its own info, see virtual::compiled_method_info
|
|
|
|
|
|
|
|
|
|
|
|
class Method < Object
|
|
|
|
|
2015-05-24 12:53:49 +02:00
|
|
|
def initialize clazz , name , arg_names
|
2015-05-21 20:50:17 +02:00
|
|
|
super()
|
2015-05-24 12:53:49 +02:00
|
|
|
raise "No class #{name}" unless clazz
|
|
|
|
@for_class = clazz
|
2015-05-20 15:43:26 +02:00
|
|
|
@name = name
|
2015-05-28 20:10:27 +02:00
|
|
|
@code = BinaryCode.new_object name
|
2015-05-20 15:43:26 +02:00
|
|
|
@arg_names = arg_names
|
2015-05-31 13:44:26 +02:00
|
|
|
@locals = List.new
|
|
|
|
@tmps = List.new
|
2015-05-20 15:43:26 +02:00
|
|
|
end
|
2015-05-26 19:17:43 +02:00
|
|
|
attr_reader :name , :arg_names , :for_class , :code
|
2015-05-20 15:43:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
# determine whether this method has a variable by the given name
|
|
|
|
# variables are locals and and arguments
|
|
|
|
# used to determine if a send must be issued
|
|
|
|
# return index of the name into the message if so
|
|
|
|
def has_var name
|
2015-06-01 16:31:35 +02:00
|
|
|
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
|
2015-05-20 15:43:26 +02:00
|
|
|
index = has_arg(name)
|
|
|
|
return index if index
|
|
|
|
has_local(name)
|
|
|
|
end
|
|
|
|
|
|
|
|
# determine whether this method has an argument by the name
|
|
|
|
def has_arg name
|
2015-06-01 16:31:35 +02:00
|
|
|
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
|
2015-05-20 16:29:08 +02:00
|
|
|
@arg_names.index_of name
|
2015-05-20 15:43:26 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
# determine if method has a local variable or tmp (anonymous local) by given name
|
|
|
|
def has_local name
|
2015-06-01 16:31:35 +02:00
|
|
|
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
|
|
|
|
index = @locals.index_of(name)
|
|
|
|
index = @tmps.index_of(name) unless index
|
2015-05-20 15:43:26 +02:00
|
|
|
index
|
|
|
|
end
|
|
|
|
|
|
|
|
def ensure_local name
|
|
|
|
index = has_local name
|
|
|
|
return index if index
|
2015-06-01 16:31:35 +02:00
|
|
|
@locals.push name
|
2015-06-03 09:01:59 +02:00
|
|
|
@locals.get_length
|
2015-05-20 15:43:26 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def get_var name
|
|
|
|
var = has_var name
|
|
|
|
raise "no var #{name} in method #{self.name} , #{@locals} #{@arg_names}" unless var
|
|
|
|
var
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|