2008-05-10 03:13:25 +02:00
|
|
|
// If the number of args is odd then the last arg is the default result.
|
2005-08-21 03:19:56 +02:00
|
|
|
|
2004-03-03 21:24:06 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "defs.h"
|
|
|
|
|
|
|
|
void
|
2005-08-07 16:42:42 +02:00
|
|
|
eval_test(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
2005-08-21 03:19:56 +02:00
|
|
|
p1 = cdr(p1);
|
2006-01-11 01:01:41 +01:00
|
|
|
while (iscons(p1)) {
|
2006-01-16 20:37:31 +01:00
|
|
|
if (cdr(p1) == symbol(NIL)) {
|
2006-01-11 01:01:41 +01:00
|
|
|
push(car(p1)); // default case
|
2005-08-21 03:19:56 +02:00
|
|
|
eval();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
push(car(p1));
|
|
|
|
eval_predicate();
|
|
|
|
p2 = pop();
|
2006-01-11 00:30:19 +01:00
|
|
|
if (!iszero(p2)) {
|
2005-08-21 03:19:56 +02:00
|
|
|
push(cadr(p1));
|
2005-08-07 16:42:42 +02:00
|
|
|
eval();
|
|
|
|
return;
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
2005-08-21 03:19:56 +02:00
|
|
|
p1 = cddr(p1);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-13 21:52:59 +01:00
|
|
|
// The test for equality is weaker than the other relational operators.
|
|
|
|
|
|
|
|
// For example, A<=B causes a stop when the result of A minus B is not a
|
|
|
|
// numerical value.
|
|
|
|
|
|
|
|
// However, A==B never causes a stop.
|
|
|
|
|
|
|
|
// For A==B, any nonzero result for A minus B indicates inequality.
|
|
|
|
|
2004-03-03 21:24:06 +01:00
|
|
|
void
|
2005-08-07 16:42:42 +02:00
|
|
|
eval_testeq(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
2006-01-13 21:52:59 +01:00
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
subtract();
|
|
|
|
p1 = pop();
|
|
|
|
if (iszero(p1))
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(1);
|
2004-03-03 21:24:06 +01:00
|
|
|
else
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-13 21:52:59 +01:00
|
|
|
// Relational operators expect a numeric result for operand difference.
|
|
|
|
|
2004-03-03 21:24:06 +01:00
|
|
|
void
|
2005-08-07 16:42:42 +02:00
|
|
|
eval_testge(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
2006-01-12 19:12:19 +01:00
|
|
|
if (cmp_args() >= 0)
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(1);
|
2005-08-07 16:42:42 +02:00
|
|
|
else
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-08-07 16:42:42 +02:00
|
|
|
eval_testgt(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
2006-01-12 19:12:19 +01:00
|
|
|
if (cmp_args() > 0)
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(1);
|
2005-08-07 16:42:42 +02:00
|
|
|
else
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-08-07 16:42:42 +02:00
|
|
|
eval_testle(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
2006-01-12 19:12:19 +01:00
|
|
|
if (cmp_args() <= 0)
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(1);
|
2005-08-07 16:42:42 +02:00
|
|
|
else
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-08-07 16:42:42 +02:00
|
|
|
eval_testlt(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
2006-01-12 19:12:19 +01:00
|
|
|
if (cmp_args() < 0)
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(1);
|
2004-03-03 21:24:06 +01:00
|
|
|
else
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2005-09-02 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
eval_not(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval_predicate();
|
|
|
|
p1 = pop();
|
2006-01-11 00:30:19 +01:00
|
|
|
if (iszero(p1))
|
|
|
|
push_integer(1);
|
2005-09-02 21:41:19 +02:00
|
|
|
else
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2005-09-02 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
eval_and(void)
|
|
|
|
{
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval_predicate();
|
2006-01-11 00:30:19 +01:00
|
|
|
p2 = pop();
|
|
|
|
if (iszero(p2)) {
|
|
|
|
push_integer(0);
|
2005-09-02 21:41:19 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(1);
|
2005-09-02 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
eval_or(void)
|
|
|
|
{
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval_predicate();
|
2006-01-11 00:30:19 +01:00
|
|
|
p2 = pop();
|
|
|
|
if (!iszero(p2)) {
|
|
|
|
push_integer(1);
|
2005-09-02 21:41:19 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
2006-01-11 00:30:19 +01:00
|
|
|
push_integer(0);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-12 19:12:19 +01:00
|
|
|
// use subtract for cases like A < A + 1
|
|
|
|
|
|
|
|
int
|
|
|
|
cmp_args(void)
|
|
|
|
{
|
|
|
|
int t;
|
2007-04-11 23:16:33 +02:00
|
|
|
|
2006-01-12 19:12:19 +01:00
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
subtract();
|
|
|
|
p1 = pop();
|
2007-04-11 23:16:33 +02:00
|
|
|
|
|
|
|
// try floating point if necessary
|
|
|
|
|
|
|
|
if (p1->k != NUM && p1->k != DOUBLE) {
|
|
|
|
push(p1);
|
|
|
|
yyfloat();
|
|
|
|
eval();
|
|
|
|
p1 = pop();
|
|
|
|
}
|
|
|
|
|
2006-01-12 19:12:19 +01:00
|
|
|
if (iszero(p1))
|
|
|
|
return 0;
|
2007-04-11 23:16:33 +02:00
|
|
|
|
2006-01-12 19:12:19 +01:00
|
|
|
switch (p1->k) {
|
|
|
|
case NUM:
|
|
|
|
if (MSIGN(p1->u.q.a) == -1)
|
|
|
|
t = -1;
|
|
|
|
else
|
|
|
|
t = 1;
|
|
|
|
break;
|
|
|
|
case DOUBLE:
|
|
|
|
if (p1->u.d < 0.0)
|
|
|
|
t = -1;
|
|
|
|
else
|
|
|
|
t = 1;
|
|
|
|
break;
|
|
|
|
default:
|
2007-04-11 23:16:33 +02:00
|
|
|
stop("relational operator: cannot determine due to non-numerical comparison");
|
2006-01-12 19:12:19 +01:00
|
|
|
t = 0;
|
|
|
|
}
|
2007-04-11 23:16:33 +02:00
|
|
|
|
2006-01-12 19:12:19 +01:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2007-05-08 16:57:30 +02:00
|
|
|
#if SELFTEST
|
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
static char *s[] = {
|
|
|
|
|
2006-01-12 19:12:19 +01:00
|
|
|
"a<a+1",
|
|
|
|
"1",
|
|
|
|
|
|
|
|
"a-1<a",
|
|
|
|
"1",
|
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1==1",
|
|
|
|
"1",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1==2",
|
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1>=1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"1",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1>=2",
|
2006-01-11 00:30:19 +01:00
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"2>=1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"1",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1>1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1>2",
|
2006-01-11 00:30:19 +01:00
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"2>1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"1",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1<=1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"1",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1<=2",
|
2006-01-11 00:30:19 +01:00
|
|
|
"1",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"2<=1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1<1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-07 16:42:42 +02:00
|
|
|
"1<2",
|
2006-01-11 00:30:19 +01:00
|
|
|
"1",
|
2005-08-07 16:42:42 +02:00
|
|
|
|
|
|
|
"2<1",
|
2006-01-11 00:30:19 +01:00
|
|
|
"0",
|
2005-08-07 16:42:42 +02:00
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"test(0,A,B)",
|
2005-08-21 03:19:56 +02:00
|
|
|
"B",
|
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"test(1,A,B)",
|
2005-08-21 03:19:56 +02:00
|
|
|
"A",
|
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"test(0,A,0,B)",
|
|
|
|
"0",
|
2005-08-21 03:19:56 +02:00
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"test(0,A,0,B,C)",
|
2005-08-21 03:19:56 +02:00
|
|
|
"C",
|
2005-09-02 21:41:19 +02:00
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"not(1)",
|
|
|
|
"0",
|
2005-09-02 21:41:19 +02:00
|
|
|
|
|
|
|
"not(0)",
|
2006-01-11 00:30:19 +01:00
|
|
|
"1",
|
2005-09-02 21:41:19 +02:00
|
|
|
|
|
|
|
"not(a=a)",
|
2006-01-11 00:30:19 +01:00
|
|
|
"0",
|
2005-09-02 21:41:19 +02:00
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"and(1,1)",
|
|
|
|
"1",
|
2005-09-02 21:41:19 +02:00
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"and(1,0)",
|
|
|
|
"0",
|
2005-09-02 21:41:19 +02:00
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"or(1,0)",
|
|
|
|
"1",
|
2005-09-02 21:41:19 +02:00
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
"or(0,0)",
|
|
|
|
"0",
|
2006-01-11 02:42:21 +01:00
|
|
|
|
2007-05-23 21:05:10 +02:00
|
|
|
"(0,0)==0",
|
2006-01-11 02:42:21 +01:00
|
|
|
"1",
|
2007-04-11 23:16:33 +02:00
|
|
|
|
|
|
|
"1<sqrt(3)",
|
|
|
|
"1",
|
2005-08-07 16:42:42 +02:00
|
|
|
};
|
2004-03-03 21:24:06 +01:00
|
|
|
|
|
|
|
void
|
2005-08-07 16:42:42 +02:00
|
|
|
test_test(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
2005-08-07 16:42:42 +02:00
|
|
|
test(__FILE__, s, sizeof s / sizeof (char *));
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
2007-05-08 16:57:30 +02:00
|
|
|
|
|
|
|
#endif
|