ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/calexpr.c
(Generate patch)

Comparing ray/src/common/calexpr.c (file contents):
Revision 2.20 by greg, Wed Mar 5 16:16:52 2003 UTC vs.
Revision 2.49 by greg, Mon Feb 26 18:16:35 2024 UTC

# Line 19 | Line 19 | static const char      RCSid[] = "$Id$";
19  
20   #include "copyright.h"
21  
22 #include  <stdio.h>
23
22   #include  <ctype.h>
25
23   #include  <errno.h>
27
24   #include  <math.h>
29
25   #include  <stdlib.h>
26  
27 + #include  "rtmisc.h"
28 + #include  "rtio.h"
29 + #include  "rterror.h"
30   #include  "calcomp.h"
31  
32   #define  MAXLINE        256             /* maximum line length */
33  
34   #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
35  
36 < #define  isdecimal(c)   (isdigit(c) || (c) == '.')
36 > #define  isdecimal(c)   (isdigit(c) | ((c) == '.'))
37  
38 < static double  euminus(), eargument(), enumber();
41 < static double  echannel();
42 < static double  eadd(), esubtr(), emult(), edivi(), epow();
43 < static double  ebotch();
38 > #define  envalue(ep)    ((ep)->type==NUM ? (ep)->v.num : evalue(ep))
39  
40 + static double  euminus(EPNODE *), enumber(EPNODE *);
41 + static double  echannel(EPNODE *);
42 + static double  eadd(EPNODE *), esubtr(EPNODE *),
43 +               emult(EPNODE *), edivi(EPNODE *),
44 +               epow(EPNODE *);
45 + static double  ebotch(EPNODE *);
46 +
47   unsigned int  esupport =                /* what to support */
48 <                E_VARIABLE | E_FUNCTION | E_REDEFW;
48 >                E_VARIABLE | E_FUNCTION ;
49  
50 + int  eofc = 0;                          /* optional end-of-file character */
51   int  nextc;                             /* lookahead character */
52  
53 < double  (*eoper[])() = {                /* expression operations */
53 > double  (*eoper[])(EPNODE *) = {        /* expression operations */
54          ebotch,
55          evariable,
56          enumber,
# Line 82 | Line 85 | static int  linepos;                   /* position in buffer */
85  
86  
87   EPNODE *
88 < eparse(expr)                    /* parse an expression string */
89 < char  *expr;
88 > eparse(                 /* parse an expression string */
89 >    char  *expr
90 > )
91   {
92      EPNODE  *ep;
93  
# Line 97 | Line 101 | char  *expr;
101  
102  
103   double
104 < eval(expr)                      /* evaluate an expression string */
105 < char  *expr;
104 > eval(                   /* evaluate an expression string */
105 >    char  *expr
106 > )
107   {
108 <    register EPNODE  *ep;
108 >    int  prev_support = esupport;
109 >    EPNODE  *ep;
110      double  rval;
111  
112 +    esupport &= ~E_RCONST;      /* don't bother reducing constant expr */
113      ep = eparse(expr);
114 +    esupport = prev_support;    /* as you were */
115      rval = evalue(ep);
116 <    epfree(ep);
116 >    epfree(ep,1);
117      return(rval);
118   }
119  
120  
121   int
122 < epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
123 < register EPNODE  *ep1, *ep2;
122 > epcmp(                  /* compare two expressions for equivalence */
123 >    EPNODE  *ep1,
124 >    EPNODE  *ep2
125 > )
126   {
127          double  d;
128  
# Line 128 | Line 138 | register EPNODE  *ep1, *ep2;
138                  if (ep2->v.num == 0)
139                          return(ep1->v.num != 0);
140                  d = ep1->v.num / ep2->v.num;
141 <                return(d > 1.000000000001 | d < 0.999999999999);
141 >                return((d > 1.000000000001) | (d < 0.999999999999));
142  
143          case CHAN:
144          case ARG:
# Line 138 | Line 148 | register EPNODE  *ep1, *ep2;
148          case ':':
149                  return(epcmp(ep1->v.kid->sibling, ep2->v.kid->sibling));
150  
151 <        case TICK:
151 >        case CLKT:
152          case SYM:                       /* should never get this one */
153                  return(0);
154  
# Line 159 | Line 169 | register EPNODE  *ep1, *ep2;
169  
170  
171   void
172 < epfree(epar)                    /* free a parse tree */
173 < register EPNODE  *epar;
172 > epfree(                 /* free a parse tree */
173 >    EPNODE       *epar,
174 >    int         frep
175 > )
176   {
177 <    register EPNODE  *ep;
177 >    EPNODE      *ep;
178  
179      switch (epar->type) {
180  
# Line 177 | Line 189 | register EPNODE         *epar;
189          case NUM:
190          case CHAN:
191          case ARG:
192 <        case TICK:
192 >        case CLKT:
193              break;
194  
195          default:
196 <            while ((ep = epar->v.kid) != NULL) {
197 <                epar->v.kid = ep->sibling;
198 <                epfree(ep);
199 <            }
196 >            if (epar->nkids < 0) {
197 >                ep = epar->v.kid - epar->nkids;
198 >                while (ep > epar->v.kid)
199 >                        epfree(--ep, 0);
200 >                efree(ep);      /* free array space */
201 >            } else
202 >                while ((ep = epar->v.kid) != NULL) {
203 >                    epar->v.kid = ep->sibling;
204 >                    epfree(ep, 1);
205 >                }
206              break;
207  
208      }
209 +    if (frep)
210 +        efree(epar);
211 + }
212  
213 <    efree((char *)epar);
213 >
214 > static void
215 > epflatten(                      /* flatten hierarchies for '+', '*' */
216 >        EPNODE *epar
217 > )
218 > {
219 >    EPNODE      *ep;
220 >
221 >    if (epar->nkids < 0)        /* can't handle array allocations */
222 >        return;
223 >
224 >    for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
225 >        while (ep->type == epar->type && ep->nkids > 0) {
226 >            EPNODE      *ep1 = ep->v.kid;
227 >            while (ep1->sibling != NULL)
228 >                ep1 = ep1->sibling;
229 >            ep1->sibling = ep->sibling;
230 >            epar->nkids += ep->nkids - 1;
231 >            ep1 = ep->v.kid;
232 >            *ep = *ep1;
233 >            efree(ep1);         /* not epfree()! */
234 >        }
235   }
236  
237 <                                /* the following used to be a switch */
238 < static double
239 < eargument(ep)
240 < EPNODE  *ep;
237 >
238 > void
239 > epoptimize(                     /* flatten operations, lists -> arrays */
240 >        EPNODE  *epar
241 > )
242   {
243 <    return(argument(ep->v.chan));
243 >    EPNODE      *ep;
244 >
245 >    if ((epar->type == '+') | (epar->type == '*'))
246 >        epflatten(epar);        /* flatten associative operations */
247 >
248 >    if (epar->nkids)            /* do children if any */
249 >        for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
250 >            epoptimize(ep);
251 >
252 >    if (epar->nkids > 4) {      /* make list into array if > 4 kids */
253 >        int     n = 1;
254 >        epar->v.kid = (EPNODE *)erealloc(epar->v.kid,
255 >                                        sizeof(EPNODE)*epar->nkids);
256 >        while (n < epar->nkids) {
257 >            ep = epar->v.kid[n-1].sibling;
258 >            epar->v.kid[n] = *ep;
259 >            efree(ep);          /* not epfree()! */
260 >            epar->v.kid[n-1].sibling = epar->v.kid + n;
261 >            n++;
262 >        }
263 >        epar->nkids = -n;
264 >    }
265   }
266  
267 +                                /* the following used to be a switch */
268   static double
269 < enumber(ep)
270 < EPNODE  *ep;
269 > enumber(
270 >    EPNODE      *ep
271 > )
272   {
273      return(ep->v.num);
274   }
275  
276   static double
277 < euminus(ep)
278 < EPNODE  *ep;
277 > euminus(
278 >    EPNODE      *ep
279 > )
280   {
281 <    register EPNODE  *ep1 = ep->v.kid;
281 >    EPNODE  *ep1 = ep->v.kid;
282  
283      return(-evalue(ep1));
284   }
285  
286   static double
287 < echannel(ep)
288 < EPNODE  *ep;
287 > echannel(
288 >    EPNODE      *ep
289 > )
290   {
291      return(chanvalue(ep->v.chan));
292   }
293  
294   static double
295 < eadd(ep)
296 < EPNODE  *ep;
295 > eadd(
296 >    EPNODE      *ep
297 > )
298   {
299 <    register EPNODE  *ep1 = ep->v.kid;
299 >    double  sum = 0;
300 >    EPNODE  *ep1 = ep->v.kid;
301  
302 <    return(evalue(ep1) + evalue(ep1->sibling));
302 >    do
303 >        sum += envalue(ep1);
304 >    while ((ep1 = ep1->sibling) != NULL);
305 >
306 >    return(sum);
307   }
308  
309   static double
310 < esubtr(ep)
311 < EPNODE  *ep;
310 > esubtr(
311 >    EPNODE      *ep
312 > )
313   {
314 <    register EPNODE  *ep1 = ep->v.kid;
314 >    EPNODE  *ep1 = ep->v.kid;
315 >    EPNODE  *ep2 = ep1->sibling;
316  
317 <    return(evalue(ep1) - evalue(ep1->sibling));
317 >    return(envalue(ep1) - envalue(ep2));
318   }
319  
320   static double
321 < emult(ep)
322 < EPNODE  *ep;
321 > emult(
322 >    EPNODE      *ep
323 > )
324   {
325 <    register EPNODE  *ep1 = ep->v.kid;
325 >    double  prod = 1;
326 >    EPNODE  *ep1 = ep->v.kid;
327  
328 <    return(evalue(ep1) * evalue(ep1->sibling));
328 >    do
329 >        prod *= envalue(ep1);
330 >    while ((ep1 = ep1->sibling) != NULL);
331 >
332 >    return(prod);
333   }
334  
335   static double
336 < edivi(ep)
337 < EPNODE  *ep;
336 > edivi(
337 >    EPNODE      *ep
338 > )
339   {
340 <    register EPNODE  *ep1 = ep->v.kid;
341 <    double  d;
340 >    EPNODE  *ep1 = ep->v.kid;
341 >    double  den = evalue(ep1->sibling);
342  
343 <    d = evalue(ep1->sibling);
261 <    if (d == 0.0) {
343 >    if (den == 0.0) {
344          wputs("Division by zero\n");
345          errno = ERANGE;
346          return(0.0);
347      }
348 <    return(evalue(ep1) / d);
348 >    return(envalue(ep1) / den);
349   }
350  
351   static double
352 < epow(ep)
353 < EPNODE  *ep;
352 > epow(
353 >    EPNODE      *ep
354 > )
355   {
356 <    register EPNODE  *ep1 = ep->v.kid;
356 >    EPNODE  *ep1 = ep->v.kid;
357      double  d;
358      int  lasterrno;
359  
360      lasterrno = errno;
361      errno = 0;
362      d = pow(evalue(ep1), evalue(ep1->sibling));
363 < #ifdef  IEEE
364 <    if (!finite(d))
365 <        errno = EDOM;
363 > #ifdef  isnan
364 >    if (errno == 0) {
365 >        if (isnan(d))
366 >            errno = EDOM;
367 >        else if (isinf(d))
368 >            errno = ERANGE;
369 >    }
370   #endif
371 <    if (errno == EDOM || errno == ERANGE) {
371 >    if ((errno == EDOM) | (errno == ERANGE)) {
372          wputs("Illegal power\n");
373          return(0.0);
374      }
# Line 290 | Line 377 | EPNODE *ep;
377   }
378  
379   static double
380 < ebotch(ep)
381 < EPNODE  *ep;
380 > ebotch(
381 >    EPNODE      *ep
382 > )
383   {
384      eputs("Bad expression!\n");
385      quit(1);
386 +        return 0.0; /* pro forma return */
387   }
388  
389  
390   EPNODE *
391 < ekid(ep, n)                     /* return pointer to a node's nth kid */
392 < register EPNODE  *ep;
393 < register int  n;
391 > ekid(                   /* return pointer to a node's nth kid */
392 >    EPNODE       *ep,
393 >    int  n
394 > )
395   {
396 <
397 <    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
398 <        if (--n < 0)
399 <            break;
400 <
396 >    if (ep->nkids < 0) {        /* allocated array? */
397 >        if (n >= -ep->nkids)
398 >            return(NULL);
399 >        return(ep->v.kid + n);
400 >    }
401 >    ep = ep->v.kid;             /* else get from list */
402 >    while (n-- > 0)
403 >        if ((ep = ep->sibling) == NULL)
404 >                break;
405      return(ep);
406   }
407  
408  
315 int
316 nekids(ep)                      /* return # of kids for node ep */
317 register EPNODE  *ep;
318 {
319    register int  n = 0;
320
321    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
322        n++;
323
324    return(n);
325 }
326
327
409   void
410 < initfile(fp, fn, ln)            /* prepare input file */
411 < FILE  *fp;
412 < char  *fn;
413 < int  ln;
410 > initfile(               /* prepare input file */
411 >    FILE  *fp,
412 >    char  *fn,
413 >    int  ln
414 > )
415   {
416      static char  inpbuf[MAXLINE];
417  
# Line 344 | Line 426 | int  ln;
426  
427  
428   void
429 < initstr(s, fn, ln)              /* prepare input string */
430 < char  *s;
431 < char  *fn;
432 < int  ln;
429 > initstr(                /* prepare input string */
430 >    char  *s,
431 >    char  *fn,
432 >    int  ln
433 > )
434   {
435      infp = NULL;
436      infile = fn;
# Line 359 | Line 442 | int  ln;
442  
443  
444   void
445 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
446 < char  **fnp;
447 < int  *lnp;
448 < char  **spp;
449 < FILE  **fpp;
445 > getscanpos(     /* return current scan position */
446 >    char  **fnp,
447 >    int  *lnp,
448 >    char  **spp,
449 >    FILE  **fpp
450 > )
451   {
452      if (fnp != NULL) *fnp = infile;
453      if (lnp != NULL) *lnp = lineno;
# Line 373 | Line 457 | FILE  **fpp;
457  
458  
459   int
460 < scan()                          /* scan next character, return literal next */
460 > scan(void)              /* scan next character, return literal next */
461   {
462 <    register int  lnext = 0;
462 >    int  lnext = 0;
463  
464      do {
465          if (linbuf[linepos] == '\0')
# Line 390 | Line 474 | scan()                         /* scan next character, return literal next
474              nextc = linbuf[linepos++];
475          if (!lnext)
476                  lnext = nextc;
477 +        if (nextc == eofc) {
478 +                nextc = EOF;
479 +                break;
480 +        }
481          if (nextc == '{') {
482              scan();
483              while (nextc != '}')
# Line 405 | Line 493 | scan()                         /* scan next character, return literal next
493  
494  
495   char *
496 < long2ascii(l)                         /* convert long to ascii */
497 < long  l;
496 > long2ascii(                           /* convert long to ascii */
497 >    long  l
498 > )
499   {
500      static char  buf[16];
501 <    register char  *cp;
501 >    char  *cp;
502      int  neg = 0;
503  
504      if (l == 0)
# Line 431 | Line 520 | long  l;
520  
521  
522   void
523 < syntax(err)                     /* report syntax error and quit */
524 < char  *err;
523 > syntax(                 /* report syntax error and quit */
524 >    char  *err
525 > )
526   {
527 <    register int  i;
527 >    int  i;
528  
529 <    if (infile != NULL || lineno != 0) {
529 >    if ((infile != NULL) | (lineno != 0)) {
530          if (infile != NULL) eputs(infile);
531          if (lineno != 0) {
532              eputs(infile != NULL ? ", line " : "line ");
# Line 457 | Line 547 | char  *err;
547  
548  
549   void
550 < addekid(ep, ekid)                       /* add a child to ep */
551 < register EPNODE  *ep;
552 < EPNODE  *ekid;
550 > addekid(                        /* add a child to ep */
551 >    EPNODE       *ep,
552 >    EPNODE      *ek
553 > )
554   {
555 +    if (ep->nkids < 0) {
556 +        eputs("Cannot add kid to EPNODE array\n");
557 +        quit(1);
558 +    }
559 +    ep->nkids++;
560      if (ep->v.kid == NULL)
561 <        ep->v.kid = ekid;
561 >        ep->v.kid = ek;
562      else {
563          for (ep = ep->v.kid; ep->sibling != NULL; ep = ep->sibling)
564              ;
565 <        ep->sibling = ekid;
565 >        ep->sibling = ek;
566      }
567 <    ekid->sibling = NULL;
567 >    ek->sibling = NULL;         /* shouldn't be necessary */
568   }
569  
570  
571   char *
572 < getname()                       /* scan an identifier */
572 > getname(void)                   /* scan an identifier */
573   {
574 <    static char  str[MAXWORD+1];
575 <    register int  i, lnext;
574 >    static char  str[RMAXWORD+1];
575 >    int  i, lnext;
576  
577      lnext = nextc;
578 <    for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
578 >    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
579          str[i] = lnext;
580      str[i] = '\0';
581      while (isid(lnext))         /* skip rest of name */
# Line 490 | Line 586 | getname()                      /* scan an identifier */
586  
587  
588   int
589 < getinum()                       /* scan a positive integer */
589 > getinum(void)                   /* scan a positive integer */
590   {
591 <    register int  n, lnext;
591 >    int  n, lnext;
592  
593      n = 0;
594      lnext = nextc;
# Line 505 | Line 601 | getinum()                      /* scan a positive integer */
601  
602  
603   double
604 < getnum()                        /* scan a positive float */
604 > getnum(void)                    /* scan a positive float */
605   {
606 <    register int  i, lnext;
607 <    char  str[MAXWORD+1];
606 >    int  i, lnext;
607 >    char  str[RMAXWORD+1];
608  
609      i = 0;
610      lnext = nextc;
611 <    while (isdigit(lnext) && i < MAXWORD) {
611 >    while (isdigit(lnext) && i < RMAXWORD) {
612          str[i++] = lnext;
613          lnext = scan();
614      }
615 <    if (lnext == '.' && i < MAXWORD) {
615 >    if ((lnext == '.') & (i < RMAXWORD)) {
616          str[i++] = lnext;
617          lnext = scan();
618          if (i == 1 && !isdigit(lnext))
619              syntax("badly formed number");
620 <        while (isdigit(lnext) && i < MAXWORD) {
620 >        while (isdigit(lnext) && i < RMAXWORD) {
621              str[i++] = lnext;
622              lnext = scan();
623          }
624      }
625 <    if ((lnext == 'e' | lnext == 'E') && i < MAXWORD) {
625 >    if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
626          str[i++] = lnext;
627          lnext = scan();
628 <        if ((lnext == '-' | lnext == '+') && i < MAXWORD) {
628 >        if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
629              str[i++] = lnext;
630              lnext = scan();
631          }
632          if (!isdigit(lnext))
633              syntax("missing exponent");
634 <        while (isdigit(lnext) && i < MAXWORD) {
634 >        while (isdigit(lnext) && i < RMAXWORD) {
635              str[i++] = lnext;
636              lnext = scan();
637          }
# Line 547 | Line 643 | getnum()                       /* scan a positive float */
643  
644  
645   EPNODE *
646 < getE1()                         /* E1 -> E1 ADDOP E2 */
646 > getE1(void)                     /* E1 -> E1 ADDOP E2 */
647                                  /*       E2 */
648   {
649 <    register EPNODE  *ep1, *ep2;
649 >    EPNODE  *ep1, *ep2;
650  
651      ep1 = getE2();
652 <    while (nextc == '+' || nextc == '-') {
652 >    while ((nextc == '+') | (nextc == '-')) {
653          ep2 = newnode();
654          ep2->type = nextc;
655          scan();
656          addekid(ep2, ep1);
657          addekid(ep2, getE2());
658          if (esupport&E_RCONST &&
659 <                        ep1->type == NUM && ep1->sibling->type == NUM)
659 >                        (ep1->type == NUM) & (ep1->sibling->type == NUM))
660                  ep2 = rconst(ep2);
661          ep1 = ep2;
662      }
# Line 569 | Line 665 | getE1()                                /* E1 -> E1 ADDOP E2 */
665  
666  
667   EPNODE *
668 < getE2()                         /* E2 -> E2 MULOP E3 */
668 > getE2(void)                     /* E2 -> E2 MULOP E3 */
669                                  /*       E3 */
670   {
671 <    register EPNODE  *ep1, *ep2;
671 >    EPNODE  *ep1, *ep2;
672  
673      ep1 = getE3();
674 <    while (nextc == '*' || nextc == '/') {
674 >    while ((nextc == '*') | (nextc == '/')) {
675          ep2 = newnode();
676          ep2->type = nextc;
677          scan();
678          addekid(ep2, ep1);
679          addekid(ep2, getE3());
680 <        if (esupport&E_RCONST &&
681 <                        ep1->type == NUM && ep1->sibling->type == NUM)
682 <                ep2 = rconst(ep2);
680 >        if (esupport&E_RCONST) {
681 >                EPNODE  *ep3 = ep1->sibling;
682 >                if ((ep1->type == NUM) & (ep3->type == NUM)) {
683 >                        ep2 = rconst(ep2);
684 >                } else if (ep3->type == NUM) {
685 >                        if (ep2->type == '/') {
686 >                                if (ep3->v.num == 0)
687 >                                        syntax("divide by zero constant");
688 >                                ep2->type = '*';        /* for speed */
689 >                                ep3->v.num = 1./ep3->v.num;
690 >                        } else if (ep3->v.num == 0) {
691 >                                ep1->sibling = NULL;    /* (E2 * 0) */
692 >                                epfree(ep2,1);
693 >                                ep2 = ep3;
694 >                        }
695 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
696 >                        epfree(ep3,1);          /* (0 * E3) or (0 / E3) */
697 >                        ep1->sibling = NULL;
698 >                        efree(ep2);
699 >                        ep2 = ep1;
700 >                }
701 >        }
702          ep1 = ep2;
703      }
704      return(ep1);
# Line 591 | Line 706 | getE2()                                /* E2 -> E2 MULOP E3 */
706  
707  
708   EPNODE *
709 < getE3()                         /* E3 -> E4 ^ E3 */
709 > getE3(void)                     /* E3 -> E4 ^ E3 */
710                                  /*       E4 */
711   {
712 <    register EPNODE  *ep1, *ep2;
712 >        EPNODE  *ep1, *ep2;
713  
714 <    ep1 = getE4();
715 <    if (nextc == '^') {
714 >        ep1 = getE4();
715 >        if (nextc != '^')
716 >                return(ep1);
717          ep2 = newnode();
718          ep2->type = nextc;
719          scan();
720          addekid(ep2, ep1);
721          addekid(ep2, getE3());
722 <        if (esupport&E_RCONST &&
723 <                        ep1->type == NUM && ep1->sibling->type == NUM)
724 <                ep2 = rconst(ep2);
722 >        if (esupport&E_RCONST) {
723 >                EPNODE  *ep3 = ep1->sibling;
724 >                if ((ep1->type == NUM) & (ep3->type == NUM)) {
725 >                        ep2 = rconst(ep2);
726 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
727 >                        epfree(ep3,1);          /* (0 ^ E3) */
728 >                        ep1->sibling = NULL;
729 >                        efree(ep2);
730 >                        ep2 = ep1;
731 >                } else if ((ep3->type == NUM && ep3->v.num == 0) |
732 >                                (ep1->type == NUM && ep1->v.num == 1)) {
733 >                        epfree(ep2,1);          /* (E4 ^ 0) or (1 ^ E3) */
734 >                        ep2 = newnode();
735 >                        ep2->type = NUM;
736 >                        ep2->v.num = 1;
737 >                } else if (ep3->type == NUM && ep3->v.num == 1) {
738 >                        efree(ep3);     /* (E4 ^ 1) */
739 >                        ep1->sibling = NULL;
740 >                        efree(ep2);
741 >                        ep2 = ep1;
742 >                }
743 >        }
744          return(ep2);
610    }
611    return(ep1);
745   }
746  
747  
748   EPNODE *
749 < getE4()                         /* E4 -> ADDOP E5 */
749 > getE4(void)                     /* E4 -> ADDOP E5 */
750                                  /*       E5 */
751   {
752 <    register EPNODE  *ep1, *ep2;
752 >    EPNODE  *ep1, *ep2;
753  
754      if (nextc == '-') {
755          scan();
# Line 626 | Line 759 | getE4()                                /* E4 -> ADDOP E5 */
759                  return(ep2);
760          }
761          if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
762 <            efree((char *)ep2);
763 <            return(ep2->v.kid);
762 >            ep1 = ep2->v.kid;
763 >            efree(ep2);
764 >            return(ep1);
765          }
766          ep1 = newnode();
767          ep1->type = UMINUS;
# Line 641 | Line 775 | getE4()                                /* E4 -> ADDOP E5 */
775  
776  
777   EPNODE *
778 < getE5()                         /* E5 -> (E1) */
778 > getE5(void)                     /* E5 -> (E1) */
779                                  /*       VAR */
780                                  /*       NUM */
781                                  /*       $N */
782                                  /*       FUNC(E1,..) */
783                                  /*       ARG */
784   {
785 <    int  i;
786 <    char  *nam;
787 <    register EPNODE  *ep1, *ep2;
785 >        int      i;
786 >        char  *nam;
787 >        EPNODE  *ep1, *ep2;
788  
789 <    if (nextc == '(') {
790 <        scan();
791 <        ep1 = getE1();
792 <        if (nextc != ')')
793 <            syntax("')' expected");
794 <        scan();
795 <        return(ep1);
662 <    }
663 <
664 <    if (esupport&E_INCHAN && nextc == '$') {
665 <        scan();
666 <        ep1 = newnode();
667 <        ep1->type = CHAN;
668 <        ep1->v.chan = getinum();
669 <        return(ep1);
670 <    }
671 <
672 <  if (esupport&(E_VARIABLE|E_FUNCTION) &&
673 <                (isalpha(nextc) || nextc == CNTXMARK)) {
674 <      nam = getname();
675 <      ep1 = NULL;
676 <      if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
677 <                        && curfunc != NULL)
678 <            for (i = 1, ep2 = curfunc->v.kid->sibling;
679 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
680 <                if (!strcmp(ep2->v.name, nam)) {
681 <                    ep1 = newnode();
682 <                    ep1->type = ARG;
683 <                    ep1->v.chan = i;
684 <                    break;
685 <                }
686 <        if (ep1 == NULL) {
687 <            ep1 = newnode();
688 <            ep1->type = VAR;
689 <            ep1->v.ln = varinsert(nam);
789 >        if (nextc == '(') {
790 >                scan();
791 >                ep1 = getE1();
792 >                if (nextc != ')')
793 >                        syntax("')' expected");
794 >                scan();
795 >                return(ep1);
796          }
797 <        if (esupport&E_FUNCTION && nextc == '(') {
692 <            ep2 = newnode();
693 <            ep2->type = FUNC;
694 <            addekid(ep2, ep1);
695 <            ep1 = ep2;
696 <            do {
797 >        if (esupport&E_INCHAN && nextc == '$') {
798                  scan();
799 <                addekid(ep1, getE1());
800 <            } while (nextc == ',');
801 <            if (nextc != ')')
802 <                syntax("')' expected");
803 <            scan();
804 <        } else if (!(esupport&E_VARIABLE))
805 <            syntax("'(' expected");
806 <        if (esupport&E_RCONST && isconstvar(ep1))
807 <            ep1 = rconst(ep1);
808 <        return(ep1);
809 <    }
810 <
811 <    if (isdecimal(nextc)) {
812 <        ep1 = newnode();
813 <        ep1->type = NUM;
814 <        ep1->v.num = getnum();
815 <        return(ep1);
816 <    }
817 <    syntax("unexpected character");
799 >                ep1 = newnode();
800 >                ep1->type = CHAN;
801 >                ep1->v.chan = getinum();
802 >                return(ep1);
803 >        }
804 >        if (esupport&(E_VARIABLE|E_FUNCTION) &&
805 >                        (isalpha(nextc) | (nextc == CNTXMARK))) {
806 >                nam = getname();
807 >                ep1 = NULL;
808 >                if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
809 >                                && curfunc != NULL)
810 >                        for (i = 1, ep2 = curfunc->v.kid->sibling;
811 >                                        ep2 != NULL; i++, ep2 = ep2->sibling)
812 >                                if (!strcmp(ep2->v.name, nam)) {
813 >                                        ep1 = newnode();
814 >                                        ep1->type = ARG;
815 >                                        ep1->v.chan = i;
816 >                                        break;
817 >                                }
818 >                if (ep1 == NULL) {
819 >                        ep1 = newnode();
820 >                        ep1->type = VAR;
821 >                        ep1->v.ln = varinsert(nam);
822 >                }
823 >                if (esupport&E_FUNCTION && nextc == '(') {
824 >                        ep2 = newnode();
825 >                        ep2->type = FUNC;
826 >                        addekid(ep2, ep1);
827 >                        ep1 = ep2;
828 >                        do {
829 >                                scan();
830 >                                addekid(ep1, getE1());
831 >                        } while (nextc == ',');
832 >                        if (nextc != ')')
833 >                                syntax("')' expected");
834 >                        scan();
835 >                } else if (!(esupport&E_VARIABLE))
836 >                        syntax("'(' expected");
837 >                if (esupport&E_RCONST && isconstvar(ep1))
838 >                        ep1 = rconst(ep1);
839 >                return(ep1);
840 >        }
841 >        if (isdecimal(nextc)) {
842 >                ep1 = newnode();
843 >                ep1->type = NUM;
844 >                ep1->v.num = getnum();
845 >                return(ep1);
846 >        }
847 >        syntax("unexpected character");
848 >        return NULL; /* pro forma return */
849   }
850  
851  
852   EPNODE *
853 < rconst(epar)                    /* reduce a constant expression */
854 < register EPNODE  *epar;
853 > rconst(                 /* reduce a constant expression */
854 >    EPNODE       *epar
855 > )
856   {
857 <    register EPNODE  *ep;
857 >    EPNODE  *ep;
858  
859      ep = newnode();
860      ep->type = NUM;
861      errno = 0;
862      ep->v.num = evalue(epar);
863 <    if (errno == EDOM || errno == ERANGE)
863 >    if ((errno == EDOM) | (errno == ERANGE))
864          syntax("bad constant expression");
865 <    epfree(epar);
865 >    epfree(epar,1);
866  
867      return(ep);
868   }
869  
870  
871   int
872 < isconstvar(ep)                  /* is ep linked to a constant expression? */
873 < register EPNODE  *ep;
872 > isconstvar(                     /* is ep linked to a constant expression? */
873 >    EPNODE       *ep
874 > )
875   {
876 <    register EPNODE  *ep1;
876 >    EPNODE  *ep1;
877  
878      if (esupport&E_FUNCTION && ep->type == FUNC) {
879          if (!isconstfun(ep->v.kid))
# Line 761 | Line 895 | register EPNODE         *ep;
895  
896  
897   int
898 < isconstfun(ep)                  /* is ep linked to a constant function? */
899 < register EPNODE  *ep;
898 > isconstfun(                     /* is ep linked to a constant function? */
899 >    EPNODE       *ep
900 > )
901   {
902 <    register EPNODE  *dp;
903 <    register LIBR  *lp;
902 >    EPNODE  *dp;
903 >    LIBR  *lp;
904  
905      if (ep->type != VAR)
906          return(0);
907 <    if ((dp = ep->v.ln->def) != NULL)
907 >    if ((dp = ep->v.ln->def) != NULL) {
908          if (dp->v.kid->type == FUNC)
909              return(dp->type == ':');
910          else
911              return(0);          /* don't identify masked library functions */
912 +    }
913      if ((lp = ep->v.ln->lib) != NULL)
914          return(lp->atyp == ':');
915      return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines