home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mitsch75.zip
/
scheme-7_5_17-src.zip
/
scheme-7.5.17
/
src
/
microcode
/
prmcon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-02
|
4KB
|
158 lines
/* -*-C-*-
$Id: prmcon.c,v 1.3 1999/01/02 06:11:34 cph Exp $
Copyright (c) 1990-1999 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define SCM_PRMCON_C
#include "scheme.h"
#include "prims.h"
#include "prmcon.h"
void
DEFUN (suspend_primitive,
(continuation, reentry_record_length, reentry_record),
int continuation AND
int reentry_record_length AND
SCHEME_OBJECT *reentry_record)
{
int i;
long nargs;
SCHEME_OBJECT primitive;
if (continuation > CONT_MAX_INDEX)
{
signal_error_from_primitive (ERR_UNKNOWN_PRIMITIVE_CONTINUATION);
/* NOTREACHED */
}
primitive = (Regs[REGBLOCK_PRIMITIVE]);
if (!PRIMITIVE_P (primitive))
{
outf_fatal ("\nsuspend_primitive invoked when not in primitive!\n");
Microcode_Termination (TERM_BAD_BACK_OUT);
}
nargs = (PRIMITIVE_N_ARGUMENTS (primitive));
Will_Push (CONTINUATION_SIZE + 3 + reentry_record_length);
STACK_PUSH (primitive);
STACK_PUSH (STACK_FRAME_HEADER + nargs);
for (i = (reentry_record_length - 1);
i >= 0;
i -= 1)
{
STACK_PUSH (reentry_record[i]);
}
STACK_PUSH (LONG_TO_UNSIGNED_FIXNUM (reentry_record_length));
Store_Expression (LONG_TO_UNSIGNED_FIXNUM ((long) continuation));
Store_Return (RC_PRIMITIVE_CONTINUE);
Save_Cont ();
Pushed ();
return;
}
SCHEME_OBJECT
DEFUN_VOID (continue_primitive)
{
long nargs;
int continuation, record_length;
SCHEME_OBJECT primitive, *buffer, result;
continuation = ((int) (UNSIGNED_FIXNUM_TO_LONG (Fetch_Expression ())));
if (continuation > CONT_MAX_INDEX)
{
Store_Expression (LONG_TO_UNSIGNED_FIXNUM ((long) continuation));
Store_Return (RC_PRIMITIVE_CONTINUE);
Save_Cont ();
immediate_error (ERR_UNKNOWN_PRIMITIVE_CONTINUATION);
/* NOTREACHED */
}
record_length = ((int) (UNSIGNED_FIXNUM_TO_LONG (STACK_POP ())));
if (GC_Check (record_length))
{
Request_GC (record_length);
STACK_PUSH (LONG_TO_UNSIGNED_FIXNUM ((long) record_length));
Store_Expression (LONG_TO_UNSIGNED_FIXNUM ((long) continuation));
Store_Return (RC_PRIMITIVE_CONTINUE);
Save_Cont ();
immediate_interrupt ();
/* NOTREACHED */
}
buffer = Free;
while ((--record_length) >= 0)
{
*Free++ = (STACK_POP ());
}
nargs = ((OBJECT_DATUM (STACK_POP ())) -
(STACK_ENV_FIRST_ARG - 1));
primitive = (STACK_POP ());
/* Most of the testing here is paranioa in case we disk-save in the
middle of the suspension and then disk-restore into an incompatible
microcode.
It's not complete, but will catch some errors.
*/
if (!IMPLEMENTED_PRIMITIVE_P (primitive))
{
STACK_PUSH (primitive);
STACK_PUSH (LONG_TO_UNSIGNED_FIXNUM (nargs));
immediate_error (ERR_UNIMPLEMENTED_PRIMITIVE);
/* NOTREACHED */
}
if (nargs != (PRIMITIVE_ARITY (primitive)))
{
if ((PRIMITIVE_ARITY (primitive)) != LEXPR_PRIMITIVE_ARITY)
{
STACK_PUSH (primitive);
STACK_PUSH (LONG_TO_UNSIGNED_FIXNUM (nargs));
immediate_error (ERR_WRONG_NUMBER_OF_ARGUMENTS);
}
Regs[REGBLOCK_LEXPR_ACTUALS] = ((SCHEME_OBJECT) nargs);
}
Store_Expression (primitive);
Regs[REGBLOCK_PRIMITIVE] = primitive;
result = (*(continuation_procedures[continuation]))(buffer);
Regs[REGBLOCK_PRIMITIVE] = SHARP_F;
POP_PRIMITIVE_FRAME (nargs);
return (result);
}
void
DEFUN_VOID (immediate_interrupt)
{
Setup_Interrupt (PENDING_INTERRUPTS ());
abort_to_interpreter (PRIM_APPLY);
/* NOTREACHED */
}
void
DEFUN (immediate_error, (error_code), long error_code)
{
Do_Micro_Error (error_code, false);
abort_to_interpreter (PRIM_APPLY);
/* NOTREACHED */
}