2004-03-03 21:24:06 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "defs.h"
|
|
|
|
U *varlist;
|
|
|
|
int symbol_level;
|
|
|
|
|
|
|
|
void
|
|
|
|
new_string(char *s)
|
|
|
|
{
|
|
|
|
save();
|
|
|
|
p1 = alloc();
|
|
|
|
p1->k = STR;
|
|
|
|
p1->u.str = strdup(s);
|
|
|
|
push(p1);
|
|
|
|
restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
out_of_memory(void)
|
|
|
|
{
|
|
|
|
stop("out of memory");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
push_zero_matrix(int i, int j)
|
|
|
|
{
|
|
|
|
push(alloc_tensor(i * j));
|
|
|
|
stack[tos - 1]->u.tensor->ndim = 2;
|
|
|
|
stack[tos - 1]->u.tensor->dim[0] = i;
|
|
|
|
stack[tos - 1]->u.tensor->dim[1] = j;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
push_identity_matrix(int n)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
push_zero_matrix(n, n);
|
|
|
|
for (i = 0; i < n; i++)
|
2004-06-25 22:45:15 +02:00
|
|
|
stack[tos - 1]->u.tensor->elem[i * n + i] = one;
|
2004-03-03 21:24:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
push_cars(U *p)
|
|
|
|
{
|
|
|
|
while (iscons(p)) {
|
|
|
|
push(car(p));
|
|
|
|
p = cdr(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
peek(void)
|
|
|
|
{
|
|
|
|
save();
|
|
|
|
p1 = pop();
|
|
|
|
push(p1);
|
|
|
|
printline(p1);
|
|
|
|
restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
peek2(void)
|
|
|
|
{
|
|
|
|
print_lisp(stack[tos - 2]);
|
|
|
|
print_lisp(stack[tos - 1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
equal(U *p1, U *p2)
|
|
|
|
{
|
|
|
|
if (cmp_expr(p1, p2) == 0)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
lessp(U *p1, U *p2)
|
|
|
|
{
|
|
|
|
if (cmp_expr(p1, p2) < 0)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sign(int n)
|
|
|
|
{
|
|
|
|
if (n < 0)
|
|
|
|
return -1;
|
|
|
|
else if (n > 0)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
cmp_expr(U *p1, U *p2)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
|
|
|
|
if (p1 == p2)
|
|
|
|
return 0;
|
|
|
|
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p1 == symbol(NIL))
|
2004-03-03 21:24:06 +01:00
|
|
|
return -1;
|
|
|
|
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p2 == symbol(NIL))
|
2004-03-03 21:24:06 +01:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (isnum(p1) && isnum(p2))
|
|
|
|
return sign(compare_numbers(p1, p2));
|
|
|
|
|
|
|
|
if (isnum(p1))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (isnum(p2))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (isstr(p1) && isstr(p2))
|
|
|
|
return sign(strcmp(p1->u.str, p2->u.str));
|
|
|
|
|
|
|
|
if (isstr(p1))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (isstr(p2))
|
|
|
|
return 1;
|
|
|
|
|
2005-08-06 22:57:37 +02:00
|
|
|
if (issymbol(p1) && issymbol(p2))
|
2004-04-04 10:21:10 +02:00
|
|
|
return sign(strcmp(get_printname(p1), get_printname(p2)));
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-06 22:57:37 +02:00
|
|
|
if (issymbol(p1))
|
2004-03-03 21:24:06 +01:00
|
|
|
return -1;
|
|
|
|
|
2005-08-06 22:57:37 +02:00
|
|
|
if (issymbol(p2))
|
2004-03-03 21:24:06 +01:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (istensor(p1) && istensor(p2))
|
|
|
|
return compare_tensors(p1, p2);
|
|
|
|
|
|
|
|
if (istensor(p1))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (istensor(p2))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
while (iscons(p1) && iscons(p2)) {
|
|
|
|
n = cmp_expr(car(p1), car(p2));
|
|
|
|
if (n != 0)
|
|
|
|
return n;
|
|
|
|
p1 = cdr(p1);
|
|
|
|
p2 = cdr(p2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iscons(p2))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (iscons(p1))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
length(U *p)
|
|
|
|
{
|
|
|
|
int n = 0;
|
|
|
|
while (iscons(p)) {
|
|
|
|
p = cdr(p);
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void unique_f(U *);
|
|
|
|
|
|
|
|
U *
|
|
|
|
unique(U *p)
|
|
|
|
{
|
|
|
|
save();
|
2006-01-16 20:37:31 +01:00
|
|
|
p1 = symbol(NIL);
|
|
|
|
p2 = symbol(NIL);
|
2004-03-03 21:24:06 +01:00
|
|
|
unique_f(p);
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p2 != symbol(NIL))
|
|
|
|
p1 = symbol(NIL);
|
2004-03-03 21:24:06 +01:00
|
|
|
p = p1;
|
|
|
|
restore();
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
unique_f(U *p)
|
|
|
|
{
|
2005-08-06 22:57:37 +02:00
|
|
|
if (isstr(p)) {
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p1 == symbol(NIL))
|
2004-03-03 21:24:06 +01:00
|
|
|
p1 = p;
|
|
|
|
else if (p != p1)
|
|
|
|
p2 = p;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (iscons(p)) {
|
|
|
|
unique_f(car(p));
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p2 != symbol(NIL))
|
2004-03-03 21:24:06 +01:00
|
|
|
return;
|
|
|
|
p = cdr(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
void
|
|
|
|
check_endianess(void)
|
|
|
|
{
|
|
|
|
int tmp = 1;
|
|
|
|
if (((char *) &tmp)[0] == 1 && Y_LITTLE_ENDIAN == 0) {
|
|
|
|
printf("Please change Y_LITTLE_ENDIAN to 1 in defs.h and recompile.\n");
|
|
|
|
Exit(1);
|
|
|
|
}
|
|
|
|
if (((char *) &tmp)[0] == 0 && Y_LITTLE_ENDIAN != 0) {
|
|
|
|
printf("Please change Y_LITTLE_ENDIAN to 0 in defs.h and recompile.\n");
|
|
|
|
Exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
ssqrt(void)
|
|
|
|
{
|
|
|
|
push_rational(1, 2);
|
|
|
|
power();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
conjugate(void)
|
|
|
|
{
|
|
|
|
int tmp;
|
|
|
|
tmp = conjugating;
|
|
|
|
conjugating = 1;
|
|
|
|
eval();
|
|
|
|
conjugating = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
expand(void)
|
|
|
|
{
|
|
|
|
int x;
|
|
|
|
x = expanding;
|
|
|
|
expanding = 1;
|
|
|
|
eval();
|
|
|
|
expanding = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
exponential(void)
|
|
|
|
{
|
|
|
|
push_symbol(E);
|
|
|
|
swap();
|
|
|
|
power();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
square(void)
|
|
|
|
{
|
|
|
|
push_integer(2);
|
|
|
|
power();
|
|
|
|
}
|
|
|
|
|
|
|
|
// save and restore symbols for formal arg lists, prog vars, etc.
|
|
|
|
|
|
|
|
int
|
|
|
|
save_symbols(int n)
|
|
|
|
{
|
|
|
|
int h, i;
|
|
|
|
|
|
|
|
save();
|
|
|
|
|
|
|
|
h = tos - n;
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
p1 = stack[h + i];
|
2005-08-06 22:57:37 +02:00
|
|
|
if (!issymbol(p1))
|
2004-03-03 21:24:06 +01:00
|
|
|
continue;
|
|
|
|
push(p1);
|
|
|
|
push(p1->u.sym.binding);
|
|
|
|
push(p1->u.sym.binding2);
|
|
|
|
}
|
|
|
|
|
|
|
|
list(tos - h - n);
|
|
|
|
|
|
|
|
push(varlist);
|
|
|
|
|
|
|
|
cons();
|
|
|
|
|
|
|
|
varlist = pop();
|
|
|
|
|
|
|
|
tos = h;
|
|
|
|
|
|
|
|
restore();
|
|
|
|
|
|
|
|
symbol_level++;
|
|
|
|
|
|
|
|
return symbol_level - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
restore_symbols_f(void)
|
|
|
|
{
|
|
|
|
save();
|
|
|
|
|
|
|
|
p1 = varlist;
|
|
|
|
|
|
|
|
varlist = cdr(p1);
|
|
|
|
|
|
|
|
p1 = car(p1);
|
|
|
|
|
|
|
|
while (iscons(p1)) {
|
|
|
|
p2 = car(p1);
|
|
|
|
p2->u.sym.binding = cadr(p1);
|
|
|
|
p2->u.sym.binding2 = caddr(p1);
|
|
|
|
p1 = cdddr(p1);
|
|
|
|
}
|
|
|
|
|
|
|
|
restore();
|
|
|
|
|
|
|
|
symbol_level--;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
restore_symbols(int mark)
|
|
|
|
{
|
|
|
|
while (symbol_level > mark)
|
|
|
|
restore_symbols_f();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
__cmp(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
return cmp_expr(*((U **) p1), *((U **) p2));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sort_stack(int n)
|
|
|
|
{
|
|
|
|
qsort(stack + tos - n, n, sizeof (U *), __cmp);
|
|
|
|
}
|