123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- // Evaluate an expression, for example...
- //
- // push(p1)
- // eval()
- // p2 = pop()
- #include "stdafx.h"
- #include "defs.h"
- void
- eval(void)
- {
- check_esc_flag();
- save();
- p1 = pop();
- switch (p1->k) {
- case CONS:
- eval_cons();
- break;
- case NUM:
- push(p1);
- break;
- case DOUBLE:
- push(p1);
- break;
- case STR:
- push(p1);
- break;
- case TENSOR:
- eval_tensor();
- break;
- case SYM:
- eval_sym();
- break;
- default:
- stop("atom?");
- break;
- }
- restore();
- }
- void
- eval_sym(void)
- {
- // bare keyword?
- if (iskeyword(p1)) {
- push(p1);
- push(symbol(LAST));
- list(2);
- eval();
- return;
- }
- // evaluate symbol's binding
- p2 = get_binding(p1);
- push(p2);
- if (p1 != p2)
- eval();
- }
- void
- eval_cons(void)
- {
- if (!issymbol(car(p1)))
- stop("cons?");
- switch (symnum(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 BINDING: eval_binding(); break;
- case BINOMIAL: eval_binomial(); break;
- case CEILING: eval_ceiling(); break;
- case CHECK: eval_check(); break;
- case CHOOSE: eval_choose(); break;
- case CIRCEXP: eval_circexp(); break;
- case CLEAR: eval_clear(); break;
- case CLOCK: eval_clock(); break;
- case COEFF: eval_coeff(); break;
- case COFACTOR: eval_cofactor(); break;
- case CONDENSE: eval_condense(); break;
- case CONJ: eval_conj(); break;
- case CONTRACT: eval_contract(); break;
- case COS: eval_cos(); break;
- case COSH: eval_cosh(); break;
- case DECOMP: eval_decomp(); break;
- case DEGREE: eval_degree(); break;
- case DEFINT: eval_defint(); 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 GAMMA: eval_gamma(); break;
- case GCD: eval_gcd(); 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 INVG: eval_invg(); break;
- case ISINTEGER: eval_isinteger(); break;
- case ISPRIME: eval_isprime(); break;
- case LAGUERRE: eval_laguerre(); break;
- // case LAPLACE: eval_laplace(); break;
- case LCM: eval_lcm(); break;
- case LEADING: eval_leading(); 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;
- case NROOTS: eval_nroots(); break;
- case NUMBER: eval_number(); break;
- case NUMERATOR: eval_numerator(); break;
- case OPERATOR: eval_operator(); break;
- case OR: eval_or(); break;
- case OUTER: eval_outer(); break;
- case POLAR: eval_polar(); break;
- case POWER: eval_power(); break;
- case PRIME: eval_prime(); break;
- case PRINT: eval_display(); break;
- case PRODUCT: eval_product(); break;
- case QUOTE: eval_quote(); break;
- case QUOTIENT: eval_quotient(); break;
- // case RANDOM: eval_random(); break; // by gbl08ma
- case RANK: eval_rank(); break;
- case RATIONALIZE: eval_rationalize(); break;
- case REAL: eval_real(); break;
- case YYRECT: eval_rect(); break;
- case ROOTS: eval_roots(); break;
- case SETQ: eval_setq(); break;
- case SGN: eval_sgn(); 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 TAN: eval_tan(); break;
- case TANH: eval_tanh(); break;
- case TAYLOR: eval_taylor(); 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 TRANSPOSE: eval_transpose(); break;
- case UNIT: eval_unit(); break;
- case ZERO: eval_zero(); break;
- default: eval_user_function(); break;
- }
- }
- void
- eval_binding(void)
- {
- push(get_binding(cadr(p1)));
- }
- // checks a predicate, i.e. check(A = B)
- void
- eval_check(void)
- {
- push(cadr(p1));
- eval_predicate();
- p1 = pop();
- if (iszero(p1))
- stop("check(arg): arg is zero");
- push(symbol(NIL)); // no result is printed
- }
- void
- eval_det(void)
- {
- push(cadr(p1));
- eval();
- det();
- }
- void
- 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;
- if (!istensor(p2))
- push_integer(1); // dim of scalar is 1
- else if (n < 1 || n > p2->u.tensor->ndim)
- push(p1);
- else
- push_integer(p2->u.tensor->dim[n - 1]);
- }
- void
- eval_divisors(void)
- {
- push(cadr(p1));
- eval();
- divisors();
- }
- void
- eval_do(void)
- {
- push(car(p1));
- p1 = cdr(p1);
- while (iscons(p1)) {
- pop();
- push(car(p1));
- eval();
- p1 = cdr(p1);
- }
- }
- void
- eval_dsolve(void)
- {
- push(cadr(p1));
- eval();
- push(caddr(p1));
- eval();
- push(cadddr(p1));
- eval();
- dsolve();
- }
- // for example, eval(f,x,2)
- void
- eval_eval(void)
- {
- push(cadr(p1));
- eval();
- p1 = cddr(p1);
- while (iscons(p1)) {
- push(car(p1));
- eval();
- push(cadr(p1));
- eval();
- subst();
- p1 = cddr(p1);
- }
- eval();
- }
- void
- eval_exp(void)
- {
- push(cadr(p1));
- eval();
- exponential();
- }
- void
- eval_factorial(void)
- {
- push(cadr(p1));
- eval();
- factorial();
- }
- void
- 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);
- }
- }
- void
- eval_hermite(void)
- {
- push(cadr(p1));
- eval();
- push(caddr(p1));
- eval();
- hermite();
- }
- void
- eval_hilbert(void)
- {
- push(cadr(p1));
- eval();
- hilbert();
- }
- void
- eval_index(void)
- {
- int h;
- h = tos;
- p1 = cdr(p1);
- while (iscons(p1)) {
- push(car(p1));
- eval();
- p1 = cdr(p1);
- }
- index_function(tos - h);
- }
- void
- eval_inv(void)
- {
- push(cadr(p1));
- eval();
- inv();
- }
- void
- eval_invg(void)
- {
- push(cadr(p1));
- eval();
- invg();
- }
- void
- eval_isinteger(void)
- {
- int n;
- push(cadr(p1));
- eval();
- p1 = pop();
- if (isrational(p1)) {
- if (isinteger(p1))
- push(one);
- else
- push(zero);
- return;
- }
- if (isdouble(p1)) {
- n = (int) p1->u.d;
- if (n == p1->u.d)
- push(one);
- else
- push(zero);
- return;
- }
- push_symbol(ISINTEGER);
- push(p1);
- list(2);
- }
- void
- eval_multiply(void)
- {
- push(cadr(p1));
- eval();
- p1 = cddr(p1);
- while (iscons(p1)) {
- push(car(p1));
- eval();
- multiply();
- p1 = cdr(p1);
- }
- }
- void
- eval_number(void)
- {
- push(cadr(p1));
- eval();
- p1 = pop();
- if (p1->k == NUM || p1->k == DOUBLE)
- push_integer(1);
- else
- push_integer(0);
- }
- void
- 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);
- }
- void
- eval_print(void)
- {
- p1 = cdr(p1);
- while (iscons(p1)) {
- push(car(p1));
- eval();
- if (equaln(get_binding(symbol(TTY)), 1))
- printline(pop());
- else
- display(pop());
- p1 = cdr(p1);
- }
- push(symbol(NIL));
- }
- void
- eval_quote(void)
- {
- push(cadr(p1));
- }
- void
- eval_rank(void)
- {
- push(cadr(p1));
- eval();
- p1 = pop();
- if (istensor(p1))
- push_integer(p1->u.tensor->ndim);
- else
- push(zero);
- }
- //-----------------------------------------------------------------------------
- //
- // Example: a[1] = b
- //
- // p1 *-------*-----------------------*
- // | | |
- // setq *-------*-------* b
- // | | |
- // index a 1
- //
- // cadadr(p1) -> a
- //
- //-----------------------------------------------------------------------------
- void
- setq_indexed(void)
- {
- int h;
- p4 = cadadr(p1);
- if (!issymbol(p4))
- 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();
- set_binding(p4, p3);
- push(symbol(NIL));
- }
- void
- eval_setq(void)
- {
- if (caadr(p1) == symbol(INDEX)) {
- setq_indexed();
- return;
- }
- if (iscons(cadr(p1))) {
- define_user_function();
- return;
- }
- if (!issymbol(cadr(p1)))
- stop("symbol assignment: error in symbol");
- push(caddr(p1));
- eval();
- p2 = pop();
- set_binding(cadr(p1), p2);
- push(symbol(NIL));
- }
- void
- eval_sqrt(void)
- {
- push(cadr(p1));
- eval();
- push_rational(1, 2);
- power();
- }
- void
- eval_stop(void)
- {
- stop("user stop");
- }
- void
- eval_subst(void)
- {
- push(cadddr(p1));
- eval();
- push(caddr(p1));
- eval();
- push(cadr(p1));
- eval();
- subst();
- eval(); // normalize
- }
- void
- 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++)
- p1->u.tensor->elem[n * i + i] = one;
- push(p1);
- }
- void
- eval_noexpand(void)
- {
- int x = expanding;
- expanding = 0;
- eval();
- expanding = x;
- }
- // 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();
- }
|