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.2 by greg, Thu Dec 19 14:45:47 1991 UTC vs.
Revision 2.15 by greg, Wed Sep 8 09:12:37 1993 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1991 Regents of the University of California */
1 > /* Copyright (c) 1992 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# 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 < #ifndef atof
36 < extern double  atof();
37 < #endif
38 < extern double  pow();
39 < 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();
46 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 126 | Line 130 | char  *expr;
130  
131  
132   epfree(epar)                    /* free a parse tree */
133 < register EPNODE  *epar;
133 > register EPNODE  *epar;
134   {
135      register EPNODE  *ep;
136  
# Line 136 | Line 140 | register EPNODE  *epar;
140          case VAR:
141              varfree(epar->v.ln);
142              break;
139 #endif
143              
144          case SYM:
145              freestr(epar->v.name);
146              break;
147 + #endif
148  
149          case NUM:
150          case CHAN:
# Line 149 | Line 153 | register EPNODE  *epar;
153              break;
154  
155          default:
156 <            for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
156 >            while ((ep = epar->v.kid) != NULL) {
157 >                epar->v.kid = ep->sibling;
158                  epfree(ep);
159 +            }
160              break;
161  
162      }
# Line 159 | Line 165 | register EPNODE  *epar;
165   }
166  
167                                  /* the following used to be a switch */
168 < #ifdef  FUNCTION
168 > #ifdef  FUNCTION
169   static double
170   eargument(ep)
171 < EPNODE  *ep;
171 > EPNODE  *ep;
172   {
173      return(argument(ep->v.chan));
174   }
# Line 170 | Line 176 | EPNODE  *ep;
176  
177   static double
178   enumber(ep)
179 < EPNODE  *ep;
179 > EPNODE  *ep;
180   {
181      return(ep->v.num);
182   }
183  
184   static double
185   euminus(ep)
186 < EPNODE  *ep;
186 > EPNODE  *ep;
187   {
188      register EPNODE  *ep1 = ep->v.kid;
189  
190      return(-evalue(ep1));
191   }
192  
193 < #ifdef  INCHAN
193 > #ifdef  INCHAN
194   static double
195   echannel(ep)
196 < EPNODE  *ep;
196 > EPNODE  *ep;
197   {
198      return(chanvalue(ep->v.chan));
199   }
# Line 195 | Line 201 | EPNODE  *ep;
201  
202   static double
203   eadd(ep)
204 < EPNODE  *ep;
204 > EPNODE  *ep;
205   {
206      register EPNODE  *ep1 = ep->v.kid;
207  
# Line 204 | Line 210 | EPNODE  *ep;
210  
211   static double
212   esubtr(ep)
213 < EPNODE  *ep;
213 > EPNODE  *ep;
214   {
215      register EPNODE  *ep1 = ep->v.kid;
216  
# Line 213 | Line 219 | EPNODE  *ep;
219  
220   static double
221   emult(ep)
222 < EPNODE  *ep;
222 > EPNODE  *ep;
223   {
224      register EPNODE  *ep1 = ep->v.kid;
225  
# Line 222 | Line 228 | EPNODE  *ep;
228  
229   static double
230   edivi(ep)
231 < EPNODE  *ep;
231 > EPNODE  *ep;
232   {
233      register EPNODE  *ep1 = ep->v.kid;
234      double  d;
# Line 238 | Line 244 | EPNODE  *ep;
244  
245   static double
246   epow(ep)
247 < EPNODE  *ep;
247 > EPNODE  *ep;
248   {
249      register EPNODE  *ep1 = ep->v.kid;
250      double  d;
251 <    int  lasterrno;
251 >    int  lasterrno;
252  
253      lasterrno = errno;
254      errno = 0;
255      d = pow(evalue(ep1), evalue(ep1->sibling));
256 < #ifdef  IEEE
256 > #ifdef  IEEE
257      if (!finite(d))
258          errno = EDOM;
259   #endif
# Line 261 | Line 267 | EPNODE  *ep;
267  
268   static double
269   ebotch(ep)
270 < EPNODE  *ep;
270 > EPNODE  *ep;
271   {
272      eputs("Bad expression!\n");
273      quit(1);
# Line 270 | Line 276 | EPNODE  *ep;
276  
277   EPNODE *
278   ekid(ep, n)                     /* return pointer to a node's nth kid */
279 < register EPNODE  *ep;
279 > register EPNODE  *ep;
280   register int  n;
281   {
282  
# Line 284 | Line 290 | register int  n;
290  
291   int
292   nekids(ep)                      /* return # of kids for node ep */
293 < register EPNODE  *ep;
293 > register EPNODE  *ep;
294   {
295      register int  n = 0;
296  
# Line 300 | Line 306 | FILE  *fp;
306   char  *fn;
307   int  ln;
308   {
309 <    static char  inpbuf[MAXLINE];
309 >    static char  inpbuf[MAXLINE];
310  
311      infp = fp;
312      linbuf = inpbuf;
# Line 372 | Line 378 | scan()                         /* scan next character, return literal next
378  
379  
380   char *
381 < ltoa(l)                         /* convert long to ascii */
381 > long2ascii(l)                         /* convert long to ascii */
382   long  l;
383   {
384 <    static char  buf[16];
384 >    static char  buf[16];
385      register char  *cp;
386 <    int  neg = 0;
386 >    int  neg = 0;
387  
388      if (l == 0)
389          return("0");
# Line 406 | Line 412 | char  *err;
412          if (infile != NULL) eputs(infile);
413          if (lineno != 0) {
414              eputs(infile != NULL ? ", line " : "line ");
415 <            eputs(ltoa((long)lineno));
415 >            eputs(long2ascii((long)lineno));
416          }
417 <        eputs(": syntax error:\n");
417 >        eputs(":\n");
418      }
419      eputs(linbuf);
420      if (linbuf[strlen(linbuf)-1] != '\n')
# Line 423 | Line 429 | char  *err;
429  
430  
431   addekid(ep, ekid)                       /* add a child to ep */
432 < register EPNODE  *ep;
433 < EPNODE  *ekid;
432 > register EPNODE  *ep;
433 > EPNODE  *ekid;
434   {
435      if (ep->v.kid == NULL)
436          ep->v.kid = ekid;
# Line 437 | Line 443 | EPNODE  *ekid;
443   }
444  
445  
446 + #if  defined(VARIABLE) || defined(FUNCTION)
447   char *
448   getname()                       /* scan an identifier */
449   {
450 <    static char  str[MAXWORD+1];
450 >    static char  str[MAXWORD+1];
451      register int  i, lnext;
452  
453      lnext = nextc;
# Line 452 | Line 459 | getname()                      /* scan an identifier */
459  
460      return(str);
461   }
462 + #endif
463  
464  
465   int
# Line 482 | Line 490 | getnum()                       /* scan a positive float */
490          lnext = scan();
491      }
492      if (lnext == '.' && i < MAXWORD) {
493 <        str[i++] = lnext;
494 <        lnext = scan();
493 >        str[i++] = lnext;
494 >        lnext = scan();
495          while (isdigit(lnext) && i < MAXWORD) {
496              str[i++] = lnext;
497              lnext = scan();
498          }
499      }
500      if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) {
501 <        str[i++] = lnext;
502 <        lnext = scan();
501 >        str[i++] = lnext;
502 >        lnext = scan();
503          if ((lnext == '-' || lnext == '+') && i < MAXWORD) {
504              str[i++] = lnext;
505              lnext = scan();
# Line 509 | Line 517 | getnum()                       /* scan a positive float */
517  
518   EPNODE *
519   getE1()                         /* E1 -> E1 ADDOP E2 */
520 <                                /*       E2 */
520 >                                /*       E2 */
521   {
522      register EPNODE  *ep1, *ep2;
523  
# Line 520 | Line 528 | getE1()                                /* E1 -> E1 ADDOP E2 */
528          scan();
529          addekid(ep2, ep1);
530          addekid(ep2, getE2());
531 < #ifdef  RCONST
531 > #ifdef  RCONST
532          if (ep1->type == NUM && ep1->sibling->type == NUM)
533                  ep2 = rconst(ep2);
534   #endif
# Line 532 | Line 540 | getE1()                                /* E1 -> E1 ADDOP E2 */
540  
541   EPNODE *
542   getE2()                         /* E2 -> E2 MULOP E3 */
543 <                                /*       E3 */
543 >                                /*       E3 */
544   {
545      register EPNODE  *ep1, *ep2;
546  
# Line 543 | Line 551 | getE2()                                /* E2 -> E2 MULOP E3 */
551          scan();
552          addekid(ep2, ep1);
553          addekid(ep2, getE3());
554 < #ifdef  RCONST
554 > #ifdef  RCONST
555          if (ep1->type == NUM && ep1->sibling->type == NUM)
556                  ep2 = rconst(ep2);
557   #endif
# Line 555 | Line 563 | getE2()                                /* E2 -> E2 MULOP E3 */
563  
564   EPNODE *
565   getE3()                         /* E3 -> E4 ^ E3 */
566 <                                /*       E4 */
566 >                                /*       E4 */
567   {
568      register EPNODE  *ep1, *ep2;
569  
# Line 566 | Line 574 | getE3()                                /* E3 -> E4 ^ E3 */
574          scan();
575          addekid(ep2, ep1);
576          addekid(ep2, getE3());
577 < #ifdef  RCONST
577 > #ifdef  RCONST
578          if (ep1->type == NUM && ep1->sibling->type == NUM)
579                  ep2 = rconst(ep2);
580   #endif
# Line 578 | Line 586 | getE3()                                /* E3 -> E4 ^ E3 */
586  
587   EPNODE *
588   getE4()                         /* E4 -> ADDOP E5 */
589 <                                /*       E5 */
589 >                                /*       E5 */
590   {
591      register EPNODE  *ep1, *ep2;
592  
# Line 606 | Line 614 | getE4()                                /* E4 -> ADDOP E5 */
614  
615   EPNODE *
616   getE5()                         /* E5 -> (E1) */
617 <                                /*       VAR */
618 <                                /*       NUM */
619 <                                /*       $N */
620 <                                /*       FUNC(E1,..) */
621 <                                /*       ARG */
617 >                                /*       VAR */
618 >                                /*       NUM */
619 >                                /*       $N */
620 >                                /*       FUNC(E1,..) */
621 >                                /*       ARG */
622   {
623 <    int  i;
623 >    int  i;
624      char  *nam;
625      register EPNODE  *ep1, *ep2;
626  
# Line 625 | Line 633 | getE5()                                /* E5 -> (E1) */
633          return(ep1);
634      }
635  
636 < #ifdef  INCHAN
636 > #ifdef  INCHAN
637      if (nextc == '$') {
638          scan();
639          ep1 = newnode();
# Line 642 | Line 650 | getE5()                                /* E5 -> (E1) */
650          ep1 = NULL;
651          if (curfunc != NULL)
652              for (i = 1, ep2 = curfunc->v.kid->sibling;
653 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
653 >                                ep2 != NULL; i++, ep2 = ep2->sibling)
654                  if (!strcmp(ep2->v.name, nam)) {
655                      ep1 = newnode();
656                      ep1->type = ARG;
# Line 656 | Line 664 | getE5()                                /* E5 -> (E1) */
664              ep1->type = VAR;
665              ep1->v.ln = varinsert(nam);
666          }
667 < #ifdef  FUNCTION
667 > #ifdef  FUNCTION
668          if (nextc == '(') {
669              ep2 = newnode();
670              ep2->type = FUNC;
# Line 670 | Line 678 | getE5()                                /* E5 -> (E1) */
678                  syntax("')' expected");
679              scan();
680          }
681 < #ifndef  VARIABLE
681 > #ifndef  VARIABLE
682          else
683              syntax("'(' expected");
684   #endif
685   #endif
686 < #ifdef  RCONST
686 > #ifdef  RCONST
687          if (isconstvar(ep1))
688              ep1 = rconst(ep1);
689   #endif
# Line 693 | Line 701 | getE5()                                /* E5 -> (E1) */
701   }
702  
703  
704 < #ifdef  RCONST
704 > #ifdef  RCONST
705   EPNODE *
706   rconst(epar)                    /* reduce a constant expression */
707 < register EPNODE  *epar;
707 > register EPNODE  *epar;
708   {
709      register EPNODE  *ep;
710  
# Line 705 | Line 713 | register EPNODE  *epar;
713      errno = 0;
714      ep->v.num = evalue(epar);
715      if (errno)
716 <        syntax("bad constant expression");
716 >        syntax("bad constant expression");
717      epfree(epar);
718  
719      return(ep);
# Line 713 | Line 721 | register EPNODE  *epar;
721  
722  
723   isconstvar(ep)                  /* is ep linked to a constant expression? */
724 < register EPNODE  *ep;
724 > register EPNODE  *ep;
725   {
726 < #ifdef  VARIABLE
726 > #ifdef  VARIABLE
727      register EPNODE  *ep1;
728 < #ifdef  FUNCTION
728 > #ifdef  FUNCTION
729  
730      if (ep->type == FUNC) {
731          if (!isconstfun(ep->v.kid))
# Line 733 | Line 741 | register EPNODE  *ep;
741      ep1 = ep->v.ln->def;
742      if (ep1 == NULL || ep1->type != ':')
743          return(0);
744 < #ifdef  FUNCTION
744 > #ifdef  FUNCTION
745      if (ep1->v.kid->type != SYM)
746          return(0);
747   #endif
# Line 746 | Line 754 | register EPNODE  *ep;
754  
755   #if  defined(FUNCTION) && defined(VARIABLE)
756   isconstfun(ep)                  /* is ep linked to a constant function? */
757 < register EPNODE  *ep;
757 > register EPNODE  *ep;
758   {
759      register EPNODE  *dp;
760      register LIBR  *lp;
761  
762      if (ep->type != VAR)
763          return(0);
764 <    dp = ep->v.ln->def;
765 <    if (dp != NULL && dp->type != ':')
766 <        return(0);
767 <    if ((dp == NULL || dp->v.kid->type != FUNC)
768 <            && ((lp = liblookup(ep->v.ln->name)) == NULL
761 <                    || lp->atyp != ':'))
762 <        return(0);
763 <    return(1);
764 >    if ((dp = ep->v.ln->def) != NULL && dp->v.kid->type == FUNC)
765 >        return(dp->type == ':');
766 >    if ((lp = ep->v.ln->lib) != NULL)
767 >        return(lp->atyp == ':');
768 >    return(0);
769   }
770   #endif
771   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines