# 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


