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.43 by greg, Fri Feb 23 03:47:57 2024 UTC vs.
Revision 2.47 by greg, Sun Feb 25 04:11:10 2024 UTC

# Line 35 | Line 35 | static const char      RCSid[] = "$Id$";
35  
36   #define  isdecimal(c)   (isdigit(c) | ((c) == '.'))
37  
38 + #define  envalue(ep)    ((ep)->type==NUM ? (ep)->v.num : evalue(ep))
39 +
40   static double  euminus(EPNODE *), eargument(EPNODE *), enumber(EPNODE *);
41   static double  echannel(EPNODE *);
42   static double  eadd(EPNODE *), esubtr(EPNODE *),
# Line 209 | Line 211 | epfree(                        /* free a parse tree */
211   }
212  
213  
214 + static void
215 + epflatten(                      /* flatten hierarchies for '+', '*' */
216 +        EPNODE *epar
217 + )
218 + {
219 +    EPNODE      *ep;
220 +
221 +    if (epar->nkids < 0) {
222 +        eputs("Cannot flatten EPNODE array\n");
223 +        quit(1);
224 +    }
225 +    for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
226 +        while (ep->type == epar->type) {
227 +            EPNODE      *ep1 = ep->v.kid;
228 +            while (ep1->sibling != NULL)
229 +                ep1 = ep1->sibling;
230 +            ep1->sibling = ep->sibling;
231 +            epar->nkids += nekids(ep) - 1;
232 +            ep1 = ep->v.kid;
233 +            *ep = *ep1;
234 +            efree(ep1);         /* not epfree()! */
235 +        }
236 + }
237 +
238 +
239   void
240 < epoptimize(                     /* realloc lists as arrays if > length 3 */
240 > epoptimize(                     /* flatten operations, lists -> arrays */
241          EPNODE  *epar
242   )
243   {
244      EPNODE      *ep;
245  
246 <    if (epar->nkids > 3) {      /* do this node if > 3 kids */
246 >    if ((epar->type == '+') | (epar->type == '*'))
247 >        epflatten(epar);        /* flatten associative operations */
248 >
249 >    if (epar->nkids)            /* do children if any */
250 >        for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
251 >            epoptimize(ep);
252 >
253 >    if (epar->nkids > 4) {      /* make list into array if > 4 kids */
254          int     n = 1;
255          epar->v.kid = (EPNODE *)erealloc(epar->v.kid,
256                                          sizeof(EPNODE)*epar->nkids);
# Line 227 | Line 261 | epoptimize(                    /* realloc lists as arrays if > length 3
261              epar->v.kid[n-1].sibling = epar->v.kid + n;
262              n++;
263          }
264 <        epar->nkids = -epar->nkids;
264 >        epar->nkids = -n;
265      }
232    if (epar->nkids)            /* do children if any */
233        for (ep = epar->v.kid; ep != NULL; ep = ep->sibling)
234            epoptimize(ep);
266   }
267  
268                                  /* the following used to be a switch */
# Line 274 | Line 305 | eadd(
305      EPNODE      *ep
306   )
307   {
308 +    double  sum = 0;
309      EPNODE  *ep1 = ep->v.kid;
310  
311 <    return(evalue(ep1) + evalue(ep1->sibling));
311 >    do
312 >        sum += envalue(ep1);
313 >    while ((ep1 = ep1->sibling) != NULL);
314 >
315 >    return(sum);
316   }
317  
318   static double
# Line 285 | Line 321 | esubtr(
321   )
322   {
323      EPNODE  *ep1 = ep->v.kid;
324 +    EPNODE  *ep2 = ep1->sibling;
325  
326 <    return(evalue(ep1) - evalue(ep1->sibling));
326 >    return(envalue(ep1) - envalue(ep2));
327   }
328  
329   static double
# Line 294 | Line 331 | emult(
331      EPNODE      *ep
332   )
333   {
334 +    double  prod = 1;
335      EPNODE  *ep1 = ep->v.kid;
336  
337 <    return(evalue(ep1) * evalue(ep1->sibling));
337 >    do
338 >        prod *= envalue(ep1);
339 >    while ((ep1 = ep1->sibling) != NULL);
340 >
341 >    return(prod);
342   }
343  
344   static double
# Line 305 | Line 347 | edivi(
347   )
348   {
349      EPNODE  *ep1 = ep->v.kid;
350 +    EPNODE  *ep2 = ep1->sibling;
351      double  d;
352  
353 <    d = evalue(ep1->sibling);
353 >    d = evalue(ep2);
354      if (d == 0.0) {
355          wputs("Division by zero\n");
356          errno = ERANGE;
357          return(0.0);
358      }
359 <    return(evalue(ep1) / d);
359 >    return(envalue(ep1) / d);
360   }
361  
362   static double
# Line 521 | Line 564 | addekid(                       /* add a child to ep */
564   )
565   {
566      if (ep->nkids < 0) {
567 <        eputs("Cannot add child after optimization\n");
567 >        eputs("Cannot add kid to EPNODE array\n");
568          quit(1);
569      }
570      ep->nkids++;
# Line 532 | Line 575 | addekid(                       /* add a child to ep */
575              ;
576          ep->sibling = ek;
577      }
578 <    ek->sibling = NULL;
578 >    ek->sibling = NULL;         /* shouldn't be necessary */
579   }
580  
581  
# Line 762 | Line 805 | getE5(void)                    /* E5 -> (E1) */
805                  scan();
806                  return(ep1);
807          }
765
808          if (esupport&E_INCHAN && nextc == '$') {
809                  scan();
810                  ep1 = newnode();
# Line 770 | Line 812 | getE5(void)                    /* E5 -> (E1) */
812                  ep1->v.chan = getinum();
813                  return(ep1);
814          }
773
815          if (esupport&(E_VARIABLE|E_FUNCTION) &&
816                          (isalpha(nextc) | (nextc == CNTXMARK))) {
817                  nam = getname();
# Line 808 | Line 849 | getE5(void)                    /* E5 -> (E1) */
849                          ep1 = rconst(ep1);
850                  return(ep1);
851          }
811
852          if (isdecimal(nextc)) {
853                  ep1 = newnode();
854                  ep1->type = NUM;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines