--- ray/src/common/caldefn.c 2023/09/26 00:14:02 2.35 +++ ray/src/common/caldefn.c 2024/06/20 21:21:24 2.39 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: caldefn.c,v 2.35 2023/09/26 00:14:02 greg Exp $"; +static const char RCSid[] = "$Id: caldefn.c,v 2.39 2024/06/20 21:21:24 greg Exp $"; #endif /* * Store variable definitions. @@ -58,10 +58,9 @@ static VARDEF *htpos; /* ...dfirst() and */ static EPNODE *ochpos; /* ...dnext */ static EPNODE *outchan; +static int optimized = 0; /* are we optimized? */ + EPNODE *curfunc = NULL; -#define dname(ep) ((ep)->v.kid->type == SYM ? \ - (ep)->v.kid->v.name : \ - (ep)->v.kid->v.kid->v.name) void @@ -178,14 +177,14 @@ dclear( /* delete variable definitions of name */ char *name ) { - EPNODE *ep; + VARDEF *vp; + EPNODE *dp; - while ((ep = dpop(name)) != NULL) { - if (ep->type == ':') { - dpush(name, ep); /* don't clear constants */ - return; - } - epfree(ep); + while ((vp = varlookup(name)) != NULL && + (dp = vp->def) != NULL && dp->type == '=') { + vp->def = dp->sibling; + epfree(dp,1); + varfree(vp); } } @@ -198,7 +197,7 @@ dremove( /* delete all definitions of name */ EPNODE *ep; while ((ep = dpop(name)) != NULL) - epfree(ep); + epfree(ep,1); } @@ -295,12 +294,11 @@ qualname( /* get qualified name */ static char nambuf[RMAXWORD+1]; char *cp = nambuf, *cpp; /* check for explicit local */ - if (*nam == CNTXMARK) + if (*nam == CNTXMARK) { if (lvl > 0) /* only action is to refuse search */ return(NULL); - else - nam++; - else if (nam == nambuf) /* check for repeat call */ + nam++; + } else if (nam == nambuf) /* check for repeat call */ return(lvl > 0 ? NULL : nam); /* copy name to static buffer */ while (*nam) { @@ -322,7 +320,7 @@ qualname( /* get qualified name */ while (*++cpp && *cpp != CNTXMARK) ; } - while (*cpp) { /* copy context to static buffer */ + while (*cpp) { /* add remaining context to name */ if (cp >= nambuf+RMAXWORD) goto toolong; *cp++ = *cpp++; @@ -360,6 +358,22 @@ chanout( /* set output channels */ void +doptimize(int activate) /* optimize current and future definitions? */ +{ + EPNODE *ep; + + if (activate && optimized) + return; /* already going */ + + if (!(optimized = activate)) + return; /* switching off */ + + for (ep = dfirst(); ep != NULL; ep = dnext()) + epoptimize(ep); +} + + +void dcleanup( /* clear definitions (0->vars,1->output,2->consts) */ int lvl ) @@ -380,8 +394,7 @@ dcleanup( /* clear definitions (0->vars,1->output,2-> while (outchan != NULL) { ep = outchan; outchan = ep->sibling; - ep->sibling = NULL; - epfree(ep); + epfree(ep,1); } } @@ -564,7 +577,7 @@ addchan( /* add an output channel assignment */ sp->sibling = ep; else { sp->sibling = ep->sibling; - epfree(ep); + epfree(ep,1); } return; } @@ -591,10 +604,14 @@ getstatement(void) /* get next statement */ if (esupport&E_OUTCHAN && nextc == '$') { /* channel assignment */ ep = getchan(); + if (optimized) + epoptimize(ep); /* optimize new chan expr */ addchan(ep); } else { /* ordinary definition */ ep = getdefn(); - qname = qualname(dname(ep), 0); + if (optimized) + epoptimize(ep); /* optimize new statement */ + qname = qualname(dfn_name(ep), 0); if (esupport&E_REDEFW && (vdef = varlookup(qname)) != NULL) { if (vdef->def != NULL && epcmp(ep, vdef->def)) { wputs(qname);