--- ray/src/common/calfunc.c 2019/03/04 18:16:18 2.19 +++ ray/src/common/calfunc.c 2021/09/16 23:48:47 2.26 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: calfunc.c,v 2.19 2019/03/04 18:16:18 greg Exp $"; +static const char RCSid[] = "$Id: calfunc.c,v 2.26 2021/09/16 23:48:47 greg Exp $"; #endif /* * calfunc.c - routines for calcomp using functions. @@ -40,7 +40,9 @@ static double libfunc(char *fname, VARDEF *vp); #define MAXLIB 64 /* maximum number of library functions */ #endif -static double l_if(char *), l_select(char *), l_rand(char *); +static double l_if(char *), l_select(char *); +static double l_min(char *), l_max(char *); +static double l_rand(char *); static double l_floor(char *), l_ceil(char *); static double l_sqrt(char *); static double l_sin(char *), l_cos(char *), l_tan(char *); @@ -60,6 +62,8 @@ static LIBR library[MAXLIB] = { { "if", 3, ':', l_if }, { "log", 1, ':', l_log }, { "log10", 1, ':', l_log10 }, + { "max", 1, ':', l_max }, + { "min", 1, ':', l_min }, { "rand", 1, ':', l_rand }, { "select", 1, ':', l_select }, { "sin", 1, ':', l_sin }, @@ -67,13 +71,13 @@ static LIBR library[MAXLIB] = { { "tan", 1, ':', l_tan }, }; -static int libsize = 16; +static int libsize = 18; #define resolve(ep) ((ep)->type==VAR?(ep)->v.ln:argf((ep)->v.chan)) int -fundefined( /* return # of arguments for function */ +fundefined( /* return # of req'd arguments for function */ char *fname ) { @@ -141,9 +145,13 @@ funset( /* set a library function */ ; if (cp == fname) return; - if (cp[-1] == CNTXMARK) + while (cp[-1] == CNTXMARK) { *--cp = '\0'; + if (cp == fname) return; + } if ((lp = liblookup(fname)) == NULL) { /* insert */ + if (fptr == NULL) + return; /* nothing! */ if (libsize >= MAXLIB) { eputs("Too many library functons!\n"); quit(1); @@ -195,11 +203,14 @@ argument(int n) /* return nth argument for active fu EPNODE *ep = NULL; double aval; + if (!n) /* asking for # arguments? */ + return((double)nargum()); + if (!actp | (--n < 0)) { eputs("Bad call to argument!\n"); quit(1); } - if ((n < AFLAGSIZ) & (actp->an >> n)) /* already computed? */ + if ((n < AFLAGSIZ) & actp->an >> n) /* already computed? */ return(actp->ap[n]); if (!actp->fun || !(ep = ekid(actp->fun, n+1))) { @@ -209,8 +220,8 @@ argument(int n) /* return nth argument for active fu } curact = actp->prev; /* previous context */ aval = evalue(ep); /* compute argument */ - curact = actp; /* push back context */ - if (n < ALISTSIZ) { /* save value if we can */ + curact = actp; /* put back calling context */ + if (n < ALISTSIZ) { /* save value if room */ actp->ap[n] = aval; actp->an |= 1L< nargum()-1) { + if (a1 < -.5 || n >= narg) { errno = EDOM; return(0.0); } + if (!n) /* asking max index? */ + return(narg-1); return(argument(n+1)); +} + + +static double +l_max(char *nm) /* general maximum function */ +{ + int n = nargum(); + double vmax = argument(1); + + while (--n) { + double v = argument(n); + if (vmax < v) + vmax = v; + } + return(vmax); +} + + +static double +l_min(char *nm) /* general minimum function */ +{ + int n = nargum(); + double vmin = argument(1); + + while (--n) { + double v = argument(n); + if (vmin > v) + vmin = v; + } + return(vmin); }