/* Copyright (C) 1993 by Thomas Glen Smith. All Rights Reserved. */
/* execdot APL2 V1.0.0 *************************************************
* Called from derived to handle inner product. Dottran sets *
* deriv_func to execdot. Derived calls the function specified in *
* deriv_func. *
***********************************************************************/
#define INCLUDES APLCHDEF+FUNSTRUC+APLDERIV+APLCB
#include "includes.h"
Aplcb execdot(dp,left,rite)
Aplderiv dp; /* function describing derived function */
Aplcb left,rite; /* left and right operands */
{
Errstop;
Execdota; Execdotc; Execdotd; Execdote; Execdotf; Execdotg;
Execfree; Pop;
extern int aplerr;
void *rfun;
Aplcb out=NULL;
int i,ltype,rtype,test;
test = (dp->deriv_left.sdp == NULL) ? 1 : 0; /* 1 if left nonscalar. */
test += (dp->deriv_rite.sdp == NULL) ? 2 : 0; /* 2 if rite nonscalar. */
switch (test) {
case 0: /* Both are scalar functions. */
ltype = left->aplflags & (APLMASK | APLAPL);
rtype = rite->aplflags & (APLMASK | APLAPL);
if ((ltype | rtype) & APLCHAR)
out = execdotd(left,rite,ltype,rtype,dp);
else if (ltype == rtype)
out = execdota(left,rite,ltype,
dp->deriv_left.sdp,dp->deriv_rite.sdp);
else out = execdotc(left,rite,ltype,rtype,
dp->deriv_left.sdp,dp->deriv_rite.sdp);
break;
case 1: /* left nonscalar, rite scalar. */
out = execdote(dp,left,rite);
break;
case 2: /* left scalar, rite nonscalar. */
out = execdotf(dp,left,rite);
break;
case 3: /* left nonscalar, rite nonscalar. */
out = execdotg(dp,left,rite);
break;
} /* End switch. */
if (aplerr == 0 && out == NULL)
return(errstop(78,left,rite,out));
return(out);
}