eigenmath/for.cpp

147 lines
1.9 KiB
C++

#include "stdafx.h"
//-----------------------------------------------------------------------------
//
// Input: tos-4 Index variable
//
// tos-3 Initial value
//
// tos-2 Final value
//
// tos-1 Statement
//
// Output: Result on stack
//
//-----------------------------------------------------------------------------
#include "defs.h"
#define A p1
#define J p2
#define K p3
#define B p4
static int level;
static jmp_buf break_jmp_buf;
void
for_function(void)
{
int i, j, k;
jmp_buf save_jmp_buf;
volatile int save_tos, mark;
U ** volatile save_frame;
memcpy(save_jmp_buf, break_jmp_buf, sizeof break_jmp_buf);
if (setjmp(break_jmp_buf)) {
memcpy(break_jmp_buf, save_jmp_buf, sizeof save_jmp_buf);
stack[save_tos] = pop();
tos = save_tos + 1;
frame = save_frame;
restore();
restore_symbols(mark);
level--;
return;
}
level++;
save();
B = pop();
K = pop();
J = pop();
A = pop();
save_tos = tos;
save_frame = frame;
if (A->k != SYM)
stop("variable expected in 1st arg of \"for\" function");
push(A);
mark = save_symbols(1);
push(J);
eval();
j = pop_integer();
if (j == (int) 0x80000000)
stop("integer value expected in 2nd arg of \"for\" function");
push(K);
eval();
k = pop_integer();
if (k == (int) 0x80000000)
stop("integer value expected in 3rd arg of \"for\" function");
for (i = j; i <= k; i++) {
push_integer(i);
A->u.sym.binding = pop();
A->u.sym.binding2 = nil;
push(B);
eval();
pop();
}
push(nil);
restore_symbols(mark);
restore();
level--;
}
void
break_function(void)
{
if (level == 0)
stop("break without for");
longjmp(break_jmp_buf, 1);
}
static char *s[] = {
"a=123",
"",
"b=for(a,1,10,c=a)",
"",
"a",
"123",
"b",
"nil",
"c",
"10",
"b=for(a,1,10,test(a==10,break(456)))",
"",
"a",
"123",
"b",
"456",
"a=quote(a)",
"",
"b=quote(b)",
"",
"c=quote(c)",
"",
};
void
test_for(void)
{
test(__FILE__, s, sizeof s / sizeof (char *));
}