2015-10-07 14:22:47 +02:00
|
|
|
module Phisol
|
2015-09-19 17:56:18 +02:00
|
|
|
Compiler.class_eval do
|
2015-10-05 23:27:13 +02:00
|
|
|
|
2015-10-09 16:51:14 +02:00
|
|
|
def on_function statement
|
|
|
|
#puts statement.inspect
|
|
|
|
return_type , name , parameters, kids , receiver = *statement
|
2015-09-19 15:28:41 +02:00
|
|
|
name = name.to_a.first
|
|
|
|
args = parameters.to_a.collect do |p|
|
2015-09-20 15:30:07 +02:00
|
|
|
raise "error, argument must be a identifier, not #{p}" unless p.type == :parameter
|
2015-09-27 15:06:48 +02:00
|
|
|
Parfait::Variable.new( *p)
|
2014-07-16 12:20:47 +02:00
|
|
|
end
|
2015-09-19 15:28:41 +02:00
|
|
|
|
2015-09-20 16:33:05 +02:00
|
|
|
if receiver
|
2015-07-19 12:31:13 +02:00
|
|
|
# compiler will always return slot. with known value or not
|
2015-09-20 16:33:05 +02:00
|
|
|
r = receiver.first
|
|
|
|
if( r.is_a? Parfait::Class )
|
2015-07-19 12:31:13 +02:00
|
|
|
class_name = r.value.name
|
2015-05-20 16:11:13 +02:00
|
|
|
else
|
2015-09-20 16:33:05 +02:00
|
|
|
if( r != :self)
|
|
|
|
raise "unimplemented case in function #{r}"
|
|
|
|
else
|
|
|
|
r = Virtual::Self.new()
|
|
|
|
class_name = method.for_class.name
|
|
|
|
end
|
2015-05-20 16:11:13 +02:00
|
|
|
end
|
|
|
|
else
|
2015-10-05 23:27:13 +02:00
|
|
|
r = @clazz
|
|
|
|
class_name = @clazz.name
|
|
|
|
end
|
|
|
|
raise "Already in method #{@method}" if @method
|
|
|
|
@method = @clazz.get_instance_method( name )
|
|
|
|
if(@method)
|
|
|
|
puts "Warning, redefining method #{name}" unless name == :main
|
|
|
|
#TODO check args / type compatibility
|
|
|
|
@method.source.init @method
|
|
|
|
else
|
|
|
|
@method = Virtual::MethodSource.create_method(class_name, return_type, name , args )
|
|
|
|
@method.for_class.add_instance_method @method
|
2015-05-20 16:11:13 +02:00
|
|
|
end
|
2015-10-05 23:27:13 +02:00
|
|
|
@method.source.receiver = r
|
|
|
|
puts "compile method #{@method.name}"
|
2015-06-01 16:31:35 +02:00
|
|
|
|
2015-09-19 17:56:18 +02:00
|
|
|
|
2014-07-24 20:56:31 +02:00
|
|
|
#frame = frame.new_frame
|
2015-09-19 15:28:41 +02:00
|
|
|
kids.to_a.each do |ex|
|
2015-09-19 17:56:18 +02:00
|
|
|
return_type = process(ex)
|
2015-09-19 15:28:41 +02:00
|
|
|
raise return_type.inspect if return_type.is_a? Virtual::Instruction
|
2014-07-14 13:29:33 +02:00
|
|
|
end
|
2015-10-05 23:27:13 +02:00
|
|
|
@method.source.return_type = return_type
|
|
|
|
@method = nil
|
2015-09-19 15:28:41 +02:00
|
|
|
Virtual::Return.new(return_type)
|
2014-07-14 10:29:38 +02:00
|
|
|
end
|
2015-05-08 14:10:30 +02:00
|
|
|
end
|
2015-05-04 13:22:22 +02:00
|
|
|
end
|