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.12 by greg, Fri Mar 5 15:14:00 1993 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1986 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 < extern double  atof(), pow();
37 > #ifndef atof
38 > extern double  atof();
39 > #endif
40   extern char  *fgets(), *savestr();
41   extern char  *emalloc(), *ecalloc();
42   extern EPNODE  *curfunc;
43   extern double  efunc(), evariable();
44 < static double  euminus(), echannel(), eargument(), enumber();
44 > static double  euminus(), eargument(), enumber();
45 > #ifdef  INCHAN
46 > static double  echannel();
47 > #endif
48   static double  eadd(), esubtr(), emult(), edivi(), epow();
49   static double  ebotch();
43 extern int  errno;
50  
51   int  nextc;                             /* lookahead character */
52  
53 < double  (*eoper[])() = {                /* expression operations */
53 > double  (*eoper[])() = {                /* expression operations */
54          ebotch,
55 < #ifdef  VARIABLE
55 > #ifdef  VARIABLE
56          evariable,
57   #else
58          ebotch,
59   #endif
60          enumber,
61          euminus,
62 < #ifdef  INCHAN
62 > #ifdef  INCHAN
63          echannel,
64   #else
65          ebotch,
66   #endif
67 < #ifdef  FUNCTION
67 > #ifdef  FUNCTION
68          efunc,
69          eargument,
70   #else
# Line 123 | Line 129 | char  *expr;
129  
130  
131   epfree(epar)                    /* free a parse tree */
132 < register EPNODE  *epar;
132 > register EPNODE  *epar;
133   {
134      register EPNODE  *ep;
135  
# Line 133 | Line 139 | register EPNODE  *epar;
139          case VAR:
140              varfree(epar->v.ln);
141              break;
136 #endif
142              
143          case SYM:
144              freestr(epar->v.name);
145              break;
146 + #endif
147  
148          case NUM:
149          case CHAN:
# Line 146 | Line 152 | register EPNODE  *epar;
152              break;
153  
154          default:
155 <            for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
155 >            while ((ep = epar->v.kid) != NULL) {
156 >                epar->v.kid = ep->sibling;
157                  epfree(ep);
158 +            }
159              break;
160  
161      }
# Line 156 | Line 164 | register EPNODE  *epar;
164   }
165  
166                                  /* the following used to be a switch */
167 < #ifdef  FUNCTION
167 > #ifdef  FUNCTION
168   static double
169   eargument(ep)
170 < EPNODE  *ep;
170 > EPNODE  *ep;
171   {
172      return(argument(ep->v.chan));
173   }
# Line 167 | Line 175 | EPNODE  *ep;
175  
176   static double
177   enumber(ep)
178 < EPNODE  *ep;
178 > EPNODE  *ep;
179   {
180      return(ep->v.num);
181   }
182  
183   static double
184   euminus(ep)
185 < EPNODE  *ep;
185 > EPNODE  *ep;
186   {
187      register EPNODE  *ep1 = ep->v.kid;
188  
189      return(-evalue(ep1));
190   }
191  
192 < #ifdef  INCHAN
192 > #ifdef  INCHAN
193   static double
194   echannel(ep)
195 < EPNODE  *ep;
195 > EPNODE  *ep;
196   {
197      return(chanvalue(ep->v.chan));
198   }
# Line 192 | Line 200 | EPNODE  *ep;
200  
201   static double
202   eadd(ep)
203 < EPNODE  *ep;
203 > EPNODE  *ep;
204   {
205      register EPNODE  *ep1 = ep->v.kid;
206  
# Line 201 | Line 209 | EPNODE  *ep;
209  
210   static double
211   esubtr(ep)
212 < EPNODE  *ep;
212 > EPNODE  *ep;
213   {
214      register EPNODE  *ep1 = ep->v.kid;
215  
# Line 210 | Line 218 | EPNODE  *ep;
218  
219   static double
220   emult(ep)
221 < EPNODE  *ep;
221 > EPNODE  *ep;
222   {
223      register EPNODE  *ep1 = ep->v.kid;
224  
# Line 219 | Line 227 | EPNODE  *ep;
227  
228   static double
229   edivi(ep)
230 < EPNODE  *ep;
230 > EPNODE  *ep;
231   {
232      register EPNODE  *ep1 = ep->v.kid;
233      double  d;
# Line 235 | Line 243 | EPNODE  *ep;
243  
244   static double
245   epow(ep)
246 < EPNODE  *ep;
246 > EPNODE  *ep;
247   {
248      register EPNODE  *ep1 = ep->v.kid;
249      double  d;
250 <    int  lasterrno;
250 >    int  lasterrno;
251  
252      lasterrno = errno;
253      errno = 0;
254      d = pow(evalue(ep1), evalue(ep1->sibling));
255 < #ifdef  IEEE
255 > #ifdef  IEEE
256      if (!finite(d))
257          errno = EDOM;
258   #endif
# Line 258 | Line 266 | EPNODE  *ep;
266  
267   static double
268   ebotch(ep)
269 < EPNODE  *ep;
269 > EPNODE  *ep;
270   {
271      eputs("Bad expression!\n");
272      quit(1);
# Line 267 | Line 275 | EPNODE  *ep;
275  
276   EPNODE *
277   ekid(ep, n)                     /* return pointer to a node's nth kid */
278 < register EPNODE  *ep;
278 > register EPNODE  *ep;
279   register int  n;
280   {
281  
# Line 281 | Line 289 | register int  n;
289  
290   int
291   nekids(ep)                      /* return # of kids for node ep */
292 < register EPNODE  *ep;
292 > register EPNODE  *ep;
293   {
294      register int  n = 0;
295  
# Line 297 | Line 305 | FILE  *fp;
305   char  *fn;
306   int  ln;
307   {
308 <    static char  inpbuf[MAXLINE];
308 >    static char  inpbuf[MAXLINE];
309  
310      infp = fp;
311      linbuf = inpbuf;
# Line 369 | Line 377 | scan()                         /* scan next character, return literal next
377  
378  
379   char *
380 < ltoa(l)                         /* convert long to ascii */
380 > long2ascii(l)                         /* convert long to ascii */
381   long  l;
382   {
383 <    static char  buf[16];
383 >    static char  buf[16];
384      register char  *cp;
385 <    int  neg = 0;
385 >    int  neg = 0;
386  
387      if (l == 0)
388          return("0");
# Line 403 | Line 411 | char  *err;
411          if (infile != NULL) eputs(infile);
412          if (lineno != 0) {
413              eputs(infile != NULL ? ", line " : "line ");
414 <            eputs(ltoa((long)lineno));
414 >            eputs(long2ascii((long)lineno));
415          }
416 <        eputs(": syntax error:\n");
416 >        eputs(":\n");
417      }
418      eputs(linbuf);
419      if (linbuf[strlen(linbuf)-1] != '\n')
# Line 420 | Line 428 | char  *err;
428  
429  
430   addekid(ep, ekid)                       /* add a child to ep */
431 < register EPNODE  *ep;
432 < EPNODE  *ekid;
431 > register EPNODE  *ep;
432 > EPNODE  *ekid;
433   {
434      if (ep->v.kid == NULL)
435          ep->v.kid = ekid;
# Line 434 | Line 442 | EPNODE  *ekid;
442   }
443  
444  
445 + #if  defined(VARIABLE) || defined(FUNCTION)
446   char *
447   getname()                       /* scan an identifier */
448   {
449 <    static char  str[MAXWORD+1];
449 >    static char  str[MAXWORD+1];
450      register int  i, lnext;
451  
452      lnext = nextc;
453      for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
454          str[i] = lnext;
455      str[i] = '\0';
456 +    while (isid(lnext))         /* skip rest of name */
457 +        lnext = scan();
458  
459      return(str);
460   }
461 + #endif
462  
463  
464   int
# Line 477 | Line 489 | getnum()                       /* scan a positive float */
489          lnext = scan();
490      }
491      if (lnext == '.' && i < MAXWORD) {
492 <        str[i++] = lnext;
493 <        lnext = scan();
492 >        str[i++] = lnext;
493 >        lnext = scan();
494          while (isdigit(lnext) && i < MAXWORD) {
495              str[i++] = lnext;
496              lnext = scan();
497          }
498      }
499      if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) {
500 <        str[i++] = lnext;
501 <        lnext = scan();
500 >        str[i++] = lnext;
501 >        lnext = scan();
502          if ((lnext == '-' || lnext == '+') && i < MAXWORD) {
503              str[i++] = lnext;
504              lnext = scan();
# Line 504 | Line 516 | getnum()                       /* scan a positive float */
516  
517   EPNODE *
518   getE1()                         /* E1 -> E1 ADDOP E2 */
519 <                                /*       E2 */
519 >                                /*       E2 */
520   {
521      register EPNODE  *ep1, *ep2;
522  
# Line 515 | Line 527 | getE1()                                /* E1 -> E1 ADDOP E2 */
527          scan();
528          addekid(ep2, ep1);
529          addekid(ep2, getE2());
530 < #ifdef  RCONST
530 > #ifdef  RCONST
531          if (ep1->type == NUM && ep1->sibling->type == NUM)
532                  ep2 = rconst(ep2);
533   #endif
# Line 527 | Line 539 | getE1()                                /* E1 -> E1 ADDOP E2 */
539  
540   EPNODE *
541   getE2()                         /* E2 -> E2 MULOP E3 */
542 <                                /*       E3 */
542 >                                /*       E3 */
543   {
544      register EPNODE  *ep1, *ep2;
545  
# Line 538 | Line 550 | getE2()                                /* E2 -> E2 MULOP E3 */
550          scan();
551          addekid(ep2, ep1);
552          addekid(ep2, getE3());
553 < #ifdef  RCONST
553 > #ifdef  RCONST
554          if (ep1->type == NUM && ep1->sibling->type == NUM)
555                  ep2 = rconst(ep2);
556   #endif
# Line 550 | Line 562 | getE2()                                /* E2 -> E2 MULOP E3 */
562  
563   EPNODE *
564   getE3()                         /* E3 -> E4 ^ E3 */
565 <                                /*       E4 */
565 >                                /*       E4 */
566   {
567      register EPNODE  *ep1, *ep2;
568  
# Line 561 | Line 573 | getE3()                                /* E3 -> E4 ^ E3 */
573          scan();
574          addekid(ep2, ep1);
575          addekid(ep2, getE3());
576 < #ifdef  RCONST
576 > #ifdef  RCONST
577          if (ep1->type == NUM && ep1->sibling->type == NUM)
578                  ep2 = rconst(ep2);
579   #endif
# Line 573 | Line 585 | getE3()                                /* E3 -> E4 ^ E3 */
585  
586   EPNODE *
587   getE4()                         /* E4 -> ADDOP E5 */
588 <                                /*       E5 */
588 >                                /*       E5 */
589   {
590      register EPNODE  *ep1, *ep2;
591  
# Line 584 | Line 596 | getE4()                                /* E4 -> ADDOP E5 */
596                  ep2->v.num = -ep2->v.num;
597                  return(ep2);
598          }
599 +        if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
600 +            efree((char *)ep2);
601 +            return(ep2->v.kid);
602 +        }
603          ep1 = newnode();
604          ep1->type = UMINUS;
605          addekid(ep1, ep2);
# Line 597 | Line 613 | getE4()                                /* E4 -> ADDOP E5 */
613  
614   EPNODE *
615   getE5()                         /* E5 -> (E1) */
616 <                                /*       VAR */
617 <                                /*       NUM */
618 <                                /*       $N */
619 <                                /*       FUNC(E1,..) */
620 <                                /*       ARG */
616 >                                /*       VAR */
617 >                                /*       NUM */
618 >                                /*       $N */
619 >                                /*       FUNC(E1,..) */
620 >                                /*       ARG */
621   {
622 <    int  i;
622 >    int  i;
623 >    char  *nam;
624      register EPNODE  *ep1, *ep2;
625  
626      if (nextc == '(') {
# Line 615 | Line 632 | getE5()                                /* E5 -> (E1) */
632          return(ep1);
633      }
634  
635 < #ifdef  INCHAN
635 > #ifdef  INCHAN
636      if (nextc == '$') {
637          scan();
638          ep1 = newnode();
# Line 626 | Line 643 | getE5()                                /* E5 -> (E1) */
643   #endif
644  
645   #if  defined(VARIABLE) || defined(FUNCTION)
646 <    if (isalpha(nextc)) {
647 <        ep1 = newnode();
631 <        ep1->type = VAR;
632 <        ep1->v.ln = varinsert(getname());
633 <
646 >    if (isalpha(nextc) || nextc == CNTXMARK) {
647 >        nam = getname();
648   #if  defined(VARIABLE) && defined(FUNCTION)
649 +        ep1 = NULL;
650          if (curfunc != NULL)
651              for (i = 1, ep2 = curfunc->v.kid->sibling;
652 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
653 <                if (!strcmp(ep2->v.name, ep1->v.ln->name)) {
639 <                    epfree(ep1);
652 >                                ep2 != NULL; i++, ep2 = ep2->sibling)
653 >                if (!strcmp(ep2->v.name, nam)) {
654                      ep1 = newnode();
655                      ep1->type = ARG;
656                      ep1->v.chan = i;
657                      break;
658                  }
659 +        if (ep1 == NULL)
660   #endif
661 < #ifdef  FUNCTION
661 >        {
662 >            ep1 = newnode();
663 >            ep1->type = VAR;
664 >            ep1->v.ln = varinsert(nam);
665 >        }
666 > #ifdef  FUNCTION
667          if (nextc == '(') {
668              ep2 = newnode();
669              ep2->type = FUNC;
# Line 657 | Line 677 | getE5()                                /* E5 -> (E1) */
677                  syntax("')' expected");
678              scan();
679          }
680 < #ifndef  VARIABLE
680 > #ifndef  VARIABLE
681          else
682              syntax("'(' expected");
683   #endif
684   #endif
685 < #ifdef  RCONST
685 > #ifdef  RCONST
686          if (isconstvar(ep1))
687              ep1 = rconst(ep1);
688   #endif
# Line 680 | Line 700 | getE5()                                /* E5 -> (E1) */
700   }
701  
702  
703 < #ifdef  RCONST
703 > #ifdef  RCONST
704   EPNODE *
705   rconst(epar)                    /* reduce a constant expression */
706 < register EPNODE  *epar;
706 > register EPNODE  *epar;
707   {
708      register EPNODE  *ep;
709  
# Line 692 | Line 712 | register EPNODE  *epar;
712      errno = 0;
713      ep->v.num = evalue(epar);
714      if (errno)
715 <        syntax("bad constant expression");
715 >        syntax("bad constant expression");
716      epfree(epar);
717  
718      return(ep);
# Line 700 | Line 720 | register EPNODE  *epar;
720  
721  
722   isconstvar(ep)                  /* is ep linked to a constant expression? */
723 < register EPNODE  *ep;
723 > register EPNODE  *ep;
724   {
725 < #ifdef  VARIABLE
725 > #ifdef  VARIABLE
726      register EPNODE  *ep1;
727 < #ifdef  FUNCTION
727 > #ifdef  FUNCTION
728  
729      if (ep->type == FUNC) {
730          if (!isconstfun(ep->v.kid))
# Line 720 | Line 740 | register EPNODE  *ep;
740      ep1 = ep->v.ln->def;
741      if (ep1 == NULL || ep1->type != ':')
742          return(0);
743 < #ifdef  FUNCTION
743 > #ifdef  FUNCTION
744      if (ep1->v.kid->type != SYM)
745          return(0);
746   #endif
# Line 733 | Line 753 | register EPNODE  *ep;
753  
754   #if  defined(FUNCTION) && defined(VARIABLE)
755   isconstfun(ep)                  /* is ep linked to a constant function? */
756 < register EPNODE  *ep;
756 > register EPNODE  *ep;
757   {
758      register EPNODE  *dp;
759      register LIBR  *lp;
760  
761      if (ep->type != VAR)
762          return(0);
763 <    dp = ep->v.ln->def;
764 <    if (dp != NULL && dp->type != ':')
765 <        return(0);
766 <    if ((dp == NULL || dp->v.kid->type != FUNC)
767 <            && ((lp = liblookup(ep->v.ln->name)) == NULL
748 <                    || lp->atyp != ':'))
749 <        return(0);
750 <    return(1);
763 >    if ((dp = ep->v.ln->def) != NULL && dp->v.kid->type == FUNC)
764 >        return(dp->type == ':');
765 >    if ((lp = ep->v.ln->lib) != NULL)
766 >        return(lp->atyp == ':');
767 >    return(0);
768   }
769   #endif
770   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines