Metropoli BBS
VIEWER: expand.c MODE: TEXT (ASCII)
/* Copyright (C) 1992 by Thomas Glen Smith.	All Rights Reserved. */
/* expand APL2 V1.0.0 **************************************************
* Called by slashtrb.                                                  *
* Output is the same shape as the rite argument, except a scalar rite  *
* produces a vector out.  The output is produced from rite according	 *
* to the pattern of 1s and 0s in left, a 1 meaning select the next	 *
* item from rite, and a 0 meaning fill in a zero or space.	Suppose	 *
* rite were the vector 1 2, and left were 1 0 1 0.  The result would	 *
* then be 1 0 2 0.											 *
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
Aplcb expand(left,rite,axis)
Aplcb left,rite;
int axis;
{
	Comexpa; Comexpb; Errstop; Expane; Expanf; Idyadic; Ine; Iplus;
	Ireduce; Iscalar; Ivalue; Perm; Ravel; Temp;
	extern int indxorg;
	int axicnt,botcnt,datatyp,i,identity=0,topcnt;
	Aplcb out=NULL,oldrite;

	if (0 == rite->aplrank) {
		rite = temp(ravel(rite)); /* ensure rite is at least rank 1 */
		axis = indxorg; /* with corresponding default axis */
	}
	left = comexpa(left,rite,&axis,&axicnt,&botcnt,&topcnt);
	if (NULL != left) left = perm(idyadic(ine,temp(left),iscalar(0)));
	if (NULL == left) return(errstop(0,left,rite,NULL));
	if (left->aplcount == 0) {
		axicnt = 0;
		axis = (rite->aplrank) ? rite->aplrank : 1;
	}
	else {
		i = ivalue(ireduce(iplus,&identity,left,indxorg)); /* count 1s */
		if (axicnt != i && rite->aplcount > 1)
			if (axicnt == 1)
				rite = expanf(i,axicnt,axis,botcnt,topcnt,rite);
			else return(errstop(30,temp(left),rite,out));
	}
	if (NULL == (out = comexpb(rite,axis,(axicnt=left->aplcount),botcnt,
		topcnt,&datatyp))) return(errstop(0,temp(left),rite,out));
	if (out->aplcount) /* If not empty, call expane to copy data */
		expane(left,rite,out,datatyp,axicnt,botcnt,topcnt);
	return(errstop(0,temp(left),rite,out));
}
[ RETURN TO DIRECTORY ]