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.18 by greg, Sat Feb 22 02:07:21 2003 UTC vs.
Revision 2.28 by schorsch, Fri Nov 14 17:22:06 2003 UTC

# Line 17 | Line 17 | static const char      RCSid[] = "$Id$";
17   *  2/19/03     Eliminated conditional compiles in favor of esupport extern.
18   */
19  
20 < /* ====================================================================
21 < * The Radiance Software License, Version 1.0
22 < *
23 < * Copyright (c) 1990 - 2002 The Regents of the University of California,
24 < * through Lawrence Berkeley National Laboratory.   All rights reserved.
25 < *
26 < * Redistribution and use in source and binary forms, with or without
27 < * modification, are permitted provided that the following conditions
28 < * are met:
29 < *
30 < * 1. Redistributions of source code must retain the above copyright
31 < *         notice, this list of conditions and the following disclaimer.
32 < *
33 < * 2. Redistributions in binary form must reproduce the above copyright
34 < *       notice, this list of conditions and the following disclaimer in
35 < *       the documentation and/or other materials provided with the
36 < *       distribution.
37 < *
38 < * 3. The end-user documentation included with the redistribution,
39 < *           if any, must include the following acknowledgment:
40 < *             "This product includes Radiance software
41 < *                 (http://radsite.lbl.gov/)
42 < *                 developed by the Lawrence Berkeley National Laboratory
43 < *               (http://www.lbl.gov/)."
44 < *       Alternately, this acknowledgment may appear in the software itself,
45 < *       if and wherever such third-party acknowledgments normally appear.
46 < *
47 < * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
48 < *       and "The Regents of the University of California" must
49 < *       not be used to endorse or promote products derived from this
50 < *       software without prior written permission. For written
51 < *       permission, please contact [email protected].
52 < *
53 < * 5. Products derived from this software may not be called "Radiance",
54 < *       nor may "Radiance" appear in their name, without prior written
55 < *       permission of Lawrence Berkeley National Laboratory.
56 < *
57 < * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
58 < * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
59 < * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60 < * DISCLAIMED.   IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
61 < * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
62 < * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
63 < * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
64 < * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65 < * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
66 < * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
67 < * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 < * SUCH DAMAGE.
69 < * ====================================================================
70 < *
71 < * This software consists of voluntary contributions made by many
72 < * individuals on behalf of Lawrence Berkeley National Laboratory.   For more
73 < * information on Lawrence Berkeley National Laboratory, please see
74 < * <http://www.lbl.gov/>.
75 < */
20 > #include "copyright.h"
21  
22   #include  <stdio.h>
23 <
23 > #include  <string.h>
24   #include  <ctype.h>
80
25   #include  <errno.h>
82
26   #include  <math.h>
84
27   #include  <stdlib.h>
28  
29 + #include  "rterror.h"
30   #include  "calcomp.h"
31  
32   #define  MAXLINE        256             /* maximum line length */
# Line 92 | Line 35 | static const char      RCSid[] = "$Id$";
35  
36   #define  isdecimal(c)   (isdigit(c) || (c) == '.')
37  
38 < static double  euminus(), eargument(), enumber();
39 < static double  echannel();
40 < static double  eadd(), esubtr(), emult(), edivi(), epow();
41 < static double  ebotch();
38 > static double  euminus(EPNODE *), eargument(EPNODE *), enumber(EPNODE *);
39 > static double  echannel(EPNODE *);
40 > static double  eadd(EPNODE *), esubtr(EPNODE *),
41 >               emult(EPNODE *), edivi(EPNODE *),
42 >               epow(EPNODE *);
43 > static double  ebotch(EPNODE *);
44  
45   unsigned int  esupport =                /* what to support */
46 <                E_VARIABLE | E_FUNCTION | E_REDEFW;
46 >                E_VARIABLE | E_FUNCTION ;
47  
48   int  nextc;                             /* lookahead character */
49  
50 < double  (*eoper[])() = {                /* expression operations */
50 > double  (*eoper[])(EPNODE *) = {        /* expression operations */
51          ebotch,
52          evariable,
53          enumber,
# Line 137 | Line 82 | static int  linepos;                   /* position in buffer */
82  
83  
84   EPNODE *
85 < eparse(expr)                    /* parse an expression string */
86 < char  *expr;
85 > eparse(                 /* parse an expression string */
86 >    char  *expr
87 > )
88   {
89      EPNODE  *ep;
90  
# Line 152 | Line 98 | char  *expr;
98  
99  
100   double
101 < eval(expr)                      /* evaluate an expression string */
102 < char  *expr;
101 > eval(                   /* evaluate an expression string */
102 >    char  *expr
103 > )
104   {
105      register EPNODE  *ep;
106      double  rval;
# Line 166 | Line 113 | char  *expr;
113  
114  
115   int
116 < epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
117 < register EPNODE  *ep1, *ep2;
116 > epcmp(                  /* compare two expressions for equivalence */
117 >    register EPNODE  *ep1,
118 >    register EPNODE  *ep2
119 > )
120   {
121          double  d;
122  
# Line 183 | Line 132 | register EPNODE  *ep1, *ep2;
132                  if (ep2->v.num == 0)
133                          return(ep1->v.num != 0);
134                  d = ep1->v.num / ep2->v.num;
135 <                return(d > 1.000000000001 | d < 0.999999999999);
135 >                return((d > 1.000000000001) | (d < 0.999999999999));
136  
137          case CHAN:
138          case ARG:
# Line 214 | Line 163 | register EPNODE  *ep1, *ep2;
163  
164  
165   void
166 < epfree(epar)                    /* free a parse tree */
167 < register EPNODE  *epar;
166 > epfree(                 /* free a parse tree */
167 >    register EPNODE      *epar
168 > )
169   {
170      register EPNODE  *ep;
171  
# Line 249 | Line 199 | register EPNODE         *epar;
199  
200                                  /* the following used to be a switch */
201   static double
202 < eargument(ep)
203 < EPNODE  *ep;
202 > eargument(
203 >    EPNODE      *ep
204 > )
205   {
206      return(argument(ep->v.chan));
207   }
208  
209   static double
210 < enumber(ep)
211 < EPNODE  *ep;
210 > enumber(
211 >    EPNODE      *ep
212 > )
213   {
214      return(ep->v.num);
215   }
216  
217   static double
218 < euminus(ep)
219 < EPNODE  *ep;
218 > euminus(
219 >    EPNODE      *ep
220 > )
221   {
222      register EPNODE  *ep1 = ep->v.kid;
223  
# Line 272 | Line 225 | EPNODE *ep;
225   }
226  
227   static double
228 < echannel(ep)
229 < EPNODE  *ep;
228 > echannel(
229 >    EPNODE      *ep
230 > )
231   {
232      return(chanvalue(ep->v.chan));
233   }
234  
235   static double
236 < eadd(ep)
237 < EPNODE  *ep;
236 > eadd(
237 >    EPNODE      *ep
238 > )
239   {
240      register EPNODE  *ep1 = ep->v.kid;
241  
# Line 288 | Line 243 | EPNODE *ep;
243   }
244  
245   static double
246 < esubtr(ep)
247 < EPNODE  *ep;
246 > esubtr(
247 >    EPNODE      *ep
248 > )
249   {
250      register EPNODE  *ep1 = ep->v.kid;
251  
# Line 297 | Line 253 | EPNODE *ep;
253   }
254  
255   static double
256 < emult(ep)
257 < EPNODE  *ep;
256 > emult(
257 >    EPNODE      *ep
258 > )
259   {
260      register EPNODE  *ep1 = ep->v.kid;
261  
# Line 306 | Line 263 | EPNODE *ep;
263   }
264  
265   static double
266 < edivi(ep)
267 < EPNODE  *ep;
266 > edivi(
267 >    EPNODE      *ep
268 > )
269   {
270      register EPNODE  *ep1 = ep->v.kid;
271      double  d;
# Line 322 | Line 280 | EPNODE *ep;
280   }
281  
282   static double
283 < epow(ep)
284 < EPNODE  *ep;
283 > epow(
284 >    EPNODE      *ep
285 > )
286   {
287      register EPNODE  *ep1 = ep->v.kid;
288      double  d;
# Line 336 | Line 295 | EPNODE *ep;
295      if (!finite(d))
296          errno = EDOM;
297   #endif
298 <    if (errno) {
298 >    if (errno == EDOM || errno == ERANGE) {
299          wputs("Illegal power\n");
300          return(0.0);
301      }
# Line 345 | Line 304 | EPNODE *ep;
304   }
305  
306   static double
307 < ebotch(ep)
308 < EPNODE  *ep;
307 > ebotch(
308 >    EPNODE      *ep
309 > )
310   {
311      eputs("Bad expression!\n");
312      quit(1);
313 +        return 0.0; /* pro forma return */
314   }
315  
316  
317   EPNODE *
318 < ekid(ep, n)                     /* return pointer to a node's nth kid */
319 < register EPNODE  *ep;
320 < register int  n;
318 > ekid(                   /* return pointer to a node's nth kid */
319 >    register EPNODE      *ep,
320 >    register int  n
321 > )
322   {
323  
324      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
# Line 368 | Line 330 | register int  n;
330  
331  
332   int
333 < nekids(ep)                      /* return # of kids for node ep */
334 < register EPNODE  *ep;
333 > nekids(                 /* return # of kids for node ep */
334 >    register EPNODE      *ep
335 > )
336   {
337      register int  n = 0;
338  
# Line 381 | Line 344 | register EPNODE         *ep;
344  
345  
346   void
347 < initfile(fp, fn, ln)            /* prepare input file */
348 < FILE  *fp;
349 < char  *fn;
350 < int  ln;
347 > initfile(               /* prepare input file */
348 >    FILE  *fp,
349 >    char  *fn,
350 >    int  ln
351 > )
352   {
353      static char  inpbuf[MAXLINE];
354  
# Line 399 | Line 363 | int  ln;
363  
364  
365   void
366 < initstr(s, fn, ln)              /* prepare input string */
367 < char  *s;
368 < char  *fn;
369 < int  ln;
366 > initstr(                /* prepare input string */
367 >    char  *s,
368 >    char  *fn,
369 >    int  ln
370 > )
371   {
372      infp = NULL;
373      infile = fn;
# Line 414 | Line 379 | int  ln;
379  
380  
381   void
382 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
383 < char  **fnp;
384 < int  *lnp;
385 < char  **spp;
386 < FILE  **fpp;
382 > getscanpos(     /* return current scan position */
383 >    char  **fnp,
384 >    int  *lnp,
385 >    char  **spp,
386 >    FILE  **fpp
387 > )
388   {
389      if (fnp != NULL) *fnp = infile;
390      if (lnp != NULL) *lnp = lineno;
# Line 428 | Line 394 | FILE  **fpp;
394  
395  
396   int
397 < scan()                          /* scan next character, return literal next */
397 > scan(void)              /* scan next character, return literal next */
398   {
399      register int  lnext = 0;
400  
# Line 460 | Line 426 | scan()                         /* scan next character, return literal next
426  
427  
428   char *
429 < long2ascii(l)                         /* convert long to ascii */
430 < long  l;
429 > long2ascii(                           /* convert long to ascii */
430 >    long  l
431 > )
432   {
433      static char  buf[16];
434      register char  *cp;
# Line 486 | Line 453 | long  l;
453  
454  
455   void
456 < syntax(err)                     /* report syntax error and quit */
457 < char  *err;
456 > syntax(                 /* report syntax error and quit */
457 >    char  *err
458 > )
459   {
460      register int  i;
461  
# Line 512 | Line 480 | char  *err;
480  
481  
482   void
483 < addekid(ep, ekid)                       /* add a child to ep */
484 < register EPNODE  *ep;
485 < EPNODE  *ekid;
483 > addekid(                        /* add a child to ep */
484 >    register EPNODE      *ep,
485 >    EPNODE      *ekid
486 > )
487   {
488      if (ep->v.kid == NULL)
489          ep->v.kid = ekid;
# Line 528 | Line 497 | EPNODE *ekid;
497  
498  
499   char *
500 < getname()                       /* scan an identifier */
500 > getname(void)                   /* scan an identifier */
501   {
502 <    static char  str[MAXWORD+1];
502 >    static char  str[RMAXWORD+1];
503      register int  i, lnext;
504  
505      lnext = nextc;
506 <    for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
506 >    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
507          str[i] = lnext;
508      str[i] = '\0';
509      while (isid(lnext))         /* skip rest of name */
# Line 545 | Line 514 | getname()                      /* scan an identifier */
514  
515  
516   int
517 < getinum()                       /* scan a positive integer */
517 > getinum(void)                   /* scan a positive integer */
518   {
519      register int  n, lnext;
520  
# Line 560 | Line 529 | getinum()                      /* scan a positive integer */
529  
530  
531   double
532 < getnum()                        /* scan a positive float */
532 > getnum(void)                    /* scan a positive float */
533   {
534      register int  i, lnext;
535 <    char  str[MAXWORD+1];
535 >    char  str[RMAXWORD+1];
536  
537      i = 0;
538      lnext = nextc;
539 <    while (isdigit(lnext) && i < MAXWORD) {
539 >    while (isdigit(lnext) && i < RMAXWORD) {
540          str[i++] = lnext;
541          lnext = scan();
542      }
543 <    if (lnext == '.' && i < MAXWORD) {
543 >    if (lnext == '.' && i < RMAXWORD) {
544          str[i++] = lnext;
545          lnext = scan();
546          if (i == 1 && !isdigit(lnext))
547              syntax("badly formed number");
548 <        while (isdigit(lnext) && i < MAXWORD) {
548 >        while (isdigit(lnext) && i < RMAXWORD) {
549              str[i++] = lnext;
550              lnext = scan();
551          }
552      }
553 <    if ((lnext == 'e' | lnext == 'E') && i < MAXWORD) {
553 >    if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
554          str[i++] = lnext;
555          lnext = scan();
556 <        if ((lnext == '-' | lnext == '+') && i < MAXWORD) {
556 >        if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
557              str[i++] = lnext;
558              lnext = scan();
559          }
560          if (!isdigit(lnext))
561              syntax("missing exponent");
562 <        while (isdigit(lnext) && i < MAXWORD) {
562 >        while (isdigit(lnext) && i < RMAXWORD) {
563              str[i++] = lnext;
564              lnext = scan();
565          }
# Line 602 | Line 571 | getnum()                       /* scan a positive float */
571  
572  
573   EPNODE *
574 < getE1()                         /* E1 -> E1 ADDOP E2 */
574 > getE1(void)                             /* E1 -> E1 ADDOP E2 */
575                                  /*       E2 */
576   {
577      register EPNODE  *ep1, *ep2;
# Line 624 | Line 593 | getE1()                                /* E1 -> E1 ADDOP E2 */
593  
594  
595   EPNODE *
596 < getE2()                         /* E2 -> E2 MULOP E3 */
596 > getE2(void)                             /* E2 -> E2 MULOP E3 */
597                                  /*       E3 */
598   {
599      register EPNODE  *ep1, *ep2;
# Line 646 | Line 615 | getE2()                                /* E2 -> E2 MULOP E3 */
615  
616  
617   EPNODE *
618 < getE3()                         /* E3 -> E4 ^ E3 */
618 > getE3(void)                             /* E3 -> E4 ^ E3 */
619                                  /*       E4 */
620   {
621      register EPNODE  *ep1, *ep2;
# Line 668 | Line 637 | getE3()                                /* E3 -> E4 ^ E3 */
637  
638  
639   EPNODE *
640 < getE4()                         /* E4 -> ADDOP E5 */
640 > getE4(void)                             /* E4 -> ADDOP E5 */
641                                  /*       E5 */
642   {
643      register EPNODE  *ep1, *ep2;
# Line 696 | Line 665 | getE4()                                /* E4 -> ADDOP E5 */
665  
666  
667   EPNODE *
668 < getE5()                         /* E5 -> (E1) */
668 > getE5(void)                     /* E5 -> (E1) */
669                                  /*       VAR */
670                                  /*       NUM */
671                                  /*       $N */
672                                  /*       FUNC(E1,..) */
673                                  /*       ARG */
674   {
675 <    int  i;
676 <    char  *nam;
677 <    register EPNODE  *ep1, *ep2;
675 >        int      i;
676 >        char  *nam;
677 >        register EPNODE  *ep1, *ep2;
678  
679 <    if (nextc == '(') {
680 <        scan();
681 <        ep1 = getE1();
682 <        if (nextc != ')')
683 <            syntax("')' expected");
684 <        scan();
685 <        return(ep1);
686 <    }
679 >        if (nextc == '(') {
680 >                scan();
681 >                ep1 = getE1();
682 >                if (nextc != ')')
683 >                        syntax("')' expected");
684 >                scan();
685 >                return(ep1);
686 >        }
687  
688 <    if (esupport&E_INCHAN && nextc == '$') {
689 <        scan();
690 <        ep1 = newnode();
691 <        ep1->type = CHAN;
692 <        ep1->v.chan = getinum();
693 <        return(ep1);
694 <    }
688 >        if (esupport&E_INCHAN && nextc == '$') {
689 >                scan();
690 >                ep1 = newnode();
691 >                ep1->type = CHAN;
692 >                ep1->v.chan = getinum();
693 >                return(ep1);
694 >        }
695  
696 <  if (esupport&(E_VARIABLE|E_FUNCTION) &&
697 <                (isalpha(nextc) || nextc == CNTXMARK)) {
698 <      nam = getname();
699 <      ep1 = NULL;
700 <      if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
701 <                        && curfunc != NULL)
702 <            for (i = 1, ep2 = curfunc->v.kid->sibling;
703 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
704 <                if (!strcmp(ep2->v.name, nam)) {
705 <                    ep1 = newnode();
706 <                    ep1->type = ARG;
707 <                    ep1->v.chan = i;
708 <                    break;
696 >        if (esupport&(E_VARIABLE|E_FUNCTION) &&
697 >                        (isalpha(nextc) || nextc == CNTXMARK)) {
698 >                nam = getname();
699 >                ep1 = NULL;
700 >                if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
701 >                                && curfunc != NULL)
702 >                        for (i = 1, ep2 = curfunc->v.kid->sibling;
703 >                                        ep2 != NULL; i++, ep2 = ep2->sibling)
704 >                                if (!strcmp(ep2->v.name, nam)) {
705 >                                        ep1 = newnode();
706 >                                        ep1->type = ARG;
707 >                                        ep1->v.chan = i;
708 >                                        break;
709 >                                }
710 >                if (ep1 == NULL) {
711 >                        ep1 = newnode();
712 >                        ep1->type = VAR;
713 >                        ep1->v.ln = varinsert(nam);
714                  }
715 <        if (ep1 == NULL) {
716 <            ep1 = newnode();
717 <            ep1->type = VAR;
718 <            ep1->v.ln = varinsert(nam);
715 >                if (esupport&E_FUNCTION && nextc == '(') {
716 >                        ep2 = newnode();
717 >                        ep2->type = FUNC;
718 >                        addekid(ep2, ep1);
719 >                        ep1 = ep2;
720 >                        do {
721 >                                scan();
722 >                                addekid(ep1, getE1());
723 >                        } while (nextc == ',');
724 >                        if (nextc != ')')
725 >                                syntax("')' expected");
726 >                        scan();
727 >                } else if (!(esupport&E_VARIABLE))
728 >                        syntax("'(' expected");
729 >                if (esupport&E_RCONST && isconstvar(ep1))
730 >                        ep1 = rconst(ep1);
731 >                return(ep1);
732          }
746        if (esupport&E_FUNCTION && nextc == '(') {
747            ep2 = newnode();
748            ep2->type = FUNC;
749            addekid(ep2, ep1);
750            ep1 = ep2;
751            do {
752                scan();
753                addekid(ep1, getE1());
754            } while (nextc == ',');
755            if (nextc != ')')
756                syntax("')' expected");
757            scan();
758        } else if (!(esupport&E_VARIABLE))
759            syntax("'(' expected");
760        if (esupport&E_RCONST && isconstvar(ep1))
761            ep1 = rconst(ep1);
762        return(ep1);
763    }
733  
734 <    if (isdecimal(nextc)) {
735 <        ep1 = newnode();
736 <        ep1->type = NUM;
737 <        ep1->v.num = getnum();
738 <        return(ep1);
739 <    }
740 <    syntax("unexpected character");
734 >        if (isdecimal(nextc)) {
735 >                ep1 = newnode();
736 >                ep1->type = NUM;
737 >                ep1->v.num = getnum();
738 >                return(ep1);
739 >        }
740 >        syntax("unexpected character");
741 >        return NULL; /* pro forma return */
742   }
743  
744  
745   EPNODE *
746 < rconst(epar)                    /* reduce a constant expression */
747 < register EPNODE  *epar;
746 > rconst(                 /* reduce a constant expression */
747 >    register EPNODE      *epar
748 > )
749   {
750      register EPNODE  *ep;
751  
# Line 782 | Line 753 | register EPNODE         *epar;
753      ep->type = NUM;
754      errno = 0;
755      ep->v.num = evalue(epar);
756 <    if (errno)
756 >    if (errno == EDOM || errno == ERANGE)
757          syntax("bad constant expression");
758      epfree(epar);
759  
# Line 791 | Line 762 | register EPNODE         *epar;
762  
763  
764   int
765 < isconstvar(ep)                  /* is ep linked to a constant expression? */
766 < register EPNODE  *ep;
765 > isconstvar(                     /* is ep linked to a constant expression? */
766 >    register EPNODE      *ep
767 > )
768   {
769      register EPNODE  *ep1;
770  
# Line 816 | Line 788 | register EPNODE         *ep;
788  
789  
790   int
791 < isconstfun(ep)                  /* is ep linked to a constant function? */
792 < register EPNODE  *ep;
791 > isconstfun(                     /* is ep linked to a constant function? */
792 >    register EPNODE      *ep
793 > )
794   {
795      register EPNODE  *dp;
796      register LIBR  *lp;
797  
798      if (ep->type != VAR)
799          return(0);
800 <    if ((dp = ep->v.ln->def) != NULL)
800 >    if ((dp = ep->v.ln->def) != NULL) {
801          if (dp->v.kid->type == FUNC)
802              return(dp->type == ':');
803          else
804              return(0);          /* don't identify masked library functions */
805 +    }
806      if ((lp = ep->v.ln->lib) != NULL)
807          return(lp->atyp == ':');
808      return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines