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.1 by greg, Thu Feb 2 10:34:27 1989 UTC vs.
Revision 1.16 by greg, Wed Aug 14 16:26:31 1991 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1986 Regents of the University of California */
1 > /* Copyright (c) 1991 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 27 | Line 27 | static char SCCSid[] = "$SunId$ LBL";
27   #include  "calcomp.h"
28  
29   #define  MAXLINE        256             /* maximum line length */
30 #define  MAXWORD        64              /* maximum word length */
30  
31   #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
32  
34 #define  isid(c)        (isalnum(c) || (c) == '_' || (c) == '.')
35
33   #define  isdecimal(c)   (isdigit(c) || (c) == '.')
34  
35   extern double  atof(), pow();
36   extern char  *fgets(), *savestr();
37   extern char  *emalloc(), *ecalloc();
38   extern EPNODE  *curfunc;
39 < extern double  efunc(), evariable(), enumber(), euminus(), echannel();
40 < extern double  eargument(), eadd(), esubtr(), emult(), edivi(), epow();
41 < extern double  ebotch();
39 > extern double  efunc(), evariable();
40 > static double  euminus(), echannel(), eargument(), enumber();
41 > static double  eadd(), esubtr(), emult(), edivi(), epow();
42 > static double  ebotch();
43   extern int  errno;
44  
45   int  nextc;                             /* lookahead character */
# Line 77 | Line 75 | double  (*eoper[])() = {               /* expression operations */
75          esubtr,
76          0,
77          edivi,
78 <        0,0,0,0,0,0,0,0,0,0,0,0,0,
78 >        0,0,0,0,0,0,0,0,0,0,
79          ebotch,
80 +        0,0,
81 +        ebotch,
82          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
83          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
84          epow,
85   };
86  
87 static char  *infile;                   /* input file name */
87   static FILE  *infp;                     /* input file pointer */
88   static char  *linbuf;                   /* line buffer */
89 + static char  *infile;                   /* input file name */
90 + static int  lineno;                     /* input line number */
91   static int  linepos;                    /* position in buffer */
92  
93  
# Line 96 | Line 97 | char  *expr;
97   {
98      EPNODE  *ep;
99  
100 <    initstr(NULL, expr);
100 >    initstr(expr, NULL, 0);
101   #if  defined(VARIABLE) && defined(FUNCTION)
102      curfunc = NULL;
103   #endif
# Line 128 | Line 129 | register EPNODE  *epar;
129  
130      switch (epar->type) {
131  
132 + #if  defined(VARIABLE) || defined(FUNCTION)
133          case VAR:
134              varfree(epar->v.ln);
135              break;
136 + #endif
137              
138          case SYM:
139              freestr(epar->v.name);
# Line 289 | Line 292 | register EPNODE  *ep;
292   }
293  
294  
295 < initfile(file, fp)              /* prepare input file */
293 < char  *file;
295 > initfile(fp, fn, ln)            /* prepare input file */
296   FILE  *fp;
297 + char  *fn;
298 + int  ln;
299   {
300      static char  inpbuf[MAXLINE];
301  
298    infile = file;
302      infp = fp;
303      linbuf = inpbuf;
304 +    infile = fn;
305 +    lineno = ln;
306      linepos = 0;
307      inpbuf[0] = '\0';
308      scan();
309   }
310  
311  
312 < initstr(file, s)                /* prepare input string */
308 < char  *file;
312 > initstr(s, fn, ln)              /* prepare input string */
313   char  *s;
314 + char  *fn;
315 + int  ln;
316   {
311    infile = file;
317      infp = NULL;
318 +    infile = fn;
319 +    lineno = ln;
320      linbuf = s;
321      linepos = 0;
322      scan();
323   }
324  
325  
326 < scan()                          /* scan next character */
326 > getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
327 > char  **fnp;
328 > int  *lnp;
329 > char  **spp;
330 > FILE  **fpp;
331   {
332 +    if (fnp != NULL) *fnp = infile;
333 +    if (lnp != NULL) *lnp = lineno;
334 +    if (spp != NULL) *spp = linbuf+linepos;
335 +    if (fpp != NULL) *fpp = infp;
336 + }
337 +
338 +
339 + int
340 + scan()                          /* scan next character, return literal next */
341 + {
342 +    register int  lnext = 0;
343 +
344      do {
345          if (linbuf[linepos] == '\0')
346              if (infp == NULL || fgets(linbuf, MAXLINE, infp) == NULL)
347                  nextc = EOF;
348              else {
349                  nextc = linbuf[0];
350 +                lineno++;
351                  linepos = 1;
352              }
353          else
354              nextc = linbuf[linepos++];
355 +        if (!lnext)
356 +                lnext = nextc;
357          if (nextc == '{') {
358              scan();
359              while (nextc != '}')
# Line 338 | Line 364 | scan()                         /* scan next character */
364              scan();
365          }
366      } while (isspace(nextc));
367 +    return(lnext);
368   }
369  
370  
371 + char *
372 + ltoa(l)                         /* convert long to ascii */
373 + long  l;
374 + {
375 +    static char  buf[16];
376 +    register char  *cp;
377 +    int  neg = 0;
378 +
379 +    if (l == 0)
380 +        return("0");
381 +    if (l < 0) {
382 +        l = -l;
383 +        neg++;
384 +    }
385 +    cp = buf + sizeof(buf);
386 +    *--cp = '\0';
387 +    while (l) {
388 +        *--cp = l % 10 + '0';
389 +        l /= 10;
390 +    }
391 +    if (neg)
392 +        *--cp = '-';
393 +    return(cp);
394 + }
395 +
396 +
397   syntax(err)                     /* report syntax error and quit */
398   char  *err;
399   {
400      register int  i;
401  
402 +    if (infile != NULL || lineno != 0) {
403 +        if (infile != NULL) eputs(infile);
404 +        if (lineno != 0) {
405 +            eputs(infile != NULL ? ", line " : "line ");
406 +            eputs(ltoa((long)lineno));
407 +        }
408 +        eputs(": syntax error:\n");
409 +    }
410      eputs(linbuf);
411 <    if (linbuf[0] == '\0' || linbuf[strlen(linbuf)-1] != '\n')
411 >    if (linbuf[strlen(linbuf)-1] != '\n')
412          eputs("\n");
413      for (i = 0; i < linepos-1; i++)
414          eputs(linbuf[i] == '\t' ? "\t" : " ");
415      eputs("^ ");
355    if (infile != NULL) {
356        eputs(infile);
357        eputs(": ");
358    }
416      eputs(err);
417      eputs("\n");
418      quit(1);
# Line 381 | Line 438 | char *
438   getname()                       /* scan an identifier */
439   {
440      static char  str[MAXWORD+1];
441 <    register int  i;
441 >    register int  i, lnext;
442  
443 <    for (i = 0; i < MAXWORD && isid(nextc); i++, scan())
444 <        str[i] = nextc;
443 >    lnext = nextc;
444 >    for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
445 >        str[i] = lnext;
446      str[i] = '\0';
447 +    while (isid(lnext))         /* skip rest of name */
448 +        lnext = scan();
449  
450      return(str);
451   }
# Line 394 | Line 454 | getname()                      /* scan an identifier */
454   int
455   getinum()                       /* scan a positive integer */
456   {
457 <    register int  n;
457 >    register int  n, lnext;
458  
459      n = 0;
460 <    while (isdigit(nextc)) {
461 <        n = n * 10 + nextc - '0';
462 <        scan();
460 >    lnext = nextc;
461 >    while (isdigit(lnext)) {
462 >        n = n * 10 + lnext - '0';
463 >        lnext = scan();
464      }
465      return(n);
466   }
# Line 408 | Line 469 | getinum()                      /* scan a positive integer */
469   double
470   getnum()                        /* scan a positive float */
471   {
472 <    register int  i;
472 >    register int  i, lnext;
473      char  str[MAXWORD+1];
474  
475      i = 0;
476 <    while (isdigit(nextc) && i < MAXWORD) {
477 <        str[i++] = nextc;
478 <        scan();
476 >    lnext = nextc;
477 >    while (isdigit(lnext) && i < MAXWORD) {
478 >        str[i++] = lnext;
479 >        lnext = scan();
480      }
481 <    if (nextc == '.' && i < MAXWORD) {
482 <        str[i++] = nextc;
483 <        scan();
484 <        while (isdigit(nextc) && i < MAXWORD) {
485 <            str[i++] = nextc;
486 <            scan();
481 >    if (lnext == '.' && i < MAXWORD) {
482 >        str[i++] = lnext;
483 >        lnext = scan();
484 >        while (isdigit(lnext) && i < MAXWORD) {
485 >            str[i++] = lnext;
486 >            lnext = scan();
487          }
488      }
489 <    if ((nextc == 'e' || nextc == 'E') && i < MAXWORD) {
490 <        str[i++] = nextc;
491 <        scan();
492 <        if ((nextc == '-' || nextc == '+') && i < MAXWORD) {
493 <            str[i++] = nextc;
494 <            scan();
489 >    if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) {
490 >        str[i++] = lnext;
491 >        lnext = scan();
492 >        if ((lnext == '-' || lnext == '+') && i < MAXWORD) {
493 >            str[i++] = lnext;
494 >            lnext = scan();
495          }
496 <        while (isdigit(nextc) && i < MAXWORD) {
497 <            str[i++] = nextc;
498 <            scan();
496 >        while (isdigit(lnext) && i < MAXWORD) {
497 >            str[i++] = lnext;
498 >            lnext = scan();
499          }
500      }
501      str[i] = '\0';
# Line 489 | Line 551 | getE2()                                /* E2 -> E2 MULOP E3 */
551  
552  
553   EPNODE *
554 < getE3()                         /* E3 -> E3 ^ E4 */
554 > getE3()                         /* E3 -> E4 ^ E3 */
555                                  /*       E4 */
556   {
557      register EPNODE  *ep1, *ep2;
558  
559      ep1 = getE4();
560 <    while (nextc == '^') {
560 >    if (nextc == '^') {
561          ep2 = newnode();
562          ep2->type = nextc;
563          scan();
564          addekid(ep2, ep1);
565 <        addekid(ep2, getE4());
565 >        addekid(ep2, getE3());
566   #ifdef  RCONST
567          if (ep1->type == NUM && ep1->sibling->type == NUM)
568                  ep2 = rconst(ep2);
569   #endif
570 <        ep1 = ep2;
570 >        return(ep2);
571      }
572      return(ep1);
573   }
# Line 515 | Line 577 | EPNODE *
577   getE4()                         /* E4 -> ADDOP E5 */
578                                  /*       E5 */
579   {
580 <    register EPNODE  *ep1;
580 >    register EPNODE  *ep1, *ep2;
581  
582      if (nextc == '-') {
583          scan();
584 <        ep1 = newnode();
585 < #ifndef  RCONST
586 <        if (isdecimal(nextc)) {
587 <            ep1->type = NUM;
526 <            ep1->v.num = -getnum();
527 <            return(ep1);
584 >        ep2 = getE5();
585 >        if (ep2->type == NUM) {
586 >                ep2->v.num = -ep2->v.num;
587 >                return(ep2);
588          }
589 < #endif
589 >        if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
590 >            efree((char *)ep2);
591 >            return(ep2->v.kid);
592 >        }
593 >        ep1 = newnode();
594          ep1->type = UMINUS;
595 <        addekid(ep1, getE5());
532 < #ifdef  RCONST
533 <        if (ep1->v.kid->type == NUM)
534 <                ep1 = rconst(ep1);
535 < #endif
595 >        addekid(ep1, ep2);
596          return(ep1);
597      }
598      if (nextc == '+')
# Line 550 | Line 610 | getE5()                                /* E5 -> (E1) */
610                                  /*       ARG */
611   {
612      int  i;
613 +    char  *nam;
614      register EPNODE  *ep1, *ep2;
615  
616      if (nextc == '(') {
# Line 572 | Line 633 | getE5()                                /* E5 -> (E1) */
633   #endif
634  
635   #if  defined(VARIABLE) || defined(FUNCTION)
636 <    if (isalpha(nextc)) {
637 <        ep1 = newnode();
577 <        ep1->type = VAR;
578 <        ep1->v.ln = varinsert(getname());
579 <
636 >    if (isalpha(nextc) || nextc == CNTXMARK) {
637 >        nam = getname();
638   #if  defined(VARIABLE) && defined(FUNCTION)
639 +        ep1 = NULL;
640          if (curfunc != NULL)
641              for (i = 1, ep2 = curfunc->v.kid->sibling;
642                                  ep2 != NULL; i++, ep2 = ep2->sibling)
643 <                if (!strcmp(ep2->v.name, ep1->v.ln->name)) {
585 <                    epfree(ep1);
643 >                if (!strcmp(ep2->v.name, nam)) {
644                      ep1 = newnode();
645                      ep1->type = ARG;
646                      ep1->v.chan = i;
647                      break;
648                  }
649 +        if (ep1 == NULL)
650   #endif
651 +        {
652 +            ep1 = newnode();
653 +            ep1->type = VAR;
654 +            ep1->v.ln = varinsert(nam);
655 +        }
656   #ifdef  FUNCTION
657          if (nextc == '(') {
658              ep2 = newnode();
# Line 608 | Line 672 | getE5()                                /* E5 -> (E1) */
672              syntax("'(' expected");
673   #endif
674   #endif
675 + #ifdef  RCONST
676 +        if (isconstvar(ep1))
677 +            ep1 = rconst(ep1);
678 + #endif
679          return(ep1);
680      }
681   #endif
# Line 639 | Line 707 | register EPNODE  *epar;
707  
708      return(ep);
709   }
710 +
711 +
712 + isconstvar(ep)                  /* is ep linked to a constant expression? */
713 + register EPNODE  *ep;
714 + {
715 + #ifdef  VARIABLE
716 +    register EPNODE  *ep1;
717 + #ifdef  FUNCTION
718 +
719 +    if (ep->type == FUNC) {
720 +        if (!isconstfun(ep->v.kid))
721 +                return(0);
722 +        for (ep1 = ep->v.kid->sibling; ep1 != NULL; ep1 = ep1->sibling)
723 +            if (ep1->type != NUM && !isconstfun(ep1))
724 +                return(0);
725 +        return(1);
726 +    }
727 + #endif
728 +    if (ep->type != VAR)
729 +        return(0);
730 +    ep1 = ep->v.ln->def;
731 +    if (ep1 == NULL || ep1->type != ':')
732 +        return(0);
733 + #ifdef  FUNCTION
734 +    if (ep1->v.kid->type != SYM)
735 +        return(0);
736 + #endif
737 +    return(1);
738 + #else
739 +    return(ep->type == FUNC);
740 + #endif
741 + }
742 +
743 +
744 + #if  defined(FUNCTION) && defined(VARIABLE)
745 + isconstfun(ep)                  /* is ep linked to a constant function? */
746 + register EPNODE  *ep;
747 + {
748 +    register EPNODE  *dp;
749 +    register LIBR  *lp;
750 +
751 +    if (ep->type != VAR)
752 +        return(0);
753 +    dp = ep->v.ln->def;
754 +    if (dp != NULL && dp->type != ':')
755 +        return(0);
756 +    if ((dp == NULL || dp->v.kid->type != FUNC)
757 +            && ((lp = liblookup(ep->v.ln->name)) == NULL
758 +                    || lp->atyp != ':'))
759 +        return(0);
760 +    return(1);
761 + }
762 + #endif
763   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines