package rebelsky.compiler.types;

/**
 * The type used for functions and procedures.
 *
 * @author Samuel A. Rebelsky
 * @version 1.0 of April 2004
 */
public class FunctionOrProcedure
  extends Type
{
  // +--------+------------------------------------------------------------
  // | Fields |
  // +--------+

  /**
   * The parameters to the function.  Represented as an array
   * of types.
   */
  Type[] params;

  /**
   * The return type of the function.  Should be null for procedures.
   */
  Type returnType;
 
  // +--------------+------------------------------------------------------
  // | Constructors |
  // +--------------+

  /**
   * Build a new function type.
   */
  public FunctionOrProcedure(Type[] params, Type returnType)
  {
    super("function returning " + returnType);
    this.params = params;
    this.returnType = returnType;
  } // FunctionOrProcedure(Type[], Type)

  /**
   * Build a new procedure type.
   */
  public FunctionOrProcedure(Type[] params)
  {
    super("procedure");
    this.params = params;
    this.returnType = returnType;
  } // FunctionOrProcedure(Type[])

  // +---------+-----------------------------------------------------------
  // | Methods |
  // +---------+

  /**
   * Determine if the object is a procedure.  If it's not a procedure,
   * it's a function.
   */
  public boolean isProcedure()
  {
    return (returnType == null);
  } // isProcedure()

  /**
   * Get the return type of this object.  Should only be called
   * for functions.
   */
  public Type returns()
  {
    return returnType;
  } // returns()

  /**
   * Determine the type of a parameter.  Parameters are numbered
   * starting at 0.  paramNum must be less than the number of
   * parameters.
   */
  public Type paramType(int paramNum)
  {
    return params[paramNum];
  } // paramType(int)

  /**
   * Determine how many parameters this function or procedure takes.
   */
  public int numParams()
  {
    return params.length;
  } // numParams()
} // class FunctionOrProcedure

