/* 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 */ }