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