Metropoli BBS
VIEWER: execindx.c MODE: TEXT (ASCII)
/* 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 */
}
[ RETURN TO DIRECTORY ]