process_call (TypeChecker)

    # 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