/*Copyright (C) 1992, 1995 by Thomas Glen Smith. All Rights Reserved.*/
/* execqfx APL2 V1.0.0 *************************************************
* Function establishment is called from aplcpyc, apledfx, and execmonq.*
* The argument must be an APL character matrix representing a *
* user-defined function. *
***********************************************************************/
#define INCLUDES APLCB+APLFUNCI+APLTOKEN+STRING+TREE
#include "includes.h"
Aplcb execqfx(rite)
Aplcb rite;
{
Assign; Chrvect; Errinit; Errstop; Execqfxa; Execqfxb; Execqfxf;
Execqfxi; Execqfxl; Execqfxm; Expunge; Nestchar; Treenode;
extern int aplerr;
Apltoken nametok;
Aplcb cb,*cbp,out;
Aplfunc fp=NULL,oldfunc;
int datatype,stmtcnt;
for(;;) { /* Lets me use break. */
if (errinit()) break; /* Error. */
datatype = rite->aplflags & (APLCHAR | APLAPL);
if (0 == rite->aplcount)
aplerr = 90; /* Bad input. */
else if (datatype == APLCHAR) {
if (2 != rite->aplrank)
aplerr = 90; /* Bad input. */
} else if (datatype == APLAPL) {
if (1 != rite->aplrank)
aplerr = 90; /* Bad input. */
else {
cbp = rite->aplptr.aplapl;
stmtcnt = rite->aplcount;
while(stmtcnt-- && aplerr == 0) {
cb = *cbp++;
datatype = cb->aplflags & APLCHAR;
if (datatype != APLCHAR ||
cb->aplrank > 1 || cb->aplcount == 0)
aplerr = 90; /* Bad input. */
}
}
if (aplerr) break;
rite = nestchar(rite); /* Convert to character matrix. */
}
if (aplerr) break; /* Error. */
fp = execqfxa(rite); /* go initialize function structure */
rite = NULL; /* Execqfxa disposes of rite, if necessary. */
if (aplerr) break; /* Error. */
execqfxb(fp); /* Go do initial parsing. */
if (aplerr) break; /* Error */
nametok = execqfxl(fp); /* function name token */
if (aplerr) break;
return(execqfxm(nametok,fp)); /* Clean tree, do assign. */
}
if (fp) {
expunge(fp); /* Free, we had an error */
rite = NULL; /* Expunge will've freed. */
}
return(errstop(0,NULL,rite,NULL));
}