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.42 by greg, Fri Apr 8 23:32:25 2022 UTC vs.
Revision 2.43 by greg, Fri Feb 23 03:47:57 2024 UTC

# Line 111 | Line 111 | eval(                  /* evaluate an expression string */
111      ep = eparse(expr);
112      esupport = prev_support;    /* as you were */
113      rval = evalue(ep);
114 <    epfree(ep);
114 >    epfree(ep,1);
115      return(rval);
116   }
117  
# Line 168 | Line 168 | epcmp(                 /* compare two expressions for equivalence */
168  
169   void
170   epfree(                 /* free a parse tree */
171 <    EPNODE       *epar
171 >    EPNODE       *epar,
172 >    int         frep
173   )
174   {
175 <    EPNODE  *ep;
175 >    EPNODE      *ep;
176  
177      switch (epar->type) {
178  
# Line 190 | Line 191 | epfree(                        /* free a parse tree */
191              break;
192  
193          default:
194 <            while ((ep = epar->v.kid) != NULL) {
195 <                epar->v.kid = ep->sibling;
196 <                epfree(ep);
197 <            }
194 >            if (epar->nkids < 0) {
195 >                ep = epar->v.kid - epar->nkids;
196 >                while (ep > epar->v.kid)
197 >                        epfree(--ep, 0);
198 >                efree(ep);      /* free array space */
199 >            } else
200 >                while ((ep = epar->v.kid) != NULL) {
201 >                    epar->v.kid = ep->sibling;
202 >                    epfree(ep, 1);
203 >                }
204              break;
205  
206      }
207 +    if (frep)
208 +        efree(epar);
209 + }
210  
211 <    efree(epar);
211 >
212 > void
213 > epoptimize(                     /* realloc lists as arrays if > length 3 */
214 >        EPNODE  *epar
215 > )
216 > {
217 >    EPNODE      *ep;
218 >
219 >    if (epar->nkids > 3) {      /* do this node if > 3 kids */
220 >        int     n = 1;
221 >        epar->v.kid = (EPNODE *)erealloc(epar->v.kid,
222 >                                        sizeof(EPNODE)*epar->nkids);
223 >        while (n < epar->nkids) {
224 >            ep = epar->v.kid[n-1].sibling;
225 >            epar->v.kid[n] = *ep;
226 >            efree(ep);          /* not epfree()! */
227 >            epar->v.kid[n-1].sibling = epar->v.kid + n;
228 >            n++;
229 >        }
230 >        epar->nkids = -epar->nkids;
231 >    }
232 >    if (epar->nkids)            /* do children if any */
233 >        for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
234 >            epoptimize(ep);
235   }
236  
237                                  /* the following used to be a switch */
# Line 328 | Line 361 | ekid(                  /* return pointer to a node's nth kid */
361      int  n
362   )
363   {
364 <
365 <    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
366 <        if (--n < 0)
367 <            break;
368 <
364 >    if (ep->nkids < 0) {        /* allocated array? */
365 >        if (n >= -ep->nkids)
366 >            return(NULL);
367 >        return(ep->v.kid + n);
368 >    }
369 >    ep = ep->v.kid;             /* else get from list */
370 >    while (n-- > 0)
371 >        if ((ep = ep->sibling) == NULL)
372 >                break;
373      return(ep);
374   }
375  
376  
340 int
341 nekids(                 /* return # of kids for node ep */
342    EPNODE       *ep
343 )
344 {
345    int  n = 0;
346
347    for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
348        n++;
349
350    return(n);
351 }
352
353
377   void
378   initfile(               /* prepare input file */
379      FILE  *fp,
# Line 494 | Line 517 | syntax(                        /* report syntax error and quit */
517   void
518   addekid(                        /* add a child to ep */
519      EPNODE       *ep,
520 <    EPNODE      *ekid
520 >    EPNODE      *ek
521   )
522   {
523 +    if (ep->nkids < 0) {
524 +        eputs("Cannot add child after optimization\n");
525 +        quit(1);
526 +    }
527 +    ep->nkids++;
528      if (ep->v.kid == NULL)
529 <        ep->v.kid = ekid;
529 >        ep->v.kid = ek;
530      else {
531          for (ep = ep->v.kid; ep->sibling != NULL; ep = ep->sibling)
532              ;
533 <        ep->sibling = ekid;
533 >        ep->sibling = ek;
534      }
535 <    ekid->sibling = NULL;
535 >    ek->sibling = NULL;
536   }
537  
538  
# Line 629 | Line 657 | getE2(void)                    /* E2 -> E2 MULOP E3 */
657                                  ep3->v.num = 1./ep3->v.num;
658                          } else if (ep3->v.num == 0) {
659                                  ep1->sibling = NULL;    /* (E2 * 0) */
660 <                                epfree(ep2);
660 >                                epfree(ep2,1);
661                                  ep2 = ep3;
662                          }
663                  } else if (ep1->type == NUM && ep1->v.num == 0) {
664 <                        epfree(ep3);            /* (0 * E3) or (0 / E3) */
664 >                        epfree(ep3,1);          /* (0 * E3) or (0 / E3) */
665                          ep1->sibling = NULL;
666                          efree(ep2);
667                          ep2 = ep1;
# Line 664 | Line 692 | getE3(void)                    /* E3 -> E4 ^ E3 */
692                  if ((ep1->type == NUM) & (ep3->type == NUM)) {
693                          ep2 = rconst(ep2);
694                  } else if (ep1->type == NUM && ep1->v.num == 0) {
695 <                        epfree(ep3);            /* (0 ^ E3) */
695 >                        epfree(ep3,1);          /* (0 ^ E3) */
696                          ep1->sibling = NULL;
697                          efree(ep2);
698                          ep2 = ep1;
699                  } else if ((ep3->type == NUM && ep3->v.num == 0) |
700                                  (ep1->type == NUM && ep1->v.num == 1)) {
701 <                        epfree(ep2);            /* (E4 ^ 0) or (1 ^ E3) */
701 >                        epfree(ep2,1);          /* (E4 ^ 0) or (1 ^ E3) */
702                          ep2 = newnode();
703                          ep2->type = NUM;
704                          ep2->v.num = 1;
# Line 805 | Line 833 | rconst(                        /* reduce a constant expression */
833      ep->v.num = evalue(epar);
834      if ((errno == EDOM) | (errno == ERANGE))
835          syntax("bad constant expression");
836 <    epfree(epar);
836 >    epfree(epar,1);
837  
838      return(ep);
839   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines