/* Copyright (C) 1993 by Thomas Glen Smith. All Rights Reserved. */
/* execindx - APL2 V1.0.0 **********************************************
* Called from execnexs and execnexu when an indexing operation is *
* recognized. *
***********************************************************************/
#define INCLUDES APLCB+APLCHDEF+APLTOKEN+TREE
#include "includes.h"
Apltoken execindx(op)
Apltoken op; /* token for operand to be indexed */
{
Execgeto; Execgetp; Execindy; Execpop; Exectok; Indexm; Leafdel;
Matchok; Perm; Pop; Treenode; Treesrch;
extern int aplerr;
extern Treelist treehdr;
Aplcb indices, *ixout, left, rite;
Apltoken ixnxt, ixtok;
Avlnode p;
void *wrk;
int i,offset;
indices = left = rite = NULL; /* clean slate */
ixtok = pop(&(treehdr->avlexec->avloprst)); /* pop index */
if (treehdr->avlexec->avlfunst != NULL &&
treehdr->avlexec->avlfunst->token_code == LEFT_ARROW) {
execfree(pop(&(treehdr->avlexec->avlfunst))); /* lft arr */
rite = execgeto(&(treehdr->avlexec->avloprst));
}
if (op->token_code == OPERAND_TOKEN && rite != NULL) {
if (NULL == (p = treenode(op->token_ptr.token_string)) ||
NULL == (left = p->avlleaf) ||
(left->aplflags & APLLABEL) ||
(left->aplflags & APLFUNC))
aplerr = 59; /* undefined operand */
else if (matchok(&left,&rite,APLMASK+APLAPL)
&& left != p->avlleaf) {
leafdel(p->avlleaf); /* free old leaf */
p->avlleaf = perm(left); /* replace w/converted leaf */
}
execfree(op); /* free operand token */
}
else left = execgetp(op); /* get aplcb ptr */
if (aplerr == 0 && left->aplrank < 1)
aplerr = 68; /* can't index a scalar */
if (aplerr == 0) {
offset = ixtok->token_offset; /* save offset for later */
indices = execindy(ixtok,left->aplrank); /* get indices */
}
execfree(ixtok); /* free index stack */
if (aplerr) {
endoper(left); endoper(indices); endoper(rite);
return(NULL);
}
return(exectok(indexm(left,indices,rite),offset)); /* token */
}