/* Copyright (C) 1993 by Thomas Glen Smith. All Rights Reserved. */
/* execdyat APL2 V1.0.0 ************************************************
* Called from execdyam and execdyal when the function is scalar dyadic *
* and either of the arguments left or rite are nested. *
***********************************************************************/
#define INCLUDES APLCB+FUNSTRUC
#include "includes.h"
Aplcb execdyat(pfun,left,rite,subrtne)
void *pfun; /* Function structure - see funstruc.h. */
Aplcb left,rite; /* One or both are nested. */
Aplcb (*subrtne)(void *, Aplcb, Aplcb); /* Handles unnested dyadic. */
{
Aplnest; Dyadicm; Errstop; Perm;
extern int aplerr;
int i,leftinc,lefttemp,lefttype,riteinc,ritetemp,ritetype;
Aplcb *dataout, *leftptr, out, *riteptr;
void *wrk1,*wrk2,*wrk3;
if (!(left->aplflags & APLAPL)) left = aplnest(left);
if (!(rite->aplflags & APLAPL)) rite = aplnest(rite);
wrk1 = &dataout;
wrk2 = &leftptr;
wrk3 = &riteptr;
out=dyadicm(left,rite,wrk1,wrk2,wrk3,
&leftinc,&riteinc,APLAPL); /* go build APLCB */
if (aplerr) return(NULL);
if (out->aplcount==0) return(errstop(0,left,rite,out));
if (lefttemp = left->aplflags & APLTEMP) left->aplflags -= APLTEMP;
if (ritetemp = rite->aplflags & APLTEMP) rite->aplflags -= APLTEMP;
for (i=out->aplcount; i > 0 && aplerr == 0; i--) {
*dataout++ = perm((*subrtne)(pfun,*leftptr,*riteptr));
leftptr += leftinc;
riteptr += riteinc;
}
left->aplflags += lefttemp;
rite->aplflags += ritetemp;
return(errstop(0,left,rite,out));
}