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

Comparing ray/src/common/calexpr.c (file contents):
Revision 2.30 by greg, Tue May 17 17:51:51 2005 UTC vs.
Revision 2.56 by greg, Sat Dec 6 16:39:20 2025 UTC

# Line 19 | Line 19 | static const char      RCSid[] = "$Id$";
19  
20   #include "copyright.h"
21  
22 #include  <stdio.h>
23 #include  <string.h>
22   #include  <ctype.h>
23   #include  <errno.h>
24   #include  <math.h>
# Line 35 | Line 33 | static const char      RCSid[] = "$Id$";
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(EPNODE *), eargument(EPNODE *), enumber(EPNODE *);
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 *),
# Line 92 | Line 92 | eparse(                        /* parse an expression string */
92      EPNODE  *ep;
93  
94      initstr(expr, NULL, 0);
95 <    curfunc = NULL;
95 >    ecurfunc = NULL;
96      ep = getE1();
97      if (nextc != EOF)
98 <        syntax("unexpected character");
98 >        esyntax("unexpected character");
99      return(ep);
100   }
101  
# Line 105 | Line 105 | 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(                  /* compare two expressions for equivalence */
123 <    register EPNODE  *ep1,
124 <    register EPNODE  *ep2
123 >    EPNODE  *ep1,
124 >    EPNODE  *ep2
125   )
126   {
127          double  d;
# Line 145 | Line 148 | epcmp(                 /* compare two expressions for equivalence */
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 167 | Line 170 | epcmp(                 /* compare two expressions for equivalence */
170  
171   void
172   epfree(                 /* free a parse tree */
173 <    register EPNODE      *epar
173 >    EPNODE       *epar,
174 >    int         frep
175   )
176   {
177 <    register EPNODE  *ep;
177 >    EPNODE      *ep;
178  
179      switch (epar->type) {
180  
# Line 185 | Line 189 | epfree(                        /* free a parse tree */
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 +    else
212 +        memset(epar, 0, sizeof(EPNODE));
213 + }
214  
215 <    efree((char *)epar);
215 >
216 > static void
217 > epflatten(                      /* flatten hierarchies for '+', '*' */
218 >        EPNODE *epar
219 > )
220 > {
221 >    EPNODE      *ep, *ep1;
222 >    double      combined;
223 >
224 >    if (epar->nkids <= 0)       /* can't handle array allocations */
225 >        return;
226 >
227 >    for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
228 >        while ((ep->type == epar->type) & (ep->nkids > 0)) {
229 >            ep1 = ep->v.kid;
230 >            while (ep1->sibling != NULL)
231 >                ep1 = ep1->sibling;
232 >            ep1->sibling = ep->sibling;
233 >            epar->nkids += ep->nkids - 1;
234 >            ep1 = ep->v.kid;
235 >            *ep = *ep1;
236 >            efree(ep1);         /* not epfree()! */
237 >        }
238 >    if (!(esupport & E_RCONST))
239 >        return;
240 >    ep1 = NULL;                 /* combine constants in sum/product */
241 >    for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
242 >        if (ep->type == NUM) {
243 >            if (ep1 == NULL) combined = (ep1 = ep)->v.num;
244 >            else if (epar->type == '+') combined += ep->v.num;
245 >            else /* epar->type=='*' */ combined *= ep->v.num;
246 >        }
247 >    if (ep1 == NULL)
248 >        return;
249 >    ep1->v.num = combined;      /* assumes commutative property, also */
250 >    while (ep1->sibling != NULL)
251 >        if (ep1->sibling->type == NUM) {
252 >            ep = ep1->sibling;
253 >            ep1->sibling = ep->sibling;
254 >            epar->nkids--;
255 >            efree(ep);          /* drop subsumed constant */
256 >        } else
257 >            ep1 = ep1->sibling;
258 >
259 >    if (epar->nkids == 1) {     /* late constant expression? */
260 >        ep = epar->v.kid;
261 >        *epar = *ep;
262 >        efree(ep);
263 >    }
264   }
265  
266 <                                /* the following used to be a switch */
267 < static double
268 < eargument(
269 <    EPNODE      *ep
266 >
267 > void
268 > epoptimize(                     /* flatten operations, lists -> arrays */
269 >        EPNODE  *epar
270   )
271   {
272 <    return(argument(ep->v.chan));
272 >    EPNODE      *ep;
273 >
274 >    if ((epar->type == '+') | (epar->type == '*'))
275 >        epflatten(epar);        /* flatten associative operations */
276 >
277 >    if (epar->nkids)            /* do children if any */
278 >        for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
279 >            epoptimize(ep);
280 >
281 >    if (epar->nkids > 4) {      /* make list into array if > 4 kids */
282 >        int     n = 1;
283 >        epar->v.kid = (EPNODE *)erealloc(epar->v.kid,
284 >                                        sizeof(EPNODE)*epar->nkids);
285 >        while (n < epar->nkids) {
286 >            ep = epar->v.kid[n-1].sibling;
287 >            epar->v.kid[n] = *ep;
288 >            efree(ep);          /* not epfree()! */
289 >            epar->v.kid[n-1].sibling = epar->v.kid + n;
290 >            n++;
291 >        }
292 >        epar->nkids = -n;
293 >    }
294   }
295  
296 +                                /* the following used to be a switch */
297   static double
298   enumber(
299      EPNODE      *ep
# Line 222 | Line 307 | euminus(
307      EPNODE      *ep
308   )
309   {
310 <    register EPNODE  *ep1 = ep->v.kid;
310 >    EPNODE  *ep1 = ep->v.kid;
311  
312      return(-evalue(ep1));
313   }
# Line 240 | Line 325 | eadd(
325      EPNODE      *ep
326   )
327   {
328 <    register EPNODE  *ep1 = ep->v.kid;
328 >    double  sum = 0;
329 >    EPNODE  *ep1 = ep->v.kid;
330  
331 <    return(evalue(ep1) + evalue(ep1->sibling));
331 >    do
332 >        sum += envalue(ep1);
333 >    while ((ep1 = ep1->sibling) != NULL);
334 >
335 >    return(sum);
336   }
337  
338   static double
# Line 250 | Line 340 | esubtr(
340      EPNODE      *ep
341   )
342   {
343 <    register EPNODE  *ep1 = ep->v.kid;
343 >    EPNODE  *ep1 = ep->v.kid;
344 >    EPNODE  *ep2 = ep1->sibling;
345  
346 <    return(evalue(ep1) - evalue(ep1->sibling));
346 >    return(envalue(ep1) - envalue(ep2));
347   }
348  
349   static double
# Line 260 | Line 351 | emult(
351      EPNODE      *ep
352   )
353   {
354 <    register EPNODE  *ep1 = ep->v.kid;
354 >    double  prod = 1;
355 >    EPNODE  *ep1 = ep->v.kid;
356  
357 <    return(evalue(ep1) * evalue(ep1->sibling));
357 >    do
358 >        prod *= envalue(ep1);
359 >    while ((ep1 = ep1->sibling) != NULL);
360 >
361 >    return(prod);
362   }
363  
364   static double
# Line 270 | Line 366 | edivi(
366      EPNODE      *ep
367   )
368   {
369 <    register EPNODE  *ep1 = ep->v.kid;
370 <    double  d;
369 >    EPNODE  *ep1 = ep->v.kid;
370 >    double  den = evalue(ep1->sibling);
371  
372 <    d = evalue(ep1->sibling);
277 <    if (d == 0.0) {
372 >    if (den == 0.0) {
373          wputs("Division by zero\n");
374          errno = ERANGE;
375          return(0.0);
376      }
377 <    return(evalue(ep1) / d);
377 >    return(envalue(ep1) / den);
378   }
379  
380   static double
# Line 287 | Line 382 | epow(
382      EPNODE      *ep
383   )
384   {
385 <    register EPNODE  *ep1 = ep->v.kid;
385 >    EPNODE  *ep1 = ep->v.kid;
386      double  d;
387      int  lasterrno;
388  
389      lasterrno = errno;
390      errno = 0;
391      d = pow(evalue(ep1), evalue(ep1->sibling));
392 < #ifdef  IEEE
393 <    if (!finite(d))
394 <        errno = EDOM;
392 > #ifdef  isnan
393 >    if (errno == 0) {
394 >        if (isnan(d))
395 >            errno = EDOM;
396 >        else if (isinf(d))
397 >            errno = ERANGE;
398 >    }
399   #endif
400 <    if (errno == EDOM || errno == ERANGE) {
400 >    if ((errno == EDOM) | (errno == ERANGE)) {
401          wputs("Illegal power\n");
402          return(0.0);
403      }
# Line 319 | Line 418 | ebotch(
418  
419   EPNODE *
420   ekid(                   /* return pointer to a node's nth kid */
421 <    register EPNODE      *ep,
422 <    register int  n
421 >    EPNODE       *ep,
422 >    int  n
423   )
424   {
425 <
426 <    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
427 <        if (--n < 0)
428 <            break;
429 <
425 >    if (ep->nkids < 0) {        /* allocated array? */
426 >        if (n >= -ep->nkids)
427 >            return(NULL);
428 >        return(ep->v.kid + n);
429 >    }
430 >    ep = ep->v.kid;             /* else get from list */
431 >    while (n-- > 0)
432 >        if ((ep = ep->sibling) == NULL)
433 >                break;
434      return(ep);
435   }
436  
437  
335 int
336 nekids(                 /* return # of kids for node ep */
337    register EPNODE      *ep
338 )
339 {
340    register int  n = 0;
341
342    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
343        n++;
344
345    return(n);
346 }
347
348
438   void
439   initfile(               /* prepare input file */
440      FILE  *fp,
# Line 361 | Line 450 | initfile(              /* prepare input file */
450      lineno = ln;
451      linepos = 0;
452      inpbuf[0] = '\0';
453 <    scan();
453 >    escan();
454   }
455  
456  
# Line 377 | Line 466 | initstr(               /* prepare input string */
466      lineno = ln;
467      linbuf = s;
468      linepos = 0;
469 <    scan();
469 >    escan();
470   }
471  
472  
# Line 397 | Line 486 | getscanpos(    /* return current scan position */
486  
487  
488   int
489 < scan(void)              /* scan next character, return literal next */
489 > escan(void)             /* scan next character, return literal next */
490   {
491 <    register int  lnext = 0;
491 >    int  lnext = 0;
492  
493      do {
494          if (linbuf[linepos] == '\0')
# Line 419 | Line 508 | scan(void)             /* scan next character, return literal nex
508                  break;
509          }
510          if (nextc == '{') {
511 <            scan();
511 >            escan();
512              while (nextc != '}')
513                  if (nextc == EOF)
514 <                    syntax("'}' expected");
514 >                    esyntax("'}' expected");
515                  else
516 <                    scan();
517 <            scan();
516 >                    escan();
517 >            escan();
518          }
519      } while (isspace(nextc));
520      return(lnext);
# Line 438 | Line 527 | long2ascii(                          /* convert long to ascii */
527   )
528   {
529      static char  buf[16];
530 <    register char  *cp;
530 >    char  *cp;
531      int  neg = 0;
532  
533      if (l == 0)
# Line 460 | Line 549 | long2ascii(                          /* convert long to ascii */
549  
550  
551   void
552 < syntax(                 /* report syntax error and quit */
552 > esyntax(                        /* report syntax error and quit */
553      char  *err
554   )
555   {
556 <    register int  i;
556 >    int  i;
557  
558 <    if (infile != NULL || lineno != 0) {
558 >    if ((infile != NULL) | (lineno != 0)) {
559          if (infile != NULL) eputs(infile);
560          if (lineno != 0) {
561              eputs(infile != NULL ? ", line " : "line ");
# Line 488 | Line 577 | syntax(                        /* report syntax error and quit */
577  
578   void
579   addekid(                        /* add a child to ep */
580 <    register EPNODE      *ep,
581 <    EPNODE      *ekid
580 >    EPNODE       *ep,
581 >    EPNODE      *ek
582   )
583   {
584 +    if (ep->nkids < 0) {
585 +        eputs("Cannot add kid to EPNODE array\n");
586 +        quit(1);
587 +    }
588 +    ep->nkids++;
589      if (ep->v.kid == NULL)
590 <        ep->v.kid = ekid;
590 >        ep->v.kid = ek;
591      else {
592          for (ep = ep->v.kid; ep->sibling != NULL; ep = ep->sibling)
593              ;
594 <        ep->sibling = ekid;
594 >        ep->sibling = ek;
595      }
596 <    ekid->sibling = NULL;
596 >    ek->sibling = NULL;         /* shouldn't be necessary */
597   }
598  
599  
# Line 507 | Line 601 | char *
601   getname(void)                   /* scan an identifier */
602   {
603      static char  str[RMAXWORD+1];
604 <    register int  i, lnext;
604 >    int  i, lnext;
605  
606      lnext = nextc;
607 <    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
607 >    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = escan())
608          str[i] = lnext;
609      str[i] = '\0';
610      while (isid(lnext))         /* skip rest of name */
611 <        lnext = scan();
611 >        lnext = escan();
612  
613      return(str);
614   }
# Line 523 | Line 617 | getname(void)                  /* scan an identifier */
617   int
618   getinum(void)                   /* scan a positive integer */
619   {
620 <    register int  n, lnext;
620 >    int  n, lnext;
621  
622      n = 0;
623      lnext = nextc;
624      while (isdigit(lnext)) {
625          n = n * 10 + lnext - '0';
626 <        lnext = scan();
626 >        lnext = escan();
627      }
628      return(n);
629   }
# Line 538 | Line 632 | getinum(void)                  /* scan a positive integer */
632   double
633   getnum(void)                    /* scan a positive float */
634   {
635 <    register int  i, lnext;
635 >    int  i, lnext;
636      char  str[RMAXWORD+1];
637  
638      i = 0;
639      lnext = nextc;
640      while (isdigit(lnext) && i < RMAXWORD) {
641          str[i++] = lnext;
642 <        lnext = scan();
642 >        lnext = escan();
643      }
644 <    if (lnext == '.' && i < RMAXWORD) {
644 >    if ((lnext == '.') & (i < RMAXWORD)) {
645          str[i++] = lnext;
646 <        lnext = scan();
646 >        lnext = escan();
647          if (i == 1 && !isdigit(lnext))
648 <            syntax("badly formed number");
648 >            esyntax("badly formed number");
649          while (isdigit(lnext) && i < RMAXWORD) {
650              str[i++] = lnext;
651 <            lnext = scan();
651 >            lnext = escan();
652          }
653      }
654      if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
655          str[i++] = lnext;
656 <        lnext = scan();
656 >        lnext = escan();
657          if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
658              str[i++] = lnext;
659 <            lnext = scan();
659 >            lnext = escan();
660          }
661          if (!isdigit(lnext))
662 <            syntax("missing exponent");
662 >            esyntax("missing exponent");
663          while (isdigit(lnext) && i < RMAXWORD) {
664              str[i++] = lnext;
665 <            lnext = scan();
665 >            lnext = escan();
666          }
667      }
668      str[i] = '\0';
# Line 578 | Line 672 | getnum(void)                   /* scan a positive float */
672  
673  
674   EPNODE *
675 < getE1(void)                             /* E1 -> E1 ADDOP E2 */
675 > getE1(void)                     /* E1 -> E1 ADDOP E2 */
676                                  /*       E2 */
677   {
678 <    register EPNODE  *ep1, *ep2;
678 >    EPNODE  *ep1, *ep2;
679  
680      ep1 = getE2();
681 <    while (nextc == '+' || nextc == '-') {
681 >    while ((nextc == '+') | (nextc == '-')) {
682          ep2 = newnode();
683          ep2->type = nextc;
684 <        scan();
684 >        escan();
685          addekid(ep2, ep1);
686          addekid(ep2, getE2());
687 <        if (esupport&E_RCONST &&
688 <                        ep1->type == NUM && ep1->sibling->type == NUM)
687 >        if (esupport&E_RCONST && ep1->sibling->type == NUM) {
688 >            if (ep1->type == NUM) {
689                  ep2 = rconst(ep2);
690 +            } else if (ep2->type == '-') {
691 +                ep1->sibling->v.num *= -1;
692 +                ep2->type = '+';        /* associative&commutative */
693 +            }
694 +        }
695          ep1 = ep2;
696      }
697      return(ep1);
# Line 600 | Line 699 | getE1(void)                            /* E1 -> E1 ADDOP E2 */
699  
700  
701   EPNODE *
702 < getE2(void)                             /* E2 -> E2 MULOP E3 */
702 > getE2(void)                     /* E2 -> E2 MULOP E3 */
703                                  /*       E3 */
704   {
705 <    register EPNODE  *ep1, *ep2;
705 >    EPNODE  *ep1, *ep2;
706  
707      ep1 = getE3();
708 <    while (nextc == '*' || nextc == '/') {
708 >    while ((nextc == '*') | (nextc == '/')) {
709          ep2 = newnode();
710          ep2->type = nextc;
711 <        scan();
711 >        escan();
712          addekid(ep2, ep1);
713          addekid(ep2, getE3());
714 <        if (esupport&E_RCONST &&
715 <                        ep1->type == NUM && ep1->sibling->type == NUM)
714 >        if (esupport&E_RCONST) {
715 >            EPNODE      *ep3 = ep1->sibling;
716 >            if ((ep1->type == NUM) & (ep3->type == NUM)) {
717                  ep2 = rconst(ep2);
718 +            } else if (ep3->type == NUM) {
719 +                if (ep2->type == '/') {
720 +                    if (ep3->v.num == 0)
721 +                        esyntax("divide by zero constant");
722 +                    ep2->type = '*';            /* for speed */
723 +                    ep3->v.num = 1./ep3->v.num;
724 +                } else if (ep3->v.num == 0) {
725 +                    ep1->sibling = NULL;        /* (E2 * 0) */
726 +                    epfree(ep2,1);
727 +                    ep2 = ep3;
728 +                }
729 +            } else if (ep1->type == NUM && ep1->v.num == 0) {
730 +                epfree(ep3,1);                  /* (0 * E3) or (0 / E3) */
731 +                ep1->sibling = NULL;
732 +                efree(ep2);
733 +                ep2 = ep1;
734 +            }
735 +        }
736          ep1 = ep2;
737      }
738      return(ep1);
# Line 622 | Line 740 | getE2(void)                            /* E2 -> E2 MULOP E3 */
740  
741  
742   EPNODE *
743 < getE3(void)                             /* E3 -> E4 ^ E3 */
743 > getE3(void)                     /* E3 -> E4 ^ E3 */
744                                  /*       E4 */
745   {
746 <    register EPNODE  *ep1, *ep2;
746 >        EPNODE  *ep1, *ep2;
747  
748 <    ep1 = getE4();
749 <    if (nextc == '^') {
748 >        ep1 = getE4();
749 >        if (nextc != '^')
750 >                return(ep1);
751          ep2 = newnode();
752          ep2->type = nextc;
753 <        scan();
753 >        escan();
754          addekid(ep2, ep1);
755          addekid(ep2, getE3());
756 <        if (esupport&E_RCONST &&
757 <                        ep1->type == NUM && ep1->sibling->type == NUM)
756 >        if (esupport&E_RCONST) {
757 >            EPNODE      *ep3 = ep1->sibling;
758 >            if ((ep1->type == NUM) & (ep3->type == NUM)) {
759                  ep2 = rconst(ep2);
760 +            } else if (ep1->type == NUM && ep1->v.num == 0) {
761 +                epfree(ep3,1);          /* (0 ^ E3) */
762 +                ep1->sibling = NULL;
763 +                efree(ep2);
764 +                ep2 = ep1;
765 +            } else if ((ep3->type == NUM && ep3->v.num == 0) |
766 +                                (ep1->type == NUM && ep1->v.num == 1)) {
767 +                epfree(ep2,0);          /* (E4 ^ 0) or (1 ^ E3) */
768 +                ep2->type = NUM;
769 +                ep2->v.num = 1;
770 +            } else if (ep3->type == NUM && ep3->v.num == 1) {
771 +                efree(ep3);             /* (E4 ^ 1) */
772 +                ep1->sibling = NULL;
773 +                efree(ep2);
774 +                ep2 = ep1;
775 +            }
776 +        }
777          return(ep2);
641    }
642    return(ep1);
778   }
779  
780  
781   EPNODE *
782 < getE4(void)                             /* E4 -> ADDOP E5 */
782 > getE4(void)                     /* E4 -> ADDOP E5 */
783                                  /*       E5 */
784   {
785 <    register EPNODE  *ep1, *ep2;
785 >    EPNODE  *ep1, *ep2;
786  
787      if (nextc == '-') {
788 <        scan();
788 >        escan();
789          ep2 = getE5();
790          if (ep2->type == NUM) {
791 <                ep2->v.num = -ep2->v.num;
792 <                return(ep2);
791 >            ep2->v.num = -ep2->v.num;
792 >            return(ep2);
793          }
794          if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
795 <            efree((char *)ep2);
796 <            return(ep2->v.kid);
795 >            ep1 = ep2->v.kid;
796 >            efree(ep2);
797 >            return(ep1);
798          }
799          ep1 = newnode();
800          ep1->type = UMINUS;
# Line 666 | Line 802 | getE4(void)                            /* E4 -> ADDOP E5 */
802          return(ep1);
803      }
804      if (nextc == '+')
805 <        scan();
805 >        escan();
806      return(getE5());
807   }
808  
# Line 681 | Line 817 | getE5(void)                    /* E5 -> (E1) */
817   {
818          int      i;
819          char  *nam;
820 <        register EPNODE  *ep1, *ep2;
820 >        EPNODE  *ep1, *ep2;
821  
822          if (nextc == '(') {
823 <                scan();
824 <                ep1 = getE1();
825 <                if (nextc != ')')
826 <                        syntax("')' expected");
827 <                scan();
828 <                return(ep1);
823 >            escan();
824 >            ep1 = getE1();
825 >            if (nextc != ')')
826 >                esyntax("')' expected");
827 >            escan();
828 >            return(ep1);
829          }
694
830          if (esupport&E_INCHAN && nextc == '$') {
831 <                scan();
832 <                ep1 = newnode();
833 <                ep1->type = CHAN;
834 <                ep1->v.chan = getinum();
835 <                return(ep1);
831 >            escan();
832 >            ep1 = newnode();
833 >            ep1->type = CHAN;
834 >            ep1->v.chan = getinum();
835 >            return(ep1);
836          }
702
837          if (esupport&(E_VARIABLE|E_FUNCTION) &&
838 <                        (isalpha(nextc) || nextc == CNTXMARK)) {
839 <                nam = getname();
840 <                ep1 = NULL;
841 <                if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
842 <                                && curfunc != NULL)
843 <                        for (i = 1, ep2 = curfunc->v.kid->sibling;
844 <                                        ep2 != NULL; i++, ep2 = ep2->sibling)
845 <                                if (!strcmp(ep2->v.name, nam)) {
712 <                                        ep1 = newnode();
713 <                                        ep1->type = ARG;
714 <                                        ep1->v.chan = i;
715 <                                        break;
716 <                                }
717 <                if (ep1 == NULL) {
838 >                        (isalpha(nextc) | (nextc == CNTXMARK))) {
839 >            nam = getname();
840 >            ep1 = NULL;
841 >            if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
842 >                                && ecurfunc != NULL)
843 >                for (i = 1, ep2 = ecurfunc->v.kid->sibling;
844 >                                ep2 != NULL; i++, ep2 = ep2->sibling)
845 >                    if (!strcmp(ep2->v.name, nam)) {
846                          ep1 = newnode();
847 <                        ep1->type = VAR;
848 <                        ep1->v.ln = varinsert(nam);
849 <                }
850 <                if (esupport&E_FUNCTION && nextc == '(') {
851 <                        ep2 = newnode();
852 <                        ep2->type = FUNC;
853 <                        addekid(ep2, ep1);
854 <                        ep1 = ep2;
855 <                        do {
856 <                                scan();
857 <                                addekid(ep1, getE1());
858 <                        } while (nextc == ',');
859 <                        if (nextc != ')')
860 <                                syntax("')' expected");
861 <                        scan();
862 <                } else if (!(esupport&E_VARIABLE))
863 <                        syntax("'(' expected");
864 <                if (esupport&E_RCONST && isconstvar(ep1))
865 <                        ep1 = rconst(ep1);
866 <                return(ep1);
847 >                        ep1->type = ARG;
848 >                        ep1->v.chan = i;
849 >                        break;
850 >                    }
851 >            if (ep1 == NULL) {
852 >                ep1 = newnode();
853 >                ep1->type = VAR;
854 >                ep1->v.ln = varinsert(nam);
855 >            }
856 >            if (esupport&E_FUNCTION && nextc == '(') {
857 >                ep2 = newnode();
858 >                ep2->type = FUNC;
859 >                addekid(ep2, ep1);
860 >                ep1 = ep2;
861 >                do {
862 >                    escan();
863 >                    addekid(ep1, getE1());
864 >                } while (nextc == ',');
865 >                if (nextc != ')')
866 >                    esyntax("')' expected");
867 >                escan();
868 >            } else if (!(esupport&E_VARIABLE))
869 >                esyntax("'(' expected");
870 >            if (esupport&E_RCONST && isconstvar(ep1))
871 >                ep1 = rconst(ep1);
872 >            return(ep1);
873          }
740
874          if (isdecimal(nextc)) {
875 <                ep1 = newnode();
876 <                ep1->type = NUM;
877 <                ep1->v.num = getnum();
878 <                return(ep1);
875 >            ep1 = newnode();
876 >            ep1->type = NUM;
877 >            ep1->v.num = getnum();
878 >            return(ep1);
879          }
880 <        syntax("unexpected character");
880 >        esyntax("unexpected character");
881          return NULL; /* pro forma return */
882   }
883  
884  
885   EPNODE *
886   rconst(                 /* reduce a constant expression */
887 <    register EPNODE      *epar
887 >    EPNODE       *epar
888   )
889   {
890 <    register EPNODE  *ep;
890 >    EPNODE  *ep;
891  
892      ep = newnode();
893      ep->type = NUM;
894      errno = 0;
895      ep->v.num = evalue(epar);
896 <    if (errno == EDOM || errno == ERANGE)
897 <        syntax("bad constant expression");
898 <    epfree(epar);
896 >    if ((errno == EDOM) | (errno == ERANGE))
897 >        esyntax("bad constant expression");
898 >    epfree(epar,1);
899  
900      return(ep);
901   }
# Line 770 | Line 903 | rconst(                        /* reduce a constant expression */
903  
904   int
905   isconstvar(                     /* is ep linked to a constant expression? */
906 <    register EPNODE      *ep
906 >    EPNODE       *ep
907   )
908   {
909 <    register EPNODE  *ep1;
909 >    EPNODE  *ep1;
910  
911      if (esupport&E_FUNCTION && ep->type == FUNC) {
912          if (!isconstfun(ep->v.kid))
# Line 796 | Line 929 | isconstvar(                    /* is ep linked to a constant expression
929  
930   int
931   isconstfun(                     /* is ep linked to a constant function? */
932 <    register EPNODE      *ep
932 >    EPNODE       *ep
933   )
934   {
935 <    register EPNODE  *dp;
936 <    register LIBR  *lp;
935 >    EPNODE  *dp;
936 >    ELIBR  *lp;
937  
938      if (ep->type != VAR)
939          return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)