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.23 by schorsch, Thu Jul 3 22:41:44 2003 UTC vs.
Revision 2.46 by greg, Sat Feb 24 19:26:44 2024 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>
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();
38 < static double  echannel();
39 < static double  eadd(), esubtr(), emult(), edivi(), epow();
40 < static double  ebotch();
38 > #define  envalue(ep)    ((ep)->type==NUM ? (ep)->v.num : evalue(ep))
39  
40 + static double  euminus(EPNODE *), eargument(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 ;
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 79 | 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 94 | 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 125 | 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 135 | 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 156 | 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 174 | 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)        /* we don't really handle this properly */
222 >        epar->nkids *= -1;
223 >
224 >    for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
225 >        while (ep->type == epar->type) {
226 >            EPNODE      *ep1 = ep->v.kid;
227 >            while (ep1->sibling != NULL)
228 >                ep1 = ep1->sibling;
229 >            ep1->sibling = ep->sibling;
230 >            epar->nkids += nekids(ep) - 1;
231 >            ep1 = ep->v.kid;
232 >            *ep = *ep1;
233 >            efree(ep1);         /* not epfree()! */
234 >        }
235   }
236  
237 +
238 + void
239 + epoptimize(                     /* flatten operations and lists -> arrays */
240 +        EPNODE  *epar
241 + )
242 + {
243 +    EPNODE      *ep;
244 +
245 +    if ((epar->type == '+') | (epar->type == '*'))
246 +        epflatten(epar);        /* commutative & associative */
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 < eargument(ep)
270 < EPNODE  *ep;
269 > eargument(
270 >    EPNODE      *ep
271 > )
272   {
273      return(argument(ep->v.chan));
274   }
275  
276   static double
277 < enumber(ep)
278 < EPNODE  *ep;
277 > enumber(
278 >    EPNODE      *ep
279 > )
280   {
281      return(ep->v.num);
282   }
283  
284   static double
285 < euminus(ep)
286 < EPNODE  *ep;
285 > euminus(
286 >    EPNODE      *ep
287 > )
288   {
289 <    register EPNODE  *ep1 = ep->v.kid;
289 >    EPNODE  *ep1 = ep->v.kid;
290  
291      return(-evalue(ep1));
292   }
293  
294   static double
295 < echannel(ep)
296 < EPNODE  *ep;
295 > echannel(
296 >    EPNODE      *ep
297 > )
298   {
299      return(chanvalue(ep->v.chan));
300   }
301  
302   static double
303 < eadd(ep)
304 < EPNODE  *ep;
303 > eadd(
304 >    EPNODE      *ep
305 > )
306   {
307 <    register EPNODE  *ep1 = ep->v.kid;
307 >    double  sum = 0;
308 >    EPNODE  *ep1 = ep->v.kid;
309  
310 <    return(evalue(ep1) + evalue(ep1->sibling));
310 >    do
311 >        sum += envalue(ep1);
312 >    while ((ep1 = ep1->sibling) != NULL);
313 >
314 >    return(sum);
315   }
316  
317   static double
318 < esubtr(ep)
319 < EPNODE  *ep;
318 > esubtr(
319 >    EPNODE      *ep
320 > )
321   {
322 <    register EPNODE  *ep1 = ep->v.kid;
322 >    EPNODE  *ep1 = ep->v.kid;
323 >    EPNODE  *ep2 = ep1->sibling;
324  
325 <    return(evalue(ep1) - evalue(ep1->sibling));
325 >    return(envalue(ep1) - envalue(ep2));
326   }
327  
328   static double
329 < emult(ep)
330 < EPNODE  *ep;
329 > emult(
330 >    EPNODE      *ep
331 > )
332   {
333 <    register EPNODE  *ep1 = ep->v.kid;
333 >    double  prod = 1;
334 >    EPNODE  *ep1 = ep->v.kid;
335  
336 <    return(evalue(ep1) * evalue(ep1->sibling));
336 >    do
337 >        prod *= envalue(ep1);
338 >    while ((ep1 = ep1->sibling) != NULL);
339 >
340 >    return(prod);
341   }
342  
343   static double
344 < edivi(ep)
345 < EPNODE  *ep;
344 > edivi(
345 >    EPNODE      *ep
346 > )
347   {
348 <    register EPNODE  *ep1 = ep->v.kid;
348 >    EPNODE  *ep1 = ep->v.kid;
349 >    EPNODE  *ep2 = ep1->sibling;
350      double  d;
351  
352 <    d = evalue(ep1->sibling);
352 >    d = evalue(ep2);
353      if (d == 0.0) {
354          wputs("Division by zero\n");
355          errno = ERANGE;
356          return(0.0);
357      }
358 <    return(evalue(ep1) / d);
358 >    return(envalue(ep1) / d);
359   }
360  
361   static double
362 < epow(ep)
363 < EPNODE  *ep;
362 > epow(
363 >    EPNODE      *ep
364 > )
365   {
366 <    register EPNODE  *ep1 = ep->v.kid;
366 >    EPNODE  *ep1 = ep->v.kid;
367      double  d;
368      int  lasterrno;
369  
370      lasterrno = errno;
371      errno = 0;
372      d = pow(evalue(ep1), evalue(ep1->sibling));
373 < #ifdef  IEEE
374 <    if (!finite(d))
375 <        errno = EDOM;
373 > #ifdef  isnan
374 >    if (errno == 0) {
375 >        if (isnan(d))
376 >            errno = EDOM;
377 >        else if (isinf(d))
378 >            errno = ERANGE;
379 >    }
380   #endif
381 <    if (errno == EDOM || errno == ERANGE) {
381 >    if ((errno == EDOM) | (errno == ERANGE)) {
382          wputs("Illegal power\n");
383          return(0.0);
384      }
# Line 287 | Line 387 | EPNODE *ep;
387   }
388  
389   static double
390 < ebotch(ep)
391 < EPNODE  *ep;
390 > ebotch(
391 >    EPNODE      *ep
392 > )
393   {
394      eputs("Bad expression!\n");
395      quit(1);
# Line 297 | Line 398 | EPNODE *ep;
398  
399  
400   EPNODE *
401 < ekid(ep, n)                     /* return pointer to a node's nth kid */
402 < register EPNODE  *ep;
403 < register int  n;
401 > ekid(                   /* return pointer to a node's nth kid */
402 >    EPNODE       *ep,
403 >    int  n
404 > )
405   {
406 <
407 <    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
408 <        if (--n < 0)
409 <            break;
410 <
406 >    if (ep->nkids < 0) {        /* allocated array? */
407 >        if (n >= -ep->nkids)
408 >            return(NULL);
409 >        return(ep->v.kid + n);
410 >    }
411 >    ep = ep->v.kid;             /* else get from list */
412 >    while (n-- > 0)
413 >        if ((ep = ep->sibling) == NULL)
414 >                break;
415      return(ep);
416   }
417  
418  
313 int
314 nekids(ep)                      /* return # of kids for node ep */
315 register EPNODE  *ep;
316 {
317    register int  n = 0;
318
319    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
320        n++;
321
322    return(n);
323 }
324
325
419   void
420 < initfile(fp, fn, ln)            /* prepare input file */
421 < FILE  *fp;
422 < char  *fn;
423 < int  ln;
420 > initfile(               /* prepare input file */
421 >    FILE  *fp,
422 >    char  *fn,
423 >    int  ln
424 > )
425   {
426      static char  inpbuf[MAXLINE];
427  
# Line 342 | Line 436 | int  ln;
436  
437  
438   void
439 < initstr(s, fn, ln)              /* prepare input string */
440 < char  *s;
441 < char  *fn;
442 < int  ln;
439 > initstr(                /* prepare input string */
440 >    char  *s,
441 >    char  *fn,
442 >    int  ln
443 > )
444   {
445      infp = NULL;
446      infile = fn;
# Line 357 | Line 452 | int  ln;
452  
453  
454   void
455 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
456 < char  **fnp;
457 < int  *lnp;
458 < char  **spp;
459 < FILE  **fpp;
455 > getscanpos(     /* return current scan position */
456 >    char  **fnp,
457 >    int  *lnp,
458 >    char  **spp,
459 >    FILE  **fpp
460 > )
461   {
462      if (fnp != NULL) *fnp = infile;
463      if (lnp != NULL) *lnp = lineno;
# Line 371 | Line 467 | FILE  **fpp;
467  
468  
469   int
470 < scan()                          /* scan next character, return literal next */
470 > scan(void)              /* scan next character, return literal next */
471   {
472 <    register int  lnext = 0;
472 >    int  lnext = 0;
473  
474      do {
475          if (linbuf[linepos] == '\0')
# Line 388 | Line 484 | scan()                         /* scan next character, return literal next
484              nextc = linbuf[linepos++];
485          if (!lnext)
486                  lnext = nextc;
487 +        if (nextc == eofc) {
488 +                nextc = EOF;
489 +                break;
490 +        }
491          if (nextc == '{') {
492              scan();
493              while (nextc != '}')
# Line 403 | Line 503 | scan()                         /* scan next character, return literal next
503  
504  
505   char *
506 < long2ascii(l)                         /* convert long to ascii */
507 < long  l;
506 > long2ascii(                           /* convert long to ascii */
507 >    long  l
508 > )
509   {
510      static char  buf[16];
511 <    register char  *cp;
511 >    char  *cp;
512      int  neg = 0;
513  
514      if (l == 0)
# Line 429 | Line 530 | long  l;
530  
531  
532   void
533 < syntax(err)                     /* report syntax error and quit */
534 < char  *err;
533 > syntax(                 /* report syntax error and quit */
534 >    char  *err
535 > )
536   {
537 <    register int  i;
537 >    int  i;
538  
539 <    if (infile != NULL || lineno != 0) {
539 >    if ((infile != NULL) | (lineno != 0)) {
540          if (infile != NULL) eputs(infile);
541          if (lineno != 0) {
542              eputs(infile != NULL ? ", line " : "line ");
# Line 455 | Line 557 | char  *err;
557  
558  
559   void
560 < addekid(ep, ekid)                       /* add a child to ep */
561 < register EPNODE  *ep;
562 < EPNODE  *ekid;
560 > addekid(                        /* add a child to ep */
561 >    EPNODE       *ep,
562 >    EPNODE      *ek
563 > )
564   {
565 +    if (ep->nkids < 0)          /* we don't really handle this properly */
566 +        ep->nkids *= -1;
567 +    ep->nkids++;
568      if (ep->v.kid == NULL)
569 <        ep->v.kid = ekid;
569 >        ep->v.kid = ek;
570      else {
571          for (ep = ep->v.kid; ep->sibling != NULL; ep = ep->sibling)
572              ;
573 <        ep->sibling = ekid;
573 >        ep->sibling = ek;
574      }
575 <    ekid->sibling = NULL;
575 >    ek->sibling = NULL;         /* shouldn't be necessary */
576   }
577  
578  
579   char *
580 < getname()                       /* scan an identifier */
580 > getname(void)                   /* scan an identifier */
581   {
582      static char  str[RMAXWORD+1];
583 <    register int  i, lnext;
583 >    int  i, lnext;
584  
585      lnext = nextc;
586      for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
# Line 488 | Line 594 | getname()                      /* scan an identifier */
594  
595  
596   int
597 < getinum()                       /* scan a positive integer */
597 > getinum(void)                   /* scan a positive integer */
598   {
599 <    register int  n, lnext;
599 >    int  n, lnext;
600  
601      n = 0;
602      lnext = nextc;
# Line 503 | Line 609 | getinum()                      /* scan a positive integer */
609  
610  
611   double
612 < getnum()                        /* scan a positive float */
612 > getnum(void)                    /* scan a positive float */
613   {
614 <    register int  i, lnext;
614 >    int  i, lnext;
615      char  str[RMAXWORD+1];
616  
617      i = 0;
# Line 514 | Line 620 | getnum()                       /* scan a positive float */
620          str[i++] = lnext;
621          lnext = scan();
622      }
623 <    if (lnext == '.' && i < RMAXWORD) {
623 >    if ((lnext == '.') & (i < RMAXWORD)) {
624          str[i++] = lnext;
625          lnext = scan();
626          if (i == 1 && !isdigit(lnext))
# Line 524 | Line 630 | getnum()                       /* scan a positive float */
630              lnext = scan();
631          }
632      }
633 <    if ((lnext == 'e' | lnext == 'E') && i < RMAXWORD) {
633 >    if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
634          str[i++] = lnext;
635          lnext = scan();
636 <        if ((lnext == '-' | lnext == '+') && i < RMAXWORD) {
636 >        if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
637              str[i++] = lnext;
638              lnext = scan();
639          }
# Line 545 | Line 651 | getnum()                       /* scan a positive float */
651  
652  
653   EPNODE *
654 < getE1()                         /* E1 -> E1 ADDOP E2 */
654 > getE1(void)                     /* E1 -> E1 ADDOP E2 */
655                                  /*       E2 */
656   {
657 <    register EPNODE  *ep1, *ep2;
657 >    EPNODE  *ep1, *ep2;
658  
659      ep1 = getE2();
660 <    while (nextc == '+' || nextc == '-') {
660 >    while ((nextc == '+') | (nextc == '-')) {
661          ep2 = newnode();
662          ep2->type = nextc;
663          scan();
664          addekid(ep2, ep1);
665          addekid(ep2, getE2());
666          if (esupport&E_RCONST &&
667 <                        ep1->type == NUM && ep1->sibling->type == NUM)
667 >                        (ep1->type == NUM) & (ep1->sibling->type == NUM))
668                  ep2 = rconst(ep2);
669          ep1 = ep2;
670      }
# Line 567 | Line 673 | getE1()                                /* E1 -> E1 ADDOP E2 */
673  
674  
675   EPNODE *
676 < getE2()                         /* E2 -> E2 MULOP E3 */
676 > getE2(void)                     /* E2 -> E2 MULOP E3 */
677                                  /*       E3 */
678   {
679 <    register EPNODE  *ep1, *ep2;
679 >    EPNODE  *ep1, *ep2;
680  
681      ep1 = getE3();
682 <    while (nextc == '*' || nextc == '/') {
682 >    while ((nextc == '*') | (nextc == '/')) {
683          ep2 = newnode();
684          ep2->type = nextc;
685          scan();
686          addekid(ep2, ep1);
687          addekid(ep2, getE3());
688 <        if (esupport&E_RCONST &&
689 <                        ep1->type == NUM && ep1->sibling->type == NUM)
690 <                ep2 = rconst(ep2);
688 >        if (esupport&E_RCONST) {
689 >                EPNODE  *ep3 = ep1->sibling;
690 >                if ((ep1->type == NUM) & (ep3->type == NUM)) {
691 >                        ep2 = rconst(ep2);
692 >                } else if (ep3->type == NUM) {
693 >                        if (ep2->type == '/') {
694 >                                if (ep3->v.num == 0)
695 >                                        syntax("divide by zero constant");
696 >                                ep2->type = '*';        /* for speed */
697 >                                ep3->v.num = 1./ep3->v.num;
698 >                        } else if (ep3->v.num == 0) {
699 >                                ep1->sibling = NULL;    /* (E2 * 0) */
700 >                                epfree(ep2,1);
701 >                                ep2 = ep3;
702 >                        }
703 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
704 >                        epfree(ep3,1);          /* (0 * E3) or (0 / E3) */
705 >                        ep1->sibling = NULL;
706 >                        efree(ep2);
707 >                        ep2 = ep1;
708 >                }
709 >        }
710          ep1 = ep2;
711      }
712      return(ep1);
# Line 589 | Line 714 | getE2()                                /* E2 -> E2 MULOP E3 */
714  
715  
716   EPNODE *
717 < getE3()                         /* E3 -> E4 ^ E3 */
717 > getE3(void)                     /* E3 -> E4 ^ E3 */
718                                  /*       E4 */
719   {
720 <    register EPNODE  *ep1, *ep2;
720 >        EPNODE  *ep1, *ep2;
721  
722 <    ep1 = getE4();
723 <    if (nextc == '^') {
722 >        ep1 = getE4();
723 >        if (nextc != '^')
724 >                return(ep1);
725          ep2 = newnode();
726          ep2->type = nextc;
727          scan();
728          addekid(ep2, ep1);
729          addekid(ep2, getE3());
730 <        if (esupport&E_RCONST &&
731 <                        ep1->type == NUM && ep1->sibling->type == NUM)
732 <                ep2 = rconst(ep2);
730 >        if (esupport&E_RCONST) {
731 >                EPNODE  *ep3 = ep1->sibling;
732 >                if ((ep1->type == NUM) & (ep3->type == NUM)) {
733 >                        ep2 = rconst(ep2);
734 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
735 >                        epfree(ep3,1);          /* (0 ^ E3) */
736 >                        ep1->sibling = NULL;
737 >                        efree(ep2);
738 >                        ep2 = ep1;
739 >                } else if ((ep3->type == NUM && ep3->v.num == 0) |
740 >                                (ep1->type == NUM && ep1->v.num == 1)) {
741 >                        epfree(ep2,1);          /* (E4 ^ 0) or (1 ^ E3) */
742 >                        ep2 = newnode();
743 >                        ep2->type = NUM;
744 >                        ep2->v.num = 1;
745 >                } else if (ep3->type == NUM && ep3->v.num == 1) {
746 >                        efree(ep3);     /* (E4 ^ 1) */
747 >                        ep1->sibling = NULL;
748 >                        efree(ep2);
749 >                        ep2 = ep1;
750 >                }
751 >        }
752          return(ep2);
608    }
609    return(ep1);
753   }
754  
755  
756   EPNODE *
757 < getE4()                         /* E4 -> ADDOP E5 */
757 > getE4(void)                     /* E4 -> ADDOP E5 */
758                                  /*       E5 */
759   {
760 <    register EPNODE  *ep1, *ep2;
760 >    EPNODE  *ep1, *ep2;
761  
762      if (nextc == '-') {
763          scan();
# Line 624 | Line 767 | getE4()                                /* E4 -> ADDOP E5 */
767                  return(ep2);
768          }
769          if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
770 <            efree((char *)ep2);
771 <            return(ep2->v.kid);
770 >            ep1 = ep2->v.kid;
771 >            efree(ep2);
772 >            return(ep1);
773          }
774          ep1 = newnode();
775          ep1->type = UMINUS;
# Line 639 | Line 783 | getE4()                                /* E4 -> ADDOP E5 */
783  
784  
785   EPNODE *
786 < getE5()                         /* E5 -> (E1) */
786 > getE5(void)                     /* E5 -> (E1) */
787                                  /*       VAR */
788                                  /*       NUM */
789                                  /*       $N */
# Line 648 | Line 792 | getE5()                                /* E5 -> (E1) */
792   {
793          int      i;
794          char  *nam;
795 <        register EPNODE  *ep1, *ep2;
795 >        EPNODE  *ep1, *ep2;
796  
797          if (nextc == '(') {
798                  scan();
# Line 658 | Line 802 | getE5()                                /* E5 -> (E1) */
802                  scan();
803                  return(ep1);
804          }
661
805          if (esupport&E_INCHAN && nextc == '$') {
806                  scan();
807                  ep1 = newnode();
# Line 666 | Line 809 | getE5()                                /* E5 -> (E1) */
809                  ep1->v.chan = getinum();
810                  return(ep1);
811          }
669
812          if (esupport&(E_VARIABLE|E_FUNCTION) &&
813 <                        (isalpha(nextc) || nextc == CNTXMARK)) {
813 >                        (isalpha(nextc) | (nextc == CNTXMARK))) {
814                  nam = getname();
815                  ep1 = NULL;
816                  if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
# Line 704 | Line 846 | getE5()                                /* E5 -> (E1) */
846                          ep1 = rconst(ep1);
847                  return(ep1);
848          }
707
849          if (isdecimal(nextc)) {
850                  ep1 = newnode();
851                  ep1->type = NUM;
# Line 717 | Line 858 | getE5()                                /* E5 -> (E1) */
858  
859  
860   EPNODE *
861 < rconst(epar)                    /* reduce a constant expression */
862 < register EPNODE  *epar;
861 > rconst(                 /* reduce a constant expression */
862 >    EPNODE       *epar
863 > )
864   {
865 <    register EPNODE  *ep;
865 >    EPNODE  *ep;
866  
867      ep = newnode();
868      ep->type = NUM;
869      errno = 0;
870      ep->v.num = evalue(epar);
871 <    if (errno == EDOM || errno == ERANGE)
871 >    if ((errno == EDOM) | (errno == ERANGE))
872          syntax("bad constant expression");
873 <    epfree(epar);
873 >    epfree(epar,1);
874  
875      return(ep);
876   }
877  
878  
879   int
880 < isconstvar(ep)                  /* is ep linked to a constant expression? */
881 < register EPNODE  *ep;
880 > isconstvar(                     /* is ep linked to a constant expression? */
881 >    EPNODE       *ep
882 > )
883   {
884 <    register EPNODE  *ep1;
884 >    EPNODE  *ep1;
885  
886      if (esupport&E_FUNCTION && ep->type == FUNC) {
887          if (!isconstfun(ep->v.kid))
# Line 760 | Line 903 | register EPNODE         *ep;
903  
904  
905   int
906 < isconstfun(ep)                  /* is ep linked to a constant function? */
907 < register EPNODE  *ep;
906 > isconstfun(                     /* is ep linked to a constant function? */
907 >    EPNODE       *ep
908 > )
909   {
910 <    register EPNODE  *dp;
911 <    register LIBR  *lp;
910 >    EPNODE  *dp;
911 >    LIBR  *lp;
912  
913      if (ep->type != VAR)
914          return(0);
915 <    if ((dp = ep->v.ln->def) != NULL)
915 >    if ((dp = ep->v.ln->def) != NULL) {
916          if (dp->v.kid->type == FUNC)
917              return(dp->type == ':');
918          else
919              return(0);          /* don't identify masked library functions */
920 +    }
921      if ((lp = ep->v.ln->lib) != NULL)
922          return(lp->atyp == ':');
923      return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines