To call a subroutine, use the CALL statement; a typical CALL statement may look like this:
CALL MYSUB(X,Y,Z)
and will cause the subroutine MYSUB to run.
Note that when CALLing a user-defined subroutine (or using a user-defined function) within a program in which that subprogram is not declared, no separator other than a comma can be used. (This does not apply in EASY mode.)
EXALT includes several built-in subroutines. While it would have been equally easy to implement each such subroutine as a new type of executable statement, these subroutines all refer to activities which have been considered more appropriate to express in this manner for one reason or another.
_SETK(x) | set the k parameter for future evaluation of limited-argument versions of the elliptic integral functions to x. |
_SETM(x) | set the k parameter to _SQR(x). |
_SALPHA(x) | set the k parameter to _SIN(x). |
_ISORT(a,b,c) | where a is an array, sort a (along its lowest dimension if multidimensional), placing the result in b, and filling c with numbers such that b(i)=a(c(i)). (if multidimensional, b(...j,i)=a(...j,c(...j,i)).) |
_EXIT | CALL _EXIT is equivalent to STOP with no return code. |
_DUMP(a,b,f) | similar to PDUMP in FORTRAN; dumps all memory from where a is located to where b is located inclusive in the format indicated by f. |
The possible values of f, and the formats in which they cause a memory dump, are as follows:
1 Continuous octal/Character 102 Signed byte 2 Continuous hexadecimal/Character 103 Halfword 8 Continuous decimal/Character 104 Integer 11 Continuous octal 105 Long integer 12 Continuous hexadecimal 112 Byte 18 Continuous decimal 113 Unsigned halfword 21 Octal/Instructions 114 Unsigned integer 22 Hexadecimal/Instructions 115 Long unsigned 23 Decimal/Instructions 152 Real 50 Character 153 Double precision 60 Fixed-string 154 Quadruple precision
_INSERT(a,m,n;b=x,c=y) | adds all the facts in the lists m and n, and the facts b=x and c=y, to the list a (b=x,c=y is actually a single argument in LIST_EQUATE mode, or VLIST_EQUATE mode if a is a VLIST) |
_PFF(a,b,c) | where a is a floating-point number with the value 273.442, this subroutine assigns to b the value of the string "273442" plus an implementation-dependent number of trailing zeroes, and assigns to c the integer value 3, indicating that a was .273442 times ten to the third power. The sign of a is ignored by this routine. This is used as a primitive for building up specialized printing formats; using a character variable as the device in a PRINT statement is preferred when an existing format is to be used. |
_PDIV(a,b,c,d) | where a and b are one-dimensional arrays of numbers (if they have a greater dimension, the operation is performed once for each value for their higher dimensions) they are considered to contain the coefficients of polynomials, the first number being the coefficient of the highest power in x in both. This routine performs division of a by b as polynomials, placing the quotient in c, and the remainder in d (which may be omitted). |
_SIF(a,b,c) | where a is a floating-point number, _SIF gives b, an integer, and c, a floating-point number, values such that a equals c * (_FBASE ^ b), and if a is not zero, the absolute value of c will be between 1 and _FBASE. If a is zero, c will be zero, and b will have a value less than or equal to the least possible value of b for nonzero a. Both a and c will have the same sign. The purpose of this function is to make available the internal form of a floating-point number for the efficient implementation of logarithm and square-root functions, or similar applications, in a form that both requires a minimum of conversion and also has the value of _FBASE as its only machine dependency relevant for most purposes. (The value of b for a=0 is also machine dependent, of course.) |
Certain facts about function and subroutine arguments in EXALT may be noted at this point. If a constant appears in the argument list of a function or subroutine, it is treated as an expression: its value but not its address are passed (in most implementations, this means that it will be copied into a temporary storage location, the address of which will be passed) so that under no circumstances will an errant subroutine able to cause every 5 in a program to act like a 3, as can actually happen in some implementations of FORTRAN.
In addition, variables will recieve the same treatment under two circumstances: where they are arguments to a function or subroutine declared MATHEMATICAL in the calling program, or where the same variable appears more than once in the same argument list in positions which may, as far as the compiler is aware, result in changes to the variable's value. (Of course, appearance of a variable as part of an expression in the argument list of a subprogram does not render it subject to change by that subprogram, and so does not count for purposes of this rule.) In the latter case, one temporary copy is made for each appearance of the variable. This is not done, however, for PFUNs and PSUBs which contain a MATHEMATICAL declaration within themselves affecting the requisite positions in the argument list, as they can be trusted. Also, it can be disabled with the declaration
TRUST subprogram,subprogram,...subprogram
but no external subprogram is ever trusted with constants.
Note that if it is necessary to execute a call such as
CALL XBV(N,35,X,X,Y)
and it is desired to take the value returned in the fourth argument position (the second ocurrence of X) as the new value of X, all that is required is to declare the third argument position MATHEMATICAL in a PSUB or XSUB statement, so that X does not appear twice in positions where it is potentially subject to change.
It should also be noted that while an assignment can appear as a subprogram argument under some conditions, and such assignments may be to LEFT_FUNCTIONS, a subprogram argument list like that of XBK below:
XBK(R,3*ZBY,FUN(L))
will never result in FUN(L) being considered a LEFT_FUNCTION instead of an expression; no explicit declaration for such a situation is provided by EXALT; asymmetry in favoring the ordinary function interpretation of the syntax to avoid ambiguity is considered necessary to maintain program readability.