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 1.13 by greg, Thu Aug 8 12:11:19 1991 UTC vs.
Revision 2.17 by gwlarson, Mon Aug 17 17:57:30 1998 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1986 Regents of the University of California */
1 > /* Copyright (c) 1998 Silicon Graphics, Inc. */
2  
3   #ifndef lint
4 < static char SCCSid[] = "$SunId$ LBL";
4 > static char SCCSid[] = "$SunId$ SGI";
5   #endif
6  
7   /*
# Line 24 | Line 24 | static char SCCSid[] = "$SunId$ LBL";
24  
25   #include  <errno.h>
26  
27 + #include  <math.h>
28 +
29   #include  "calcomp.h"
30  
31 < #define  MAXLINE        256             /* maximum line length */
31 > #define  MAXLINE        256             /* maximum line length */
32  
33 < #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
33 > #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
34  
35 < #define  isdecimal(c)   (isdigit(c) || (c) == '.')
35 > #define  isdecimal(c)   (isdigit(c) || (c) == '.')
36  
37 < extern double  atof(), pow();
36 < extern char  *fgets(), *savestr();
37 > extern char  *savestr();
38   extern char  *emalloc(), *ecalloc();
39   extern EPNODE  *curfunc;
40   extern double  efunc(), evariable();
41 < static double  euminus(), echannel(), eargument(), enumber();
41 > static double  euminus(), eargument(), enumber();
42 > #ifdef  INCHAN
43 > static double  echannel();
44 > #endif
45   static double  eadd(), esubtr(), emult(), edivi(), epow();
46   static double  ebotch();
43 extern int  errno;
47  
48 + #ifdef  DCL_ATOF
49 + extern double  atof();
50 + #endif
51 +
52   int  nextc;                             /* lookahead character */
53  
54 < double  (*eoper[])() = {                /* expression operations */
54 > double  (*eoper[])() = {                /* expression operations */
55          ebotch,
56 < #ifdef  VARIABLE
56 > #ifdef  VARIABLE
57          evariable,
58   #else
59          ebotch,
60   #endif
61          enumber,
62          euminus,
63 < #ifdef  INCHAN
63 > #ifdef  INCHAN
64          echannel,
65   #else
66          ebotch,
67   #endif
68 < #ifdef  FUNCTION
68 > #ifdef  FUNCTION
69          efunc,
70          eargument,
71   #else
# Line 122 | Line 129 | char  *expr;
129   }
130  
131  
132 + epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
133 + register EPNODE  *ep1, *ep2;
134 + {
135 +        double  d;
136 +
137 +        if (ep1->type != ep2->type)
138 +                return(1);
139 +
140 +        switch (ep1->type) {
141 +
142 +        case VAR:
143 +                return(ep1->v.ln != ep2->v.ln);
144 +
145 +        case NUM:
146 +                if (ep2->v.num == 0)
147 +                        return(ep1->v.num != 0);
148 +                d = ep1->v.num / ep2->v.num;
149 +                return(d > 1.000000000001 | d < 0.999999999999);
150 +
151 +        case CHAN:
152 +        case ARG:
153 +                return(ep1->v.chan != ep2->v.chan);
154 +
155 +        case '=':
156 +        case ':':
157 +                return(epcmp(ep1->v.kid->sibling, ep2->v.kid->sibling));
158 +
159 +        case TICK:
160 +        case SYM:                       /* should never get this one */
161 +                return(0);
162 +
163 +        default:
164 +                ep1 = ep1->v.kid;
165 +                ep2 = ep2->v.kid;
166 +                while (ep1 != NULL) {
167 +                        if (ep2 == NULL)
168 +                                return(1);
169 +                        if (epcmp(ep1, ep2))
170 +                                return(1);
171 +                        ep1 = ep1->sibling;
172 +                        ep2 = ep2->sibling;
173 +                }
174 +                return(ep2 != NULL);
175 +        }
176 + }
177 +
178 +
179   epfree(epar)                    /* free a parse tree */
180 < register EPNODE  *epar;
180 > register EPNODE  *epar;
181   {
182      register EPNODE  *ep;
183  
# Line 133 | Line 187 | register EPNODE  *epar;
187          case VAR:
188              varfree(epar->v.ln);
189              break;
136 #endif
190              
191          case SYM:
192              freestr(epar->v.name);
193              break;
194 + #endif
195  
196          case NUM:
197          case CHAN:
# Line 146 | Line 200 | register EPNODE  *epar;
200              break;
201  
202          default:
203 <            for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
203 >            while ((ep = epar->v.kid) != NULL) {
204 >                epar->v.kid = ep->sibling;
205                  epfree(ep);
206 +            }
207              break;
208  
209      }
# Line 156 | Line 212 | register EPNODE  *epar;
212   }
213  
214                                  /* the following used to be a switch */
215 < #ifdef  FUNCTION
215 > #ifdef  FUNCTION
216   static double
217   eargument(ep)
218 < EPNODE  *ep;
218 > EPNODE  *ep;
219   {
220      return(argument(ep->v.chan));
221   }
# Line 167 | Line 223 | EPNODE  *ep;
223  
224   static double
225   enumber(ep)
226 < EPNODE  *ep;
226 > EPNODE  *ep;
227   {
228      return(ep->v.num);
229   }
230  
231   static double
232   euminus(ep)
233 < EPNODE  *ep;
233 > EPNODE  *ep;
234   {
235      register EPNODE  *ep1 = ep->v.kid;
236  
237      return(-evalue(ep1));
238   }
239  
240 < #ifdef  INCHAN
240 > #ifdef  INCHAN
241   static double
242   echannel(ep)
243 < EPNODE  *ep;
243 > EPNODE  *ep;
244   {
245      return(chanvalue(ep->v.chan));
246   }
# Line 192 | Line 248 | EPNODE  *ep;
248  
249   static double
250   eadd(ep)
251 < EPNODE  *ep;
251 > EPNODE  *ep;
252   {
253      register EPNODE  *ep1 = ep->v.kid;
254  
# Line 201 | Line 257 | EPNODE  *ep;
257  
258   static double
259   esubtr(ep)
260 < EPNODE  *ep;
260 > EPNODE  *ep;
261   {
262      register EPNODE  *ep1 = ep->v.kid;
263  
# Line 210 | Line 266 | EPNODE  *ep;
266  
267   static double
268   emult(ep)
269 < EPNODE  *ep;
269 > EPNODE  *ep;
270   {
271      register EPNODE  *ep1 = ep->v.kid;
272  
# Line 219 | Line 275 | EPNODE  *ep;
275  
276   static double
277   edivi(ep)
278 < EPNODE  *ep;
278 > EPNODE  *ep;
279   {
280      register EPNODE  *ep1 = ep->v.kid;
281      double  d;
# Line 235 | Line 291 | EPNODE  *ep;
291  
292   static double
293   epow(ep)
294 < EPNODE  *ep;
294 > EPNODE  *ep;
295   {
296      register EPNODE  *ep1 = ep->v.kid;
297      double  d;
298 <    int  lasterrno;
298 >    int  lasterrno;
299  
300      lasterrno = errno;
301      errno = 0;
302      d = pow(evalue(ep1), evalue(ep1->sibling));
303 < #ifdef  IEEE
303 > #ifdef  IEEE
304      if (!finite(d))
305          errno = EDOM;
306   #endif
# Line 258 | Line 314 | EPNODE  *ep;
314  
315   static double
316   ebotch(ep)
317 < EPNODE  *ep;
317 > EPNODE  *ep;
318   {
319      eputs("Bad expression!\n");
320      quit(1);
# Line 267 | Line 323 | EPNODE  *ep;
323  
324   EPNODE *
325   ekid(ep, n)                     /* return pointer to a node's nth kid */
326 < register EPNODE  *ep;
326 > register EPNODE  *ep;
327   register int  n;
328   {
329  
# Line 281 | Line 337 | register int  n;
337  
338   int
339   nekids(ep)                      /* return # of kids for node ep */
340 < register EPNODE  *ep;
340 > register EPNODE  *ep;
341   {
342      register int  n = 0;
343  
# Line 297 | Line 353 | FILE  *fp;
353   char  *fn;
354   int  ln;
355   {
356 <    static char  inpbuf[MAXLINE];
356 >    static char  inpbuf[MAXLINE];
357  
358      infp = fp;
359      linbuf = inpbuf;
# Line 369 | Line 425 | scan()                         /* scan next character, return literal next
425  
426  
427   char *
428 < ltoa(l)                         /* convert long to ascii */
428 > long2ascii(l)                         /* convert long to ascii */
429   long  l;
430   {
431 <    static char  buf[16];
431 >    static char  buf[16];
432      register char  *cp;
433 <    int  neg = 0;
433 >    int  neg = 0;
434  
435      if (l == 0)
436          return("0");
# Line 403 | Line 459 | char  *err;
459          if (infile != NULL) eputs(infile);
460          if (lineno != 0) {
461              eputs(infile != NULL ? ", line " : "line ");
462 <            eputs(ltoa((long)lineno));
462 >            eputs(long2ascii((long)lineno));
463          }
464 <        eputs(": syntax error:\n");
464 >        eputs(":\n");
465      }
466      eputs(linbuf);
467      if (linbuf[strlen(linbuf)-1] != '\n')
# Line 420 | Line 476 | char  *err;
476  
477  
478   addekid(ep, ekid)                       /* add a child to ep */
479 < register EPNODE  *ep;
480 < EPNODE  *ekid;
479 > register EPNODE  *ep;
480 > EPNODE  *ekid;
481   {
482      if (ep->v.kid == NULL)
483          ep->v.kid = ekid;
# Line 434 | Line 490 | EPNODE  *ekid;
490   }
491  
492  
493 + #if  defined(VARIABLE) || defined(FUNCTION)
494   char *
495   getname()                       /* scan an identifier */
496   {
497 <    static char  str[MAXWORD+1];
497 >    static char  str[MAXWORD+1];
498      register int  i, lnext;
499  
500      lnext = nextc;
501      for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
502          str[i] = lnext;
503      str[i] = '\0';
504 +    while (isid(lnext))         /* skip rest of name */
505 +        lnext = scan();
506  
507      return(str);
508   }
509 + #endif
510  
511  
512   int
# Line 477 | Line 537 | getnum()                       /* scan a positive float */
537          lnext = scan();
538      }
539      if (lnext == '.' && i < MAXWORD) {
540 <        str[i++] = lnext;
541 <        lnext = scan();
540 >        str[i++] = lnext;
541 >        lnext = scan();
542 >        if (i == 1 && !isdigit(lnext))
543 >            syntax("badly formed number");
544          while (isdigit(lnext) && i < MAXWORD) {
545              str[i++] = lnext;
546              lnext = scan();
547          }
548      }
549 <    if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) {
550 <        str[i++] = lnext;
551 <        lnext = scan();
552 <        if ((lnext == '-' || lnext == '+') && i < MAXWORD) {
549 >    if ((lnext == 'e' | lnext == 'E') && i < MAXWORD) {
550 >        str[i++] = lnext;
551 >        lnext = scan();
552 >        if ((lnext == '-' | lnext == '+') && i < MAXWORD) {
553              str[i++] = lnext;
554              lnext = scan();
555          }
556 +        if (!isdigit(lnext))
557 +            syntax("missing exponent");
558          while (isdigit(lnext) && i < MAXWORD) {
559              str[i++] = lnext;
560              lnext = scan();
# Line 504 | Line 568 | getnum()                       /* scan a positive float */
568  
569   EPNODE *
570   getE1()                         /* E1 -> E1 ADDOP E2 */
571 <                                /*       E2 */
571 >                                /*       E2 */
572   {
573      register EPNODE  *ep1, *ep2;
574  
# Line 515 | Line 579 | getE1()                                /* E1 -> E1 ADDOP E2 */
579          scan();
580          addekid(ep2, ep1);
581          addekid(ep2, getE2());
582 < #ifdef  RCONST
582 > #ifdef  RCONST
583          if (ep1->type == NUM && ep1->sibling->type == NUM)
584                  ep2 = rconst(ep2);
585   #endif
# Line 527 | Line 591 | getE1()                                /* E1 -> E1 ADDOP E2 */
591  
592   EPNODE *
593   getE2()                         /* E2 -> E2 MULOP E3 */
594 <                                /*       E3 */
594 >                                /*       E3 */
595   {
596      register EPNODE  *ep1, *ep2;
597  
# Line 538 | Line 602 | getE2()                                /* E2 -> E2 MULOP E3 */
602          scan();
603          addekid(ep2, ep1);
604          addekid(ep2, getE3());
605 < #ifdef  RCONST
605 > #ifdef  RCONST
606          if (ep1->type == NUM && ep1->sibling->type == NUM)
607                  ep2 = rconst(ep2);
608   #endif
# Line 550 | Line 614 | getE2()                                /* E2 -> E2 MULOP E3 */
614  
615   EPNODE *
616   getE3()                         /* E3 -> E4 ^ E3 */
617 <                                /*       E4 */
617 >                                /*       E4 */
618   {
619      register EPNODE  *ep1, *ep2;
620  
# Line 561 | Line 625 | getE3()                                /* E3 -> E4 ^ E3 */
625          scan();
626          addekid(ep2, ep1);
627          addekid(ep2, getE3());
628 < #ifdef  RCONST
628 > #ifdef  RCONST
629          if (ep1->type == NUM && ep1->sibling->type == NUM)
630                  ep2 = rconst(ep2);
631   #endif
# Line 573 | Line 637 | getE3()                                /* E3 -> E4 ^ E3 */
637  
638   EPNODE *
639   getE4()                         /* E4 -> ADDOP E5 */
640 <                                /*       E5 */
640 >                                /*       E5 */
641   {
642      register EPNODE  *ep1, *ep2;
643  
# Line 584 | Line 648 | getE4()                                /* E4 -> ADDOP E5 */
648                  ep2->v.num = -ep2->v.num;
649                  return(ep2);
650          }
651 +        if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
652 +            efree((char *)ep2);
653 +            return(ep2->v.kid);
654 +        }
655          ep1 = newnode();
656          ep1->type = UMINUS;
657          addekid(ep1, ep2);
# Line 597 | Line 665 | getE4()                                /* E4 -> ADDOP E5 */
665  
666   EPNODE *
667   getE5()                         /* E5 -> (E1) */
668 <                                /*       VAR */
669 <                                /*       NUM */
670 <                                /*       $N */
671 <                                /*       FUNC(E1,..) */
672 <                                /*       ARG */
668 >                                /*       VAR */
669 >                                /*       NUM */
670 >                                /*       $N */
671 >                                /*       FUNC(E1,..) */
672 >                                /*       ARG */
673   {
674 <    int  i;
674 >    int  i;
675 >    char  *nam;
676      register EPNODE  *ep1, *ep2;
677  
678      if (nextc == '(') {
# Line 615 | Line 684 | getE5()                                /* E5 -> (E1) */
684          return(ep1);
685      }
686  
687 < #ifdef  INCHAN
687 > #ifdef  INCHAN
688      if (nextc == '$') {
689          scan();
690          ep1 = newnode();
# Line 626 | Line 695 | getE5()                                /* E5 -> (E1) */
695   #endif
696  
697   #if  defined(VARIABLE) || defined(FUNCTION)
698 <    if (isalpha(nextc)) {
699 <        ep1 = newnode();
631 <        ep1->type = VAR;
632 <        ep1->v.ln = varinsert(getname());
633 <
698 >    if (isalpha(nextc) || nextc == CNTXMARK) {
699 >        nam = getname();
700   #if  defined(VARIABLE) && defined(FUNCTION)
701 +        ep1 = NULL;
702          if (curfunc != NULL)
703              for (i = 1, ep2 = curfunc->v.kid->sibling;
704 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
705 <                if (!strcmp(ep2->v.name, ep1->v.ln->name)) {
639 <                    epfree(ep1);
704 >                                ep2 != NULL; i++, ep2 = ep2->sibling)
705 >                if (!strcmp(ep2->v.name, nam)) {
706                      ep1 = newnode();
707                      ep1->type = ARG;
708                      ep1->v.chan = i;
709                      break;
710                  }
711 +        if (ep1 == NULL)
712   #endif
713 < #ifdef  FUNCTION
713 >        {
714 >            ep1 = newnode();
715 >            ep1->type = VAR;
716 >            ep1->v.ln = varinsert(nam);
717 >        }
718 > #ifdef  FUNCTION
719          if (nextc == '(') {
720              ep2 = newnode();
721              ep2->type = FUNC;
# Line 657 | Line 729 | getE5()                                /* E5 -> (E1) */
729                  syntax("')' expected");
730              scan();
731          }
732 < #ifndef  VARIABLE
732 > #ifndef  VARIABLE
733          else
734              syntax("'(' expected");
735   #endif
736   #endif
737 < #ifdef  RCONST
737 > #ifdef  RCONST
738          if (isconstvar(ep1))
739              ep1 = rconst(ep1);
740   #endif
# Line 680 | Line 752 | getE5()                                /* E5 -> (E1) */
752   }
753  
754  
755 < #ifdef  RCONST
755 > #ifdef  RCONST
756   EPNODE *
757   rconst(epar)                    /* reduce a constant expression */
758 < register EPNODE  *epar;
758 > register EPNODE  *epar;
759   {
760      register EPNODE  *ep;
761  
# Line 692 | Line 764 | register EPNODE  *epar;
764      errno = 0;
765      ep->v.num = evalue(epar);
766      if (errno)
767 <        syntax("bad constant expression");
767 >        syntax("bad constant expression");
768      epfree(epar);
769  
770      return(ep);
# Line 700 | Line 772 | register EPNODE  *epar;
772  
773  
774   isconstvar(ep)                  /* is ep linked to a constant expression? */
775 < register EPNODE  *ep;
775 > register EPNODE  *ep;
776   {
777 < #ifdef  VARIABLE
777 > #ifdef  VARIABLE
778      register EPNODE  *ep1;
779 < #ifdef  FUNCTION
779 > #ifdef  FUNCTION
780  
781      if (ep->type == FUNC) {
782          if (!isconstfun(ep->v.kid))
# Line 720 | Line 792 | register EPNODE  *ep;
792      ep1 = ep->v.ln->def;
793      if (ep1 == NULL || ep1->type != ':')
794          return(0);
795 < #ifdef  FUNCTION
795 > #ifdef  FUNCTION
796      if (ep1->v.kid->type != SYM)
797          return(0);
798   #endif
# Line 733 | Line 805 | register EPNODE  *ep;
805  
806   #if  defined(FUNCTION) && defined(VARIABLE)
807   isconstfun(ep)                  /* is ep linked to a constant function? */
808 < register EPNODE  *ep;
808 > register EPNODE  *ep;
809   {
810      register EPNODE  *dp;
811      register LIBR  *lp;
812  
813      if (ep->type != VAR)
814          return(0);
815 <    dp = ep->v.ln->def;
816 <    if (dp != NULL && dp->type != ':')
817 <        return(0);
818 <    if ((dp == NULL || dp->v.kid->type != FUNC)
819 <            && ((lp = liblookup(ep->v.ln->name)) == NULL
748 <                    || lp->atyp != ':'))
749 <        return(0);
750 <    return(1);
815 >    if ((dp = ep->v.ln->def) != NULL && dp->v.kid->type == FUNC)
816 >        return(dp->type == ':');
817 >    if ((lp = ep->v.ln->lib) != NULL)
818 >        return(lp->atyp == ':');
819 >    return(0);
820   }
821   #endif
822   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines