--- ray/src/common/caldefn.c 1990/05/31 10:24:28 1.2 +++ ray/src/common/caldefn.c 1991/04/24 08:17:22 1.9 @@ -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"; @@ -18,6 +18,8 @@ static char SCCSid[] = "$SunId$ LBL"; * 11/16/88 Added VARDEF structure for hard linking. * * 5/31/90 Added conditional compile (REDEFW) for redefinition warning. + * + * 4/23/91 Added ':' defines for constant expressions (RCONST) */ #include @@ -34,7 +36,7 @@ static char SCCSid[] = "$SunId$ LBL"; extern char *ecalloc(), *savestr(); -extern double dvalue(); +static double dvalue(); long eclock = -1; /* value storage timer */ @@ -68,7 +70,7 @@ char *fname; eputs(": cannot open\n"); quit(1); } - initfile(fname, fp); + initfile(fp, fname, 0); while (nextc != EOF) loaddefn(); if (fname != NULL) @@ -76,11 +78,12 @@ char *fname; } -scompile(file, str) /* get definitions from a string */ -char *file; +scompile(str, fn, ln) /* get definitions from a string */ char *str; +char *fn; +int ln; { - initstr(file, str); + initstr(str, fn, ln); while (nextc != EOF) loaddefn(); } @@ -104,8 +107,9 @@ EPNODE *ep; } -varset(vname, val) /* set a variable's value */ +varset(vname, assign, val) /* set a variable's value */ char *vname; +int assign; double val; { register EPNODE *ep1, *ep2; @@ -114,13 +118,13 @@ double val; ep2 = ep1->v.kid->sibling; if (ep2->type == NUM) { ep2->v.num = val; - ep2->sibling->v.tick = -1; + ep1->type = assign; return; } } /* hand build definition */ ep1 = newnode(); - ep1->type = '='; + ep1->type = assign; ep2 = newnode(); ep2->type = SYM; ep2->v.name = savestr(vname); @@ -129,23 +133,31 @@ double val; ep2->type = NUM; ep2->v.num = val; addekid(ep1, ep2); - ep2 = newnode(); - ep2->type = TICK; - ep2->v.tick = -1; - addekid(ep1, ep2); - ep2 = newnode(); - ep2->type = NUM; - addekid(ep1, ep2); - dclear(vname); + dremove(vname); dpush(ep1); } -dclear(name) /* delete all definitions of name */ +dclear(name) /* delete variable definitions of name */ char *name; { register EPNODE *ep; + while ((ep = dpop(name)) != NULL) { + if (ep->type == ':') { + dpush(ep); /* don't clear constants */ + return; + } + epfree(ep); + } +} + + +dremove(name) /* delete all definitions of name */ +char *name; +{ + register EPNODE *ep; + while ((ep = dpop(name)) != NULL) epfree(ep); } @@ -161,18 +173,20 @@ char *name; #ifdef OUTCHAN -chanout() /* set output channels */ +chanout(cs) /* set output channels */ +int (*cs)(); { register EPNODE *ep; for (ep = outchan; ep != NULL; ep = ep->sibling) - chanset(ep->v.kid->v.chan, evalue(ep->v.kid->sibling)); + (*cs)(ep->v.kid->v.chan, evalue(ep->v.kid->sibling)); } #endif -dclearall() /* clear all definitions */ +dcleanup(cons, ochans) /* clear definitions */ +int cons, ochans; { register int i; register VARDEF *vp; @@ -180,11 +194,16 @@ dclearall() /* clear all definitions */ for (i = 0; i < NHASH; i++) for (vp = hashtbl[i]; vp != NULL; vp = vp->next) - dclear(vp->name); + if (cons) + dremove(vp->name); + else + dclear(vp->name); #ifdef OUTCHAN - for (ep = outchan; ep != NULL; ep = ep->sibling) - epfree(ep); - outchan = NULL; + if (ochans) { + for (ep = outchan; ep != NULL; ep = ep->sibling) + epfree(ep); + outchan = NULL; + } #endif } @@ -374,10 +393,20 @@ loaddefn() /* load next definition */ ep = getdefn(); #ifdef REDEFW if (dlookup(dname(ep)) != NULL) { - dclear(dname(ep)); - wputs(dname(ep)); + dclear(dname(ep)); + wputs(dname(ep)); + if (dlookup(dname(ep)) == NULL) wputs(": redefined\n"); + else + wputs(": redefined constant expression\n"); } +#ifdef FUNCTION + else if (ep->v.kid->type == FUNC && + liblookup(ep->v.kid->v.kid->v.name) != NULL) { + wputs(ep->v.kid->v.kid->v.name); + wputs(": redefined library function\n"); + } +#endif #else dclear(dname(ep)); #endif @@ -393,7 +422,9 @@ loaddefn() /* load next definition */ EPNODE * getdefn() /* A -> SYM = E1 */ + /* SYM : E1 */ /* FUNC(SYM,..) = E1 */ + /* FUNC(SYM,..) : E1 */ { register EPNODE *ep1, *ep2; @@ -427,19 +458,29 @@ getdefn() /* A -> SYM = E1 */ curfunc = NULL; #endif - if (nextc != '=') - syntax("'=' expected"); - scan(); + if (nextc != '=' && nextc != ':') + syntax("'=' or ':' expected"); ep2 = newnode(); - ep2->type = '='; + ep2->type = nextc; + scan(); addekid(ep2, ep1); +#ifdef RCONST + if ( +#ifdef FUNCTION + ep1->type == SYM && +#endif + ep2->type == ':') + addekid(ep2, rconst(getE1())); + else +#endif addekid(ep2, getE1()); + if ( #ifdef FUNCTION - if (ep1->type == SYM) + ep1->type == SYM && #endif - { + ep1->sibling->type != NUM) { ep1 = newnode(); ep1->type = TICK; ep1->v.tick = -1; @@ -500,13 +541,15 @@ EPNODE *d; quit(1); } ep1 = d->v.kid->sibling; /* get expression */ + if (ep1->type == NUM) + return(ep1->v.num); /* return if number */ ep2 = ep1->sibling; /* check time */ if (ep2->v.tick < 0 || ep2->v.tick < eclock) { - ep2->v.tick = eclock; + ep2->v.tick = d->type == ':' ? 1L<<30 : eclock; ep2 = ep2->sibling; - ep2->v.num = evalue(ep1); /* compute new value */ + ep2->v.num = evalue(ep1); /* needs new value */ } else - ep2 = ep2->sibling; /* reuse old value */ + ep2 = ep2->sibling; /* else reuse old value */ return(ep2->v.num); }