This section deals with some type declaration and executable statements that are directly related to one specific capability of YAL: execution-time expression evaluation. (Later, we will see how the features required for this capability also provide YAL with other abilities.)
YAL posesses the built-in function
_EXEV(text,list,list...)
which evaluates the expression in text using the built-in features of YAL and the items in the list parameters. List can be omitted, which can still be useful where text is a variable.
For example, the following code:
LIST(MUTABLE)*6 L . L=_L(X=3,Y=4) . Y=_EXEV('X*Y',L) PRINT Y END
would produce the output
12
While the function EXEV can use all the built-in functions of FALCON, like SIN, SQR, and so on, it cannot refer to variables within a FALCON program. Their names are forgotten after a program is compiled, except for the names of externally-callable subroutines, of COMMON blocks, and similar items.
It is possible to pass user-defined functions or operators to EXEV through variables of type LIST:
The statement
. X=FUN(R)
assigns the numerical result of the function FUN applied to the value of R to X. To note in an expression that the name of a function is to be used to refer to the function itself rather than the result of the function requires the notation %%S(...). The same applies to operators, and here the question marks delimiting the name would appear in the parentheses.
One would then assign such an entity to a variable of type SUBPROGRAM, declared with the SUBPROGRAM statement:
SUBPROGRAM VTX(10)
defines an array of ten functions/subroutines/operators, or, more precisely, an array of ten pointers to such things.
Since SUBPROGRAM, as well as LOGICAL, CHARACTER, or REAL, is a simple FALCON type, it is available within the MUTABLE type.
Thus, in the program above, if we said
. L=_L(X=3,Y=4,FUN=%%S(FUN))
then FUN, under (coincidentally) its old name, would be available within the expression evaluated by EXEV.
To create a SUBPROGRAM-valued constant referring to a built-in YAL function, that function must be fully specified: for example, %%S(_SIN) is meaningless, but %%S(_SIN((REAL))) refers to a specific real subroutine. The same applies to alias constructs, but the user functions from which they are built are usually accessible. (Alias constructs generating in-line code, or using multiple ampersands, can also be used; the compiler generates needed constants as it encounters their use, and that includes subroutine-valued constants!)
Note that %%S(...) has the subprogram itself as its value, while %S(...) is also available, and has the entry address of the subprogram as its value.
The requirement for full specification of functions for subprogram-valued constants is precisely the same as that for passing of subprograms as arguments to other subprograms.
In addition to _EXEV, there is also _SIMEV within YAL; SIMEV has the same syntax as EXEV, but restricts the expression to the use of the contents of the list, not allowing the direct use of any built-in YAL functions or operators, even + or *. The reserved identifier _SIMOPS is a LIST of SUBPROGRAMS containing the MUTABLE versions of the basic YAL operators which can be used in building a list for SIMEV where plus and times, but not the gamma function, are to be allowed.
Also present in YAL is the built-in subroutine
_ASEX(text,list,list...;list,list...)
which executes the assignment which is the value of its text parameter, altering or creating an entry in the list parameters to do so, as well as using them as its source of information.
A multiple assignment may be its text parameter.
When a pseudovariable is assigned a value, ASEX first searches, starting with the first list parameter, up to the semicolon, if any, for a list already containing that pseudovariable; if one is found, the change is made in that list. If there is no such list, the pseudovariable is added to the first list parameter.
Note that this subroutine only causes changes to the LIST variables that are its arguments under normal circumstances. However, the list arguments in a call to _ASEX or _EXEV may also be of type VLIST, which allows access to other YAL variables.
In EASY mode, EXEV and ASEX perform expression evaluations and assignments using the full variable pool of the YAL program, thus not requiring LIST arguments. INTEV is available, between EXEV and SIMEV, to exclude YAL variables when that is specifically desired.
Note that the EXEV function is useful in implementing spreadsheets. In the example below, showing a routine to perform a spreadsheet recalculation in column/row order, note that expressions have been translated from a spreadsheet form such as
@TAN(C8)*E7
to an internal form of
_TAN(A(3,8))*A(5,7)
suitable for internal use by YAL. (C=3, E=5)
Example code:
REAL A(100,100) LOGICAL EXPR(100,100) CHARACTER*40 E(100,100) VLIST ML . ML=_LMAKE(A) Only recalculation is shown... other code must go here 17 FOR I=1,100 27 FOR J=1,100 IF EXPR(J,I), {. A(J,I)=_EXEV(E(J,I),L)} REPEAT 27 REPEAT 17