eigenmath/run.cpp

204 lines
2.8 KiB
C++
Raw Permalink Normal View History

2004-03-03 21:24:06 +01:00
#include "stdafx.h"
#include "defs.h"
2004-08-28 00:09:03 +02:00
extern int test_flag;
2004-03-03 21:24:06 +01:00
jmp_buf stop_return;
static char *errstr;
void
2004-08-28 00:09:03 +02:00
stop(char *str)
2004-03-03 21:24:06 +01:00
{
2004-08-28 00:09:03 +02:00
errstr = str; // don't print str now, jmp_buf might be redirected
2004-03-03 21:24:06 +01:00
longjmp(stop_return, 1);
}
void
run(char *s)
{
2004-08-31 02:56:15 +02:00
int n;
2004-03-03 21:24:06 +01:00
2004-08-28 00:38:58 +02:00
esc_flag = 0;
2006-10-11 19:37:38 +02:00
draw_flag = 0;
2004-08-28 00:38:58 +02:00
2004-03-03 21:24:06 +01:00
if (setjmp(stop_return)) {
if (errstr) {
2004-09-01 16:55:03 +02:00
printstr("Stop: ");
2004-03-03 21:24:06 +01:00
printstr(errstr);
printstr("\n");
}
return;
}
2004-08-28 00:09:03 +02:00
init();
2004-03-03 21:24:06 +01:00
tos = 0;
frame = stack + TOS;
2004-08-28 00:09:03 +02:00
if (dash_dash_command(s))
return;
2004-03-03 21:24:06 +01:00
while (1) {
n = scan(s);
if (n == 0)
break;
s += n;
setup();
p1 = pop();
2004-08-28 00:09:03 +02:00
check_stack();
2007-05-02 07:18:20 +02:00
push(p1);
2006-09-20 18:46:38 +02:00
top_level_eval();
2004-08-28 00:09:03 +02:00
2004-03-03 21:24:06 +01:00
p2 = pop();
2004-08-28 00:09:03 +02:00
check_stack();
2004-03-03 21:24:06 +01:00
2007-05-02 21:54:17 +02:00
if (p2 == symbol(NIL))
continue;
2004-03-03 21:24:06 +01:00
// print string w/o quotes
2005-08-06 22:57:37 +02:00
if (isstr(p2)) {
2004-03-03 21:24:06 +01:00
printstr(p2->u.str);
printstr("\n");
continue;
}
2004-08-31 02:56:15 +02:00
if (equal(symbol(TTY)->u.sym.binding, one) || test_flag) // tty mode?
2004-03-03 21:24:06 +01:00
printline(p2);
else {
2004-06-12 01:27:33 +02:00
#ifdef LINUX
display(p2);
#else
2004-03-03 21:24:06 +01:00
cmdisplay(p2);
2004-06-12 01:27:33 +02:00
#endif
2004-03-03 21:24:06 +01:00
}
}
}
2005-12-16 02:09:51 +01:00
int
2004-08-28 00:09:03 +02:00
dash_dash_command(char *s)
{
if (strncmp(s, "--mem", 5) == 0) {
print_mem_info();
return 1;
}
if (strncmp(s, "--gc", 4) == 0) {
gc();
2005-06-25 21:29:07 +02:00
printstr("OK\n");
2004-08-28 00:09:03 +02:00
return 1;
}
2007-05-08 16:57:30 +02:00
#if SELFTEST
2004-08-28 00:09:03 +02:00
if (strncmp(s, "--test", 6) == 0) {
selftest();
return 1;
}
2007-05-08 16:57:30 +02:00
#endif
2004-08-28 00:09:03 +02:00
return 0;
}
2005-12-16 02:09:51 +01:00
void
2004-08-28 00:09:03 +02:00
check_stack(void)
2004-03-03 21:24:06 +01:00
{
if (tos != 0)
2004-08-28 00:09:03 +02:00
stop("stack error");
2004-03-03 21:24:06 +01:00
if (frame != stack + TOS)
2004-08-28 00:09:03 +02:00
stop("frame error");
2004-03-03 21:24:06 +01:00
}
2006-07-13 02:09:33 +02:00
// cannot reference symbols yet
void
echo_input(char *s)
{
printstr(s);
printstr("\n");
}
2006-09-20 18:46:38 +02:00
2007-05-02 21:54:17 +02:00
// returns nil on stack if no result to print
2006-09-20 18:46:38 +02:00
void
top_level_eval(void)
{
2007-05-02 07:18:20 +02:00
save();
2006-09-20 18:46:38 +02:00
2007-05-02 07:18:20 +02:00
p1 = pop();
2007-05-02 06:13:54 +02:00
push(p1);
eval();
2007-05-02 07:18:20 +02:00
p2 = pop();
2007-05-05 06:55:43 +02:00
// "draw", "for" and "setq" return "nil", there is no result to print
2007-05-02 21:54:17 +02:00
2007-05-05 06:55:43 +02:00
if (p2 == symbol(NIL)) {
2007-05-02 21:54:17 +02:00
push(p2);
restore();
return;
}
2006-09-20 18:46:38 +02:00
2007-05-05 06:55:43 +02:00
// update "last"
2007-05-02 21:54:17 +02:00
symbol(LAST)->u.sym.binding = p2;
symbol(LAST)->u.sym.arglist = symbol(NIL);
2006-09-20 18:46:38 +02:00
2007-05-02 21:54:17 +02:00
if (!iszero(symbol(BAKE)->u.sym.binding)) {
push(p2);
bake();
p2 = pop();
2006-09-20 18:46:38 +02:00
}
2007-05-02 07:18:20 +02:00
2007-05-02 21:54:17 +02:00
// If we evaluated the symbol "i" or "j" and the result was sqrt(-1)
// then don't do anything.
// Otherwise if "j" is an imaginary unit then subst.
// Otherwise if "i" is an imaginary unit then subst.
if ((p1 == symbol(SYMBOL_I) || p1 == symbol(SYMBOL_J))
&& isimaginaryunit(p2))
;
else if (isimaginaryunit(symbol(SYMBOL_J)->u.sym.binding)) {
push(p2);
push(imaginaryunit);
push_symbol(SYMBOL_J);
subst();
p2 = pop();
} else if (isimaginaryunit(symbol(SYMBOL_I)->u.sym.binding)) {
push(p2);
push(imaginaryunit);
push_symbol(SYMBOL_I);
subst();
p2 = pop();
}
#ifndef LINUX
// if we evaluated the symbol "a" and got "b" then print "a=b"
// do not print "a=a"
2007-05-08 20:58:41 +02:00
if (issymbol(p1) && !iskeyword(p1) && p1 != p2 && test_flag == 0) {
2007-05-02 21:54:17 +02:00
push_symbol(SETQ);
push(p1);
push(p2);
list(3);
p2 = pop();
}
#endif
push(p2);
2007-05-02 07:18:20 +02:00
restore();
2006-09-20 18:46:38 +02:00
}
2006-10-09 21:13:45 +02:00
void
check_esc_flag(void)
{
if (esc_flag)
stop("esc key");
}