2004-07-16 02:26:21 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
2004-08-16 21:05:38 -04:00
|
|
|
void signal_handler(int signal, siginfo_t* siginfo, void* uap)
|
|
|
|
{
|
|
|
|
general_error(ERROR_SIGNAL,tag_fixnum(signal));
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_signals(void)
|
|
|
|
{
|
|
|
|
struct sigaction custom_sigaction;
|
2004-08-20 21:16:47 -04:00
|
|
|
struct sigaction ign_sigaction;
|
2004-08-16 21:05:38 -04:00
|
|
|
custom_sigaction.sa_sigaction = signal_handler;
|
|
|
|
custom_sigaction.sa_flags = SA_SIGINFO;
|
2004-08-20 21:16:47 -04:00
|
|
|
ign_sigaction.sa_handler = SIG_IGN;
|
|
|
|
ign_sigaction.sa_flags = 0;
|
2004-08-16 21:05:38 -04:00
|
|
|
sigaction(SIGABRT,&custom_sigaction,NULL);
|
|
|
|
sigaction(SIGFPE,&custom_sigaction,NULL);
|
|
|
|
sigaction(SIGBUS,&custom_sigaction,NULL);
|
|
|
|
sigaction(SIGSEGV,&custom_sigaction,NULL);
|
2004-08-17 20:44:57 -04:00
|
|
|
sigaction(SIGPIPE,&custom_sigaction,NULL);
|
2004-08-16 21:05:38 -04:00
|
|
|
}
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
void clear_environment(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < USER_ENV; i++)
|
2004-08-20 18:48:08 -04:00
|
|
|
userenv[i] = 0;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
2004-07-27 23:29:37 -04:00
|
|
|
#define EXECUTE(w) ((XT)(w->xt))()
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
void run(void)
|
|
|
|
{
|
|
|
|
CELL next;
|
|
|
|
|
|
|
|
/* Error handling. */
|
2004-08-16 21:25:01 -04:00
|
|
|
sigsetjmp(toplevel, 1);
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
for(;;)
|
|
|
|
{
|
2004-08-20 18:48:08 -04:00
|
|
|
if(callframe == F)
|
2004-07-16 02:26:21 -04:00
|
|
|
{
|
2004-08-20 18:48:08 -04:00
|
|
|
callframe = cpop();
|
2004-07-16 02:26:21 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2004-08-20 18:48:08 -04:00
|
|
|
callframe = (CELL)untag_cons(callframe);
|
|
|
|
next = get(callframe);
|
|
|
|
callframe = get(callframe + CELLS);
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
if(TAG(next) == WORD_TYPE)
|
|
|
|
{
|
2004-08-20 18:48:08 -04:00
|
|
|
executing = (WORD*)UNTAG(next);
|
|
|
|
EXECUTE(executing);
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
else
|
2004-08-12 17:36:36 -04:00
|
|
|
dpush(next);
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XT of deferred words */
|
|
|
|
void undefined()
|
|
|
|
{
|
2004-08-20 18:48:08 -04:00
|
|
|
general_error(ERROR_UNDEFINED_WORD,tag_word(executing));
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* XT of compound definitions */
|
|
|
|
void call()
|
|
|
|
{
|
|
|
|
/* tail call optimization */
|
2004-08-20 18:48:08 -04:00
|
|
|
if(callframe != F)
|
|
|
|
cpush(callframe);
|
2004-07-16 02:26:21 -04:00
|
|
|
/* the parameter is the colon def */
|
2004-08-20 18:48:08 -04:00
|
|
|
callframe = executing->parameter;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void primitive_execute(void)
|
|
|
|
{
|
2004-08-12 17:36:36 -04:00
|
|
|
WORD* word = untag_word(dpop());
|
2004-08-20 18:48:08 -04:00
|
|
|
executing = word;
|
|
|
|
EXECUTE(executing);
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_call(void)
|
|
|
|
{
|
2004-08-12 17:36:36 -04:00
|
|
|
CELL calling = dpop();
|
2004-08-20 18:48:08 -04:00
|
|
|
if(callframe != F)
|
|
|
|
cpush(callframe);
|
|
|
|
callframe = calling;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_ifte(void)
|
|
|
|
{
|
2004-08-12 17:36:36 -04:00
|
|
|
CELL f = dpop();
|
2004-07-16 02:26:21 -04:00
|
|
|
CELL t = dpop();
|
|
|
|
CELL cond = dpop();
|
|
|
|
CELL calling = (untag_boolean(cond) ? t : f);
|
2004-08-20 18:48:08 -04:00
|
|
|
if(callframe != F)
|
|
|
|
cpush(callframe);
|
|
|
|
callframe = calling;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_getenv(void)
|
|
|
|
{
|
2004-08-12 17:36:36 -04:00
|
|
|
FIXNUM e = to_fixnum(dpeek());
|
2004-07-16 02:26:21 -04:00
|
|
|
if(e < 0 || e >= USER_ENV)
|
|
|
|
range_error(F,e,USER_ENV);
|
2004-08-20 18:48:08 -04:00
|
|
|
drepl(userenv[e]);
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_setenv(void)
|
|
|
|
{
|
2004-08-12 17:36:36 -04:00
|
|
|
FIXNUM e = to_fixnum(dpop());
|
2004-07-16 02:26:21 -04:00
|
|
|
CELL value = dpop();
|
|
|
|
if(e < 0 || e >= USER_ENV)
|
|
|
|
range_error(F,e,USER_ENV);
|
2004-08-20 18:48:08 -04:00
|
|
|
userenv[e] = value;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|