# File lib/type_checker.rb, line 277
  def process_call(exp)
    lhs = process exp.shift     # can be nil
    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 # TODO: maybe void instead of unknown

    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