Previous: ProcInd, Up: Procedures


4.3 Applying the operator to arguments

A procedure call is an expression context that specifies the procedure to be called and the arguments to be supplied.

The module exports computational roles to support analysis of procedure calls:

ArgumentListRoot
The computational role inherited by a grammar symbol that represents a subtree that is the argument list of a procedure call.
ArgumentListElem
The computational role inherited by a grammar symbol that represents an expression subtree that provides an argument to a call. It must be a descendant of ArgumentListRoot.

CallContext(`e1',`rator',`args') is a context-dependent computation used in the context of a procedure call. The arguments are all grammar symbols. Argument `e1' plays the ExpressionSymbol role of the result, `rator' plays the OperatorSymbol role, and `args' plays the ArgumentListRoot role.

Here is a specification of a Mystery procedure call:

     SYMBOL Actuals INHERITS ArgumentListRoot END;
     
     RULE: Expr ::= Expr '(' Actuals ')'
     COMPUTE
       CallContext(Expr[1],,Actuals);
       Indication(Expr[2].Type);
       IF(OR(BadIndication,BadOperator),
         message(ERROR,"Not a procedure",0,COORDREF));
     END;

(Recall that a Mystery procedure is a value of a procedure type, and therefore we used the type as the operator indication.)

A multi-dimensional array access is handled exactly like a procedure call. The grammar symbol representing the subscript list inherits the ArgumentListRoot role, and the grammar symbol representing a subscript inherits the ArgumentListElem role. CallContext performs the necessary computations.

If the language limits arrays to a single dimension, it is inconvenient to provide grammar symbols playing the ArgumentListRoot and ArgumentListElem roles. In this case, we simply apply the monadic access operator defined for the array. Here is the Mystery specification:

     RULE: Expr ::= Expr '[' Subscript ']'
     COMPUTE
       MonadicContext(Expr[1],,Subscript);
       Indication(Expr[2].Type);
       IF(OR(BadIndication,BadOperator),
         message(ERROR,"Not an array",0,COORDREF));
     END;