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.14 by greg, Thu Aug 8 13:40:09 1991 UTC vs.
Revision 2.7 by greg, Sat Sep 26 08:13:32 1992 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 26 | Line 26 | static char SCCSid[] = "$SunId$ LBL";
26  
27   #include  "calcomp.h"
28  
29 < #define  MAXLINE        256             /* maximum line length */
29 > #define  MAXLINE        256             /* maximum line length */
30  
31 < #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
31 > #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
32  
33 < #define  isdecimal(c)   (isdigit(c) || (c) == '.')
33 > #define  isdecimal(c)   (isdigit(c) || (c) == '.')
34  
35 < extern double  atof(), pow();
35 > #ifndef atof
36 > extern double  atof();
37 > #endif
38 > extern double  pow();
39   extern char  *fgets(), *savestr();
40   extern char  *emalloc(), *ecalloc();
41   extern EPNODE  *curfunc;
# Line 40 | Line 43 | extern double  efunc(), evariable();
43   static double  euminus(), echannel(), eargument(), enumber();
44   static double  eadd(), esubtr(), emult(), edivi(), epow();
45   static double  ebotch();
43 extern int  errno;
46  
47   int  nextc;                             /* lookahead character */
48  
49 < double  (*eoper[])() = {                /* expression operations */
49 > double  (*eoper[])() = {                /* expression operations */
50          ebotch,
51 < #ifdef  VARIABLE
51 > #ifdef  VARIABLE
52          evariable,
53   #else
54          ebotch,
55   #endif
56          enumber,
57          euminus,
58 < #ifdef  INCHAN
58 > #ifdef  INCHAN
59          echannel,
60   #else
61          ebotch,
62   #endif
63 < #ifdef  FUNCTION
63 > #ifdef  FUNCTION
64          efunc,
65          eargument,
66   #else
# Line 123 | Line 125 | char  *expr;
125  
126  
127   epfree(epar)                    /* free a parse tree */
128 < register EPNODE  *epar;
128 > register EPNODE  *epar;
129   {
130      register EPNODE  *ep;
131  
# Line 133 | Line 135 | register EPNODE  *epar;
135          case VAR:
136              varfree(epar->v.ln);
137              break;
136 #endif
138              
139          case SYM:
140              freestr(epar->v.name);
141              break;
142 + #endif
143  
144          case NUM:
145          case CHAN:
# Line 156 | Line 158 | register EPNODE  *epar;
158   }
159  
160                                  /* the following used to be a switch */
161 < #ifdef  FUNCTION
161 > #ifdef  FUNCTION
162   static double
163   eargument(ep)
164 < EPNODE  *ep;
164 > EPNODE  *ep;
165   {
166      return(argument(ep->v.chan));
167   }
# Line 167 | Line 169 | EPNODE  *ep;
169  
170   static double
171   enumber(ep)
172 < EPNODE  *ep;
172 > EPNODE  *ep;
173   {
174      return(ep->v.num);
175   }
176  
177   static double
178   euminus(ep)
179 < EPNODE  *ep;
179 > EPNODE  *ep;
180   {
181      register EPNODE  *ep1 = ep->v.kid;
182  
183      return(-evalue(ep1));
184   }
185  
186 < #ifdef  INCHAN
186 > #ifdef  INCHAN
187   static double
188   echannel(ep)
189 < EPNODE  *ep;
189 > EPNODE  *ep;
190   {
191      return(chanvalue(ep->v.chan));
192   }
# Line 192 | Line 194 | EPNODE  *ep;
194  
195   static double
196   eadd(ep)
197 < EPNODE  *ep;
197 > EPNODE  *ep;
198   {
199      register EPNODE  *ep1 = ep->v.kid;
200  
# Line 201 | Line 203 | EPNODE  *ep;
203  
204   static double
205   esubtr(ep)
206 < EPNODE  *ep;
206 > EPNODE  *ep;
207   {
208      register EPNODE  *ep1 = ep->v.kid;
209  
# Line 210 | Line 212 | EPNODE  *ep;
212  
213   static double
214   emult(ep)
215 < EPNODE  *ep;
215 > EPNODE  *ep;
216   {
217      register EPNODE  *ep1 = ep->v.kid;
218  
# Line 219 | Line 221 | EPNODE  *ep;
221  
222   static double
223   edivi(ep)
224 < EPNODE  *ep;
224 > EPNODE  *ep;
225   {
226      register EPNODE  *ep1 = ep->v.kid;
227      double  d;
# Line 235 | Line 237 | EPNODE  *ep;
237  
238   static double
239   epow(ep)
240 < EPNODE  *ep;
240 > EPNODE  *ep;
241   {
242      register EPNODE  *ep1 = ep->v.kid;
243      double  d;
244 <    int  lasterrno;
244 >    int  lasterrno;
245  
246      lasterrno = errno;
247      errno = 0;
248      d = pow(evalue(ep1), evalue(ep1->sibling));
249 < #ifdef  IEEE
249 > #ifdef  IEEE
250      if (!finite(d))
251          errno = EDOM;
252   #endif
# Line 258 | Line 260 | EPNODE  *ep;
260  
261   static double
262   ebotch(ep)
263 < EPNODE  *ep;
263 > EPNODE  *ep;
264   {
265      eputs("Bad expression!\n");
266      quit(1);
# Line 267 | Line 269 | EPNODE  *ep;
269  
270   EPNODE *
271   ekid(ep, n)                     /* return pointer to a node's nth kid */
272 < register EPNODE  *ep;
272 > register EPNODE  *ep;
273   register int  n;
274   {
275  
# Line 281 | Line 283 | register int  n;
283  
284   int
285   nekids(ep)                      /* return # of kids for node ep */
286 < register EPNODE  *ep;
286 > register EPNODE  *ep;
287   {
288      register int  n = 0;
289  
# Line 297 | Line 299 | FILE  *fp;
299   char  *fn;
300   int  ln;
301   {
302 <    static char  inpbuf[MAXLINE];
302 >    static char  inpbuf[MAXLINE];
303  
304      infp = fp;
305      linbuf = inpbuf;
# Line 372 | Line 374 | char *
374   ltoa(l)                         /* convert long to ascii */
375   long  l;
376   {
377 <    static char  buf[16];
377 >    static char  buf[16];
378      register char  *cp;
379 <    int  neg = 0;
379 >    int  neg = 0;
380  
381      if (l == 0)
382          return("0");
# Line 405 | Line 407 | char  *err;
407              eputs(infile != NULL ? ", line " : "line ");
408              eputs(ltoa((long)lineno));
409          }
410 <        eputs(": syntax error:\n");
410 >        eputs(":\n");
411      }
412      eputs(linbuf);
413      if (linbuf[strlen(linbuf)-1] != '\n')
# Line 420 | Line 422 | char  *err;
422  
423  
424   addekid(ep, ekid)                       /* add a child to ep */
425 < register EPNODE  *ep;
426 < EPNODE  *ekid;
425 > register EPNODE  *ep;
426 > EPNODE  *ekid;
427   {
428      if (ep->v.kid == NULL)
429          ep->v.kid = ekid;
# Line 434 | Line 436 | EPNODE  *ekid;
436   }
437  
438  
439 + #if  defined(VARIABLE) || defined(FUNCTION)
440   char *
441   getname()                       /* scan an identifier */
442   {
443 <    static char  str[MAXWORD+1];
443 >    static char  str[MAXWORD+1];
444      register int  i, lnext;
445  
446      lnext = nextc;
447      for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
448          str[i] = lnext;
449      str[i] = '\0';
450 +    while (isid(lnext))         /* skip rest of name */
451 +        lnext = scan();
452  
453      return(str);
454   }
455 + #endif
456  
457  
458   int
# Line 477 | Line 483 | getnum()                       /* scan a positive float */
483          lnext = scan();
484      }
485      if (lnext == '.' && i < MAXWORD) {
486 <        str[i++] = lnext;
487 <        lnext = scan();
486 >        str[i++] = lnext;
487 >        lnext = scan();
488          while (isdigit(lnext) && i < MAXWORD) {
489              str[i++] = lnext;
490              lnext = scan();
491          }
492      }
493      if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) {
494 <        str[i++] = lnext;
495 <        lnext = scan();
494 >        str[i++] = lnext;
495 >        lnext = scan();
496          if ((lnext == '-' || lnext == '+') && i < MAXWORD) {
497              str[i++] = lnext;
498              lnext = scan();
# Line 504 | Line 510 | getnum()                       /* scan a positive float */
510  
511   EPNODE *
512   getE1()                         /* E1 -> E1 ADDOP E2 */
513 <                                /*       E2 */
513 >                                /*       E2 */
514   {
515      register EPNODE  *ep1, *ep2;
516  
# Line 515 | Line 521 | getE1()                                /* E1 -> E1 ADDOP E2 */
521          scan();
522          addekid(ep2, ep1);
523          addekid(ep2, getE2());
524 < #ifdef  RCONST
524 > #ifdef  RCONST
525          if (ep1->type == NUM && ep1->sibling->type == NUM)
526                  ep2 = rconst(ep2);
527   #endif
# Line 527 | Line 533 | getE1()                                /* E1 -> E1 ADDOP E2 */
533  
534   EPNODE *
535   getE2()                         /* E2 -> E2 MULOP E3 */
536 <                                /*       E3 */
536 >                                /*       E3 */
537   {
538      register EPNODE  *ep1, *ep2;
539  
# Line 538 | Line 544 | getE2()                                /* E2 -> E2 MULOP E3 */
544          scan();
545          addekid(ep2, ep1);
546          addekid(ep2, getE3());
547 < #ifdef  RCONST
547 > #ifdef  RCONST
548          if (ep1->type == NUM && ep1->sibling->type == NUM)
549                  ep2 = rconst(ep2);
550   #endif
# Line 550 | Line 556 | getE2()                                /* E2 -> E2 MULOP E3 */
556  
557   EPNODE *
558   getE3()                         /* E3 -> E4 ^ E3 */
559 <                                /*       E4 */
559 >                                /*       E4 */
560   {
561      register EPNODE  *ep1, *ep2;
562  
# Line 561 | Line 567 | getE3()                                /* E3 -> E4 ^ E3 */
567          scan();
568          addekid(ep2, ep1);
569          addekid(ep2, getE3());
570 < #ifdef  RCONST
570 > #ifdef  RCONST
571          if (ep1->type == NUM && ep1->sibling->type == NUM)
572                  ep2 = rconst(ep2);
573   #endif
# Line 573 | Line 579 | getE3()                                /* E3 -> E4 ^ E3 */
579  
580   EPNODE *
581   getE4()                         /* E4 -> ADDOP E5 */
582 <                                /*       E5 */
582 >                                /*       E5 */
583   {
584      register EPNODE  *ep1, *ep2;
585  
# Line 584 | Line 590 | getE4()                                /* E4 -> ADDOP E5 */
590                  ep2->v.num = -ep2->v.num;
591                  return(ep2);
592          }
593 +        if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
594 +            efree((char *)ep2);
595 +            return(ep2->v.kid);
596 +        }
597          ep1 = newnode();
598          ep1->type = UMINUS;
599          addekid(ep1, ep2);
# Line 597 | Line 607 | getE4()                                /* E4 -> ADDOP E5 */
607  
608   EPNODE *
609   getE5()                         /* E5 -> (E1) */
610 <                                /*       VAR */
611 <                                /*       NUM */
612 <                                /*       $N */
613 <                                /*       FUNC(E1,..) */
614 <                                /*       ARG */
610 >                                /*       VAR */
611 >                                /*       NUM */
612 >                                /*       $N */
613 >                                /*       FUNC(E1,..) */
614 >                                /*       ARG */
615   {
616 <    int  i;
616 >    int  i;
617      char  *nam;
618      register EPNODE  *ep1, *ep2;
619  
# Line 616 | Line 626 | getE5()                                /* E5 -> (E1) */
626          return(ep1);
627      }
628  
629 < #ifdef  INCHAN
629 > #ifdef  INCHAN
630      if (nextc == '$') {
631          scan();
632          ep1 = newnode();
# Line 627 | Line 637 | getE5()                                /* E5 -> (E1) */
637   #endif
638  
639   #if  defined(VARIABLE) || defined(FUNCTION)
640 <    if (isalpha(nextc)) {
640 >    if (isalpha(nextc) || nextc == CNTXMARK) {
641          nam = getname();
642   #if  defined(VARIABLE) && defined(FUNCTION)
643          ep1 = NULL;
644          if (curfunc != NULL)
645              for (i = 1, ep2 = curfunc->v.kid->sibling;
646 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
646 >                                ep2 != NULL; i++, ep2 = ep2->sibling)
647                  if (!strcmp(ep2->v.name, nam)) {
648                      ep1 = newnode();
649                      ep1->type = ARG;
# Line 647 | Line 657 | getE5()                                /* E5 -> (E1) */
657              ep1->type = VAR;
658              ep1->v.ln = varinsert(nam);
659          }
660 < #ifdef  FUNCTION
660 > #ifdef  FUNCTION
661          if (nextc == '(') {
662              ep2 = newnode();
663              ep2->type = FUNC;
# Line 661 | Line 671 | getE5()                                /* E5 -> (E1) */
671                  syntax("')' expected");
672              scan();
673          }
674 < #ifndef  VARIABLE
674 > #ifndef  VARIABLE
675          else
676              syntax("'(' expected");
677   #endif
678   #endif
679 < #ifdef  RCONST
679 > #ifdef  RCONST
680          if (isconstvar(ep1))
681              ep1 = rconst(ep1);
682   #endif
# Line 684 | Line 694 | getE5()                                /* E5 -> (E1) */
694   }
695  
696  
697 < #ifdef  RCONST
697 > #ifdef  RCONST
698   EPNODE *
699   rconst(epar)                    /* reduce a constant expression */
700 < register EPNODE  *epar;
700 > register EPNODE  *epar;
701   {
702      register EPNODE  *ep;
703  
# Line 696 | Line 706 | register EPNODE  *epar;
706      errno = 0;
707      ep->v.num = evalue(epar);
708      if (errno)
709 <        syntax("bad constant expression");
709 >        syntax("bad constant expression");
710      epfree(epar);
711  
712      return(ep);
# Line 704 | Line 714 | register EPNODE  *epar;
714  
715  
716   isconstvar(ep)                  /* is ep linked to a constant expression? */
717 < register EPNODE  *ep;
717 > register EPNODE  *ep;
718   {
719 < #ifdef  VARIABLE
719 > #ifdef  VARIABLE
720      register EPNODE  *ep1;
721 < #ifdef  FUNCTION
721 > #ifdef  FUNCTION
722  
723      if (ep->type == FUNC) {
724          if (!isconstfun(ep->v.kid))
# Line 724 | Line 734 | register EPNODE  *ep;
734      ep1 = ep->v.ln->def;
735      if (ep1 == NULL || ep1->type != ':')
736          return(0);
737 < #ifdef  FUNCTION
737 > #ifdef  FUNCTION
738      if (ep1->v.kid->type != SYM)
739          return(0);
740   #endif
# Line 737 | Line 747 | register EPNODE  *ep;
747  
748   #if  defined(FUNCTION) && defined(VARIABLE)
749   isconstfun(ep)                  /* is ep linked to a constant function? */
750 < register EPNODE  *ep;
750 > register EPNODE  *ep;
751   {
752      register EPNODE  *dp;
753      register LIBR  *lp;
754  
755      if (ep->type != VAR)
756          return(0);
757 <    dp = ep->v.ln->def;
758 <    if (dp != NULL && dp->type != ':')
759 <        return(0);
760 <    if ((dp == NULL || dp->v.kid->type != FUNC)
761 <            && ((lp = liblookup(ep->v.ln->name)) == NULL
752 <                    || lp->atyp != ':'))
753 <        return(0);
754 <    return(1);
757 >    if ((dp = ep->v.ln->def) != NULL && dp->v.kid->type == FUNC)
758 >        return(dp->type == ':');
759 >    if ((lp = ep->v.ln->lib) != NULL)
760 >        return(lp->atyp == ':');
761 >    return(0);
762   }
763   #endif
764   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines