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.31 by greg, Wed May 10 15:21:20 2006 UTC vs.
Revision 2.54 by greg, Sat Dec 6 02:58:05 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 ((epar->nkids <= 2) | !(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;      /* drop following constants */
250 >    while (ep1->sibling != NULL)
251 >        if (ep1->sibling->type == NUM) {
252 >            ep = ep1->sibling;
253 >            ep1->sibling = ep->sibling;
254 >            efree(ep);
255 >        } else
256 >            ep1 = ep1->sibling;
257   }
258  
259 <                                /* the following used to be a switch */
260 < static double
261 < eargument(
262 <    EPNODE      *ep
259 >
260 > void
261 > epoptimize(                     /* flatten operations, lists -> arrays */
262 >        EPNODE  *epar
263   )
264   {
265 <    return(argument(ep->v.chan));
265 >    EPNODE      *ep;
266 >
267 >    if ((epar->type == '+') | (epar->type == '*'))
268 >        epflatten(epar);        /* flatten associative operations */
269 >
270 >    if (epar->nkids)            /* do children if any */
271 >        for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
272 >            epoptimize(ep);
273 >
274 >    if (epar->nkids > 4) {      /* make list into array if > 4 kids */
275 >        int     n = 1;
276 >        epar->v.kid = (EPNODE *)erealloc(epar->v.kid,
277 >                                        sizeof(EPNODE)*epar->nkids);
278 >        while (n < epar->nkids) {
279 >            ep = epar->v.kid[n-1].sibling;
280 >            epar->v.kid[n] = *ep;
281 >            efree(ep);          /* not epfree()! */
282 >            epar->v.kid[n-1].sibling = epar->v.kid + n;
283 >            n++;
284 >        }
285 >        epar->nkids = -n;
286 >    }
287   }
288  
289 +                                /* the following used to be a switch */
290   static double
291   enumber(
292      EPNODE      *ep
# Line 222 | Line 300 | euminus(
300      EPNODE      *ep
301   )
302   {
303 <    register EPNODE  *ep1 = ep->v.kid;
303 >    EPNODE  *ep1 = ep->v.kid;
304  
305      return(-evalue(ep1));
306   }
# Line 240 | Line 318 | eadd(
318      EPNODE      *ep
319   )
320   {
321 <    register EPNODE  *ep1 = ep->v.kid;
321 >    double  sum = 0;
322 >    EPNODE  *ep1 = ep->v.kid;
323  
324 <    return(evalue(ep1) + evalue(ep1->sibling));
324 >    do
325 >        sum += envalue(ep1);
326 >    while ((ep1 = ep1->sibling) != NULL);
327 >
328 >    return(sum);
329   }
330  
331   static double
# Line 250 | Line 333 | esubtr(
333      EPNODE      *ep
334   )
335   {
336 <    register EPNODE  *ep1 = ep->v.kid;
336 >    EPNODE  *ep1 = ep->v.kid;
337 >    EPNODE  *ep2 = ep1->sibling;
338  
339 <    return(evalue(ep1) - evalue(ep1->sibling));
339 >    return(envalue(ep1) - envalue(ep2));
340   }
341  
342   static double
# Line 260 | Line 344 | emult(
344      EPNODE      *ep
345   )
346   {
347 <    register EPNODE  *ep1 = ep->v.kid;
347 >    double  prod = 1;
348 >    EPNODE  *ep1 = ep->v.kid;
349  
350 <    return(evalue(ep1) * evalue(ep1->sibling));
350 >    do
351 >        prod *= envalue(ep1);
352 >    while ((ep1 = ep1->sibling) != NULL);
353 >
354 >    return(prod);
355   }
356  
357   static double
# Line 270 | Line 359 | edivi(
359      EPNODE      *ep
360   )
361   {
362 <    register EPNODE  *ep1 = ep->v.kid;
363 <    double  d;
362 >    EPNODE  *ep1 = ep->v.kid;
363 >    double  den = evalue(ep1->sibling);
364  
365 <    d = evalue(ep1->sibling);
277 <    if (d == 0.0) {
365 >    if (den == 0.0) {
366          wputs("Division by zero\n");
367          errno = ERANGE;
368          return(0.0);
369      }
370 <    return(evalue(ep1) / d);
370 >    return(envalue(ep1) / den);
371   }
372  
373   static double
# Line 287 | Line 375 | epow(
375      EPNODE      *ep
376   )
377   {
378 <    register EPNODE  *ep1 = ep->v.kid;
378 >    EPNODE  *ep1 = ep->v.kid;
379      double  d;
380      int  lasterrno;
381  
# Line 295 | Line 383 | epow(
383      errno = 0;
384      d = pow(evalue(ep1), evalue(ep1->sibling));
385   #ifdef  isnan
386 <    if (errno == 0)
386 >    if (errno == 0) {
387          if (isnan(d))
388              errno = EDOM;
389          else if (isinf(d))
390              errno = ERANGE;
391 +    }
392   #endif
393 <    if (errno == EDOM || errno == ERANGE) {
393 >    if ((errno == EDOM) | (errno == ERANGE)) {
394          wputs("Illegal power\n");
395          return(0.0);
396      }
# Line 322 | Line 411 | ebotch(
411  
412   EPNODE *
413   ekid(                   /* return pointer to a node's nth kid */
414 <    register EPNODE      *ep,
415 <    register int  n
414 >    EPNODE       *ep,
415 >    int  n
416   )
417   {
418 <
419 <    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
420 <        if (--n < 0)
421 <            break;
422 <
418 >    if (ep->nkids < 0) {        /* allocated array? */
419 >        if (n >= -ep->nkids)
420 >            return(NULL);
421 >        return(ep->v.kid + n);
422 >    }
423 >    ep = ep->v.kid;             /* else get from list */
424 >    while (n-- > 0)
425 >        if ((ep = ep->sibling) == NULL)
426 >                break;
427      return(ep);
428   }
429  
430  
338 int
339 nekids(                 /* return # of kids for node ep */
340    register EPNODE      *ep
341 )
342 {
343    register int  n = 0;
344
345    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
346        n++;
347
348    return(n);
349 }
350
351
431   void
432   initfile(               /* prepare input file */
433      FILE  *fp,
# Line 364 | Line 443 | initfile(              /* prepare input file */
443      lineno = ln;
444      linepos = 0;
445      inpbuf[0] = '\0';
446 <    scan();
446 >    escan();
447   }
448  
449  
# Line 380 | Line 459 | initstr(               /* prepare input string */
459      lineno = ln;
460      linbuf = s;
461      linepos = 0;
462 <    scan();
462 >    escan();
463   }
464  
465  
# Line 400 | Line 479 | getscanpos(    /* return current scan position */
479  
480  
481   int
482 < scan(void)              /* scan next character, return literal next */
482 > escan(void)             /* scan next character, return literal next */
483   {
484 <    register int  lnext = 0;
484 >    int  lnext = 0;
485  
486      do {
487          if (linbuf[linepos] == '\0')
# Line 422 | Line 501 | scan(void)             /* scan next character, return literal nex
501                  break;
502          }
503          if (nextc == '{') {
504 <            scan();
504 >            escan();
505              while (nextc != '}')
506                  if (nextc == EOF)
507 <                    syntax("'}' expected");
507 >                    esyntax("'}' expected");
508                  else
509 <                    scan();
510 <            scan();
509 >                    escan();
510 >            escan();
511          }
512      } while (isspace(nextc));
513      return(lnext);
# Line 441 | Line 520 | long2ascii(                          /* convert long to ascii */
520   )
521   {
522      static char  buf[16];
523 <    register char  *cp;
523 >    char  *cp;
524      int  neg = 0;
525  
526      if (l == 0)
# Line 463 | Line 542 | long2ascii(                          /* convert long to ascii */
542  
543  
544   void
545 < syntax(                 /* report syntax error and quit */
545 > esyntax(                        /* report syntax error and quit */
546      char  *err
547   )
548   {
549 <    register int  i;
549 >    int  i;
550  
551 <    if (infile != NULL || lineno != 0) {
551 >    if ((infile != NULL) | (lineno != 0)) {
552          if (infile != NULL) eputs(infile);
553          if (lineno != 0) {
554              eputs(infile != NULL ? ", line " : "line ");
# Line 491 | Line 570 | syntax(                        /* report syntax error and quit */
570  
571   void
572   addekid(                        /* add a child to ep */
573 <    register EPNODE      *ep,
574 <    EPNODE      *ekid
573 >    EPNODE       *ep,
574 >    EPNODE      *ek
575   )
576   {
577 +    if (ep->nkids < 0) {
578 +        eputs("Cannot add kid to EPNODE array\n");
579 +        quit(1);
580 +    }
581 +    ep->nkids++;
582      if (ep->v.kid == NULL)
583 <        ep->v.kid = ekid;
583 >        ep->v.kid = ek;
584      else {
585          for (ep = ep->v.kid; ep->sibling != NULL; ep = ep->sibling)
586              ;
587 <        ep->sibling = ekid;
587 >        ep->sibling = ek;
588      }
589 <    ekid->sibling = NULL;
589 >    ek->sibling = NULL;         /* shouldn't be necessary */
590   }
591  
592  
# Line 510 | Line 594 | char *
594   getname(void)                   /* scan an identifier */
595   {
596      static char  str[RMAXWORD+1];
597 <    register int  i, lnext;
597 >    int  i, lnext;
598  
599      lnext = nextc;
600 <    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
600 >    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = escan())
601          str[i] = lnext;
602      str[i] = '\0';
603      while (isid(lnext))         /* skip rest of name */
604 <        lnext = scan();
604 >        lnext = escan();
605  
606      return(str);
607   }
# Line 526 | Line 610 | getname(void)                  /* scan an identifier */
610   int
611   getinum(void)                   /* scan a positive integer */
612   {
613 <    register int  n, lnext;
613 >    int  n, lnext;
614  
615      n = 0;
616      lnext = nextc;
617      while (isdigit(lnext)) {
618          n = n * 10 + lnext - '0';
619 <        lnext = scan();
619 >        lnext = escan();
620      }
621      return(n);
622   }
# Line 541 | Line 625 | getinum(void)                  /* scan a positive integer */
625   double
626   getnum(void)                    /* scan a positive float */
627   {
628 <    register int  i, lnext;
628 >    int  i, lnext;
629      char  str[RMAXWORD+1];
630  
631      i = 0;
632      lnext = nextc;
633      while (isdigit(lnext) && i < RMAXWORD) {
634          str[i++] = lnext;
635 <        lnext = scan();
635 >        lnext = escan();
636      }
637 <    if (lnext == '.' && i < RMAXWORD) {
637 >    if ((lnext == '.') & (i < RMAXWORD)) {
638          str[i++] = lnext;
639 <        lnext = scan();
639 >        lnext = escan();
640          if (i == 1 && !isdigit(lnext))
641 <            syntax("badly formed number");
641 >            esyntax("badly formed number");
642          while (isdigit(lnext) && i < RMAXWORD) {
643              str[i++] = lnext;
644 <            lnext = scan();
644 >            lnext = escan();
645          }
646      }
647      if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
648          str[i++] = lnext;
649 <        lnext = scan();
649 >        lnext = escan();
650          if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
651              str[i++] = lnext;
652 <            lnext = scan();
652 >            lnext = escan();
653          }
654          if (!isdigit(lnext))
655 <            syntax("missing exponent");
655 >            esyntax("missing exponent");
656          while (isdigit(lnext) && i < RMAXWORD) {
657              str[i++] = lnext;
658 <            lnext = scan();
658 >            lnext = escan();
659          }
660      }
661      str[i] = '\0';
# Line 581 | Line 665 | getnum(void)                   /* scan a positive float */
665  
666  
667   EPNODE *
668 < getE1(void)                             /* E1 -> E1 ADDOP E2 */
668 > getE1(void)                     /* E1 -> E1 ADDOP E2 */
669                                  /*       E2 */
670   {
671 <    register EPNODE  *ep1, *ep2;
671 >    EPNODE  *ep1, *ep2;
672  
673      ep1 = getE2();
674 <    while (nextc == '+' || nextc == '-') {
674 >    while ((nextc == '+') | (nextc == '-')) {
675          ep2 = newnode();
676          ep2->type = nextc;
677 <        scan();
677 >        escan();
678          addekid(ep2, ep1);
679          addekid(ep2, getE2());
680          if (esupport&E_RCONST &&
681 <                        ep1->type == NUM && ep1->sibling->type == NUM)
681 >                        (ep1->type == NUM) & (ep1->sibling->type == NUM))
682                  ep2 = rconst(ep2);
683          ep1 = ep2;
684      }
# Line 603 | Line 687 | getE1(void)                            /* E1 -> E1 ADDOP E2 */
687  
688  
689   EPNODE *
690 < getE2(void)                             /* E2 -> E2 MULOP E3 */
690 > getE2(void)                     /* E2 -> E2 MULOP E3 */
691                                  /*       E3 */
692   {
693 <    register EPNODE  *ep1, *ep2;
693 >    EPNODE  *ep1, *ep2;
694  
695      ep1 = getE3();
696 <    while (nextc == '*' || nextc == '/') {
696 >    while ((nextc == '*') | (nextc == '/')) {
697          ep2 = newnode();
698          ep2->type = nextc;
699 <        scan();
699 >        escan();
700          addekid(ep2, ep1);
701          addekid(ep2, getE3());
702 <        if (esupport&E_RCONST &&
703 <                        ep1->type == NUM && ep1->sibling->type == NUM)
702 >        if (esupport&E_RCONST) {
703 >            EPNODE      *ep3 = ep1->sibling;
704 >            if ((ep1->type == NUM) & (ep3->type == NUM)) {
705                  ep2 = rconst(ep2);
706 +            } else if (ep3->type == NUM) {
707 +                if (ep2->type == '/') {
708 +                    if (ep3->v.num == 0)
709 +                        esyntax("divide by zero constant");
710 +                    ep2->type = '*';            /* for speed */
711 +                    ep3->v.num = 1./ep3->v.num;
712 +                } else if (ep3->v.num == 0) {
713 +                    ep1->sibling = NULL;        /* (E2 * 0) */
714 +                    epfree(ep2,1);
715 +                    ep2 = ep3;
716 +                }
717 +            } else if (ep1->type == NUM && ep1->v.num == 0) {
718 +                epfree(ep3,1);                  /* (0 * E3) or (0 / E3) */
719 +                ep1->sibling = NULL;
720 +                efree(ep2);
721 +                ep2 = ep1;
722 +            }
723 +        }
724          ep1 = ep2;
725      }
726      return(ep1);
# Line 625 | Line 728 | getE2(void)                            /* E2 -> E2 MULOP E3 */
728  
729  
730   EPNODE *
731 < getE3(void)                             /* E3 -> E4 ^ E3 */
731 > getE3(void)                     /* E3 -> E4 ^ E3 */
732                                  /*       E4 */
733   {
734 <    register EPNODE  *ep1, *ep2;
734 >        EPNODE  *ep1, *ep2;
735  
736 <    ep1 = getE4();
737 <    if (nextc == '^') {
736 >        ep1 = getE4();
737 >        if (nextc != '^')
738 >                return(ep1);
739          ep2 = newnode();
740          ep2->type = nextc;
741 <        scan();
741 >        escan();
742          addekid(ep2, ep1);
743          addekid(ep2, getE3());
744 <        if (esupport&E_RCONST &&
745 <                        ep1->type == NUM && ep1->sibling->type == NUM)
744 >        if (esupport&E_RCONST) {
745 >            EPNODE      *ep3 = ep1->sibling;
746 >            if ((ep1->type == NUM) & (ep3->type == NUM)) {
747                  ep2 = rconst(ep2);
748 +            } else if (ep1->type == NUM && ep1->v.num == 0) {
749 +                epfree(ep3,1);          /* (0 ^ E3) */
750 +                ep1->sibling = NULL;
751 +                efree(ep2);
752 +                ep2 = ep1;
753 +            } else if ((ep3->type == NUM && ep3->v.num == 0) |
754 +                                (ep1->type == NUM && ep1->v.num == 1)) {
755 +                epfree(ep2,0);          /* (E4 ^ 0) or (1 ^ E3) */
756 +                ep2->type = NUM;
757 +                ep2->v.num = 1;
758 +            } else if (ep3->type == NUM && ep3->v.num == 1) {
759 +                efree(ep3);             /* (E4 ^ 1) */
760 +                ep1->sibling = NULL;
761 +                efree(ep2);
762 +                ep2 = ep1;
763 +            }
764 +        }
765          return(ep2);
644    }
645    return(ep1);
766   }
767  
768  
769   EPNODE *
770 < getE4(void)                             /* E4 -> ADDOP E5 */
770 > getE4(void)                     /* E4 -> ADDOP E5 */
771                                  /*       E5 */
772   {
773 <    register EPNODE  *ep1, *ep2;
773 >    EPNODE  *ep1, *ep2;
774  
775      if (nextc == '-') {
776 <        scan();
776 >        escan();
777          ep2 = getE5();
778          if (ep2->type == NUM) {
779 <                ep2->v.num = -ep2->v.num;
780 <                return(ep2);
779 >            ep2->v.num = -ep2->v.num;
780 >            return(ep2);
781          }
782          if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
783 <            efree((char *)ep2);
784 <            return(ep2->v.kid);
783 >            ep1 = ep2->v.kid;
784 >            efree(ep2);
785 >            return(ep1);
786          }
787          ep1 = newnode();
788          ep1->type = UMINUS;
# Line 669 | Line 790 | getE4(void)                            /* E4 -> ADDOP E5 */
790          return(ep1);
791      }
792      if (nextc == '+')
793 <        scan();
793 >        escan();
794      return(getE5());
795   }
796  
# Line 684 | Line 805 | getE5(void)                    /* E5 -> (E1) */
805   {
806          int      i;
807          char  *nam;
808 <        register EPNODE  *ep1, *ep2;
808 >        EPNODE  *ep1, *ep2;
809  
810          if (nextc == '(') {
811 <                scan();
812 <                ep1 = getE1();
813 <                if (nextc != ')')
814 <                        syntax("')' expected");
815 <                scan();
816 <                return(ep1);
811 >            escan();
812 >            ep1 = getE1();
813 >            if (nextc != ')')
814 >                esyntax("')' expected");
815 >            escan();
816 >            return(ep1);
817          }
697
818          if (esupport&E_INCHAN && nextc == '$') {
819 <                scan();
820 <                ep1 = newnode();
821 <                ep1->type = CHAN;
822 <                ep1->v.chan = getinum();
823 <                return(ep1);
819 >            escan();
820 >            ep1 = newnode();
821 >            ep1->type = CHAN;
822 >            ep1->v.chan = getinum();
823 >            return(ep1);
824          }
705
825          if (esupport&(E_VARIABLE|E_FUNCTION) &&
826 <                        (isalpha(nextc) || nextc == CNTXMARK)) {
827 <                nam = getname();
828 <                ep1 = NULL;
829 <                if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
830 <                                && curfunc != NULL)
831 <                        for (i = 1, ep2 = curfunc->v.kid->sibling;
832 <                                        ep2 != NULL; i++, ep2 = ep2->sibling)
833 <                                if (!strcmp(ep2->v.name, nam)) {
715 <                                        ep1 = newnode();
716 <                                        ep1->type = ARG;
717 <                                        ep1->v.chan = i;
718 <                                        break;
719 <                                }
720 <                if (ep1 == NULL) {
826 >                        (isalpha(nextc) | (nextc == CNTXMARK))) {
827 >            nam = getname();
828 >            ep1 = NULL;
829 >            if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
830 >                                && ecurfunc != NULL)
831 >                for (i = 1, ep2 = ecurfunc->v.kid->sibling;
832 >                                ep2 != NULL; i++, ep2 = ep2->sibling)
833 >                    if (!strcmp(ep2->v.name, nam)) {
834                          ep1 = newnode();
835 <                        ep1->type = VAR;
836 <                        ep1->v.ln = varinsert(nam);
837 <                }
838 <                if (esupport&E_FUNCTION && nextc == '(') {
839 <                        ep2 = newnode();
840 <                        ep2->type = FUNC;
841 <                        addekid(ep2, ep1);
842 <                        ep1 = ep2;
843 <                        do {
844 <                                scan();
845 <                                addekid(ep1, getE1());
846 <                        } while (nextc == ',');
847 <                        if (nextc != ')')
848 <                                syntax("')' expected");
849 <                        scan();
850 <                } else if (!(esupport&E_VARIABLE))
851 <                        syntax("'(' expected");
852 <                if (esupport&E_RCONST && isconstvar(ep1))
853 <                        ep1 = rconst(ep1);
854 <                return(ep1);
835 >                        ep1->type = ARG;
836 >                        ep1->v.chan = i;
837 >                        break;
838 >                    }
839 >            if (ep1 == NULL) {
840 >                ep1 = newnode();
841 >                ep1->type = VAR;
842 >                ep1->v.ln = varinsert(nam);
843 >            }
844 >            if (esupport&E_FUNCTION && nextc == '(') {
845 >                ep2 = newnode();
846 >                ep2->type = FUNC;
847 >                addekid(ep2, ep1);
848 >                ep1 = ep2;
849 >                do {
850 >                    escan();
851 >                    addekid(ep1, getE1());
852 >                } while (nextc == ',');
853 >                if (nextc != ')')
854 >                    esyntax("')' expected");
855 >                escan();
856 >            } else if (!(esupport&E_VARIABLE))
857 >                esyntax("'(' expected");
858 >            if (esupport&E_RCONST && isconstvar(ep1))
859 >                ep1 = rconst(ep1);
860 >            return(ep1);
861          }
743
862          if (isdecimal(nextc)) {
863 <                ep1 = newnode();
864 <                ep1->type = NUM;
865 <                ep1->v.num = getnum();
866 <                return(ep1);
863 >            ep1 = newnode();
864 >            ep1->type = NUM;
865 >            ep1->v.num = getnum();
866 >            return(ep1);
867          }
868 <        syntax("unexpected character");
868 >        esyntax("unexpected character");
869          return NULL; /* pro forma return */
870   }
871  
872  
873   EPNODE *
874   rconst(                 /* reduce a constant expression */
875 <    register EPNODE      *epar
875 >    EPNODE       *epar
876   )
877   {
878 <    register EPNODE  *ep;
878 >    EPNODE  *ep;
879  
880      ep = newnode();
881      ep->type = NUM;
882      errno = 0;
883      ep->v.num = evalue(epar);
884 <    if (errno == EDOM || errno == ERANGE)
885 <        syntax("bad constant expression");
886 <    epfree(epar);
884 >    if ((errno == EDOM) | (errno == ERANGE))
885 >        esyntax("bad constant expression");
886 >    epfree(epar,1);
887  
888      return(ep);
889   }
# Line 773 | Line 891 | rconst(                        /* reduce a constant expression */
891  
892   int
893   isconstvar(                     /* is ep linked to a constant expression? */
894 <    register EPNODE      *ep
894 >    EPNODE       *ep
895   )
896   {
897 <    register EPNODE  *ep1;
897 >    EPNODE  *ep1;
898  
899      if (esupport&E_FUNCTION && ep->type == FUNC) {
900          if (!isconstfun(ep->v.kid))
# Line 799 | Line 917 | isconstvar(                    /* is ep linked to a constant expression
917  
918   int
919   isconstfun(                     /* is ep linked to a constant function? */
920 <    register EPNODE      *ep
920 >    EPNODE       *ep
921   )
922   {
923 <    register EPNODE  *dp;
924 <    register LIBR  *lp;
923 >    EPNODE  *dp;
924 >    ELIBR  *lp;
925  
926      if (ep->type != VAR)
927          return(0);

Diff Legend

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