--- ray/src/common/calexpr.c 1991/04/23 15:26:26 1.9 +++ ray/src/common/calexpr.c 1992/05/19 20:21:58 2.5 @@ -1,4 +1,4 @@ -/* Copyright (c) 1986 Regents of the University of California */ +/* Copyright (c) 1991 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -27,15 +27,15 @@ static char SCCSid[] = "$SunId$ LBL"; #include "calcomp.h" #define MAXLINE 256 /* maximum line length */ -#define MAXWORD 64 /* maximum word length */ #define newnode() (EPNODE *)ecalloc(1, sizeof(EPNODE)) -#define isid(c) (isalnum(c) || (c) == '_' || (c) == '.') - #define isdecimal(c) (isdigit(c) || (c) == '.') -extern double atof(), pow(); +#ifndef atof +extern double atof(); +#endif +extern double pow(); extern char *fgets(), *savestr(); extern char *emalloc(), *ecalloc(); extern EPNODE *curfunc; @@ -136,11 +136,11 @@ register EPNODE *epar; case VAR: varfree(epar->v.ln); break; -#endif case SYM: freestr(epar->v.name); break; +#endif case NUM: case CHAN: @@ -326,8 +326,24 @@ int ln; } -scan() /* scan next character */ +getscanpos(fnp, lnp, spp, fpp) /* return current scan position */ +char **fnp; +int *lnp; +char **spp; +FILE **fpp; { + if (fnp != NULL) *fnp = infile; + if (lnp != NULL) *lnp = lineno; + if (spp != NULL) *spp = linbuf+linepos; + if (fpp != NULL) *fpp = infp; +} + + +int +scan() /* scan next character, return literal next */ +{ + register int lnext = 0; + do { if (linbuf[linepos] == '\0') if (infp == NULL || fgets(linbuf, MAXLINE, infp) == NULL) @@ -339,6 +355,8 @@ scan() /* scan next character */ } else nextc = linbuf[linepos++]; + if (!lnext) + lnext = nextc; if (nextc == '{') { scan(); while (nextc != '}') @@ -349,6 +367,7 @@ scan() /* scan next character */ scan(); } } while (isspace(nextc)); + return(lnext); } @@ -418,29 +437,35 @@ EPNODE *ekid; } +#if defined(VARIABLE) || defined(FUNCTION) char * getname() /* scan an identifier */ { static char str[MAXWORD+1]; - register int i; + register int i, lnext; - for (i = 0; i < MAXWORD && isid(nextc); i++, scan()) - str[i] = nextc; + lnext = nextc; + for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan()) + str[i] = lnext; str[i] = '\0'; + while (isid(lnext)) /* skip rest of name */ + lnext = scan(); return(str); } +#endif int getinum() /* scan a positive integer */ { - register int n; + register int n, lnext; n = 0; - while (isdigit(nextc)) { - n = n * 10 + nextc - '0'; - scan(); + lnext = nextc; + while (isdigit(lnext)) { + n = n * 10 + lnext - '0'; + lnext = scan(); } return(n); } @@ -449,32 +474,33 @@ getinum() /* scan a positive integer */ double getnum() /* scan a positive float */ { - register int i; + register int i, lnext; char str[MAXWORD+1]; i = 0; - while (isdigit(nextc) && i < MAXWORD) { - str[i++] = nextc; - scan(); + lnext = nextc; + while (isdigit(lnext) && i < MAXWORD) { + str[i++] = lnext; + lnext = scan(); } - if (nextc == '.' && i < MAXWORD) { - str[i++] = nextc; - scan(); - while (isdigit(nextc) && i < MAXWORD) { - str[i++] = nextc; - scan(); + if (lnext == '.' && i < MAXWORD) { + str[i++] = lnext; + lnext = scan(); + while (isdigit(lnext) && i < MAXWORD) { + str[i++] = lnext; + lnext = scan(); } } - if ((nextc == 'e' || nextc == 'E') && i < MAXWORD) { - str[i++] = nextc; - scan(); - if ((nextc == '-' || nextc == '+') && i < MAXWORD) { - str[i++] = nextc; - scan(); + if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) { + str[i++] = lnext; + lnext = scan(); + if ((lnext == '-' || lnext == '+') && i < MAXWORD) { + str[i++] = lnext; + lnext = scan(); } - while (isdigit(nextc) && i < MAXWORD) { - str[i++] = nextc; - scan(); + while (isdigit(lnext) && i < MAXWORD) { + str[i++] = lnext; + lnext = scan(); } } str[i] = '\0'; @@ -565,6 +591,10 @@ getE4() /* E4 -> ADDOP E5 */ ep2->v.num = -ep2->v.num; return(ep2); } + if (ep2->type == UMINUS) { /* don't generate -(-E5) */ + efree((char *)ep2); + return(ep2->v.kid); + } ep1 = newnode(); ep1->type = UMINUS; addekid(ep1, ep2); @@ -585,6 +615,7 @@ getE5() /* E5 -> (E1) */ /* ARG */ { int i; + char *nam; register EPNODE *ep1, *ep2; if (nextc == '(') { @@ -607,23 +638,26 @@ getE5() /* E5 -> (E1) */ #endif #if defined(VARIABLE) || defined(FUNCTION) - if (isalpha(nextc)) { - ep1 = newnode(); - ep1->type = VAR; - ep1->v.ln = varinsert(getname()); - + if (isalpha(nextc) || nextc == CNTXMARK) { + nam = getname(); #if defined(VARIABLE) && defined(FUNCTION) + ep1 = NULL; if (curfunc != NULL) for (i = 1, ep2 = curfunc->v.kid->sibling; ep2 != NULL; i++, ep2 = ep2->sibling) - if (!strcmp(ep2->v.name, ep1->v.ln->name)) { - epfree(ep1); + if (!strcmp(ep2->v.name, nam)) { ep1 = newnode(); ep1->type = ARG; ep1->v.chan = i; break; } + if (ep1 == NULL) #endif + { + ep1 = newnode(); + ep1->type = VAR; + ep1->v.ln = varinsert(nam); + } #ifdef FUNCTION if (nextc == '(') { ep2 = newnode(); @@ -680,24 +714,18 @@ register EPNODE *epar; } -isconstvar(ep) /* is ep linked to a constant? */ +isconstvar(ep) /* is ep linked to a constant expression? */ register EPNODE *ep; { #ifdef VARIABLE register EPNODE *ep1; - #ifdef FUNCTION + if (ep->type == FUNC) { - if (ep->v.kid->type != VAR) - return(0); - ep1 = ep->v.kid->v.ln->def; - if (ep1 != NULL && ep1->type != ':') - return(0); - if ((ep1 == NULL || ep1->v.kid->type != FUNC) - && liblookup(ep->v.kid->v.ln->name) == NULL) - return(0); + if (!isconstfun(ep->v.kid)) + return(0); for (ep1 = ep->v.kid->sibling; ep1 != NULL; ep1 = ep1->sibling) - if (ep1->type != NUM) + if (ep1->type != NUM && !isconstfun(ep1)) return(0); return(1); } @@ -716,4 +744,22 @@ register EPNODE *ep; return(ep->type == FUNC); #endif } + + +#if defined(FUNCTION) && defined(VARIABLE) +isconstfun(ep) /* is ep linked to a constant function? */ +register EPNODE *ep; +{ + register EPNODE *dp; + register LIBR *lp; + + if (ep->type != VAR) + return(0); + if ((dp = ep->v.ln->def) != NULL && dp->v.kid->type == FUNC) + return(dp->type == ':'); + if ((lp = ep->v.ln->lib) != NULL) + return(lp->atyp == ':'); + return(0); +} +#endif #endif