def process_call(exp)
lhs = process exp.shift
name = exp.shift
args = process exp.shift
arg_types = if args.nil? then
[]
else
if args.first == :arglist then
args.sexp_types
elsif args.first == :splat then
[args.sexp_type]
else
raise "That's not a Ruby Sexp you handed me, I'm freaking out on: #{args.inspect}"
end
end
if name == :=== then
rhs = args[1]
raise "lhs of === may not be nil" if lhs.nil?
raise "rhs of === may not be nil" if rhs.nil?
raise "Help! I can't figure out what kind of #=== comparison to use" if
lhs.sexp_type.unknown? and rhs.sexp_type.unknown?
equal_type = lhs.sexp_type.unknown? ? rhs.sexp_type : lhs.sexp_type
name = "case_equal_#{equal_type.list_type}".intern
end
return_type = Type.unknown
lhs_type = lhs.nil? ? Type.unknown : lhs.sexp_type
function_type = Type.function(lhs_type, arg_types, return_type)
@functions.unify(name, function_type) do
@functions.add_function(name, function_type)
$stderr.puts "\nWARNING: function #{name} called w/o being defined. Registering #{function_type.inspect}" if $DEBUG
end
return_type = function_type.list_type.return_type
return t(:call, lhs, name, args, return_type)
end