Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (04/15/90)
Submitted-by: rusty@fe2o3.UUCP (Rusty Haddock) Posting-number: Volume 90, Issue 141 Archive-name: applications/xscheme-0.20/part03 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 7)." # Contents: Src/xscheme.h Src/xsdmem.c Src/xsftab.c Src/xsmath.c # Wrapped by tadguy@xanth on Sat Apr 14 17:07:24 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Src/xscheme.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Src/xscheme.h'\" else echo shar: Extracting \"'Src/xscheme.h'\" \(13100 characters\) sed "s/^X//" >'Src/xscheme.h' <<'END_OF_FILE' X/* xscheme.h - xscheme definitions */ X/* Copyright (c) 1988, by David Michael Betz X All Rights Reserved X Permission is granted for unrestricted non-commercial use */ X X/* system specific definitions */ X#define AZTEC_AMIGA X X#include <stdio.h> X#include <ctype.h> X#include <setjmp.h> X X/* FORWARD type of a forward declaration () */ X/* LOCAL type of a local function (static) */ X/* AFMT printf format for addresses ("%x") */ X/* OFFTYPE number the size of an address (int) */ X/* FIXTYPE data type for fixed point numbers (long) */ X/* ITYPE fixed point input conversion routine type (long atol()) */ X/* ICNV fixed point input conversion routine (atol) */ X/* IFMT printf format for fixed point numbers ("%ld") */ X/* FLOTYPE data type for floating point numbers (float) */ X/* FFMT printf format for floating point numbers (%.15g) */ X X/* for the Lightspeed C compiler - Macintosh */ X#ifdef LSC X#define AFMT "%lx" X#define OFFTYPE long X#define NIL (void *)0 X#define MACINTOSH X#endif X X/* for the UNIX System V C compiler */ X#ifdef UNIX X#endif X X/* for the Aztec C compiler - Amiga */ X#ifdef AZTEC_AMIGA X#define AFMT "%lx" X#define OFFTYPE long X#define FLOTYPE double X#endif X X/* for the Mark Williams C compiler - Atari ST */ X#ifdef MWC X#define AFMT "%lx" X#define OFFTYPE long X#endif X X/* for the Microsoft C 5.0 compiler */ X#ifdef MSC X#define AFMT "%lx" X#define OFFTYPE long X#define INSEGMENT(n,s) (((OFFTYPE)(n) >> 16) == ((OFFTYPE)(s) >> 16)) X#define VCOMPARE(f,s,t) ((LVAL huge *)(f) + (s) < (LVAL huge *)(t)) X/* #define MSDOS -- MSC 5.0 defines this automatically */ X#endif X X/* for the Turbo C compiler */ X#ifdef _TURBOC_ X#define AFMT "%lx" X#define OFFTYPE long X#define INSEGMENT(n,s) (((OFFTYPE)(n) >> 16) == ((OFFTYPE)(s) >> 16)) X#define VCOMPARE(f,s,t) ((LVAL huge *)(f) + (s) < (LVAL huge *)(t)) X#define MSDOS X#endif X X/* size of each type of memory segment */ X#ifndef NSSIZE X#define NSSIZE 4000 /* number of nodes per node segment */ X#endif X#ifndef VSSIZE X#define VSSIZE 10000 /* number of LVAL's per vector segment */ X#endif X X/* default important definitions */ X#ifndef FORWARD X#define FORWARD X#endif X#ifndef LOCAL X#define LOCAL static X#endif X#ifndef AFMT X#define AFMT "%x" X#endif X#ifndef OFFTYPE X#define OFFTYPE int X#endif X#ifndef FIXTYPE X#define FIXTYPE long X#endif X#ifndef ITYPE X#define ITYPE long atol() X#endif X#ifndef ICNV X#define ICNV(n) atol(n) X#endif X#ifndef IFMT X#define IFMT "%ld" X#endif X#ifndef FLOTYPE X#define FLOTYPE double X#endif X#ifndef FFMT X#define FFMT "%.15g" X#endif X#ifndef SFIXMIN X#define SFIXMIN -1048576 X#define SFIXMAX 1048575 X#endif X#ifndef INSEGMENT X#define INSEGMENT(n,s) ((n) >= &(s)->ns_data[0] \ X && (n) < &(s)->ns_data[0] + (s)->ns_size) X#endif X#ifndef VCOMPARE X#define VCOMPARE(f,s,t) ((f) + (s) < (t)) X#endif X X/* useful definitions */ X#define TRUE 1 X#define FALSE 0 X#ifndef NIL X#define NIL (LVAL)0 X#endif X X/* program limits */ X#define STRMAX 100 /* maximum length of a string constant */ X#define HSIZE 199 /* symbol hash table size */ X#define SAMPLE 100 /* control character sample rate */ X X/* stack manipulation macros */ X#define check(n) { if (xlsp - (n) < xlstkbase) xlstkover(); } X#define cpush(v) { if (xlsp > xlstkbase) push(v); else xlstkover(); } X#define push(v) (*--xlsp = (v)) X#define pop() (*xlsp++) X#define top() (*xlsp) X#define settop(v) (*xlsp = (v)) X#define drop(n) (xlsp += (n)) X X/* argument list parsing macros */ X#define xlgetarg() (testarg(nextarg())) X#define xllastarg() {if (xlargc != 0) xltoomany();} X#define xlpoprest() {xlsp += xlargc;} X#define testarg(e) (moreargs() ? (e) : xltoofew()) X#define typearg(tp) (tp(*xlsp) ? nextarg() : xlbadtype(*xlsp)) X#define nextarg() (--xlargc, *xlsp++) X#define moreargs() (xlargc > 0) X X/* macros to get arguments of a particular type */ X#define xlgacons() (testarg(typearg(consp))) X#define xlgalist() (testarg(typearg(listp))) X#define xlgasymbol() (testarg(typearg(symbolp))) X#define xlgastring() (testarg(typearg(stringp))) X#define xlgaobject() (testarg(typearg(objectp))) X#define xlgafixnum() (testarg(typearg(fixp))) X#define xlganumber() (testarg(typearg(numberp))) X#define xlgachar() (testarg(typearg(charp))) X#define xlgavector() (testarg(typearg(vectorp))) X#define xlgaport() (testarg(typearg(portp))) X#define xlgaiport() (testarg(typearg(iportp))) X#define xlgaoport() (testarg(typearg(oportp))) X#define xlgaclosure() (testarg(typearg(closurep))) X#define xlgaenv() (testarg(typearg(envp))) X X/* node types */ X#define FREE 0 X#define CONS 1 X#define SYMBOL 2 X#define FIXNUM 3 X#define FLONUM 4 X#define STRING 5 X#define OBJECT 6 X#define PORT 7 X#define VECTOR 8 X#define CLOSURE 9 X#define METHOD 10 X#define CODE 11 X#define SUBR 12 X#define XSUBR 13 X#define CSUBR 14 X#define CONTINUATION 15 X#define CHAR 16 X#define PROMISE 17 X#define ENV 18 X X/* node flags */ X#define MARK 1 X#define LEFT 2 X X/* port flags */ X#define PF_INPUT 1 X#define PF_OUTPUT 2 X#define PF_BINARY 4 X X/* new node access macros */ X#define ntype(x) ((OFFTYPE)(x) & 1 ? FIXNUM : (x)->n_type) X X/* macro to determine if a non-nil value is a pointer */ X#define ispointer(x) (((OFFTYPE)(x) & 1) == 0) X X/* type predicates */ X#define atom(x) ((x) == NIL || ntype(x) != CONS) X#define null(x) ((x) == NIL) X#define listp(x) ((x) == NIL || ntype(x) == CONS) X#define numberp(x) ((x) && ntype(x) == FIXNUM || ntype(x) == FLONUM) X#define boundp(x) (getvalue(x) != s_unbound) X#define iportp(x) (portp(x) && (getpflags(x) & PF_INPUT) != 0) X#define oportp(x) (portp(x) && (getpflags(x) & PF_OUTPUT) != 0) X X/* basic type predicates */ X#define consp(x) ((x) && ntype(x) == CONS) X#define stringp(x) ((x) && ntype(x) == STRING) X#define symbolp(x) ((x) && ntype(x) == SYMBOL) X#define portp(x) ((x) && ntype(x) == PORT) X#define objectp(x) ((x) && ntype(x) == OBJECT) X#define fixp(x) ((x) && ntype(x) == FIXNUM) X#define floatp(x) ((x) && ntype(x) == FLONUM) X#define vectorp(x) ((x) && ntype(x) == VECTOR) X#define closurep(x) ((x) && ntype(x) == CLOSURE) X#define codep(x) ((x) && ntype(x) == CODE) X#define methodp(x) ((x) && ntype(x) == METHOD) X#define subrp(x) ((x) && ntype(x) == SUBR) X#define xsubrp(x) ((x) && ntype(x) == XSUBR) X#define charp(x) ((x) && ntype(x) == CHAR) X#define promisep(x) ((x) && ntype(x) == PROMISE) X#define envp(x) ((x) && ntype(x) == ENV) X#define booleanp(x) ((x) == NIL || ntype(x) == BOOLEAN) X X/* cons access macros */ X#define car(x) ((x)->n_car) X#define cdr(x) ((x)->n_cdr) X#define rplaca(x,y) ((x)->n_car = (y)) X#define rplacd(x,y) ((x)->n_cdr = (y)) X X/* symbol access macros */ X#define getvalue(x) ((x)->n_vdata[0]) X#define setvalue(x,v) ((x)->n_vdata[0] = (v)) X#define getpname(x) ((x)->n_vdata[1]) X#define setpname(x,v) ((x)->n_vdata[1] = (v)) X#define getplist(x) ((x)->n_vdata[2]) X#define setplist(x,v) ((x)->n_vdata[2] = (v)) X#define SYMSIZE 3 X X/* vector access macros */ X#define getsize(x) ((x)->n_vsize) X#define getelement(x,i) ((x)->n_vdata[i]) X#define setelement(x,i,v) ((x)->n_vdata[i] = (v)) X X/* object access macros */ X#define getclass(x) ((x)->n_vdata[1]) X#define setclass(x,v) ((x)->n_vdata[1] = (v)) X#define getivar(x,i) ((x)->n_vdata[i]) X#define setivar(x,i,v) ((x)->n_vdata[i] = (v)) X X/* promise access macros */ X#define getpproc(x) ((x)->n_car) X#define setpproc(x,v) ((x)->n_car = (v)) X#define getpvalue(x) ((x)->n_cdr) X#define setpvalue(x,v) ((x)->n_cdr = (v)) X X/* closure access macros */ X#define getcode(x) ((x)->n_car) X#define getenv(x) ((x)->n_cdr) X X/* code access macros */ X#define getbcode(x) ((x)->n_vdata[0]) X#define setbcode(x,v) ((x)->n_vdata[0] = (v)) X#define getcname(x) ((x)->n_vdata[1]) X#define setcname(x,v) ((x)->n_vdata[1] = (v)) X#define getvnames(x) ((x)->n_vdata[2]) X#define setvnames(x,v) ((x)->n_vdata[2] = (v)) X#define FIRSTLIT 3 X X/* fixnum/flonum/character access macros */ X#define getfixnum(x) ((OFFTYPE)(x) & 1 ? getsfixnum(x) : (x)->n_int) X#define getflonum(x) ((x)->n_flonum) X#define getchcode(x) ((x)->n_chcode) X X/* small fixnum access macros */ X#define cvsfixnum(x) ((LVAL)(((OFFTYPE)x << 1) | 1)) X#define getsfixnum(x) ((FIXTYPE)((OFFTYPE)(x) >> 1)) X X/* string access macros */ X#define getstring(x) ((unsigned char *)(x)->n_vdata) X#define getslength(x) ((x)->n_vsize) X X/* iport/oport access macros */ X#define getfile(x) ((x)->n_fp) X#define setfile(x,v) ((x)->n_fp = (v)) X#define getsavech(x) ((x)->n_savech) X#define setsavech(x,v) ((x)->n_savech = (v)) X#define getpflags(x) ((x)->n_pflags) X#define setpflags(x,v) ((x)->n_pflags = (v)) X X/* subr access macros */ X#define getsubr(x) ((x)->n_subr) X#define getoffset(x) ((x)->n_offset) X X/* list node */ X#define n_car n_info.n_xlist.xl_car X#define n_cdr n_info.n_xlist.xl_cdr X X/* integer node */ X#define n_int n_info.n_xint.xi_int X X/* flonum node */ X#define n_flonum n_info.n_xflonum.xf_flonum X X/* character node */ X#define n_chcode n_info.n_xchar.xc_chcode X X/* string node */ X#define n_str n_info.n_xstr.xst_str X#define n_strlen n_info.n_xstr.xst_length X X/* file pointer node */ X#define n_fp n_info.n_xfptr.xf_fp X#define n_savech n_info.n_xfptr.xf_savech X#define n_pflags n_info.n_xfptr.xf_pflags X X/* vector/object node */ X#define n_vsize n_info.n_xvect.xv_size X#define n_vdata n_info.n_xvect.xv_data X X/* subr node */ X#define n_subr n_info.n_xsubr.xs_subr X#define n_offset n_info.n_xsubr.xs_offset X X/* node structure */ Xtypedef struct node { X char n_type; /* type of node */ X char n_flags; /* flag bits */ X union ninfo { /* value */ X struct xlist { /* list node (cons) */ X struct node *xl_car; /* the car pointer */ X struct node *xl_cdr; /* the cdr pointer */ X } n_xlist; X struct xint { /* integer node */ X FIXTYPE xi_int; /* integer value */ X } n_xint; X struct xflonum { /* flonum node */ X FLOTYPE xf_flonum; /* flonum value */ X } n_xflonum; X struct xchar { /* character node */ X int xc_chcode; /* character code */ X } n_xchar; X struct xstr { /* string node */ X int xst_length; /* string length */ X unsigned char *xst_str; /* string pointer */ X } n_xstr; X struct xfptr { /* file pointer node */ X FILE *xf_fp; /* the file pointer */ X short xf_savech; /* lookahead character for input files */ X short xf_pflags; /* port flags */ X } n_xfptr; X struct xvect { /* vector node */ X int xv_size; /* vector size */ X struct node **xv_data; /* vector data */ X } n_xvect; X struct xsubr { /* subr/fsubr node */ X struct node *(*xs_subr)(); /* function pointer */ X int xs_offset; /* offset into funtab */ X } n_xsubr; X } n_info; X} NODE,*LVAL; X X/* memory allocator definitions */ X X/* macros to compute the size of a segment */ X#define nsegsize(n) (sizeof(NSEGMENT)+((n)-1)*sizeof(struct node)) X#define vsegsize(n) (sizeof(VSEGMENT)+((n)-1)*sizeof(LVAL)) X X/* macro to convert a byte size to a word size */ X#define btow_size(n) (((n) + sizeof(LVAL) - 1) / sizeof(LVAL)) X X/* node segment structure */ Xtypedef struct nsegment { X struct nsegment *ns_next; /* next node segment */ X unsigned int ns_size; /* number of nodes in this segment */ X struct node ns_data[1]; /* segment data */ X} NSEGMENT; X X/* vector segment structure */ Xtypedef struct vsegment { X struct vsegment *vs_next; /* next vector segment */ X LVAL *vs_free; /* next free location in this segment */ X LVAL *vs_top; /* top of segment (plus one) */ X LVAL vs_data[1]; /* segment data */ X} VSEGMENT; X X/* function definition structure */ Xtypedef struct { X char *fd_name; /* function name */ X LVAL (*fd_subr)(); /* function entry point */ X} FUNDEF; X X/* external variables */ Xextern LVAL *xlstkbase; /* base of value stack */ Xextern LVAL *xlstktop; /* top of value stack */ Xextern LVAL *xlsp; /* value stack pointer */ Xextern int xlargc; /* argument count for current call */ X X/* external routine declarations */ Xextern LVAL cons(); /* (cons x y) */ Xextern LVAL xlenter(); /* enter a symbol */ Xextern LVAL xlgetprop(); /* get the value of a property */ Xextern LVAL cvsymbol(); /* convert a string to a symbol */ Xextern LVAL cvstring(); /* convert a string */ Xextern LVAL cvfixnum(); /* convert a fixnum */ Xextern LVAL cvflonum(); /* convert a flonum */ Xextern LVAL cvchar(); /* convert a character */ Xextern LVAL cvclosure(); /* convert code and an env to a closure */ Xextern LVAL cvmethod(); /* convert code and an env to a method */ Xextern LVAL cvsubr(); /* convert a function into a subr */ Xextern LVAL cvport(); /* convert a file pointer to an input port */ Xextern LVAL cvpromise(); /* convert a procedure to a promise */ Xextern LVAL newstring(); /* create a new string */ Xextern LVAL newobject(); /* create a new object */ Xextern LVAL newvector(); /* create a new vector */ Xextern LVAL newcode(); /* create a new code object */ Xextern LVAL newcontinuation(); /* create a new continuation object */ Xextern LVAL newframe(); /* create a new environment frame */ Xextern LVAL newnode(); /* create a new node */ Xextern LVAL xltoofew(); /* report "too few arguments" */ Xextern LVAL xlbadtype(); /* report "wrong argument type" */ Xextern LVAL curinput(); /* get the current input port */ Xextern LVAL curoutput(); /* get the current output port */ END_OF_FILE if test 13100 -ne `wc -c <'Src/xscheme.h'`; then echo shar: \"'Src/xscheme.h'\" unpacked with wrong size! fi # end of 'Src/xscheme.h' fi if test -f 'Src/xsdmem.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Src/xsdmem.c'\" else echo shar: Extracting \"'Src/xsdmem.c'\" \(15137 characters\) sed "s/^X//" >'Src/xsdmem.c' <<'END_OF_FILE' X/* xsdmem.c - xscheme dynamic memory management routines */ X/* Copyright (c) 1988, by David Michael Betz X All Rights Reserved X Permission is granted for unrestricted non-commercial use */ X X#include "xscheme.h" X X/* virtual machine registers */ XLVAL xlfun=NIL; /* current function */ XLVAL xlenv=NIL; /* current environment */ XLVAL xlval=NIL; /* value of most recent instruction */ XLVAL *xlsp=NULL; /* value stack pointer */ X X/* stack limits */ XLVAL *xlstkbase=NULL; /* base of value stack */ XLVAL *xlstktop=NULL; /* top of value stack (actually, one beyond) */ X X/* variables shared with xsimage.c */ XFIXTYPE total=0; /* total number of bytes of memory in use */ XFIXTYPE gccalls=0; /* number of calls to the garbage collector */ X X/* node space */ XNSEGMENT *nsegments=NULL; /* list of node segments */ XNSEGMENT *nslast=NULL; /* last node segment */ Xint nscount=0; /* number of node segments */ XFIXTYPE nnodes=0; /* total number of nodes */ XFIXTYPE nfree=0; /* number of nodes in free list */ XLVAL fnodes=NIL; /* list of free nodes */ X X/* vector (and string) space */ XVSEGMENT *vsegments=NULL; /* list of vector segments */ XVSEGMENT *vscurrent=NULL; /* current vector segment */ Xint vscount=0; /* number of vector segments */ XLVAL *vfree=NULL; /* next free location in vector space */ XLVAL *vtop=NULL; /* top of vector space */ X X/* external variables */ Xextern LVAL s_unbound; /* *UNBOUND* symbol */ Xextern LVAL obarray; /* *OBARRAY* symbol */ Xextern LVAL default_object; /* default object */ Xextern LVAL eof_object; /* eof object */ Xextern LVAL true; /* truth value */ X X/* external routines */ Xextern unsigned char *calloc(); X X/* forward declarations */ XFORWARD LVAL allocnode(); XFORWARD LVAL allocvector(); X X/* cons - construct a new cons node */ XLVAL cons(x,y) X LVAL x,y; X{ X LVAL nnode; X X /* get a free node */ X if ((nnode = fnodes) == NIL) { X check(2); X push(x); X push(y); X findmemory(); X if ((nnode = fnodes) == NIL) X xlabort("insufficient node space"); X drop(2); X } X X /* unlink the node from the free list */ X fnodes = cdr(nnode); X --nfree; X X /* initialize the new node */ X nnode->n_type = CONS; X rplaca(nnode,x); X rplacd(nnode,y); X X /* return the new node */ X return (nnode); X} X X/* newframe - create a new environment frame */ XLVAL newframe(parent,size) X LVAL parent; int size; X{ X LVAL frame; X frame = cons(newvector(size),parent); X frame->n_type = ENV; X return (frame); X} X X/* cvstring - convert a string to a string node */ XLVAL cvstring(str) X unsigned char *str; X{ X LVAL val; X val = newstring(strlen(str)+1); X strcpy(getstring(val),str); X return (val); X} X X/* cvsymbol - convert a string to a symbol */ XLVAL cvsymbol(pname) X unsigned char *pname; X{ X LVAL val; X val = allocvector(SYMBOL,SYMSIZE); X cpush(val); X setvalue(val,s_unbound); X setpname(val,cvstring(pname)); X setplist(val,NIL); X return (pop()); X} X X/* cvfixnum - convert an integer to a fixnum node */ XLVAL cvfixnum(n) X FIXTYPE n; X{ X LVAL val; X if (n >= SFIXMIN && n <= SFIXMAX) X return (cvsfixnum(n)); X val = allocnode(FIXNUM); X val->n_int = n; X return (val); X} X X/* cvflonum - convert a floating point number to a flonum node */ XLVAL cvflonum(n) X FLOTYPE n; X{ X LVAL val; X val = allocnode(FLONUM); X val->n_flonum = n; X return (val); X} X X/* cvchar - convert an integer to a character node */ XLVAL cvchar(ch) X int ch; X{ X LVAL val; X val = allocnode(CHAR); X val->n_chcode = ch; X return (val); X} X X/* cvclosure - convert code and an environment to a closure */ XLVAL cvclosure(code,env) X LVAL code,env; X{ X LVAL val; X val = cons(code,env); X val->n_type = CLOSURE; X return (val); X} X X/* cvpromise - convert a procedure to a promise */ XLVAL cvpromise(code,env) X LVAL code,env; X{ X LVAL val; X val = cons(cvclosure(code,env),NIL); X val->n_type = PROMISE; X return (val); X} X X/* cvmethod - convert code and an environment to a method */ XLVAL cvmethod(code,class) X LVAL code,class; X{ X LVAL val; X val = cons(code,class); X val->n_type = METHOD; X return (val); X} X X/* cvsubr - convert a function to a subr/xsubr */ XLVAL cvsubr(type,fcn,offset) X int type; LVAL (*fcn)(); int offset; X{ X LVAL val; X val = allocnode(type); X val->n_subr = fcn; X val->n_offset = offset; X return (val); X} X X/* cvport - convert a file pointer to an port */ XLVAL cvport(fp,flags) X FILE *fp; int flags; X{ X LVAL val; X val = allocnode(PORT); X setfile(val,fp); X setsavech(val,'\0'); X setpflags(val,flags); X return (val); X} X X/* newvector - allocate and initialize a new vector */ XLVAL newvector(size) X int size; X{ X return (allocvector(VECTOR,size)); X} X X/* newstring - allocate and initialize a new string */ XLVAL newstring(size) X int size; X{ X LVAL val; X val = allocvector(STRING,btow_size(size)); X val->n_vsize = size; X return (val); X} X X/* newcode - create a new code object */ XLVAL newcode(nlits) X int nlits; X{ X return (allocvector(CODE,nlits)); X} X X/* newcontinuation - create a new continuation object */ XLVAL newcontinuation(size) X int size; X{ X return (allocvector(CONTINUATION,size)); X} X X/* newobject - allocate and initialize a new object */ XLVAL newobject(cls,size) X LVAL cls; int size; X{ X LVAL val; X val = allocvector(OBJECT,size+2); /* class, ivars */ X setclass(val,cls); X return (val); X} X X/* allocnode - allocate a new node */ XLOCAL LVAL allocnode(type) X int type; X{ X LVAL nnode; X X /* get a free node */ X if ((nnode = fnodes) == NIL) { X findmemory(); X if ((nnode = fnodes) == NIL) X xlabort("insufficient node space"); X } X X /* unlink the node from the free list */ X fnodes = cdr(nnode); X --nfree; X X /* initialize the new node */ X nnode->n_type = type; X rplacd(nnode,NIL); X X /* return the new node */ X return (nnode); X} X X/* findmemory - garbage collect, then add more node space if necessary */ XLOCAL findmemory() X{ X /* first try garbage collecting */ X gc(); X X /* expand memory only if less than one segment is free */ X if (nfree < (long)NSSIZE) X nexpand(1); X} X X/* nexpand - expand node space */ Xnexpand(n) X int n; X{ X NSEGMENT *newnsegment(),*newseg; X LVAL p; X int i; X X /* try to add n segments */ X while (--n >= 0) { X X /* allocate the new segment */ X if ((newseg = newnsegment(NSSIZE)) == NULL) X return; X X /* add each new node to the free list */ X p = &newseg->ns_data[0]; X for (i = NSSIZE; --i >= 0; ++p) { X p->n_type = FREE; X p->n_flags = 0; X rplacd(p,fnodes); X fnodes = p; X } X } X} X X/* allocvector - allocate and initialize a new vector node */ XLOCAL LVAL allocvector(type,size) X int type,size; X{ X register LVAL val,*p; X register int i; X X /* get a free node */ X if ((val = fnodes) == NIL) { X findmemory(); X if ((val = fnodes) == NIL) X xlabort("insufficient node space"); X } X X /* unlink the node from the free list */ X fnodes = cdr(fnodes); X --nfree; X X /* initialize the vector node */ X val->n_type = type; X val->n_vsize = size; X val->n_vdata = NULL; X cpush(val); X X /* add space for the backpointer */ X ++size; X X /* make sure there's enough space */ X if (!VCOMPARE(vfree,size,vtop)) { X findvmemory(size); X if (!VCOMPARE(vfree,size,vtop)) X xlabort("insufficient vector space"); X } X X /* allocate the next available block */ X p = vfree; X vfree += size; X X /* store the backpointer */ X *p++ = top(); X val->n_vdata = p; X X /* set all the elements to NIL */ X for (i = size; i > 1; --i) X *p++ = NIL; X X /* return the new vector */ X return (pop()); X} X X/* findvmemory - find vector memory */ Xfindvmemory(size) X int size; X{ X gc(); X makevmemory(size); X} X X/* makevmemory - make vector memory (used by 'xsimage.c') */ Xmakevmemory(size) X int size; X{ X VSEGMENT *vseg; X X /* look for a vector segment with enough space */ X for (vseg = vsegments; vseg != NULL; vseg = vseg->vs_next) X if (VCOMPARE(vseg->vs_free,size,vseg->vs_top)) { X if (vscurrent != NULL) X vscurrent->vs_free = vfree; X vfree = vseg->vs_free; X vtop = vseg->vs_top; X vscurrent = vseg; X return; X } X X /* allocate a new vector segment and make it current */ X vexpand(1); X} X X/* vexpand - expand vector space */ Xvexpand(n) X int n; X{ X VSEGMENT *newvsegment(),*vseg; X X /* try to add n segments */ X while (--n >= 0) { X if ((vseg = newvsegment(VSSIZE)) == NULL) X return; X if (vscurrent != NULL) X vscurrent->vs_free = vfree; X vfree = vseg->vs_free; X vtop = vseg->vs_top; X vscurrent = vseg; X } X} X X/* newnsegment - create a new node segment */ XNSEGMENT *newnsegment(n) X unsigned int n; X{ X NSEGMENT *newseg; X X /* allocate the new segment */ X if ((newseg = (NSEGMENT *)calloc(1,nsegsize(n))) == NULL) X return (NULL); X X /* initialize the new segment */ X newseg->ns_size = n; X newseg->ns_next = NULL; X if (nsegments) X nslast->ns_next = newseg; X else X nsegments = newseg; X nslast = newseg; X X /* update the statistics */ X total += (long)nsegsize(n); X nnodes += (long)n; X nfree += (long)n; X ++nscount; X X /* return the new segment */ X return (newseg); X} X X/* newvsegment - create a new vector segment */ XVSEGMENT *newvsegment(n) X unsigned int n; X{ X VSEGMENT *newseg; X X /* allocate the new segment */ X if ((newseg = (VSEGMENT *)calloc(1,vsegsize(n))) == NULL) X return (NULL); X X /* initialize the new segment */ X newseg->vs_free = &newseg->vs_data[0]; X newseg->vs_top = newseg->vs_free + n; X newseg->vs_next = vsegments; X vsegments = newseg; X X /* update the statistics */ X total += (long)vsegsize(n); X ++vscount; X X /* return the new segment */ X return (newseg); X} X X/* gc - garbage collect */ Xgc() X{ X register LVAL *p,tmp; X int compact(); X X /* mark the obarray and the current environment */ X if (obarray && ispointer(obarray)) X mark(obarray); X if (xlfun && ispointer(xlfun)) X mark(xlfun); X if (xlenv && ispointer(xlenv)) X mark(xlenv); X if (xlval && ispointer(xlval)) X mark(xlval); X if (default_object && ispointer(default_object)) X mark(default_object); X if (eof_object && ispointer(eof_object)) X mark(eof_object); X if (true && ispointer(true)) X mark(true); X X /* mark the stack */ X for (p = xlsp; p < xlstktop; ++p) X if ((tmp = *p) && ispointer(tmp)) X mark(tmp); X X /* compact vector space */ X gc_protect(compact); X X /* sweep memory collecting all unmarked nodes */ X sweep(); X X /* count the gc call */ X ++gccalls; X} X X/* mark - mark all accessible nodes */ XLOCAL mark(ptr) X LVAL ptr; X{ X register LVAL this,prev,tmp; X X /* initialize */ X prev = NIL; X this = ptr; X X /* mark this node */ X for (;;) { X X /* descend as far as we can */ X while (!(this->n_flags & MARK)) X X /* mark this node and trace its children */ X switch (this->n_type) { X case CONS: /* mark cons-like nodes */ X case CLOSURE: X case METHOD: X case PROMISE: X case ENV: X this->n_flags |= MARK; X if ((tmp = car(this)) && ispointer(tmp)) { X this->n_flags |= LEFT; X rplaca(this,prev); X prev = this; X this = tmp; X } X else if ((tmp = cdr(this)) && ispointer(tmp)) { X rplacd(this,prev); X prev = this; X this = tmp; X } X break; X case SYMBOL: /* mark vector-like nodes */ X case OBJECT: X case VECTOR: X case CODE: X case CONTINUATION: X this->n_flags |= MARK; X markvector(this); X break; X default: /* mark all other types of nodes */ X this->n_flags |= MARK; X break; X } X X /* backup to a point where we can continue descending */ X for (;;) X X /* make sure there is a previous node */ X if (prev) { X if (prev->n_flags & LEFT) { /* came from left side */ X prev->n_flags &= ~LEFT; X tmp = car(prev); X rplaca(prev,this); X if ((this = cdr(prev)) && ispointer(this)) { X rplacd(prev,tmp); X break; X } X } X else { /* came from right side */ X tmp = cdr(prev); X rplacd(prev,this); X } X this = prev; /* step back up the branch */ X prev = tmp; X } X X /* no previous node, must be done */ X else X return; X } X} X X/* markvector - mark a vector-like node */ XLOCAL markvector(vect) X LVAL vect; X{ X register LVAL tmp,*p; X register int n; X if (p = vect->n_vdata) { X n = getsize(vect); X while (--n >= 0) X if ((tmp = *p++) != NULL && ispointer(tmp)) X mark(tmp); X } X} X X/* compact - compact vector space */ XLOCAL compact() X{ X VSEGMENT *vseg; X X /* store the current segment information */ X if (vscurrent) X vscurrent->vs_free = vfree; X X /* compact each vector segment */ X for (vseg = vsegments; vseg != NULL; vseg = vseg->vs_next) X compact_vector(vseg); X X /* make the first vector segment current */ X if (vscurrent = vsegments) { X vfree = vscurrent->vs_free; X vtop = vscurrent->vs_top; X } X} X X/* compact_vector - compact a vector segment */ XLOCAL compact_vector(vseg) X VSEGMENT *vseg; X{ X register LVAL *vdata,*vnext,*vfree,vector; X register int vsize; X X vdata = vnext = &vseg->vs_data[0]; X vfree = vseg->vs_free; X while (vdata < vfree) { X vector = *vdata; X if (vector->n_type == STRING) X vsize = btow_size(vector->n_vsize) + 1; X else X vsize = vector->n_vsize + 1; X if (vector->n_flags & MARK) { X if (vdata == vnext) { X vdata += vsize; X vnext += vsize; X } X else { X vector->n_vdata = vnext + 1; X while (vsize > 0) { X *vnext++ = *vdata++; X --vsize; X } X } X } X else X vdata += vsize; X } X vseg->vs_free = vnext; X} X X/* sweep - sweep all unmarked nodes and add them to the free list */ XLOCAL sweep() X{ X NSEGMENT *nseg; X X /* empty the free list */ X fnodes = NIL; X nfree = 0L; X X /* sweep each node segment */ X for (nseg = nsegments; nseg != NULL; nseg = nseg->ns_next) X sweep_segment(nseg); X} X X/* sweep_segment - sweep a node segment */ XLOCAL sweep_segment(nseg) X NSEGMENT *nseg; X{ X register FIXTYPE n; X register LVAL p; X X /* add all unmarked nodes */ X for (p = &nseg->ns_data[0], n = nseg->ns_size; --n >= 0L; ++p) X if (!(p->n_flags & MARK)) { X switch (p->n_type) { X case PORT: X if (getfile(p)) X osclose(getfile(p)); X break; X } X p->n_type = FREE; X rplacd(p,fnodes); X fnodes = p; X ++nfree; X } X else X p->n_flags &= ~MARK; X} X X/* xlminit - initialize the dynamic memory module */ Xxlminit(ssize) X unsigned int ssize; X{ X unsigned int n; X X /* initialize our internal variables */ X gccalls = 0; X total = 0L; X X /* initialize node space */ X nsegments = nslast = NULL; X nscount = 0; X nnodes = nfree = 0L; X fnodes = NIL; X X /* initialize vector space */ X vsegments = vscurrent = NULL; X vscount = 0; X vfree = vtop = NULL; X X /* allocate the value stack */ X n = ssize * sizeof(LVAL); X if ((xlstkbase = (LVAL *)calloc(1,n)) == NULL) X xlfatal("insufficient memory"); X total += (long)n; X X /* initialize structures that are marked by the collector */ X obarray = default_object = eof_object = true = NIL; X xlfun = xlenv = xlval = NIL; X X /* initialize the stack */ X xlsp = xlstktop = xlstkbase + ssize; X} END_OF_FILE if test 15137 -ne `wc -c <'Src/xsdmem.c'`; then echo shar: \"'Src/xsdmem.c'\" unpacked with wrong size! fi # end of 'Src/xsdmem.c' fi if test -f 'Src/xsftab.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Src/xsftab.c'\" else echo shar: Extracting \"'Src/xsftab.c'\" \(14063 characters\) sed "s/^X//" >'Src/xsftab.c' <<'END_OF_FILE' X/* xsftab.c - built-in function table */ X/* Copyright (c) 1988, by David Michael Betz X All Rights Reserved X Permission is granted for unrestricted non-commercial use */ X X#include "xscheme.h" X X/* external variables */ Xextern LVAL s_stdin,s_stdout; X X/* external functions */ Xextern LVAL X xapply(),xcallcc(),xmap(),xmap1(),xforeach(),xforeach1(), X xforce(),xforce1(),xcallwi(),xcallwo(),xwithfile1(), X xload(),xloadnoisily(),xload1(), X xsendsuper(),clnew(),clisnew(),clanswer(), X obisnew(),obclass(),obshow(), X xcons(),xcar(),xcdr(), X xcaar(),xcadr(),xcdar(),xcddr(), X xcaaar(),xcaadr(),xcadar(),xcaddr(), X xcdaar(),xcdadr(),xcddar(),xcdddr(), X xcaaaar(),xcaaadr(),xcaadar(),xcaaddr(), X xcadaar(),xcadadr(),xcaddar(),xcadddr(), X xcdaaar(),xcdaadr(),xcdadar(),xcdaddr(), X xcddaar(),xcddadr(),xcdddar(),xcddddr(), X xsetcar(),xsetcdr(),xlist(), X xappend(),xreverse(),xlastpair(),xlength(),xlistref(),xlisttail(), X xmember(),xmemv(),xmemq(),xassoc(),xassv(),xassq(), X xsymvalue(),xsetsymvalue(),xsymplist(),xsetsymplist(),xgensym(), X xboundp(),xget(),xput(), X xtheenvironment(),xprocenvironment(),xenvp(),xenvbindings(),xenvparent(), X xvector(),xmakevector(),xvlength(),xvref(),xvset(), X xvectlist(),xlistvect(), X xmakearray(),xaref(),xaset(), X xsymstr(),xstrsym(), X xnull(),xatom(),xlistp(),xnumberp(),xbooleanp(), X xpairp(),xsymbolp(),xintegerp(),xrealp(),xcharp(),xstringp(),xvectorp(), X xprocedurep(),xobjectp(),xdefaultobjectp(), X xinputportp(),xoutputportp(),xportp(), X xeq(),xeqv(),xequal(), X xzerop(),xpositivep(),xnegativep(),xoddp(),xevenp(), X xexactp(),xinexactp(), X xadd1(),xsub1(),xabs(),xgcd(),xrandom(), X xadd(),xsub(),xmul(),xdiv(),xquo(),xrem(),xmin(),xmax(), X xsin(),xcos(),xtan(),xasin(),xacos(),xatan(), X xxexp(),xsqrt(),xexpt(),xxlog(),xtruncate(),xfloor(),xceiling(),xround(), X xlogand(),xlogior(),xlogxor(),xlognot(), X xlss(),xleq(),xeql(),xgeq(),xgtr(), X xstrlen(),xstrnullp(),xstrappend(),xstrref(),xsubstring(), X xstrlist(),xliststring(), X xstrlss(),xstrleq(),xstreql(),xstrgeq(),xstrgtr(), X xstrilss(),xstrileq(),xstrieql(),xstrigeq(),xstrigtr(), X xcharint(),xintchar(), X xchrlss(),xchrleq(),xchreql(),xchrgeq(),xchrgtr(), X xchrilss(),xchrileq(),xchrieql(),xchrigeq(),xchrigtr(), X xread(),xrdchar(),xrdbyte(),xrdshort(),xrdlong(),xeofobjectp(), X xwrite(),xwrchar(),xwrbyte(),xwrshort(),xwrlong(), X xdisplay(),xnewline(),xprint(),xprbreadth(),xprdepth(), X xopeni(),xopeno(),xopena(),xopenu(),xclosei(),xcloseo(),xclose(), X xgetfposition(),xsetfposition(),xcurinput(),xcuroutput(), X xtranson(),xtransoff(),xgetarg(),xexit(),xcompile(),xdecompile(),xgc(), X xsave(),xrestore(),xtraceon(),xtraceoff(),xreset(),xerror(), X xicar(),xicdr(),xisetcar(),xisetcdr(),xivlength(),xivref(),xivset(); X#ifdef MACINTOSH Xextern LVAL xhidepen(),xshowpen(),xgetpen(),xpensize(),xpenmode(); Xextern LVAL xpenpat(),xpennormal(),xmoveto(),xmove(),xlineto(),xline(); Xextern LVAL xshowgraphics(),xhidegraphics(),xcleargraphics(); X#endif X#ifdef MSDOS Xextern LVAL xint86(),xinbyte(),xoutbyte(),xsystem(),xgetkey(); X#endif X#ifdef UNIX Xextern LVAL xsystem(); X#endif X#ifdef AZTEC_AMIGA Xextern LVAL xsystem(); X#endif X Xint xsubrcnt = 12; /* number of XSUBR functions */ Xint csubrcnt = 17; /* number of CSUBR functions + xsubrcnt */ X X/* built-in functions */ XFUNDEF funtab[] = { X X /* functions that call eval or apply (# must match xsubrcnt) */ X{ "APPLY", xapply }, X{ "CALL-WITH-CURRENT-CONTINUATION", xcallcc }, X{ "CALL/CC", xcallcc }, X{ "MAP", xmap }, X{ "FOR-EACH", xforeach }, X{ "CALL-WITH-INPUT-FILE", xcallwi }, X{ "CALL-WITH-OUTPUT-FILE", xcallwo }, X{ "LOAD", xload }, X{ "LOAD-NOISILY", xloadnoisily }, X{ "SEND-SUPER", xsendsuper }, X{ "%CLASS-NEW", clnew }, X{ "FORCE", xforce }, X X /* continuations for xsubrs (# must match csubrcnt) */ X{ "%MAP1", xmap1 }, X{ "%FOR-EACH1", xforeach1 }, X{ "%WITH-FILE1", xwithfile1 }, X{ "%LOAD1", xload1 }, X{ "%FORCE1", xforce1 }, X X /* methods */ X{ "%CLASS-ISNEW", clisnew }, X{ "%CLASS-ANSWER", clanswer }, X{ "%OBJECT-ISNEW", obisnew }, X{ "%OBJECT-CLASS", obclass }, X{ "%OBJECT-SHOW", obshow }, X X /* list functions */ X{ "CONS", xcons }, X{ "CAR", xcar }, X{ "CDR", xcdr }, X{ "CAAR", xcaar }, X{ "CADR", xcadr }, X{ "CDAR", xcdar }, X{ "CDDR", xcddr }, X{ "CAAAR", xcaaar }, X{ "CAADR", xcaadr }, X{ "CADAR", xcadar }, X{ "CADDR", xcaddr }, X{ "CDAAR", xcdaar }, X{ "CDADR", xcdadr }, X{ "CDDAR", xcddar }, X{ "CDDDR", xcdddr }, X{ "CAAAAR", xcaaaar }, X{ "CAAADR", xcaaadr }, X{ "CAADAR", xcaadar }, X{ "CAADDR", xcaaddr }, X{ "CADAAR", xcadaar }, X{ "CADADR", xcadadr }, X{ "CADDAR", xcaddar }, X{ "CADDDR", xcadddr }, X{ "CDAAAR", xcdaaar }, X{ "CDAADR", xcdaadr }, X{ "CDADAR", xcdadar }, X{ "CDADDR", xcdaddr }, X{ "CDDAAR", xcddaar }, X{ "CDDADR", xcddadr }, X{ "CDDDAR", xcdddar }, X{ "CDDDDR", xcddddr }, X{ "LIST", xlist }, X{ "APPEND", xappend }, X{ "REVERSE", xreverse }, X{ "LAST-PAIR", xlastpair }, X{ "LENGTH", xlength }, X{ "MEMBER", xmember }, X{ "MEMV", xmemv }, X{ "MEMQ", xmemq }, X{ "ASSOC", xassoc }, X{ "ASSV", xassv }, X{ "ASSQ", xassq }, X{ "LIST-REF", xlistref }, X{ "LIST-TAIL", xlisttail }, X X /* destructive list functions */ X{ "SET-CAR!", xsetcar }, X{ "SET-CDR!", xsetcdr }, X X X /* symbol functions */ X{ "BOUND?", xboundp }, X{ "SYMBOL-VALUE", xsymvalue }, X{ "SET-SYMBOL-VALUE!", xsetsymvalue }, X{ "SYMBOL-PLIST", xsymplist }, X{ "SET-SYMBOL-PLIST!", xsetsymplist }, X{ "GENSYM", xgensym }, X{ "GET", xget }, X{ "PUT", xput }, X X /* environment functions */ X{ "THE-ENVIRONMENT", xtheenvironment }, X{ "PROCEDURE-ENVIRONMENT", xprocenvironment}, X{ "ENVIRONMENT?", xenvp }, X{ "ENVIRONMENT-BINDINGS", xenvbindings }, X{ "ENVIRONMENT-PARENT", xenvparent }, X X /* vector functions */ X{ "VECTOR", xvector }, X{ "MAKE-VECTOR", xmakevector }, X{ "VECTOR-LENGTH", xvlength }, X{ "VECTOR-REF", xvref }, X{ "VECTOR-SET!", xvset }, X X /* array functions */ X{ "MAKE-ARRAY", xmakearray }, X{ "ARRAY-REF", xaref }, X{ "ARRAY-SET!", xaset }, X X /* conversion functions */ X{ "SYMBOL->STRING", xsymstr }, X{ "STRING->SYMBOL", xstrsym }, X{ "VECTOR->LIST", xvectlist }, X{ "LIST->VECTOR", xlistvect }, X{ "STRING->LIST", xstrlist }, X{ "LIST->STRING", xliststring }, X{ "CHAR->INTEGER", xcharint }, X{ "INTEGER->CHAR", xintchar }, X X /* predicate functions */ X{ "NULL?", xnull }, X{ "ATOM?", xatom }, X{ "LIST?", xlistp }, X{ "NUMBER?", xnumberp }, X{ "BOOLEAN?", xbooleanp }, X{ "PAIR?", xpairp }, X{ "SYMBOL?", xsymbolp }, X{ "COMPLEX?", xrealp }, /*(1)*/ X{ "REAL?", xrealp }, X{ "RATIONAL?", xintegerp }, /*(1)*/ X{ "INTEGER?", xintegerp }, X{ "CHAR?", xcharp }, X{ "STRING?", xstringp }, X{ "VECTOR?", xvectorp }, X{ "PROCEDURE?", xprocedurep }, X{ "PORT?", xportp }, X{ "INPUT-PORT?", xinputportp }, X{ "OUTPUT-PORT?", xoutputportp }, X{ "OBJECT?", xobjectp }, X{ "EOF-OBJECT?", xeofobjectp }, X{ "DEFAULT-OBJECT?", xdefaultobjectp }, X{ "EQ?", xeq }, X{ "EQV?", xeqv }, X{ "EQUAL?", xequal }, X X /* arithmetic functions */ X{ "ZERO?", xzerop }, X{ "POSITIVE?", xpositivep }, X{ "NEGATIVE?", xnegativep }, X{ "ODD?", xoddp }, X{ "EVEN?", xevenp }, X{ "EXACT?", xexactp }, X{ "INEXACT?", xinexactp }, X{ "TRUNCATE", xtruncate }, X{ "FLOOR", xfloor }, X{ "CEILING", xceiling }, X{ "ROUND", xround }, X{ "1+", xadd1 }, X{ "-1+", xsub1 }, X{ "ABS", xabs }, X{ "GCD", xgcd }, X{ "RANDOM", xrandom }, X{ "+", xadd }, X{ "-", xsub }, X{ "*", xmul }, X{ "/", xdiv }, X{ "QUOTIENT", xquo }, X{ "REMAINDER", xrem }, X{ "MIN", xmin }, X{ "MAX", xmax }, X{ "SIN", xsin }, X{ "COS", xcos }, X{ "TAN", xtan }, X{ "ASIN", xasin }, X{ "ACOS", xacos }, X{ "ATAN", xatan }, X{ "EXP", xxexp }, X{ "SQRT", xsqrt }, X{ "EXPT", xexpt }, X{ "LOG", xxlog }, X X /* bitwise logical functions */ X{ "LOGAND", xlogand }, X{ "LOGIOR", xlogior }, X{ "LOGXOR", xlogxor }, X{ "LOGNOT", xlognot }, X X /* numeric comparison functions */ X{ "<", xlss }, X{ "<=", xleq }, X{ "=", xeql }, X{ ">=", xgeq }, X{ ">", xgtr }, X X /* string functions */ X{ "STRING-LENGTH", xstrlen }, X{ "STRING-NULL?", xstrnullp }, X{ "STRING-APPEND", xstrappend }, X{ "STRING-REF", xstrref }, X{ "SUBSTRING", xsubstring }, X{ "STRING<?", xstrlss }, X{ "STRING<=?", xstrleq }, X{ "STRING=?", xstreql }, X{ "STRING>=?", xstrgeq }, X{ "STRING>?", xstrgtr }, X{ "STRING-CI<?", xstrilss }, X{ "STRING-CI<=?", xstrileq }, X{ "STRING-CI=?", xstrieql }, X{ "STRING-CI>=?", xstrigeq }, X{ "STRING-CI>?", xstrigtr }, X X /* character functions */ X{ "CHAR<?", xchrlss }, X{ "CHAR<=?", xchrleq }, X{ "CHAR=?", xchreql }, X{ "CHAR>=?", xchrgeq }, X{ "CHAR>?", xchrgtr }, X{ "CHAR-CI<?", xchrilss }, X{ "CHAR-CI<=?", xchrileq }, X{ "CHAR-CI=?", xchrieql }, X{ "CHAR-CI>=?", xchrigeq }, X{ "CHAR-CI>?", xchrigtr }, X X /* I/O functions */ X{ "READ", xread }, X{ "READ-CHAR", xrdchar }, X{ "READ-BYTE", xrdbyte }, X{ "READ-SHORT", xrdshort }, X{ "READ-LONG", xrdlong }, X{ "WRITE", xwrite }, X{ "WRITE-CHAR", xwrchar }, X{ "WRITE-BYTE", xwrbyte }, X{ "WRITE-SHORT", xwrshort }, X{ "WRITE-LONG", xwrlong }, X{ "DISPLAY", xdisplay }, X{ "PRINT", xprint }, X{ "NEWLINE", xnewline }, X X /* print control functions */ X{ "PRINT-BREADTH", xprbreadth }, X{ "PRINT-DEPTH", xprdepth }, X X /* file I/O functions */ X{ "OPEN-INPUT-FILE", xopeni }, X{ "OPEN-OUTPUT-FILE", xopeno }, X{ "OPEN-APPEND-FILE", xopena }, X{ "OPEN-UPDATE-FILE", xopenu }, X{ "CLOSE-PORT", xclose }, X{ "CLOSE-INPUT-PORT", xclosei }, X{ "CLOSE-OUTPUT-PORT", xcloseo }, X{ "GET-FILE-POSITION", xgetfposition }, X{ "SET-FILE-POSITION!", xsetfposition }, X{ "CURRENT-INPUT-PORT", xcurinput }, X{ "CURRENT-OUTPUT-PORT", xcuroutput }, X X /* utility functions */ X{ "TRANSCRIPT-ON", xtranson }, X{ "TRANSCRIPT-OFF", xtransoff }, X{ "GETARG", xgetarg }, X{ "EXIT", xexit }, X{ "COMPILE", xcompile }, X{ "DECOMPILE", xdecompile }, X{ "GC", xgc }, X{ "SAVE", xsave }, X{ "RESTORE", xrestore }, X{ "RESET", xreset }, X{ "ERROR", xerror }, X X /* debugging functions */ X{ "TRACE-ON", xtraceon }, X{ "TRACE-OFF", xtraceoff }, X X /* internal functions */ X{ "%CAR", xicar }, X{ "%CDR", xicdr }, X{ "%SET-CAR!", xisetcar }, X{ "%SET-CDR!", xisetcdr }, X{ "%VECTOR-LENGTH", xivlength }, X{ "%VECTOR-REF", xivref }, X{ "%VECTOR-SET!", xivset }, X X#ifdef MACINTOSH X{ "HIDEPEN", xhidepen }, X{ "SHOWPEN", xshowpen }, X{ "GETPEN", xgetpen }, X{ "PENSIZE", xpensize }, X{ "PENMODE", xpenmode }, X{ "PENPAT", xpenpat }, X{ "PENNORMAL", xpennormal }, X{ "MOVETO", xmoveto }, X{ "MOVE", xmove }, X{ "LINETO", xlineto }, X{ "LINE", xline }, X{ "SHOW-GRAPHICS", xshowgraphics }, X{ "HIDE-GRAPHICS", xhidegraphics }, X{ "CLEAR-GRAPHICS", xcleargraphics }, X#endif X X#ifdef MSDOS X{ "INT86", xint86 }, X{ "INBYTE", xinbyte }, X{ "OUTBYTE", xoutbyte }, X{ "SYSTEM", xsystem }, X{ "GET-KEY", xgetkey }, X#endif X X#ifdef UNIX X{ "SYSTEM", xsystem }, X#endif X X#ifdef AZTEC_AMIGA X{ "SYSTEM", xsystem }, X#endif X X{0,0} /* end of table marker */ X X}; X X/* Notes: X X (1) This version only supports integers and reals. X X*/ X X/* curinput - get the current input port */ XLVAL curinput() X{ X return (getvalue(s_stdin)); X} X X/* curoutput - get the current output port */ XLVAL curoutput() X{ X return (getvalue(s_stdout)); X} X X/* eq - internal 'eq?' function */ Xint eq(arg1,arg2) X LVAL arg1,arg2; X{ X return (arg1 == arg2); X} X X/* eqv - internal 'eqv?' function */ Xint eqv(arg1,arg2) X LVAL arg1,arg2; X{ X /* try the eq test first */ X if (arg1 == arg2) X return (TRUE); X X /* compare fixnums, flonums and characters */ X if (!null(arg1)) { X switch (ntype(arg1)) { X case FIXNUM: X return (fixp(arg2) X && getfixnum(arg1) == getfixnum(arg2)); X case FLONUM: X return (floatp(arg2) X && getflonum(arg1) == getflonum(arg2)); X case CHAR: X return (charp(arg2) X && getchcode(arg1) == getchcode(arg2)); X } X } X return (FALSE); X} X X/* equal - internal 'equal?' function */ Xint equal(arg1,arg2) X LVAL arg1,arg2; X{ X /* try the eq test first */ X if (arg1 == arg2) X return (TRUE); X X /* compare fixnums, flonums, characters, strings, vectors and conses */ X if (!null(arg1)) { X switch (ntype(arg1)) { X case FIXNUM: X return (fixp(arg2) X && getfixnum(arg1) == getfixnum(arg2)); X case FLONUM: X return (floatp(arg2) X && getflonum(arg1) == getflonum(arg2)); X case CHAR: X return (charp(arg2) X && getchcode(arg1) == getchcode(arg2)); X case STRING: X return (stringp(arg2) X && strcmp(getstring(arg1),getstring(arg2)) == 0); X case VECTOR: X return (vectorp(arg2) X && vectorequal(arg1,arg2)); X case CONS: X return (consp(arg2) X && equal(car(arg1),car(arg2)) X && equal(cdr(arg1),cdr(arg2))); X } X } X return (FALSE); X} X X/* vectorequal - compare two vectors */ Xint vectorequal(v1,v2) X LVAL v1,v2; X{ X int len,i; X X /* compare the vector lengths */ X if ((len = getsize(v1)) != getsize(v2)) X return (FALSE); X X /* compare the vector elements */ X for (i = 0; i < len; ++i) X if (!equal(getelement(v1,i),getelement(v2,i))) X return (FALSE); X return (TRUE); X} X X/* xltoofew - too few arguments to this function */ XLVAL xltoofew() X{ X xlfail("too few arguments"); X} X X/* xltoomany - too many arguments to this function */ Xxltoomany() X{ X xlfail("too many arguments"); X} X X/* xlbadtype - incorrect argument type */ XLVAL xlbadtype(val) X LVAL val; X{ X xlerror("incorrect type",val); X} END_OF_FILE if test 14063 -ne `wc -c <'Src/xsftab.c'`; then echo shar: \"'Src/xsftab.c'\" unpacked with wrong size! fi # end of 'Src/xsftab.c' fi if test -f 'Src/xsmath.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Src/xsmath.c'\" else echo shar: Extracting \"'Src/xsmath.c'\" \(13437 characters\) sed "s/^X//" >'Src/xsmath.c' <<'END_OF_FILE' X/* xsmath.c - xscheme built-in arithmetic functions */ X/* Copyright (c) 1988, by David Michael Betz X All Rights Reserved X Permission is granted for unrestricted non-commercial use */ X X#include "xscheme.h" X#include <math.h> X X/* external variables */ Xextern LVAL true; X X/* forward declarations */ XFORWARD LVAL unary(); XFORWARD LVAL binary(); XFORWARD LVAL predicate(); XFORWARD LVAL compare(); XFORWARD FLOTYPE toflotype(); X X/* xexactp - built-in function 'exact?' */ X/**** THIS IS REALLY JUST A STUB FOR NOW ****/ XLVAL xexactp() X{ X LVAL arg; X arg = xlganumber(); X xllastarg(); X return (NIL); X} X X/* xinexactp - built-in function 'inexact?' */ X/**** THIS IS REALLY JUST A STUB FOR NOW ****/ XLVAL xinexactp() X{ X LVAL arg; X arg = xlganumber(); X xllastarg(); X return (true); X} X X/* xatan - built-in function 'atan' */ XLVAL xatan() X{ X LVAL arg,arg2; X FLOTYPE val; X X /* get the first argument */ X arg = xlganumber(); X X /* handle two argument (atan y x) */ X if (moreargs()) { X arg2 = xlganumber(); X xllastarg(); X val = atan2(toflotype(arg),toflotype(arg2)); X } X X /* handle one argument (atan x) */ X else X val = atan(toflotype(arg)); X X /* return the resulting flonum */ X return (cvflonum(val)); X} X X/* xfloor - built-in function 'floor' */ XLVAL xfloor() X{ X LVAL arg; X X /* get the argument */ X arg = xlgetarg(); X xllastarg(); X X /* check its type */ X if (fixp(arg)) X return (arg); X else if (floatp(arg)) X return (cvfixnum((FIXTYPE)floor(getflonum(arg)))); X else X xlbadtype(arg); X} X X/* xceiling - built-in function 'ceiling' */ XLVAL xceiling() X{ X LVAL arg; X X /* get the argument */ X arg = xlgetarg(); X xllastarg(); X X /* check its type */ X if (fixp(arg)) X return (arg); X else if (floatp(arg)) X return (cvfixnum((FIXTYPE)ceil(getflonum(arg)))); X else X xlbadtype(arg); X} X X/* xround - built-in function 'round' */ XLVAL xround() X{ X FLOTYPE x,y,z; X LVAL arg; X X /* get the argument */ X arg = xlgetarg(); X xllastarg(); X X /* check its type */ X if (fixp(arg)) X return (arg); X else if (floatp(arg)) { X x = getflonum(arg); X y = floor(x); X z = x - y; X if (z == 0.5) { X if (((FIXTYPE)y & 1) == 1) X y += 1.0; X return (cvfixnum((FIXTYPE)y)); X } X else if (z < 0.5) X return (cvfixnum((FIXTYPE)y)); X else X return (cvfixnum((FIXTYPE)(y + 1.0))); X } X else X xlbadtype(arg); X} X X/* xtruncate - built-in function 'truncate' */ XLVAL xtruncate() X{ X LVAL arg; X X /* get the argument */ X arg = xlgetarg(); X xllastarg(); X X /* check its type */ X if (fixp(arg)) X return (arg); X else if (floatp(arg)) X return (cvfixnum((FIXTYPE)(getflonum(arg)))); X else X xlbadtype(arg); X} X X/* binary functions */ XLVAL xadd() /* + */ X{ X if (!moreargs()) X return (cvfixnum((FIXTYPE)0)); X return (binary('+')); X} XLVAL xmul() /* * */ X{ X if (!moreargs()) X return (cvfixnum((FIXTYPE)1)); X return (binary('*')); X} XLVAL xsub() { return (binary('-')); } /* - */ XLVAL xdiv() { return (binary('/')); } /* / */ XLVAL xquo() { return (binary('Q')); } /* quotient */ XLVAL xrem() { return (binary('R')); } /* remainder */ XLVAL xmin() { return (binary('m')); } /* min */ XLVAL xmax() { return (binary('M')); } /* max */ XLVAL xexpt() { return (binary('E')); } /* expt */ XLVAL xlogand() { return (binary('&')); } /* logand */ XLVAL xlogior() { return (binary('|')); } /* logior */ XLVAL xlogxor() { return (binary('^')); } /* logxor */ X X/* binary - handle binary operations */ XLOCAL LVAL binary(fcn) X int fcn; X{ X FIXTYPE ival,iarg; X FLOTYPE fval,farg; X LVAL arg; X int mode; X X /* get the first argument */ X arg = xlgetarg(); X X /* set the type of the first argument */ X if (fixp(arg)) { X ival = getfixnum(arg); X mode = 'I'; X } X else if (floatp(arg)) { X fval = getflonum(arg); X mode = 'F'; X } X else X xlbadtype(arg); X X /* treat a single argument as a special case */ X if (!moreargs()) { X switch (fcn) { X case '-': X switch (mode) { X case 'I': X ival = -ival; X break; X case 'F': X fval = -fval; X break; X } X break; X case '/': X switch (mode) { X case 'I': X checkizero(ival); X if (ival != 1) { X fval = 1.0 / (FLOTYPE)ival; X mode = 'F'; X } X break; X case 'F': X checkfzero(fval); X fval = 1.0 / fval; X break; X } X } X } X X /* handle each remaining argument */ X while (moreargs()) { X X /* get the next argument */ X arg = xlgetarg(); X X /* check its type */ X if (fixp(arg)) { X switch (mode) { X case 'I': X iarg = getfixnum(arg); X break; X case 'F': X farg = (FLOTYPE)getfixnum(arg); X break; X } X } X else if (floatp(arg)) { X switch (mode) { X case 'I': X fval = (FLOTYPE)ival; X farg = getflonum(arg); X mode = 'F'; X break; X case 'F': X farg = getflonum(arg); X break; X } X } X else X xlbadtype(arg); X X /* accumulate the result value */ X switch (mode) { X case 'I': X switch (fcn) { X case '+': ival += iarg; break; X case '-': ival -= iarg; break; X case '*': ival *= iarg; break; X case '/': checkizero(iarg); X if ((ival % iarg) == 0) X ival /= iarg; X else { X fval = (FLOTYPE)ival; X farg = (FLOTYPE)iarg; X fval /= farg; X mode = 'F'; X } X break; X case 'Q': checkizero(iarg); ival /= iarg; break; X case 'R': checkizero(iarg); ival %= iarg; break; X case 'M': if (iarg > ival) ival = iarg; break; X case 'm': if (iarg < ival) ival = iarg; break; X case 'E': return (cvflonum((FLOTYPE)pow((FLOTYPE)ival,(FLOTYPE)iarg))); X case '&': ival &= iarg; break; X case '|': ival |= iarg; break; X case '^': ival ^= iarg; break; X default: badiop(); X } X break; X case 'F': X switch (fcn) { X case '+': fval += farg; break; X case '-': fval -= farg; break; X case '*': fval *= farg; break; X case '/': checkfzero(farg); fval /= farg; break; X case 'M': if (farg > fval) fval = farg; break; X case 'm': if (farg < fval) fval = farg; break; X case 'E': fval = pow(fval,farg); break; X default: badfop(); X } X break; X } X } X X /* return the result */ X switch (mode) { X case 'I': return (cvfixnum(ival)); X case 'F': return (cvflonum(fval)); X } X} X X/* unary functions */ XLVAL xlognot() { return (unary('~')); } /* lognot */ XLVAL xabs() { return (unary('A')); } /* abs */ XLVAL xadd1() { return (unary('+')); } /* 1+ */ XLVAL xsub1() { return (unary('-')); } /* -1+ */ XLVAL xsin() { return (unary('S')); } /* sin */ XLVAL xcos() { return (unary('C')); } /* cos */ XLVAL xtan() { return (unary('T')); } /* tan */ XLVAL xasin() { return (unary('s')); } /* asin */ XLVAL xacos() { return (unary('c')); } /* acos */ XLVAL xxexp() { return (unary('E')); } /* exp */ XLVAL xsqrt() { return (unary('R')); } /* sqrt */ XLVAL xxlog() { return (unary('L')); } /* log */ XLVAL xrandom() { return (unary('?')); } /* random */ X X/* unary - handle unary operations */ XLOCAL LVAL unary(fcn) X int fcn; X{ X FLOTYPE fval; X FIXTYPE ival; X LVAL arg; X X /* get the argument */ X arg = xlgetarg(); X xllastarg(); X X /* check its type */ X if (fixp(arg)) { X ival = getfixnum(arg); X switch (fcn) { X case '~': ival = ~ival; break; X case 'A': ival = (ival < 0 ? -ival : ival); break; X case '+': ival++; break; X case '-': ival--; break; X case 'S': return (cvflonum((FLOTYPE)sin((FLOTYPE)ival))); X case 'C': return (cvflonum((FLOTYPE)cos((FLOTYPE)ival))); X case 'T': return (cvflonum((FLOTYPE)tan((FLOTYPE)ival))); X case 's': return (cvflonum((FLOTYPE)asin((FLOTYPE)ival))); X case 'c': return (cvflonum((FLOTYPE)acos((FLOTYPE)ival))); X case 't': return (cvflonum((FLOTYPE)atan((FLOTYPE)ival))); X case 'E': return (cvflonum((FLOTYPE)exp((FLOTYPE)ival))); X case 'L': return (cvflonum((FLOTYPE)log((FLOTYPE)ival))); X case 'R': checkineg(ival); X return (cvflonum((FLOTYPE)sqrt((FLOTYPE)ival))); X case '?': ival = (FIXTYPE)osrand((int)ival); break; X default: badiop(); X } X return (cvfixnum(ival)); X } X else if (floatp(arg)) { X fval = getflonum(arg); X switch (fcn) { X case 'A': fval = (fval < 0.0 ? -fval : fval); break; X case '+': fval += 1.0; break; X case '-': fval -= 1.0; break; X case 'S': fval = sin(fval); break; X case 'C': fval = cos(fval); break; X case 'T': fval = tan(fval); break; X case 's': fval = asin(fval); break; X case 'c': fval = acos(fval); break; X case 't': fval = atan(fval); break; X case 'E': fval = exp(fval); break; X case 'L': fval = log(fval); break; X case 'R': checkfneg(fval); X fval = sqrt(fval); break; X default: badfop(); X } X return (cvflonum(fval)); X } X else X xlbadtype(arg); X} X X/* xgcd - greatest common divisor */ XLVAL xgcd() X{ X FIXTYPE m,n,r; X LVAL arg; X X if (!moreargs()) /* check for identity case */ X return (cvfixnum((FIXTYPE)0)); X arg = xlgafixnum(); X n = getfixnum(arg); X if (n < (FIXTYPE)0) n = -n; /* absolute value */ X while (moreargs()) { X arg = xlgafixnum(); X m = getfixnum(arg); X if (m < (FIXTYPE)0) m = -m; /* absolute value */ X for (;;) { /* euclid's algorithm */ X r = m % n; X if (r == (FIXTYPE)0) X break; X m = n; X n = r; X } X } X return (cvfixnum(n)); X} X X/* unary predicates */ XLVAL xnegativep() { return (predicate('-')); } /* negative? */ XLVAL xzerop() { return (predicate('Z')); } /* zero? */ XLVAL xpositivep() { return (predicate('+')); } /* positive? */ XLVAL xevenp() { return (predicate('E')); } /* even? */ XLVAL xoddp() { return (predicate('O')); } /* odd? */ X X/* predicate - handle a predicate function */ XLOCAL LVAL predicate(fcn) X int fcn; X{ X FLOTYPE fval; X FIXTYPE ival; X LVAL arg; X X /* get the argument */ X arg = xlgetarg(); X xllastarg(); X X /* check the argument type */ X if (fixp(arg)) { X ival = getfixnum(arg); X switch (fcn) { X case '-': ival = (ival < 0); break; X case 'Z': ival = (ival == 0); break; X case '+': ival = (ival > 0); break; X case 'E': ival = ((ival & 1) == 0); break; X case 'O': ival = ((ival & 1) != 0); break; X default: badiop(); X } X } X else if (floatp(arg)) { X fval = getflonum(arg); X switch (fcn) { X case '-': ival = (fval < 0); break; X case 'Z': ival = (fval == 0); break; X case '+': ival = (fval > 0); break; X default: badfop(); X } X } X else X xlbadtype(arg); X X /* return the result value */ X return (ival ? true : NIL); X} X X/* comparison functions */ XLVAL xlss() { return (compare('<')); } /* < */ XLVAL xleq() { return (compare('L')); } /* <= */ XLVAL xeql() { return (compare('=')); } /* = */ XLVAL xgeq() { return (compare('G')); } /* >= */ XLVAL xgtr() { return (compare('>')); } /* > */ X X/* compare - common compare function */ XLOCAL LVAL compare(fcn) X int fcn; X{ X FIXTYPE icmp,ival,iarg; X FLOTYPE fcmp,fval,farg; X LVAL arg; X int mode; X X /* get the first argument */ X arg = xlgetarg(); X X /* set the type of the first argument */ X if (fixp(arg)) { X ival = getfixnum(arg); X mode = 'I'; X } X else if (floatp(arg)) { X fval = getflonum(arg); X mode = 'F'; X } X else X xlbadtype(arg); X X /* handle each remaining argument */ X for (icmp = TRUE; icmp && moreargs(); ival = iarg, fval = farg) { X X /* get the next argument */ X arg = xlgetarg(); X X /* check its type */ X if (fixp(arg)) { X switch (mode) { X case 'I': X iarg = getfixnum(arg); X break; X case 'F': X farg = (FLOTYPE)getfixnum(arg); X break; X } X } X else if (floatp(arg)) { X switch (mode) { X case 'I': X fval = (FLOTYPE)ival; X farg = getflonum(arg); X mode = 'F'; X break; X case 'F': X farg = getflonum(arg); X break; X } X } X else X xlbadtype(arg); X X /* compute result of the compare */ X switch (mode) { X case 'I': X icmp = ival - iarg; X switch (fcn) { X case '<': icmp = (icmp < 0); break; X case 'L': icmp = (icmp <= 0); break; X case '=': icmp = (icmp == 0); break; X case 'G': icmp = (icmp >= 0); break; X case '>': icmp = (icmp > 0); break; X } X break; X case 'F': X fcmp = fval - farg; X switch (fcn) { X case '<': icmp = (fcmp < 0.0); break; X case 'L': icmp = (fcmp <= 0.0); break; X case '=': icmp = (fcmp == 0.0); break; X case 'G': icmp = (fcmp >= 0.0); break; X case '>': icmp = (fcmp > 0.0); break; X } X break; X } X } X X /* return the result */ X return (icmp ? true : NIL); X} X X/* toflotype - convert a lisp value to a floating point number */ XFLOTYPE toflotype(val) X LVAL val; X{ X /* must be a number for this to work */ X switch (ntype(val)) { X case FIXNUM: return ((FLOTYPE)getfixnum(val)); X case FLONUM: return (getflonum(val)); X } X} X X/* checkizero - check for integer division by zero */ Xcheckizero(iarg) X FIXTYPE iarg; X{ X if (iarg == 0) X xlfail("division by zero"); X} X X/* checkineg - check for square root of a negative number */ Xcheckineg(iarg) X FIXTYPE iarg; X{ X if (iarg < 0) X xlfail("square root of a negative number"); X} X X/* checkfzero - check for floating point division by zero */ Xcheckfzero(farg) X FLOTYPE farg; X{ X if (farg == 0.0) X xlfail("division by zero"); X} X X/* checkfneg - check for square root of a negative number */ Xcheckfneg(farg) X FLOTYPE farg; X{ X if (farg < 0.0) X xlfail("square root of a negative number"); X} X X/* badiop - bad integer operation */ XLOCAL badiop() X{ X xlfail("bad integer operation"); X} X X/* badfop - bad floating point operation */ XLOCAL badfop() X{ X xlfail("bad floating point operation"); X} END_OF_FILE if test 13437 -ne `wc -c <'Src/xsmath.c'`; then echo shar: \"'Src/xsmath.c'\" unpacked with wrong size! fi # end of 'Src/xsmath.c' fi echo shar: End of archive 3 \(of 7\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 7 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>. Mail comments to the moderator at <amiga-request@cs.odu.edu>. Post requests for sources, and general discussion to comp.sys.amiga.