home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
languages
/
siod_v2
/
c
/
slib
< prev
Wrap
Text File
|
1992-06-23
|
39KB
|
1,622 lines
/* Scheme In One Defun, but in C this time.
* COPYRIGHT (c) 1989 BY *
* PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. *
* ALL RIGHTS RESERVED *
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all copies
and that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of Paradigm Associates
Inc not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
PARADIGM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
PARADIGM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
*/
/*
gjc@paradigm.com
Paradigm Associates Inc Phone: 617-492-6079
29 Putnam Ave, Suite 6
Cambridge, MA 02138
Release 1.0: 24-APR-88
Release 1.1: 25-APR-88, added: macros, predicates, load. With additions by
Barak.Pearlmutter@DOGHEN.BOLTZ.CS.CMU.EDU: Full flonum recognizer,
cleaned up uses of NULL/0. Now distributed with siod.scm.
Release 1.2: 28-APR-88, name changes as requested by JAR@AI.AI.MIT.EDU,
plus some bug fixes.
Release 1.3: 1-MAY-88, changed env to use frames instead of alist.
define now works properly. vms specific function edit.
Release 1.4 20-NOV-89. Minor Cleanup and remodularization.
Now in 3 files, siod.h, slib.c, siod.c. Makes it easier to write your
own main loops. Some short-int changes for lightspeed C included.
Release 1.5 29-NOV-89. Added startup flag -g, select stop and copy
or mark-and-sweep garbage collection, which assumes that the stack/register
marking code is correct for your architecture.
Release 2.0 1-DEC-89. Added repl_hooks, Catch, Throw. This is significantly
different enough (from 1.3) now that I'm calling it a major release.
Release 2.1 4-DEC-89. Small reader features, dot, backquote, comma.
Release 2.2 5-DEC-89. gc,read,print,eval, hooks for user defined datatypes.
Release 2.3 6-DEC-89. save_forms, obarray intern mechanism. comment char.
Release 2.3a......... minor speed-ups. i/o interrupt considerations.
Release 2.4 27-APR-90 gen_readr, for read-from-string.
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <setjmp.h>
#include <signal.h>
#include <math.h>
#ifdef vms
#include <stdlib.h>
#endif
#ifdef ARM
#include <stdlib.h>
#endif
#include "siod.h"
LISP heap_1,heap_2;
LISP heap,heap_end,heap_org;
long heap_size = 5000;
long old_heap_used;
long which_heap;
long gc_status_flag = 1;
char *init_file = (char *) NULL;
char tkbuffer[TKBUFFERN];
long gc_kind_copying = 1;
long gc_cells_allocated = 0;
double gc_time_taken;
LISP *stack_start_ptr;
LISP freelist;
jmp_buf errjmp;
long errjmp_ok = 0;
long nointerrupt = 1;
long interrupt_differed = 0;
LISP oblistvar = NIL;
LISP truth = NIL;
LISP eof_val = NIL;
LISP sym_errobj = NIL;
LISP sym_progn = NIL;
LISP sym_lambda = NIL;
LISP sym_quote = NIL;
LISP sym_dot = NIL;
LISP open_files = NIL;
LISP unbound_marker = NIL;
LISP *obarray;
long obarray_dim = 100;
struct catch_frame
{LISP tag;
LISP retval;
jmp_buf cframe;
struct catch_frame *next;};
struct gc_protected
{LISP *location;
long length;
struct gc_protected *next;};
struct catch_frame *catch_framep = (struct catch_frame *) NULL;
process_cla(argc,argv,warnflag)
int argc,warnflag; char **argv;
{int k;
for(k=1;k<argc;++k)
{if (strlen(argv[k])<2) continue;
if (argv[k][0] != '-')
{if (warnflag) printf("bad arg: %s\n",argv[k]);continue;}
switch(argv[k][1])
{case 'h':
heap_size = atol(&(argv[k][2])); break;
case 'o':
obarray_dim = atol(&(argv[k][2])); break;
case 'i':
init_file = &(argv[k][2]); break;
case 'g':
gc_kind_copying = atol(&(argv[k][2])); break;
default: if (warnflag) printf("bad arg: %s\n",argv[k]);}}}
print_welcome()
{printf("Welcome to SIOD, Scheme In One Defun, Version 2.4\n");
printf("(C) Copyright 1988, 1989, 1990 Paradigm Associates Inc.\n");}
print_hs_1()
{printf("heap_size = %ld cells, %ld bytes. GC is %s\n",
heap_size,heap_size*sizeof(struct obj),
(gc_kind_copying == 1) ? "stop and copy" : "mark and sweep");}
print_hs_2()
{if (gc_kind_copying == 1)
printf("heap_1 at 0x%lX, heap_2 at 0x%lX\n",heap_1,heap_2);
else
printf("heap_1 at 0x%lX\n",heap_1);}
long no_interrupt(n)
long n;
{long x;
x = nointerrupt;
nointerrupt = n;
if ((nointerrupt == 0) && (interrupt_differed == 1))
{interrupt_differed = 0;
err_ctrl_c();}
return(x);}
void handle_sigfpe(sig,code,scp)
long sig,code; struct sigcontext *scp;
{signal(SIGFPE,handle_sigfpe);
err("floating point exception",NIL);}
void handle_sigint(sig,code,scp)
long sig,code; struct sigcontext *scp;
{signal(SIGINT,handle_sigint);
if (nointerrupt == 1)
interrupt_differed = 1;
else
err_ctrl_c();}
err_ctrl_c()
{err("control-c interrupt",NIL);}
LISP get_eof_val()
{return(eof_val);}
repl_driver(want_sigint,want_init)
long want_sigint,want_init;
{int k;
LISP stack_start;
stack_start_ptr = &stack_start;
k = setjmp(errjmp);
if (k == 2) return;
if (want_sigint) signal(SIGFPE,handle_sigfpe);
signal(SIGINT,handle_sigint);
close_open_files();
catch_framep = (struct catch_frame *) NULL;
errjmp_ok = 1;
interrupt_differed = 0;
nointerrupt = 0;
if (want_init && init_file && (k == 0)) vload(init_file,0);
repl();}
#ifdef unix
#include <sys/types.h>
#include <sys/times.h>
struct tms time_buffer;
double myruntime()
{times(&time_buffer);
return(time_buffer.tms_utime/60.0);}
#else
#ifdef vms
#include <time.h>
double myruntime()
{return(clock() * 1.0e-2);}
#else
#ifdef ARM
/* this is still wrong */
#include <time.h>
double myruntime()
{clock_t x;
x = clock();
return(((double) x)/((double) CLOCKS_PER_SEC));}
#else
double myruntime()
{long x;
long time();
time(&x);
return((double) x);}
#endif
#endif
#endif
void (*repl_puts)() = NULL;
LISP (*repl_read)() = NULL;
LISP (*repl_eval)() = NULL;
void (*repl_print)() = NULL;
void set_repl_hooks(puts_f,read_f,eval_f,print_f)
void (*puts_f)();
LISP (*read_f)();
LISP (*eval_f)();
void (*print_f)();
{repl_puts = puts_f;
repl_read = read_f;
repl_eval = eval_f;
repl_print = print_f;}
fput_st(f,st)
FILE *f;
char *st;
{long flag;
flag = no_interrupt(1);
fprintf(f,"%s",st);
no_interrupt(flag);}
put_st(st)
char *st;
{fput_st(stdout,st);}
grepl_puts(st)
char *st;
{if (repl_puts == NULL)
put_st(st);
else
(*repl_puts)(st);}
repl()
{LISP x,cw;
double rt;
while(1)
{if ((gc_kind_copying == 1) && ((gc_status_flag) || heap >= heap_end))
{rt = myruntime();
gc_stop_and_copy();
sprintf(tkbuffer,
"GC took %g seconds, %ld compressed to %ld, %ld free\n",
myruntime()-rt,old_heap_used,heap-heap_org,heap_end-heap);
grepl_puts(tkbuffer);}
grepl_puts("> ");
if (repl_read == NULL) x = lread();
else x = (*repl_read)();
if EQ(x,eof_val) break;
rt = myruntime();
if (gc_kind_copying == 1)
cw = heap;
else
{gc_cells_allocated = 0;
gc_time_taken = 0.0;}
if (repl_eval == NULL) x = leval(x,NIL);
else x = (*repl_eval)();
if (gc_kind_copying == 1)
sprintf(tkbuffer,
"Evaluation took %g seconds %ld cons work\n",
myruntime()-rt,
heap-cw);
else
sprintf(tkbuffer,
"Evaluation took %g seconds (%g in gc) %ld cons work\n",
myruntime()-rt,
gc_time_taken,
gc_cells_allocated);
grepl_puts(tkbuffer);
if (repl_print == NULL) lprint(x);
else (*repl_print)(x);}}
err(message,x)
char *message; LISP x;
{nointerrupt = 1;
if NNULLP(x)
print