/*Copyright (C) 1992, 1996 by Thomas Glen Smith. All Rights Reserved.*/ /* popnest APL2 V1.0.0 ************************************************* * Called by execnexu. Pops elements from the operand stack, and builds * * nested array if more than one element is on the stack. * ***********************************************************************/ #define INCLUDES APLCHDEF+APLTOKEN+APLCB+TREE #include "includes.h" Apltoken popnest(hdr) Apltoken *hdr; { Endoper; Execgetp; Exectok; Getcb; Pop; Popnesc; Popnesu; Popnesv; Popnesw; Popnesx; Typeget; extern int aplerr; extern Treelist treehdr; Apltoken tok, toklast, toknext; int datacnt, datatyp, newtype, offset, resolved; Aplcb out=NULL; if (NULL == (tok = *hdr)) return(NULL); /* nothing on stack */ if (NULL == tok->token_queue.token_next_ptr) return(pop(hdr)); /* one element in stack */ offset = tok->token_offset; /* save for later */ datacnt = datatyp = 0; toklast = (Apltoken ) hdr; while (tok) { datacnt++; /* count of items on operand stack */ toknext = tok->token_queue.token_next_ptr; switch(tok->token_code) { case VECTOR_TOKEN: case QUOTE: resolved = 1; break; default: resolved = 0; } if (!resolved) { out = execgetp(tok); /* resolve operand, free tok */ if (out == NULL) { /* Clean up stack and quit. */ toklast->token_queue.token_next_ptr = toknext; return(NULL); } tok = exectok(out,offset); /* get new token */ toklast->token_queue.token_next_ptr = tok; tok->token_queue.token_next_ptr = toknext; } out = tok->token_ptr.token_vector; if (out->aplrank) datatyp = APLAPL; /* nested array */ else datatyp = typeget(datatyp, out->aplflags & (APLMASK + APLAPL)); toklast = tok; /* save prior on stack */ tok = toknext; /* point to next on stack */ } out = getcb(NULL, datacnt, datatyp + APLTEMP, 1, NULL); if (aplerr) return(NULL); /* probably out of storage */ switch (datatyp) { case APLAPL: popnesu(hdr,out); break; case APLCHAR: popnesv(hdr,out); break; case APLINT: popnesw(hdr,out); break; case APLNUMB: popnesx(hdr,out); break; case APLCPLX: popnesc(hdr,out); break; default: aplerr = 999; /* internal error */ } if (aplerr) { endoper(out); return(NULL); } if (treehdr->lastfun == LEFT_ARROW) treehdr->lastfun = 0; /* last thing done wasn't assignment. */ return(exectok(out,offset)); }