2004-03-03 21:24:06 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "defs.h"
|
2005-10-27 23:18:32 +02:00
|
|
|
|
2004-03-03 21:24:06 +01:00
|
|
|
int trigmode;
|
2005-08-07 16:42:42 +02:00
|
|
|
static char errstr[24];
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
|
|
|
eval(void)
|
|
|
|
{
|
|
|
|
save();
|
|
|
|
p1 = pop();
|
|
|
|
switch (p1->k) {
|
|
|
|
case CONS:
|
|
|
|
eval_cons();
|
|
|
|
break;
|
|
|
|
case NUM:
|
|
|
|
push(p1);
|
|
|
|
if (floating)
|
|
|
|
bignum_float();
|
|
|
|
break;
|
|
|
|
case DOUBLE:
|
|
|
|
push(p1);
|
|
|
|
break;
|
|
|
|
case STR:
|
|
|
|
push(p1);
|
|
|
|
break;
|
|
|
|
case TENSOR:
|
|
|
|
eval_tensor();
|
|
|
|
break;
|
|
|
|
case SYM:
|
2006-05-06 01:27:26 +02:00
|
|
|
eval_sym();
|
2006-01-04 03:30:50 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
sprintf(errstr, "atom %d?", p1->k);
|
|
|
|
stop(errstr);
|
|
|
|
break;
|
|
|
|
}
|
2006-01-16 20:37:31 +01:00
|
|
|
if (stack[tos - 1] != symbol(NIL))
|
2006-01-04 03:30:50 +01:00
|
|
|
symbol(YYLAST)->u.sym.binding = stack[tos - 1];
|
|
|
|
restore();
|
|
|
|
}
|
|
|
|
|
2006-05-06 01:27:26 +02:00
|
|
|
void
|
|
|
|
eval_sym(void)
|
|
|
|
{
|
|
|
|
// bare keyword?
|
|
|
|
|
|
|
|
if (symbol_index(p1) < NIL) {
|
|
|
|
push(p1);
|
|
|
|
push(symbol(LAST));
|
|
|
|
list(2);
|
|
|
|
eval();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
push(p1->u.sym.binding);
|
|
|
|
|
|
|
|
// if (p1 != p1->u.sym.binding)
|
|
|
|
// eval();
|
|
|
|
|
|
|
|
if (floating) {
|
|
|
|
p1 = pop();
|
|
|
|
if (p1 == symbol(PI))
|
|
|
|
push_double(M_PI);
|
|
|
|
else if (p1 == symbol(E))
|
|
|
|
push_double(M_E);
|
|
|
|
else
|
|
|
|
push(p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
|
|
|
eval_cons(void)
|
|
|
|
{
|
|
|
|
if (!issymbol(car(p1))) {
|
|
|
|
sprintf(errstr, "form %d?", car(p1)->k);
|
|
|
|
stop(errstr);
|
|
|
|
}
|
|
|
|
switch (symbol_index(car(p1))) {
|
|
|
|
case ABS: eval_abs(); break;
|
|
|
|
case ADD: eval_add(); break;
|
|
|
|
case ADJ: eval_adj(); break;
|
|
|
|
case AND: eval_and(); break;
|
|
|
|
case ARCCOS: eval_arccos(); break;
|
|
|
|
case ARCCOSH: eval_arccosh(); break;
|
|
|
|
case ARCSIN: eval_arcsin(); break;
|
|
|
|
case ARCSINH: eval_arcsinh(); break;
|
|
|
|
case ARCTAN: eval_arctan(); break;
|
|
|
|
case ARCTANH: eval_arctanh(); break;
|
|
|
|
case ARG: eval_arg(); break;
|
|
|
|
case ATOMIZE: eval_atomize(); break;
|
|
|
|
case BESSELJ: eval_besselj(); break;
|
|
|
|
case BESSELY: eval_bessely(); break;
|
|
|
|
case BINDING2: eval_binding2(); break;
|
|
|
|
case BINOMIAL: eval_binomial(); break;
|
|
|
|
case BREAK: eval_break(); break;
|
|
|
|
case CARAC: eval_carac(); break;
|
|
|
|
case CEILING: eval_ceiling(); break;
|
|
|
|
case CHECK: eval_check(); break;
|
2006-05-06 01:27:26 +02:00
|
|
|
case CIRCEXP: eval_circexp(); break;
|
2006-01-04 03:30:50 +01:00
|
|
|
case CLEAR: eval_clear(); break;
|
|
|
|
case CLS: eval_cls(); break;
|
|
|
|
case COEFF: eval_coeff(); break;
|
2006-01-06 04:13:23 +01:00
|
|
|
case COFACTOR: eval_cofactor(); break;
|
2006-01-04 03:30:50 +01:00
|
|
|
case CONDENSE: eval_condense(); break;
|
|
|
|
case CONJ: eval_conj(); break;
|
|
|
|
case CONTRACT: eval_contract(); break;
|
|
|
|
case CONVOLUTION: eval_convolution(); break;
|
|
|
|
case COS: eval_cos(); break;
|
|
|
|
case COSH: eval_cosh(); break;
|
2006-05-12 22:17:48 +02:00
|
|
|
case DECOMP: eval_decomp(); break;
|
2006-01-04 03:30:50 +01:00
|
|
|
case DEGREE: eval_degree(); break;
|
|
|
|
case DENOMINATOR: eval_denominator(); break;
|
|
|
|
case DERIVATIVE: eval_derivative(); break;
|
|
|
|
case DET: eval_det(); break;
|
|
|
|
case DIM: eval_dim(); break;
|
|
|
|
case DIRAC: eval_dirac(); break;
|
|
|
|
case DISPLAY: eval_display(); break;
|
|
|
|
case DIVISORS: eval_divisors(); break;
|
|
|
|
case DO: eval_do(); break;
|
|
|
|
case DOT: eval_inner(); break;
|
|
|
|
case DRAW: eval_draw(); break;
|
|
|
|
case DSOLVE: eval_dsolve(); break;
|
|
|
|
case EIGEN: eval_eigen(); break;
|
|
|
|
case EIGENVAL: eval_eigenval(); break;
|
|
|
|
case EIGENVEC: eval_eigenvec(); break;
|
|
|
|
case ERF: eval_erf(); break;
|
|
|
|
case ERFC: eval_erfc(); break;
|
|
|
|
case EVAL: eval_eval(); break;
|
|
|
|
case EXP: eval_exp(); break;
|
|
|
|
case EXPAND: eval_expand(); break;
|
|
|
|
case EXPCOS: eval_expcos(); break;
|
|
|
|
case EXPSIN: eval_expsin(); break;
|
|
|
|
case FACTOR: eval_factor(); break;
|
|
|
|
case FACTORIAL: eval_factorial(); break;
|
|
|
|
case FACTORPOLY: eval_factorpoly(); break;
|
|
|
|
case FILTER: eval_filter(); break;
|
|
|
|
case FLOATF: eval_float(); break;
|
|
|
|
case FLOOR: eval_floor(); break;
|
|
|
|
case FOR: eval_for(); break;
|
|
|
|
case FOURIER: eval_fourier(); break;
|
|
|
|
case GAMMA: eval_gamma(); break;
|
|
|
|
case GCD: eval_gcd(); break;
|
|
|
|
case HEAVISIDE: eval_heaviside(); break;
|
|
|
|
case HERMITE: eval_hermite(); break;
|
|
|
|
case HILBERT: eval_hilbert(); break;
|
|
|
|
case IMAG: eval_imag(); break;
|
|
|
|
case INDEX: eval_index(); break;
|
|
|
|
case INNER: eval_inner(); break;
|
|
|
|
case INTEGRAL: eval_integral(); break;
|
|
|
|
case INV: eval_inv(); break;
|
|
|
|
case INVFOURIER: eval_invfourier(); break;
|
|
|
|
case INVG: eval_invg(); break;
|
|
|
|
case ISINTEGER: eval_isinteger(); break;
|
|
|
|
case ISPRIME: eval_isprime(); break;
|
|
|
|
case LAGUERRE: eval_laguerre(); break;
|
|
|
|
case LCM: eval_lcm(); break;
|
|
|
|
case LEGENDRE: eval_legendre(); break;
|
|
|
|
case LOG: eval_log(); break;
|
|
|
|
case MAG: eval_mag(); break;
|
|
|
|
case MOD: eval_mod(); break;
|
|
|
|
case MULTIPLY: eval_multiply(); break;
|
|
|
|
case NOT: eval_not(); break;
|
2006-01-13 21:52:59 +01:00
|
|
|
case NUMBER: eval_number(); break;
|
2006-01-04 03:30:50 +01:00
|
|
|
case NUMERATOR: eval_numerator(); break;
|
|
|
|
case OPERATOR: eval_operator(); break;
|
|
|
|
case OR: eval_or(); break;
|
|
|
|
case OUTER: eval_outer(); break;
|
2006-02-10 20:24:36 +01:00
|
|
|
case POLAR: eval_polar(); break;
|
2006-01-04 03:30:50 +01:00
|
|
|
case POWER: eval_power(); break;
|
|
|
|
case PRIME: eval_prime(); break;
|
|
|
|
case PRINT: eval_print(); break;
|
|
|
|
case PRODUCT: eval_product(); break;
|
|
|
|
case PROG: eval_prog(); break;
|
|
|
|
case QUOTE: eval_quote(); break;
|
2006-02-10 01:55:47 +01:00
|
|
|
case QUOTIENT: eval_quotient(); break;
|
2006-01-04 03:30:50 +01:00
|
|
|
case RANK: eval_rank(); break;
|
|
|
|
case RATIONALIZE: eval_rationalize(); break;
|
|
|
|
case REAL: eval_real(); break;
|
|
|
|
case YYRECT: eval_rect(); break;
|
|
|
|
case RETURN: eval_return(); break;
|
|
|
|
case ROOTS: eval_roots(); break;
|
|
|
|
case SETQ: eval_setq(); break;
|
|
|
|
case SGN: eval_sgn(); break;
|
|
|
|
case SIMFAC: eval_simfac(); break;
|
|
|
|
case SIMPLIFY: eval_simplify(); break;
|
|
|
|
case SIN: eval_sin(); break;
|
|
|
|
case SINH: eval_sinh(); break;
|
|
|
|
case SQRT: eval_sqrt(); break;
|
|
|
|
case STOP: eval_stop(); break;
|
|
|
|
case SUBST: eval_subst(); break;
|
|
|
|
case SUM: eval_sum(); break;
|
|
|
|
case SUMMARIZE: eval_summarize(); break;
|
|
|
|
case TAB: eval_tab(); break;
|
|
|
|
case TAN: eval_tan(); break;
|
|
|
|
case TANH: eval_tanh(); break;
|
|
|
|
case TAYLOR: eval_taylor(); break;
|
|
|
|
case TCHEBYCHEVT: eval_tchebychevT(); break;
|
|
|
|
case TCHEBYCHEVU: eval_tchebychevU(); break;
|
|
|
|
case TEST: eval_test(); break;
|
|
|
|
case TESTEQ: eval_testeq(); break;
|
|
|
|
case TESTGE: eval_testge(); break;
|
|
|
|
case TESTGT: eval_testgt(); break;
|
|
|
|
case TESTLE: eval_testle(); break;
|
|
|
|
case TESTLT: eval_testlt(); break;
|
|
|
|
case TRACE: eval_trace(); break;
|
|
|
|
case TRANSPOSE: eval_transpose(); break;
|
|
|
|
case UNIT: eval_unit(); break;
|
|
|
|
case ZERO: eval_zero(); break;
|
|
|
|
default: eval_user_function(); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-03 21:24:06 +01:00
|
|
|
void
|
|
|
|
setup(void)
|
|
|
|
{
|
|
|
|
U *p;
|
|
|
|
|
2006-05-06 01:27:26 +02:00
|
|
|
exp_flag = 0;
|
2004-03-03 21:24:06 +01:00
|
|
|
trigmode = 0;
|
2006-05-06 01:27:26 +02:00
|
|
|
floating = 0;
|
2004-03-03 21:24:06 +01:00
|
|
|
|
|
|
|
p = symbol(AUTOEXPAND);
|
|
|
|
if (iszero(p->u.sym.binding))
|
|
|
|
expanding = 0;
|
|
|
|
else
|
|
|
|
expanding = 1;
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_add(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
p1 = cddr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
add();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_break(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
break_function();
|
|
|
|
}
|
|
|
|
|
2006-01-11 00:30:19 +01:00
|
|
|
// checks a predicate, i.e. check(A = B)
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_check(void)
|
|
|
|
{
|
2005-09-02 21:41:19 +02:00
|
|
|
push(cadr(p1));
|
|
|
|
eval_predicate();
|
2004-03-03 21:24:06 +01:00
|
|
|
p1 = pop();
|
2006-01-11 00:30:19 +01:00
|
|
|
if (iszero(p1))
|
|
|
|
stop("check(arg): arg is zero");
|
2006-02-12 14:19:18 +01:00
|
|
|
push(symbol(NIL)); // no result is printed
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-05-06 01:27:26 +02:00
|
|
|
// change circular functions to exponentials
|
|
|
|
|
|
|
|
void
|
|
|
|
eval_circexp(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
exp_flag++;
|
|
|
|
eval();
|
|
|
|
exp_flag--;
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_cls(void)
|
|
|
|
{
|
|
|
|
clear_term();
|
2006-01-16 20:37:31 +01:00
|
|
|
push(symbol(NIL));
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_conj(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
conjugate();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_det(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
det();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_dim(void)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
p2 = pop();
|
|
|
|
if (iscons(cddr(p1))) {
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
n = pop_integer();
|
|
|
|
} else
|
|
|
|
n = 1;
|
2005-08-06 22:57:37 +02:00
|
|
|
if (!istensor(p2) || n < 1 || n > p2->u.tensor->ndim)
|
2004-03-03 21:24:06 +01:00
|
|
|
push(p1);
|
|
|
|
else
|
|
|
|
push_integer(p2->u.tensor->dim[n - 1]);
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_divisors(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
divisors();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_do(void)
|
|
|
|
{
|
|
|
|
push(car(p1));
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
pop();
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_dsolve(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
push(cadddr(p1));
|
|
|
|
eval();
|
|
|
|
dsolve();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_eval(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
eval();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_exp(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
exponential();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_expand(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
expand();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_factorial(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
factorial();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_factorpoly(void)
|
|
|
|
{
|
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
factorpoly();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
factorpoly();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Must do eval then second eval to handle functions that want integer args
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_float(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
2006-05-06 01:27:26 +02:00
|
|
|
floating++;
|
2004-03-03 21:24:06 +01:00
|
|
|
eval();
|
2006-05-06 01:27:26 +02:00
|
|
|
floating--;
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_for(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
push(caddr(p1));
|
|
|
|
push(cadddr(p1));
|
|
|
|
push(caddddr(p1));
|
|
|
|
for_function();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_hermite(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
hermite();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_hilbert(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
hilbert();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_index(void)
|
|
|
|
{
|
|
|
|
int h;
|
|
|
|
h = tos;
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
index_function(tos - h);
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_inv(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
inv();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_invg(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
invg();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_isinteger(void)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
p1 = pop();
|
2005-08-06 22:57:37 +02:00
|
|
|
if (isrational(p1)) {
|
2004-03-03 21:24:06 +01:00
|
|
|
if (isinteger(p1))
|
2004-06-25 22:45:15 +02:00
|
|
|
push(one);
|
2004-03-03 21:24:06 +01:00
|
|
|
else
|
2004-06-25 22:45:15 +02:00
|
|
|
push(zero);
|
2004-03-03 21:24:06 +01:00
|
|
|
return;
|
|
|
|
}
|
2005-08-06 22:57:37 +02:00
|
|
|
if (isdouble(p1)) {
|
2004-03-03 21:24:06 +01:00
|
|
|
n = (int) p1->u.d;
|
|
|
|
if (n == p1->u.d)
|
2004-06-25 22:45:15 +02:00
|
|
|
push(one);
|
2004-03-03 21:24:06 +01:00
|
|
|
else
|
2004-06-25 22:45:15 +02:00
|
|
|
push(zero);
|
2004-03-03 21:24:06 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
push_symbol(ISINTEGER);
|
|
|
|
push(p1);
|
|
|
|
list(2);
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_laguerre(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
if (iscons(cdddr(p1))) {
|
|
|
|
push(cadddr(p1));
|
|
|
|
eval();
|
|
|
|
} else
|
2004-06-25 22:45:15 +02:00
|
|
|
push(zero);
|
2004-03-03 21:24:06 +01:00
|
|
|
laguerre();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_legendre(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
if (iscons(cdddr(p1))) {
|
|
|
|
push(cadddr(p1));
|
|
|
|
eval();
|
|
|
|
} else
|
2004-06-25 22:45:15 +02:00
|
|
|
push(zero);
|
2004-03-03 21:24:06 +01:00
|
|
|
legendre();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_multiply(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
p1 = cddr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
multiply();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-13 21:52:59 +01:00
|
|
|
void
|
|
|
|
eval_number(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
p1 = pop();
|
|
|
|
if (p1->k == NUM || p1->k == DOUBLE)
|
|
|
|
push_integer(1);
|
|
|
|
else
|
|
|
|
push_integer(0);
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_operator(void)
|
|
|
|
{
|
|
|
|
int h = tos;
|
|
|
|
push_symbol(OPERATOR);
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
list(tos - h);
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_power(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
power();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_prime(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
prime();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern void printstack(int);
|
|
|
|
|
2004-06-09 04:45:50 +02:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_print(void)
|
|
|
|
{
|
2004-06-09 04:45:50 +02:00
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
print(pop());
|
2004-03-03 21:24:06 +01:00
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
2004-06-09 04:45:50 +02:00
|
|
|
printchar(' ');
|
2004-03-03 21:24:06 +01:00
|
|
|
push(car(p1));
|
|
|
|
eval();
|
2004-06-09 04:45:50 +02:00
|
|
|
print(pop());
|
2004-03-03 21:24:06 +01:00
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
2004-06-09 04:45:50 +02:00
|
|
|
printchar('\n');
|
2006-01-16 20:37:31 +01:00
|
|
|
push(symbol(NIL));
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_prog(void)
|
|
|
|
{
|
|
|
|
push(cdr(p1));
|
|
|
|
prog();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_quote(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_rank(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
2004-08-15 21:30:02 +02:00
|
|
|
p1 = pop();
|
2005-08-06 22:57:37 +02:00
|
|
|
if (istensor(p1))
|
2004-08-15 21:30:02 +02:00
|
|
|
push_integer(p1->u.tensor->ndim);
|
|
|
|
else
|
2004-06-25 22:45:15 +02:00
|
|
|
push(zero);
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_return(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
prog_return();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Example: a[1] = b
|
|
|
|
//
|
|
|
|
// p1 *-------*-----------------------*
|
|
|
|
// | | |
|
|
|
|
// setq *-------*-------* b
|
|
|
|
// | | |
|
|
|
|
// index a 1
|
|
|
|
//
|
|
|
|
// cadadr(p1) -> a
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
setq_indexed(void)
|
|
|
|
{
|
|
|
|
int h;
|
|
|
|
p4 = cadadr(p1);
|
2005-08-06 22:57:37 +02:00
|
|
|
if (!issymbol(p4))
|
2004-03-03 21:24:06 +01:00
|
|
|
stop("indexed assignment: error in symbol");
|
|
|
|
h = tos;
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
p2 = cdadr(p1);
|
|
|
|
while (iscons(p2)) {
|
|
|
|
push(car(p2));
|
|
|
|
eval();
|
|
|
|
p2 = cdr(p2);
|
|
|
|
}
|
|
|
|
set_component(tos - h);
|
|
|
|
p3 = pop();
|
|
|
|
p4->u.sym.binding = p3;
|
2006-01-16 20:37:31 +01:00
|
|
|
p4->u.sym.binding2 = symbol(NIL);
|
|
|
|
push(symbol(NIL));
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_setq(void)
|
|
|
|
{
|
|
|
|
if (caadr(p1) == symbol(INDEX)) {
|
|
|
|
setq_indexed();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iscons(cadr(p1))) {
|
|
|
|
define_user_function();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-08-06 22:57:37 +02:00
|
|
|
if (!issymbol(cadr(p1)))
|
2004-03-03 21:24:06 +01:00
|
|
|
stop("symbol assignment: error in symbol");
|
|
|
|
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
p2 = pop();
|
|
|
|
cadr(p1)->u.sym.binding = p2;
|
2006-01-16 20:37:31 +01:00
|
|
|
cadr(p1)->u.sym.binding2 = symbol(NIL);
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2006-01-16 20:37:31 +01:00
|
|
|
push(symbol(NIL));
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_sqrt(void)
|
|
|
|
{
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
push_rational(1, 2);
|
|
|
|
power();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_stop(void)
|
|
|
|
{
|
|
|
|
stop("user stop");
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_subst(void)
|
|
|
|
{
|
|
|
|
push(cadddr(p1));
|
|
|
|
eval();
|
|
|
|
push(caddr(p1));
|
|
|
|
eval();
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
subst();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_tab(void)
|
|
|
|
{
|
|
|
|
push(car(p1));
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
list(2);
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
eval_unit(void)
|
|
|
|
{
|
|
|
|
int i, n;
|
|
|
|
push(cadr(p1));
|
|
|
|
eval();
|
|
|
|
n = pop_integer();
|
|
|
|
if (n < 2) {
|
|
|
|
push(p1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
p1 = alloc_tensor(n * n);
|
|
|
|
p1->u.tensor->ndim = 2;
|
|
|
|
p1->u.tensor->dim[0] = n;
|
|
|
|
p1->u.tensor->dim[1] = n;
|
|
|
|
for (i = 0; i < n; i++)
|
2004-06-25 22:45:15 +02:00
|
|
|
p1->u.tensor->elem[n * i + i] = one;
|
2004-03-03 21:24:06 +01:00
|
|
|
push(p1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
eval_noexpand(void)
|
|
|
|
{
|
|
|
|
int x = expanding;
|
|
|
|
expanding = 0;
|
|
|
|
eval();
|
|
|
|
expanding = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
eval_filter(void)
|
|
|
|
{
|
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
filter();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
filter(void)
|
|
|
|
{
|
|
|
|
save();
|
|
|
|
p2 = pop();
|
|
|
|
p1 = pop();
|
|
|
|
filter_f();
|
|
|
|
restore();
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
filter_f(void)
|
|
|
|
{
|
|
|
|
if (car(p1) == symbol(ADD))
|
|
|
|
filter_sum();
|
2005-08-06 22:57:37 +02:00
|
|
|
else if (istensor(p1))
|
2004-03-03 21:24:06 +01:00
|
|
|
filter_tensor();
|
|
|
|
else if (find(p1, p2))
|
|
|
|
push_integer(0);
|
|
|
|
else
|
|
|
|
push(p1);
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
filter_sum(void)
|
|
|
|
{
|
|
|
|
push_integer(0);
|
|
|
|
p1 = cdr(p1);
|
|
|
|
while (iscons(p1)) {
|
|
|
|
push(car(p1));
|
|
|
|
push(p2);
|
|
|
|
filter();
|
|
|
|
add();
|
|
|
|
p1 = cdr(p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-04 03:30:50 +01:00
|
|
|
void
|
2004-03-03 21:24:06 +01:00
|
|
|
filter_tensor(void)
|
|
|
|
{
|
|
|
|
int i, n;
|
|
|
|
n = p1->u.tensor->nelem;
|
|
|
|
p3 = alloc_tensor(n);
|
|
|
|
p3->u.tensor->ndim = p1->u.tensor->ndim;
|
|
|
|
for (i = 0; i < p1->u.tensor->ndim; i++)
|
|
|
|
p3->u.tensor->dim[i] = p1->u.tensor->dim[i];
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
push(p1->u.tensor->elem[i]);
|
|
|
|
push(p2);
|
|
|
|
filter();
|
|
|
|
p3->u.tensor->elem[i] = pop();
|
|
|
|
}
|
|
|
|
push(p3);
|
2004-05-06 20:07:45 +02:00
|
|
|
}
|
2005-08-21 03:19:56 +02:00
|
|
|
|
|
|
|
// like eval() except "=" is evaluated as "=="
|
|
|
|
|
|
|
|
void
|
|
|
|
eval_predicate(void)
|
|
|
|
{
|
|
|
|
save();
|
|
|
|
p1 = pop();
|
|
|
|
if (car(p1) == symbol(SETQ))
|
|
|
|
eval_testeq();
|
|
|
|
else {
|
|
|
|
push(p1);
|
|
|
|
eval();
|
|
|
|
}
|
|
|
|
restore();
|
2005-08-21 03:27:28 +02:00
|
|
|
}
|