die("internal error -- garbled READ list\n");
else
{
+ /* FIXME: read into subscripted variables and slices won't work */
value *v = &(tp->syminf->value);
int n;
{
value leftside, rightside, result, cond;
node *np;
+ int n;
+ jmp_buf jmpperf;
switch(tree->type)
{
return(result);
case WHILE:
- /* FIXME: implement WHILE */
- die("WHILE is not implemented\n");
+ do {
+ cupl_eval(tree->cdr);
+
+ cond = cupl_eval(tree->car);
+ } while
+ (cond.rank);
result.rank = FAIL;
return(result);
return(result);
case TIMES:
- /* FIXME: implement TIMES */
- die("TIMES is not implemented\n");
+ result = cupl_eval(tree->car);
+ for (n = floor(result.elements[0]); n; n--)
+ (void) cupl_eval(tree->cdr);
result.rank = FAIL;
return(result);
case PERFORM:
- next = tree->car;
- pushstack(pc->cdr);
- longjmp(nextbuf, 1);
+ if (setjmp(jmpperf) == 0)
+ cupl_eval(tree->car);
+ result.rank = FAIL;
+ return(result);
case BLOCK:
next = pc->endnode->cdr;
next = tree->car;
longjmp(nextbuf, 1);
- case END:
case OG:
- next = popstack();
- longjmp(nextbuf, 1);
+ case END:
+ longjmp(jmpperf, 1);
case IF:
leftside = EVAL_WRAP(cupl_eval(tree->car));
*
****************************************************************************/
-static bool normalize(scalar *ep1, scalar *ep2)
-/* normalize a pair of scalars for conversion purposes */
-{
- int mult;
-
- if (*ep1 == 0 && *ep2 == 0)
- return;
-
- /*
- * Note: this is not precisely the roundoff method used by original
- * CUPL, though it should (famous last words) be equivalent.
- */
- if (fabs(*ep1) > fabs(*ep2))
- mult = pow(10, log10(*ep2) + 14);
- else
- mult = pow(10, log10(*ep1) + 14);
-
- *ep1 *= mult;
- *ep2 *= mult;
-
- *ep1 = floor(*ep1);
- *ep2 = floor(*ep2);
-}
+/*
+ * Original CUPL's roundoff rule for relations seems to have been designed
+ * to throw away all digits of precision more than 14,
+ */
+#define FUZZY_EQUAL(m, n) (fabs((m) - (n)) < 10e-15)
bool cupl_eq(value v1, value v2)
/* test any two CUPL values for pairwise equality */
for (n = 0; n < v2.width * v2.depth; n++)
{
- scalar e1 = v1.elements[n], e2 = v1.elements[n];
-
- normalize(&e1, &e2);
+ scalar e1 = v1.elements[n], e2 = v2.elements[n];
- if (e1 != e2)
+ if (!FUZZY_EQUAL(e1, e2))
return(FALSE);
}
for (n = 0; n < v2.width * v2.depth; n++)
{
- scalar e1 = v1.elements[n], e2 = v1.elements[n];
+ scalar e1 = v1.elements[n], e2 = v2.elements[n];
- normalize(&e1, &e2);
-
- if (e1 > e2)
+ if (!FUZZY_EQUAL(e1, e2) && e1 > e2)
return(FALSE);
}
for (n = 0; n < v2.width * v2.depth; n++)
{
- scalar e1 = v1.elements[n], e2 = v1.elements[n];
-
- normalize(&e1, &e2);
+ scalar e1 = v1.elements[n], e2 = v2.elements[n];
- if (e1 < e2)
+ if (!FUZZY_EQUAL(e1, e2) && e1 < e2)
return(FALSE);
}