david hoskin found a bug in cpp.  - is evaluated right to left, so
it computes the wrong result.  for example

        # if 0 - 0 + 4 != 4
        # error bogus preprocessor
        # endif

errors, because cpp computes this as if it were

        # if 0 - (0 + 4) != 4

this is because it evaluates right to left, not right to left.  it turns
out this is because the evalop uses < rather than <= as the
pop (loop) condition for the prec stack.  thus a + b + c
will push to the end then pop from the right.

while the according-to-hoyle fix is to change < to <=, this was
done on purpose.  it allows symbols that need no eval to be
omitted.  it would be a major rework to change this assumption.

so the hack-upon-hack solution might be to just convert - to
+ UMINUS(thing).  this is going to cause trouble if someone
is doing fancy arithmetic with division and counting on
non-underflow.

here is the diff that works on the test cases, and on everything
in /sys/src/cmd/ape.  is this acceptable?

- erik
----

chula; 9diff eval.c
/n/sources/plan9/sys/src/cmd/cpp/eval.c:122,127 - eval.c:122,128
        op = ops;
        *op++ = END;
        for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
+       retry:
                if(op >= ops + NSTAK)
                        sysfatal("cpp: can't evaluate #if: increase NSTAK");
                switch(tp->type) {
/n/sources/plan9/sys/src/cmd/cpp/eval.c:161,166 - eval.c:162,173
                                }
                                continue;
                        }
+                       if(tp->type==MINUS){
+                               *op++ = UMINUS;
+                               tp->type = PLUS;
+                               goto retry;
+                       }
+                               
                        /* flow through */
  
                /* plain binary */

Reply via email to