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.19 by greg, Tue Feb 25 02:47:21 2003 UTC vs.
Revision 2.39 by greg, Sat Dec 28 18:05:13 2019 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 */
# Line 37 | Line 35 | static const char      RCSid[] = "$Id$";
35  
36   #define  isdecimal(c)   (isdigit(c) || (c) == '.')
37  
38 < static double  euminus(), eargument(), enumber();
39 < static double  echannel();
40 < static double  eadd(), esubtr(), emult(), edivi(), epow();
41 < static double  ebotch();
38 > static double  euminus(EPNODE *), eargument(EPNODE *), enumber(EPNODE *);
39 > static double  echannel(EPNODE *);
40 > static double  eadd(EPNODE *), esubtr(EPNODE *),
41 >               emult(EPNODE *), edivi(EPNODE *),
42 >               epow(EPNODE *);
43 > static double  ebotch(EPNODE *);
44  
45   unsigned int  esupport =                /* what to support */
46 <                E_VARIABLE | E_FUNCTION | E_REDEFW;
46 >                E_VARIABLE | E_FUNCTION ;
47  
48 + int  eofc = 0;                          /* optional end-of-file character */
49   int  nextc;                             /* lookahead character */
50  
51 < double  (*eoper[])() = {                /* expression operations */
51 > double  (*eoper[])(EPNODE *) = {        /* expression operations */
52          ebotch,
53          evariable,
54          enumber,
# Line 82 | Line 83 | static int  linepos;                   /* position in buffer */
83  
84  
85   EPNODE *
86 < eparse(expr)                    /* parse an expression string */
87 < char  *expr;
86 > eparse(                 /* parse an expression string */
87 >    char  *expr
88 > )
89   {
90      EPNODE  *ep;
91  
# Line 97 | Line 99 | char  *expr;
99  
100  
101   double
102 < eval(expr)                      /* evaluate an expression string */
103 < char  *expr;
102 > eval(                   /* evaluate an expression string */
103 >    char  *expr
104 > )
105   {
106 <    register EPNODE  *ep;
106 >    int  prev_support = esupport;
107 >    EPNODE  *ep;
108      double  rval;
109  
110 +    esupport &= ~E_RCONST;      /* don't bother reducing constant expr */
111      ep = eparse(expr);
112 +    esupport = prev_support;    /* as you were */
113      rval = evalue(ep);
114      epfree(ep);
115      return(rval);
# Line 111 | Line 117 | char  *expr;
117  
118  
119   int
120 < epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
121 < register EPNODE  *ep1, *ep2;
120 > epcmp(                  /* compare two expressions for equivalence */
121 >    EPNODE  *ep1,
122 >    EPNODE  *ep2
123 > )
124   {
125          double  d;
126  
# Line 128 | Line 136 | register EPNODE  *ep1, *ep2;
136                  if (ep2->v.num == 0)
137                          return(ep1->v.num != 0);
138                  d = ep1->v.num / ep2->v.num;
139 <                return(d > 1.000000000001 | d < 0.999999999999);
139 >                return((d > 1.000000000001) | (d < 0.999999999999));
140  
141          case CHAN:
142          case ARG:
# Line 138 | Line 146 | register EPNODE  *ep1, *ep2;
146          case ':':
147                  return(epcmp(ep1->v.kid->sibling, ep2->v.kid->sibling));
148  
149 <        case TICK:
149 >        case CLKT:
150          case SYM:                       /* should never get this one */
151                  return(0);
152  
# Line 159 | Line 167 | register EPNODE  *ep1, *ep2;
167  
168  
169   void
170 < epfree(epar)                    /* free a parse tree */
171 < register EPNODE  *epar;
170 > epfree(                 /* free a parse tree */
171 >    EPNODE       *epar
172 > )
173   {
174 <    register EPNODE  *ep;
174 >    EPNODE  *ep;
175  
176      switch (epar->type) {
177  
# Line 177 | Line 186 | register EPNODE         *epar;
186          case NUM:
187          case CHAN:
188          case ARG:
189 <        case TICK:
189 >        case CLKT:
190              break;
191  
192          default:
# Line 194 | Line 203 | register EPNODE         *epar;
203  
204                                  /* the following used to be a switch */
205   static double
206 < eargument(ep)
207 < EPNODE  *ep;
206 > eargument(
207 >    EPNODE      *ep
208 > )
209   {
210      return(argument(ep->v.chan));
211   }
212  
213   static double
214 < enumber(ep)
215 < EPNODE  *ep;
214 > enumber(
215 >    EPNODE      *ep
216 > )
217   {
218      return(ep->v.num);
219   }
220  
221   static double
222 < euminus(ep)
223 < EPNODE  *ep;
222 > euminus(
223 >    EPNODE      *ep
224 > )
225   {
226 <    register EPNODE  *ep1 = ep->v.kid;
226 >    EPNODE  *ep1 = ep->v.kid;
227  
228      return(-evalue(ep1));
229   }
230  
231   static double
232 < echannel(ep)
233 < EPNODE  *ep;
232 > echannel(
233 >    EPNODE      *ep
234 > )
235   {
236      return(chanvalue(ep->v.chan));
237   }
238  
239   static double
240 < eadd(ep)
241 < EPNODE  *ep;
240 > eadd(
241 >    EPNODE      *ep
242 > )
243   {
244 <    register EPNODE  *ep1 = ep->v.kid;
244 >    EPNODE  *ep1 = ep->v.kid;
245  
246      return(evalue(ep1) + evalue(ep1->sibling));
247   }
248  
249   static double
250 < esubtr(ep)
251 < EPNODE  *ep;
250 > esubtr(
251 >    EPNODE      *ep
252 > )
253   {
254 <    register EPNODE  *ep1 = ep->v.kid;
254 >    EPNODE  *ep1 = ep->v.kid;
255  
256      return(evalue(ep1) - evalue(ep1->sibling));
257   }
258  
259   static double
260 < emult(ep)
261 < EPNODE  *ep;
260 > emult(
261 >    EPNODE      *ep
262 > )
263   {
264 <    register EPNODE  *ep1 = ep->v.kid;
264 >    EPNODE  *ep1 = ep->v.kid;
265  
266      return(evalue(ep1) * evalue(ep1->sibling));
267   }
268  
269   static double
270 < edivi(ep)
271 < EPNODE  *ep;
270 > edivi(
271 >    EPNODE      *ep
272 > )
273   {
274 <    register EPNODE  *ep1 = ep->v.kid;
274 >    EPNODE  *ep1 = ep->v.kid;
275      double  d;
276  
277      d = evalue(ep1->sibling);
# Line 267 | Line 284 | EPNODE *ep;
284   }
285  
286   static double
287 < epow(ep)
288 < EPNODE  *ep;
287 > epow(
288 >    EPNODE      *ep
289 > )
290   {
291 <    register EPNODE  *ep1 = ep->v.kid;
291 >    EPNODE  *ep1 = ep->v.kid;
292      double  d;
293      int  lasterrno;
294  
295      lasterrno = errno;
296      errno = 0;
297      d = pow(evalue(ep1), evalue(ep1->sibling));
298 < #ifdef  IEEE
299 <    if (!finite(d))
300 <        errno = EDOM;
298 > #ifdef  isnan
299 >    if (errno == 0) {
300 >        if (isnan(d))
301 >            errno = EDOM;
302 >        else if (isinf(d))
303 >            errno = ERANGE;
304 >    }
305   #endif
306 <    if (errno) {
306 >    if (errno == EDOM || errno == ERANGE) {
307          wputs("Illegal power\n");
308          return(0.0);
309      }
# Line 290 | Line 312 | EPNODE *ep;
312   }
313  
314   static double
315 < ebotch(ep)
316 < EPNODE  *ep;
315 > ebotch(
316 >    EPNODE      *ep
317 > )
318   {
319      eputs("Bad expression!\n");
320      quit(1);
321 +        return 0.0; /* pro forma return */
322   }
323  
324  
325   EPNODE *
326 < ekid(ep, n)                     /* return pointer to a node's nth kid */
327 < register EPNODE  *ep;
328 < register int  n;
326 > ekid(                   /* return pointer to a node's nth kid */
327 >    EPNODE       *ep,
328 >    int  n
329 > )
330   {
331  
332      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
# Line 313 | Line 338 | register int  n;
338  
339  
340   int
341 < nekids(ep)                      /* return # of kids for node ep */
342 < register EPNODE  *ep;
341 > nekids(                 /* return # of kids for node ep */
342 >    EPNODE       *ep
343 > )
344   {
345 <    register int  n = 0;
345 >    int  n = 0;
346  
347      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
348          n++;
# Line 326 | Line 352 | register EPNODE         *ep;
352  
353  
354   void
355 < initfile(fp, fn, ln)            /* prepare input file */
356 < FILE  *fp;
357 < char  *fn;
358 < int  ln;
355 > initfile(               /* prepare input file */
356 >    FILE  *fp,
357 >    char  *fn,
358 >    int  ln
359 > )
360   {
361      static char  inpbuf[MAXLINE];
362  
# Line 344 | Line 371 | int  ln;
371  
372  
373   void
374 < initstr(s, fn, ln)              /* prepare input string */
375 < char  *s;
376 < char  *fn;
377 < int  ln;
374 > initstr(                /* prepare input string */
375 >    char  *s,
376 >    char  *fn,
377 >    int  ln
378 > )
379   {
380      infp = NULL;
381      infile = fn;
# Line 359 | Line 387 | int  ln;
387  
388  
389   void
390 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
391 < char  **fnp;
392 < int  *lnp;
393 < char  **spp;
394 < FILE  **fpp;
390 > getscanpos(     /* return current scan position */
391 >    char  **fnp,
392 >    int  *lnp,
393 >    char  **spp,
394 >    FILE  **fpp
395 > )
396   {
397      if (fnp != NULL) *fnp = infile;
398      if (lnp != NULL) *lnp = lineno;
# Line 373 | Line 402 | FILE  **fpp;
402  
403  
404   int
405 < scan()                          /* scan next character, return literal next */
405 > scan(void)              /* scan next character, return literal next */
406   {
407 <    register int  lnext = 0;
407 >    int  lnext = 0;
408  
409      do {
410          if (linbuf[linepos] == '\0')
# Line 390 | Line 419 | scan()                         /* scan next character, return literal next
419              nextc = linbuf[linepos++];
420          if (!lnext)
421                  lnext = nextc;
422 +        if (nextc == eofc) {
423 +                nextc = EOF;
424 +                break;
425 +        }
426          if (nextc == '{') {
427              scan();
428              while (nextc != '}')
# Line 405 | Line 438 | scan()                         /* scan next character, return literal next
438  
439  
440   char *
441 < long2ascii(l)                         /* convert long to ascii */
442 < long  l;
441 > long2ascii(                           /* convert long to ascii */
442 >    long  l
443 > )
444   {
445      static char  buf[16];
446 <    register char  *cp;
446 >    char  *cp;
447      int  neg = 0;
448  
449      if (l == 0)
# Line 431 | Line 465 | long  l;
465  
466  
467   void
468 < syntax(err)                     /* report syntax error and quit */
469 < char  *err;
468 > syntax(                 /* report syntax error and quit */
469 >    char  *err
470 > )
471   {
472 <    register int  i;
472 >    int  i;
473  
474      if (infile != NULL || lineno != 0) {
475          if (infile != NULL) eputs(infile);
# Line 457 | Line 492 | char  *err;
492  
493  
494   void
495 < addekid(ep, ekid)                       /* add a child to ep */
496 < register EPNODE  *ep;
497 < EPNODE  *ekid;
495 > addekid(                        /* add a child to ep */
496 >    EPNODE       *ep,
497 >    EPNODE      *ekid
498 > )
499   {
500      if (ep->v.kid == NULL)
501          ep->v.kid = ekid;
# Line 473 | Line 509 | EPNODE *ekid;
509  
510  
511   char *
512 < getname()                       /* scan an identifier */
512 > getname(void)                   /* scan an identifier */
513   {
514 <    static char  str[MAXWORD+1];
515 <    register int  i, lnext;
514 >    static char  str[RMAXWORD+1];
515 >    int  i, lnext;
516  
517      lnext = nextc;
518 <    for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
518 >    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
519          str[i] = lnext;
520      str[i] = '\0';
521      while (isid(lnext))         /* skip rest of name */
# Line 490 | Line 526 | getname()                      /* scan an identifier */
526  
527  
528   int
529 < getinum()                       /* scan a positive integer */
529 > getinum(void)                   /* scan a positive integer */
530   {
531 <    register int  n, lnext;
531 >    int  n, lnext;
532  
533      n = 0;
534      lnext = nextc;
# Line 505 | Line 541 | getinum()                      /* scan a positive integer */
541  
542  
543   double
544 < getnum()                        /* scan a positive float */
544 > getnum(void)                    /* scan a positive float */
545   {
546 <    register int  i, lnext;
547 <    char  str[MAXWORD+1];
546 >    int  i, lnext;
547 >    char  str[RMAXWORD+1];
548  
549      i = 0;
550      lnext = nextc;
551 <    while (isdigit(lnext) && i < MAXWORD) {
551 >    while (isdigit(lnext) && i < RMAXWORD) {
552          str[i++] = lnext;
553          lnext = scan();
554      }
555 <    if (lnext == '.' && i < MAXWORD) {
555 >    if (lnext == '.' && i < RMAXWORD) {
556          str[i++] = lnext;
557          lnext = scan();
558          if (i == 1 && !isdigit(lnext))
559              syntax("badly formed number");
560 <        while (isdigit(lnext) && i < MAXWORD) {
560 >        while (isdigit(lnext) && i < RMAXWORD) {
561              str[i++] = lnext;
562              lnext = scan();
563          }
564      }
565 <    if ((lnext == 'e' | lnext == 'E') && i < MAXWORD) {
565 >    if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
566          str[i++] = lnext;
567          lnext = scan();
568 <        if ((lnext == '-' | lnext == '+') && i < MAXWORD) {
568 >        if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
569              str[i++] = lnext;
570              lnext = scan();
571          }
572          if (!isdigit(lnext))
573              syntax("missing exponent");
574 <        while (isdigit(lnext) && i < MAXWORD) {
574 >        while (isdigit(lnext) && i < RMAXWORD) {
575              str[i++] = lnext;
576              lnext = scan();
577          }
# Line 547 | Line 583 | getnum()                       /* scan a positive float */
583  
584  
585   EPNODE *
586 < getE1()                         /* E1 -> E1 ADDOP E2 */
586 > getE1(void)                     /* E1 -> E1 ADDOP E2 */
587                                  /*       E2 */
588   {
589 <    register EPNODE  *ep1, *ep2;
589 >    EPNODE  *ep1, *ep2;
590  
591      ep1 = getE2();
592      while (nextc == '+' || nextc == '-') {
# Line 569 | Line 605 | getE1()                                /* E1 -> E1 ADDOP E2 */
605  
606  
607   EPNODE *
608 < getE2()                         /* E2 -> E2 MULOP E3 */
608 > getE2(void)                     /* E2 -> E2 MULOP E3 */
609                                  /*       E3 */
610   {
611 <    register EPNODE  *ep1, *ep2;
611 >    EPNODE  *ep1, *ep2;
612  
613      ep1 = getE3();
614      while (nextc == '*' || nextc == '/') {
# Line 581 | Line 617 | getE2()                                /* E2 -> E2 MULOP E3 */
617          scan();
618          addekid(ep2, ep1);
619          addekid(ep2, getE3());
620 <        if (esupport&E_RCONST &&
621 <                        ep1->type == NUM && ep1->sibling->type == NUM)
622 <                ep2 = rconst(ep2);
620 >        if (esupport&E_RCONST) {
621 >                EPNODE  *ep3 = ep1->sibling;
622 >                if (ep1->type == NUM && ep3->type == NUM) {
623 >                        ep2 = rconst(ep2);
624 >                } else if (ep3->type == NUM) {
625 >                        if (ep2->type == '/') {
626 >                                if (ep3->v.num == 0)
627 >                                        syntax("divide by zero constant");
628 >                                ep2->type = '*';        /* for speed */
629 >                                ep3->v.num = 1./ep3->v.num;
630 >                        } else if (ep3->v.num == 0) {
631 >                                ep1->sibling = NULL;    /* (E2 * 0) */
632 >                                epfree(ep2);
633 >                                ep2 = ep3;
634 >                        }
635 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
636 >                        epfree(ep3);            /* (0 * E3) or (0 / E3) */
637 >                        ep1->sibling = NULL;
638 >                        efree((char *)ep2);
639 >                        ep2 = ep1;
640 >                }
641 >        }
642          ep1 = ep2;
643      }
644      return(ep1);
# Line 591 | Line 646 | getE2()                                /* E2 -> E2 MULOP E3 */
646  
647  
648   EPNODE *
649 < getE3()                         /* E3 -> E4 ^ E3 */
649 > getE3(void)                     /* E3 -> E4 ^ E3 */
650                                  /*       E4 */
651   {
652 <    register EPNODE  *ep1, *ep2;
652 >        EPNODE  *ep1, *ep2;
653  
654 <    ep1 = getE4();
655 <    if (nextc == '^') {
654 >        ep1 = getE4();
655 >        if (nextc != '^')
656 >                return(ep1);
657          ep2 = newnode();
658          ep2->type = nextc;
659          scan();
660          addekid(ep2, ep1);
661          addekid(ep2, getE3());
662 <        if (esupport&E_RCONST &&
663 <                        ep1->type == NUM && ep1->sibling->type == NUM)
664 <                ep2 = rconst(ep2);
662 >        if (esupport&E_RCONST) {
663 >                EPNODE  *ep3 = ep1->sibling;
664 >                if (ep1->type == NUM && ep3->type == NUM) {
665 >                        ep2 = rconst(ep2);
666 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
667 >                        epfree(ep3);            /* (0 ^ E3) */
668 >                        ep1->sibling = NULL;
669 >                        efree((char *)ep2);
670 >                        ep2 = ep1;
671 >                } else if ((ep3->type == NUM && ep3->v.num == 0) ||
672 >                                (ep1->type == NUM && ep1->v.num == 1)) {
673 >                        epfree(ep2);            /* (E4 ^ 0) or (1 ^ E3) */
674 >                        ep2 = newnode();
675 >                        ep2->type = NUM;
676 >                        ep2->v.num = 1;
677 >                }
678 >        }
679          return(ep2);
610    }
611    return(ep1);
680   }
681  
682  
683   EPNODE *
684 < getE4()                         /* E4 -> ADDOP E5 */
684 > getE4(void)                     /* E4 -> ADDOP E5 */
685                                  /*       E5 */
686   {
687 <    register EPNODE  *ep1, *ep2;
687 >    EPNODE  *ep1, *ep2;
688  
689      if (nextc == '-') {
690          scan();
# Line 626 | Line 694 | getE4()                                /* E4 -> ADDOP E5 */
694                  return(ep2);
695          }
696          if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
697 +            ep1 = ep2->v.kid;
698              efree((char *)ep2);
699 <            return(ep2->v.kid);
699 >            return(ep1);
700          }
701          ep1 = newnode();
702          ep1->type = UMINUS;
# Line 641 | Line 710 | getE4()                                /* E4 -> ADDOP E5 */
710  
711  
712   EPNODE *
713 < getE5()                         /* E5 -> (E1) */
713 > getE5(void)                     /* E5 -> (E1) */
714                                  /*       VAR */
715                                  /*       NUM */
716                                  /*       $N */
717                                  /*       FUNC(E1,..) */
718                                  /*       ARG */
719   {
720 <    int  i;
721 <    char  *nam;
722 <    register EPNODE  *ep1, *ep2;
720 >        int      i;
721 >        char  *nam;
722 >        EPNODE  *ep1, *ep2;
723  
724 <    if (nextc == '(') {
725 <        scan();
726 <        ep1 = getE1();
727 <        if (nextc != ')')
728 <            syntax("')' expected");
729 <        scan();
730 <        return(ep1);
731 <    }
724 >        if (nextc == '(') {
725 >                scan();
726 >                ep1 = getE1();
727 >                if (nextc != ')')
728 >                        syntax("')' expected");
729 >                scan();
730 >                return(ep1);
731 >        }
732  
733 <    if (esupport&E_INCHAN && nextc == '$') {
734 <        scan();
735 <        ep1 = newnode();
736 <        ep1->type = CHAN;
737 <        ep1->v.chan = getinum();
738 <        return(ep1);
739 <    }
733 >        if (esupport&E_INCHAN && nextc == '$') {
734 >                scan();
735 >                ep1 = newnode();
736 >                ep1->type = CHAN;
737 >                ep1->v.chan = getinum();
738 >                return(ep1);
739 >        }
740  
741 <  if (esupport&(E_VARIABLE|E_FUNCTION) &&
742 <                (isalpha(nextc) || nextc == CNTXMARK)) {
743 <      nam = getname();
744 <      ep1 = NULL;
745 <      if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
746 <                        && curfunc != NULL)
747 <            for (i = 1, ep2 = curfunc->v.kid->sibling;
748 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
749 <                if (!strcmp(ep2->v.name, nam)) {
750 <                    ep1 = newnode();
751 <                    ep1->type = ARG;
752 <                    ep1->v.chan = i;
753 <                    break;
741 >        if (esupport&(E_VARIABLE|E_FUNCTION) &&
742 >                        (isalpha(nextc) || nextc == CNTXMARK)) {
743 >                nam = getname();
744 >                ep1 = NULL;
745 >                if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
746 >                                && curfunc != NULL)
747 >                        for (i = 1, ep2 = curfunc->v.kid->sibling;
748 >                                        ep2 != NULL; i++, ep2 = ep2->sibling)
749 >                                if (!strcmp(ep2->v.name, nam)) {
750 >                                        ep1 = newnode();
751 >                                        ep1->type = ARG;
752 >                                        ep1->v.chan = i;
753 >                                        break;
754 >                                }
755 >                if (ep1 == NULL) {
756 >                        ep1 = newnode();
757 >                        ep1->type = VAR;
758 >                        ep1->v.ln = varinsert(nam);
759                  }
760 <        if (ep1 == NULL) {
761 <            ep1 = newnode();
762 <            ep1->type = VAR;
763 <            ep1->v.ln = varinsert(nam);
760 >                if (esupport&E_FUNCTION && nextc == '(') {
761 >                        ep2 = newnode();
762 >                        ep2->type = FUNC;
763 >                        addekid(ep2, ep1);
764 >                        ep1 = ep2;
765 >                        do {
766 >                                scan();
767 >                                addekid(ep1, getE1());
768 >                        } while (nextc == ',');
769 >                        if (nextc != ')')
770 >                                syntax("')' expected");
771 >                        scan();
772 >                } else if (!(esupport&E_VARIABLE))
773 >                        syntax("'(' expected");
774 >                if (esupport&E_RCONST && isconstvar(ep1))
775 >                        ep1 = rconst(ep1);
776 >                return(ep1);
777          }
691        if (esupport&E_FUNCTION && nextc == '(') {
692            ep2 = newnode();
693            ep2->type = FUNC;
694            addekid(ep2, ep1);
695            ep1 = ep2;
696            do {
697                scan();
698                addekid(ep1, getE1());
699            } while (nextc == ',');
700            if (nextc != ')')
701                syntax("')' expected");
702            scan();
703        } else if (!(esupport&E_VARIABLE))
704            syntax("'(' expected");
705        if (esupport&E_RCONST && isconstvar(ep1))
706            ep1 = rconst(ep1);
707        return(ep1);
708    }
778  
779 <    if (isdecimal(nextc)) {
780 <        ep1 = newnode();
781 <        ep1->type = NUM;
782 <        ep1->v.num = getnum();
783 <        return(ep1);
784 <    }
785 <    syntax("unexpected character");
779 >        if (isdecimal(nextc)) {
780 >                ep1 = newnode();
781 >                ep1->type = NUM;
782 >                ep1->v.num = getnum();
783 >                return(ep1);
784 >        }
785 >        syntax("unexpected character");
786 >        return NULL; /* pro forma return */
787   }
788  
789  
790   EPNODE *
791 < rconst(epar)                    /* reduce a constant expression */
792 < register EPNODE  *epar;
791 > rconst(                 /* reduce a constant expression */
792 >    EPNODE       *epar
793 > )
794   {
795 <    register EPNODE  *ep;
795 >    EPNODE  *ep;
796  
797      ep = newnode();
798      ep->type = NUM;
799      errno = 0;
800      ep->v.num = evalue(epar);
801 <    if (errno)
801 >    if (errno == EDOM || errno == ERANGE)
802          syntax("bad constant expression");
803      epfree(epar);
804  
# Line 736 | Line 807 | register EPNODE         *epar;
807  
808  
809   int
810 < isconstvar(ep)                  /* is ep linked to a constant expression? */
811 < register EPNODE  *ep;
810 > isconstvar(                     /* is ep linked to a constant expression? */
811 >    EPNODE       *ep
812 > )
813   {
814 <    register EPNODE  *ep1;
814 >    EPNODE  *ep1;
815  
816      if (esupport&E_FUNCTION && ep->type == FUNC) {
817          if (!isconstfun(ep->v.kid))
# Line 761 | Line 833 | register EPNODE         *ep;
833  
834  
835   int
836 < isconstfun(ep)                  /* is ep linked to a constant function? */
837 < register EPNODE  *ep;
836 > isconstfun(                     /* is ep linked to a constant function? */
837 >    EPNODE       *ep
838 > )
839   {
840 <    register EPNODE  *dp;
841 <    register LIBR  *lp;
840 >    EPNODE  *dp;
841 >    LIBR  *lp;
842  
843      if (ep->type != VAR)
844          return(0);
845 <    if ((dp = ep->v.ln->def) != NULL)
845 >    if ((dp = ep->v.ln->def) != NULL) {
846          if (dp->v.kid->type == FUNC)
847              return(dp->type == ':');
848          else
849              return(0);          /* don't identify masked library functions */
850 +    }
851      if ((lp = ep->v.ln->lib) != NULL)
852          return(lp->atyp == ':');
853      return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines