algebrite
Version:
Computer Algebra System in Coffeescript
143 lines (116 loc) • 2.17 kB
text/coffeescript
# If the number of args is odd then the last arg is the default result.
Eval_test = ->
p1 = cdr(p1)
while (iscons(p1))
if (cdr(p1) == symbol(NIL))
push(car(p1)); # default case
Eval()
return
push(car(p1))
Eval_predicate()
p2 = pop()
if (!iszero(p2))
push(cadr(p1))
Eval()
return
p1 = cddr(p1)
push_integer(0)
# 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.
Eval_testeq = ->
push(cadr(p1))
Eval()
push(caddr(p1))
Eval()
subtract()
p1 = pop()
if (iszero(p1))
push_integer(1)
else
push_integer(0)
# Relational operators expect a numeric result for operand difference.
Eval_testge = ->
if (cmp_args() >= 0)
push_integer(1)
else
push_integer(0)
Eval_testgt = ->
if (cmp_args() > 0)
push_integer(1)
else
push_integer(0)
Eval_testle = ->
if (cmp_args() <= 0)
push_integer(1)
else
push_integer(0)
Eval_testlt = ->
if (cmp_args() < 0)
push_integer(1)
else
push_integer(0)
Eval_not = ->
push(cadr(p1))
Eval_predicate()
p1 = pop()
if (iszero(p1))
push_integer(1)
else
push_integer(0)
Eval_and = ->
p1 = cdr(p1)
while (iscons(p1))
push(car(p1))
Eval_predicate()
p2 = pop()
if (iszero(p2))
push_integer(0)
return
p1 = cdr(p1)
push_integer(1)
Eval_or = ->
p1 = cdr(p1)
while (iscons(p1))
push(car(p1))
Eval_predicate()
p2 = pop()
if (!iszero(p2))
push_integer(1)
return
p1 = cdr(p1)
push_integer(0)
# use subtract for cases like A < A + 1
cmp_args = ->
t = 0
push(cadr(p1))
Eval()
push(caddr(p1))
Eval()
subtract()
p1 = pop()
# try floating point if necessary
if (p1.k != NUM && p1.k != DOUBLE)
push(p1)
yyfloat()
Eval()
p1 = pop()
if (iszero(p1))
return 0
switch (p1.k)
when NUM
if (MSIGN(p1.q.a) == -1)
t = -1
else
t = 1
when DOUBLE
if (p1.d < 0.0)
t = -1
else
t = 1
else
stop("relational operator: cannot determine due to non-numerical comparison")
t = 0
return t