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.8 by greg, Wed Apr 17 10:54:58 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 */
30 < #define  MAXWORD        64              /* maximum word 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  isid(c)        (isalnum(c) || (c) == '_' || (c) == '.')
35 > #define  isdecimal(c)   (isdigit(c) || (c) == '.')
36  
37 < #define  isdecimal(c)   (isdigit(c) || (c) == '.')
38 <
39 < 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();
46 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 78 | Line 81 | double  (*eoper[])() = {               /* expression operations */
81          esubtr,
82          0,
83          edivi,
84 <        0,0,0,0,0,0,0,0,0,0,0,0,0,
84 >        0,0,0,0,0,0,0,0,0,0,
85          ebotch,
86 +        0,0,
87 +        ebotch,
88          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
89          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
90          epow,
# Line 124 | 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 134 | Line 139 | register EPNODE  *epar;
139          case VAR:
140              varfree(epar->v.ln);
141              break;
137 #endif
142              
143          case SYM:
144              freestr(epar->v.name);
145              break;
146 + #endif
147  
148          case NUM:
149          case CHAN:
# Line 147 | 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 157 | 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 168 | 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 193 | 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 202 | 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 211 | 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 220 | 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 236 | 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 259 | 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 268 | 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 282 | 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 298 | 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 324 | Line 331 | int  ln;
331   }
332  
333  
334 < scan()                          /* scan next character */
334 > getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
335 > char  **fnp;
336 > int  *lnp;
337 > char  **spp;
338 > FILE  **fpp;
339   {
340 +    if (fnp != NULL) *fnp = infile;
341 +    if (lnp != NULL) *lnp = lineno;
342 +    if (spp != NULL) *spp = linbuf+linepos;
343 +    if (fpp != NULL) *fpp = infp;
344 + }
345 +
346 +
347 + int
348 + scan()                          /* scan next character, return literal next */
349 + {
350 +    register int  lnext = 0;
351 +
352      do {
353          if (linbuf[linepos] == '\0')
354              if (infp == NULL || fgets(linbuf, MAXLINE, infp) == NULL)
# Line 337 | Line 360 | scan()                         /* scan next character */
360              }
361          else
362              nextc = linbuf[linepos++];
363 +        if (!lnext)
364 +                lnext = nextc;
365          if (nextc == '{') {
366              scan();
367              while (nextc != '}')
# Line 347 | Line 372 | scan()                         /* scan next character */
372              scan();
373          }
374      } while (isspace(nextc));
375 +    return(lnext);
376   }
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 385 | 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 402 | 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 416 | 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];
450 <    register int  i;
449 >    static char  str[MAXWORD+1];
450 >    register int  i, lnext;
451  
452 <    for (i = 0; i < MAXWORD && isid(nextc); i++, scan())
453 <        str[i] = nextc;
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
465   getinum()                       /* scan a positive integer */
466   {
467 <    register int  n;
467 >    register int  n, lnext;
468  
469      n = 0;
470 <    while (isdigit(nextc)) {
471 <        n = n * 10 + nextc - '0';
472 <        scan();
470 >    lnext = nextc;
471 >    while (isdigit(lnext)) {
472 >        n = n * 10 + lnext - '0';
473 >        lnext = scan();
474      }
475      return(n);
476   }
# Line 447 | Line 479 | getinum()                      /* scan a positive integer */
479   double
480   getnum()                        /* scan a positive float */
481   {
482 <    register int  i;
482 >    register int  i, lnext;
483      char  str[MAXWORD+1];
484  
485      i = 0;
486 <    while (isdigit(nextc) && i < MAXWORD) {
487 <        str[i++] = nextc;
488 <        scan();
486 >    lnext = nextc;
487 >    while (isdigit(lnext) && i < MAXWORD) {
488 >        str[i++] = lnext;
489 >        lnext = scan();
490      }
491 <    if (nextc == '.' && i < MAXWORD) {
492 <        str[i++] = nextc;
493 <        scan();
494 <        while (isdigit(nextc) && i < MAXWORD) {
495 <            str[i++] = nextc;
496 <            scan();
491 >    if (lnext == '.' && i < MAXWORD) {
492 >        str[i++] = lnext;
493 >        lnext = scan();
494 >        while (isdigit(lnext) && i < MAXWORD) {
495 >            str[i++] = lnext;
496 >            lnext = scan();
497          }
498      }
499 <    if ((nextc == 'e' || nextc == 'E') && i < MAXWORD) {
500 <        str[i++] = nextc;
501 <        scan();
502 <        if ((nextc == '-' || nextc == '+') && i < MAXWORD) {
503 <            str[i++] = nextc;
504 <            scan();
499 >    if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) {
500 >        str[i++] = lnext;
501 >        lnext = scan();
502 >        if ((lnext == '-' || lnext == '+') && i < MAXWORD) {
503 >            str[i++] = lnext;
504 >            lnext = scan();
505          }
506 <        while (isdigit(nextc) && i < MAXWORD) {
507 <            str[i++] = nextc;
508 <            scan();
506 >        while (isdigit(lnext) && i < MAXWORD) {
507 >            str[i++] = lnext;
508 >            lnext = scan();
509          }
510      }
511      str[i] = '\0';
# Line 483 | 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 494 | 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 506 | 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 517 | 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 529 | 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 540 | 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 552 | 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 563 | 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 576 | 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 594 | 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 605 | Line 643 | getE5()                                /* E5 -> (E1) */
643   #endif
644  
645   #if  defined(VARIABLE) || defined(FUNCTION)
646 <    if (isalpha(nextc)) {
647 <        ep1 = newnode();
610 <        ep1->type = VAR;
611 <        ep1->v.ln = varinsert(getname());
612 <
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)) {
618 <                    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 636 | 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
686 +        if (isconstvar(ep1))
687 +            ep1 = rconst(ep1);
688 + #endif
689          return(ep1);
690      }
691   #endif
# Line 655 | 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 667 | 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);
719   }
720 +
721 +
722 + isconstvar(ep)                  /* is ep linked to a constant expression? */
723 + register EPNODE  *ep;
724 + {
725 + #ifdef  VARIABLE
726 +    register EPNODE  *ep1;
727 + #ifdef  FUNCTION
728 +
729 +    if (ep->type == FUNC) {
730 +        if (!isconstfun(ep->v.kid))
731 +                return(0);
732 +        for (ep1 = ep->v.kid->sibling; ep1 != NULL; ep1 = ep1->sibling)
733 +            if (ep1->type != NUM && !isconstfun(ep1))
734 +                return(0);
735 +        return(1);
736 +    }
737 + #endif
738 +    if (ep->type != VAR)
739 +        return(0);
740 +    ep1 = ep->v.ln->def;
741 +    if (ep1 == NULL || ep1->type != ':')
742 +        return(0);
743 + #ifdef  FUNCTION
744 +    if (ep1->v.kid->type != SYM)
745 +        return(0);
746 + #endif
747 +    return(1);
748 + #else
749 +    return(ep->type == FUNC);
750 + #endif
751 + }
752 +
753 +
754 + #if  defined(FUNCTION) && defined(VARIABLE)
755 + isconstfun(ep)                  /* is ep linked to a constant function? */
756 + register EPNODE  *ep;
757 + {
758 +    register EPNODE  *dp;
759 +    register LIBR  *lp;
760 +
761 +    if (ep->type != VAR)
762 +        return(0);
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