v06i108: Xlisp version 1.6 (xlisp1.6), Part01/06
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Thu Aug 14 02:13:55 AEST 1986
Submitted by: seismo!utah-cs!b-davis (Brad Davis)
Mod.sources: Volume 6, Issue 108
Archive-name: xlisp1.6/Part01
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# xlfio.c
# xlftab.c
# xlglob.c
# xlinit.c
# xlio.c
# xlisp.c
# xljump.c
# xllist.c
# xlmath.c
# This archive created: Mon Jul 14 10:22:46 1986
export PATH; PATH=/bin:$PATH
if test -f 'xlfio.c'
then
echo shar: will not over-write existing file "'xlfio.c'"
else
cat << \SHAR_EOF > 'xlfio.c'
/* xlfio.c - xlisp file i/o */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
#ifdef MEGAMAX
overlay "io"
#endif
/* external variables */
extern NODE *s_stdin,*s_stdout,*true;
extern NODE ***xlstack;
extern int xlfsize;
extern char buf[];
/* external routines */
extern FILE *fopen();
/* forward declarations */
FORWARD NODE *printit();
FORWARD NODE *flatsize();
FORWARD NODE *openit();
/* xread - read an expression */
NODE *xread(args)
NODE *args;
{
NODE ***oldstk,*fptr,*eof,*rflag,*val;
/* create a new stack frame */
oldstk = xlsave(&fptr,&eof,(NODE **)NULL);
/* get file pointer and eof value */
fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
eof = (args ? xlarg(&args) : NIL);
rflag = (args ? xlarg(&args) : NIL);
xllastarg(args);
/* read an expression */
if (!xlread(fptr,&val,rflag != NIL))
val = eof;
/* restore the previous stack frame */
xlstack = oldstk;
/* return the expression */
return (val);
}
/* xprint - built-in function 'print' */
NODE *xprint(args)
NODE *args;
{
return (printit(args,TRUE,TRUE));
}
/* xprin1 - built-in function 'prin1' */
NODE *xprin1(args)
NODE *args;
{
return (printit(args,TRUE,FALSE));
}
/* xprinc - built-in function princ */
NODE *xprinc(args)
NODE *args;
{
return (printit(args,FALSE,FALSE));
}
/* xterpri - terminate the current print line */
NODE *xterpri(args)
NODE *args;
{
NODE *fptr;
/* get file pointer */
fptr = (args ? xlgetfile(&args) : getvalue(s_stdout));
xllastarg(args);
/* terminate the print line and return nil */
xlterpri(fptr);
return (NIL);
}
/* printit - common print function */
LOCAL NODE *printit(args,pflag,tflag)
NODE *args; int pflag,tflag;
{
NODE ***oldstk,*fptr,*val;
/* create a new stack frame */
oldstk = xlsave(&fptr,&val,(NODE **)NULL);
/* get expression to print and file pointer */
val = xlarg(&args);
fptr = (args ? xlgetfile(&args) : getvalue(s_stdout));
xllastarg(args);
/* print the value */
xlprint(fptr,val,pflag);
/* terminate the print line if necessary */
if (tflag)
xlterpri(fptr);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xflatsize - compute the size of a printed representation using prin1 */
NODE *xflatsize(args)
NODE *args;
{
return (flatsize(args,TRUE));
}
/* xflatc - compute the size of a printed representation using princ */
NODE *xflatc(args)
NODE *args;
{
return (flatsize(args,FALSE));
}
/* flatsize - compute the size of a printed expression */
LOCAL NODE *flatsize(args,pflag)
NODE *args; int pflag;
{
NODE ***oldstk,*val;
/* create a new stack frame */
oldstk = xlsave(&val,(NODE **)NULL);
/* get the expression */
val = xlarg(&args);
xllastarg(args);
/* print the value to compute its size */
xlfsize = 0;
xlprint(NIL,val,pflag);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the length of the expression */
return (cvfixnum((FIXNUM)xlfsize));
}
/* xopeni - open an input file */
NODE *xopeni(args)
NODE *args;
{
return (openit(args,"r"));
}
/* xopeno - open an output file */
NODE *xopeno(args)
NODE *args;
{
return (openit(args,"w"));
}
/* openit - common file open routine */
LOCAL NODE *openit(args,mode)
NODE *args; char *mode;
{
NODE *fname,*val;
char *name;
FILE *fp;
/* get the file name */
fname = xlarg(&args);
xllastarg(args);
/* get the name string */
if (symbolp(fname))
name = getstring(getpname(fname));
else if (stringp(fname))
name = getstring(fname);
else
xlfail("bad argument type",fname);
/* try to open the file */
if ((fp = fopen(name,mode)) != NULL)
val = cvfile(fp);
else
val = NIL;
/* return the file pointer */
return (val);
}
/* xclose - close a file */
NODE *xclose(args)
NODE *args;
{
NODE *fptr;
/* get file pointer */
fptr = xlmatch(FPTR,&args);
xllastarg(args);
/* make sure the file exists */
if (getfile(fptr) == NULL)
xlfail("file not open");
/* close the file */
fclose(getfile(fptr));
setfile(fptr,NULL);
/* return nil */
return (NIL);
}
/* xrdchar - read a character from a file */
NODE *xrdchar(args)
NODE *args;
{
NODE *fptr;
int ch;
/* get file pointer */
fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
xllastarg(args);
/* get character and check for eof */
return ((ch = xlgetc(fptr)) == EOF ? NIL : cvfixnum((FIXNUM)ch));
}
/* xpkchar - peek at a character from a file */
NODE *xpkchar(args)
NODE *args;
{
NODE *flag,*fptr;
int ch;
/* peek flag and get file pointer */
flag = (args ? xlarg(&args) : NIL);
fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
xllastarg(args);
/* skip leading white space and get a character */
if (flag)
while ((ch = xlpeek(fptr)) != EOF && isspace(ch))
xlgetc(fptr);
else
ch = xlpeek(fptr);
/* return the character */
return (ch == EOF ? NIL : cvfixnum((FIXNUM)ch));
}
/* xwrchar - write a character to a file */
NODE *xwrchar(args)
NODE *args;
{
NODE *fptr,*chr;
/* get the character and file pointer */
chr = xlmatch(INT,&args);
fptr = (args ? xlgetfile(&args) : getvalue(s_stdout));
xllastarg(args);
/* put character to the file */
xlputc(fptr,(int)getfixnum(chr));
/* return the character */
return (chr);
}
/* xreadline - read a line from a file */
NODE *xreadline(args)
NODE *args;
{
NODE ***oldstk,*fptr,*str,*newstr;
int len,blen,ch;
char *p,*sptr;
/* create a new stack frame */
oldstk = xlsave(&fptr,&str,(NODE **)NULL);
/* get file pointer */
fptr = (args ? xlgetfile(&args) : getvalue(s_stdin));
xllastarg(args);
/* get character and check for eof */
len = blen = 0; p = buf;
while ((ch = xlgetc(fptr)) != EOF && ch != '\n') {
/* check for buffer overflow */
if (blen >= STRMAX) {
newstr = newstring(len+STRMAX);
sptr = getstring(newstr); *sptr = 0;
if (str) strcat(sptr,getstring(str));
*p = 0; strcat(sptr,buf);
p = buf; blen = 0;
len += STRMAX;
str = newstr;
}
/* store the character */
*p++ = ch; blen++;
}
/* check for end of file */
if (len == 0 && p == buf && ch == EOF) {
xlstack = oldstk;
return (NIL);
}
/* append the last substring */
if (str == NIL || blen) {
newstr = newstring(len+blen);
sptr = getstring(newstr); *sptr = 0;
if (str) strcat(sptr,getstring(str));
*p = 0; strcat(sptr,buf);
str = newstr;
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the string */
return (str);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'xlftab.c'
then
echo shar: will not over-write existing file "'xlftab.c'"
else
cat << \SHAR_EOF > 'xlftab.c'
/* xlftab.c - xlisp function table */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* external functions */
extern NODE
*xeval(),*xapply(),*xfuncall(),*xquote(),*xfunction(),*xbquote(),
*xlambda(),*xset(),*xsetq(),*xsetf(),*xdefun(),*xdefmacro(),
*xgensym(),*xmakesymbol(),*xintern(),
*xsymname(),*xsymvalue(),*xsymplist(),*xget(),*xputprop(),*xremprop(),
*xhash(),*xmkarray(),*xaref(),
*xcar(),*xcdr(),
*xcaar(),*xcadr(),*xcdar(),*xcddr(),
*xcaaar(),*xcaadr(),*xcadar(),*xcaddr(),
*xcdaar(),*xcdadr(),*xcddar(),*xcdddr(),
*xcaaaar(),*xcaaadr(),*xcaadar(),*xcaaddr(),
*xcadaar(),*xcadadr(),*xcaddar(),*xcadddr(),
*xcdaaar(),*xcdaadr(),*xcdadar(),*xcdaddr(),
*xcddaar(),*xcddadr(),*xcdddar(),*xcddddr(),
*xcons(),*xlist(),*xappend(),*xreverse(),*xlast(),*xnth(),*xnthcdr(),
*xmember(),*xassoc(),*xsubst(),*xsublis(),*xremove(),*xlength(),
*xmapc(),*xmapcar(),*xmapl(),*xmaplist(),
*xrplca(),*xrplcd(),*xnconc(),*xdelete(),
*xatom(),*xsymbolp(),*xnumberp(),*xboundp(),*xnull(),*xlistp(),*xconsp(),
*xeq(),*xeql(),*xequal(),
*xcond(),*xcase(),*xand(),*xor(),*xlet(),*xletstar(),*xif(),
*xprog(),*xprogstar(),*xprog1(),*xprog2(),*xprogn(),*xgo(),*xreturn(),
*xcatch(),*xthrow(),
*xerror(),*xcerror(),*xbreak(),*xcleanup(),*xcontinue(),*xerrset(),
*xbaktrace(),*xevalhook(),
*xdo(),*xdostar(),*xdolist(),*xdotimes(),
*xminusp(),*xzerop(),*xplusp(),*xevenp(),*xoddp(),
*xfix(),*xfloat(),
*xadd(),*xsub(),*xmul(),*xdiv(),*xrem(),*xmin(),*xmax(),*xabs(),
*xadd1(),*xsub1(),*xbitand(),*xbitior(),*xbitxor(),*xbitnot(),
*xsin(),*xcos(),*xtan(),*xexpt(),*xexp(),*xsqrt(),*xrand(),
*xlss(),*xleq(),*xequ(),*xneq(),*xgeq(),*xgtr(),
*xstrcat(),*xsubstr(),*xstring(),*xchar(),
*xread(),*xprint(),*xprin1(),*xprinc(),*xterpri(),
*xflatsize(),*xflatc(),
*xopeni(),*xopeno(),*xclose(),*xrdchar(),*xpkchar(),*xwrchar(),*xreadline(),
*xload(),*xgc(),*xexpand(),*xalloc(),*xmem(),*xtype(),*xexit();
/* the function table */
struct fdef ftab[] = {
/* evaluator functions */
{ "EVAL", SUBR, xeval },
{ "APPLY", SUBR, xapply },
{ "FUNCALL", SUBR, xfuncall },
{ "QUOTE", FSUBR, xquote },
{ "FUNCTION", FSUBR, xfunction },
{ "BACKQUOTE", FSUBR, xbquote },
{ "LAMBDA", FSUBR, xlambda },
/* symbol functions */
{ "SET", SUBR, xset },
{ "SETQ", FSUBR, xsetq },
{ "SETF", FSUBR, xsetf },
{ "DEFUN", FSUBR, xdefun },
{ "DEFMACRO", FSUBR, xdefmacro },
{ "GENSYM", SUBR, xgensym },
{ "MAKE-SYMBOL", SUBR, xmakesymbol },
{ "INTERN", SUBR, xintern },
{ "SYMBOL-NAME", SUBR, xsymname },
{ "SYMBOL-VALUE", SUBR, xsymvalue },
{ "SYMBOL-PLIST", SUBR, xsymplist },
{ "GET", SUBR, xget },
{ "PUTPROP", SUBR, xputprop },
{ "REMPROP", SUBR, xremprop },
{ "HASH", SUBR, xhash },
/* array functions */
{ "MAKE-ARRAY", SUBR, xmkarray },
{ "AREF", SUBR, xaref },
/* list functions */
{ "CAR", SUBR, xcar },
{ "CDR", SUBR, xcdr },
{ "CAAR", SUBR, xcaar },
{ "CADR", SUBR, xcadr },
{ "CDAR", SUBR, xcdar },
{ "CDDR", SUBR, xcddr },
{ "CAAAR", SUBR, xcaaar },
{ "CAADR", SUBR, xcaadr },
{ "CADAR", SUBR, xcadar },
{ "CADDR", SUBR, xcaddr },
{ "CDAAR", SUBR, xcdaar },
{ "CDADR", SUBR, xcdadr },
{ "CDDAR", SUBR, xcddar },
{ "CDDDR", SUBR, xcdddr },
{ "CAAAAR", SUBR, xcaaaar },
{ "CAAADR", SUBR, xcaaadr },
{ "CAADAR", SUBR, xcaadar },
{ "CAADDR", SUBR, xcaaddr },
{ "CADAAR", SUBR, xcadaar },
{ "CADADR", SUBR, xcadadr },
{ "CADDAR", SUBR, xcaddar },
{ "CADDDR", SUBR, xcadddr },
{ "CDAAAR", SUBR, xcdaaar },
{ "CDAADR", SUBR, xcdaadr },
{ "CDADAR", SUBR, xcdadar },
{ "CDADDR", SUBR, xcdaddr },
{ "CDDAAR", SUBR, xcddaar },
{ "CDDADR", SUBR, xcddadr },
{ "CDDDAR", SUBR, xcdddar },
{ "CDDDDR", SUBR, xcddddr },
{ "CONS", SUBR, xcons },
{ "LIST", SUBR, xlist },
{ "APPEND", SUBR, xappend },
{ "REVERSE", SUBR, xreverse },
{ "LAST", SUBR, xlast },
{ "NTH", SUBR, xnth },
{ "NTHCDR", SUBR, xnthcdr },
{ "MEMBER", SUBR, xmember },
{ "ASSOC", SUBR, xassoc },
{ "SUBST", SUBR, xsubst },
{ "SUBLIS", SUBR, xsublis },
{ "REMOVE", SUBR, xremove },
{ "LENGTH", SUBR, xlength },
{ "MAPC", SUBR, xmapc },
{ "MAPCAR", SUBR, xmapcar },
{ "MAPL", SUBR, xmapl },
{ "MAPLIST", SUBR, xmaplist },
/* destructive list functions */
{ "RPLACA", SUBR, xrplca },
{ "RPLACD", SUBR, xrplcd },
{ "NCONC", SUBR, xnconc },
{ "DELETE", SUBR, xdelete },
/* predicate functions */
{ "ATOM", SUBR, xatom },
{ "SYMBOLP", SUBR, xsymbolp },
{ "NUMBERP", SUBR, xnumberp },
{ "BOUNDP", SUBR, xboundp },
{ "NULL", SUBR, xnull },
{ "NOT", SUBR, xnull },
{ "LISTP", SUBR, xlistp },
{ "CONSP", SUBR, xconsp },
{ "MINUSP", SUBR, xminusp },
{ "ZEROP", SUBR, xzerop },
{ "PLUSP", SUBR, xplusp },
{ "EVENP", SUBR, xevenp },
{ "ODDP", SUBR, xoddp },
{ "EQ", SUBR, xeq },
{ "EQL", SUBR, xeql },
{ "EQUAL", SUBR, xequal },
/* control functions */
{ "COND", FSUBR, xcond },
{ "CASE", FSUBR, xcase },
{ "AND", FSUBR, xand },
{ "OR", FSUBR, xor },
{ "LET", FSUBR, xlet },
{ "LET*", FSUBR, xletstar },
{ "IF", FSUBR, xif },
{ "PROG", FSUBR, xprog },
{ "PROG*", FSUBR, xprogstar },
{ "PROG1", FSUBR, xprog1 },
{ "PROG2", FSUBR, xprog2 },
{ "PROGN", FSUBR, xprogn },
{ "GO", FSUBR, xgo },
{ "RETURN", SUBR, xreturn },
{ "DO", FSUBR, xdo },
{ "DO*", FSUBR, xdostar },
{ "DOLIST", FSUBR, xdolist },
{ "DOTIMES", FSUBR, xdotimes },
{ "CATCH", FSUBR, xcatch },
{ "THROW", SUBR, xthrow },
/* debugging and error handling functions */
{ "ERROR", SUBR, xerror },
{ "CERROR", SUBR, xcerror },
{ "BREAK", SUBR, xbreak },
{ "CLEAN-UP", SUBR, xcleanup },
{ "CONTINUE", SUBR, xcontinue },
{ "ERRSET", FSUBR, xerrset },
{ "BAKTRACE", SUBR, xbaktrace },
{ "EVALHOOK", SUBR, xevalhook },
/* arithmetic functions */
{ "TRUNCATE", SUBR, xfix },
{ "FLOAT", SUBR, xfloat },
{ "+", SUBR, xadd },
{ "-", SUBR, xsub },
{ "*", SUBR, xmul },
{ "/", SUBR, xdiv },
{ "1+", SUBR, xadd1 },
{ "1-", SUBR, xsub1 },
{ "REM", SUBR, xrem },
{ "MIN", SUBR, xmin },
{ "MAX", SUBR, xmax },
{ "ABS", SUBR, xabs },
{ "SIN", SUBR, xsin },
{ "COS", SUBR, xcos },
{ "TAN", SUBR, xtan },
{ "EXPT", SUBR, xexpt },
{ "EXP", SUBR, xexp },
{ "SQRT", SUBR, xsqrt },
{ "RANDOM", SUBR, xrand },
/* bitwise logical functions */
{ "BIT-AND", SUBR, xbitand },
{ "BIT-IOR", SUBR, xbitior },
{ "BIT-XOR", SUBR, xbitxor },
{ "BIT-NOT", SUBR, xbitnot },
/* numeric comparison functions */
{ "<", SUBR, xlss },
{ "<=", SUBR, xleq },
{ "=", SUBR, xequ },
{ "/=", SUBR, xneq },
{ ">=", SUBR, xgeq },
{ ">", SUBR, xgtr },
/* string functions */
{ "STRCAT", SUBR, xstrcat },
{ "SUBSTR", SUBR, xsubstr },
{ "STRING", SUBR, xstring },
{ "CHAR", SUBR, xchar },
/* I/O functions */
{ "READ", SUBR, xread },
{ "PRINT", SUBR, xprint },
{ "PRIN1", SUBR, xprin1 },
{ "PRINC", SUBR, xprinc },
{ "TERPRI", SUBR, xterpri },
{ "FLATSIZE", SUBR, xflatsize },
{ "FLATC", SUBR, xflatc },
/* file I/O functions */
{ "OPENI", SUBR, xopeni },
{ "OPENO", SUBR, xopeno },
{ "CLOSE", SUBR, xclose },
{ "READ-CHAR", SUBR, xrdchar },
{ "PEEK-CHAR", SUBR, xpkchar },
{ "WRITE-CHAR", SUBR, xwrchar },
{ "READ-LINE", SUBR, xreadline },
/* system functions */
{ "LOAD", SUBR, xload },
{ "GC", SUBR, xgc },
{ "EXPAND", SUBR, xexpand },
{ "ALLOC", SUBR, xalloc },
{ "MEM", SUBR, xmem },
{ "TYPE-OF", SUBR, xtype },
{ "EXIT", SUBR, xexit },
{ 0 }
};
SHAR_EOF
fi # end of overwriting check
if test -f 'xlglob.c'
then
echo shar: will not over-write existing file "'xlglob.c'"
else
cat << \SHAR_EOF > 'xlglob.c'
/* xlglobals - xlisp global variables */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* symbols */
NODE *true = NIL, *s_dot = NIL;
NODE *s_quote = NIL, *s_function = NIL;
NODE *s_bquote = NIL, *s_comma = NIL, *s_comat = NIL;
NODE *s_evalhook = NIL, *s_applyhook = NIL;
NODE *s_lambda = NIL, *s_macro = NIL;
NODE *s_stdin = NIL, *s_stdout = NIL, *s_rtable = NIL;
NODE *s_tracenable = NIL, *s_tlimit = NIL, *s_breakenable = NIL;
NODE *s_car = NIL, *s_cdr = NIL, *s_nth = NIL;
NODE *s_get = NIL, *s_svalue = NIL, *s_splist = NIL, *s_aref = NIL;
NODE *s_eql = NIL, *k_test = NIL, *k_tnot = NIL;
NODE *k_wspace = NIL, *k_const = NIL, *k_nmacro = NIL, *k_tmacro = NIL;
NODE *k_optional = NIL, *k_rest = NIL, *k_aux = NIL;
NODE *a_subr = NIL, *a_fsubr = NIL;
NODE *a_list = NIL, *a_sym = NIL, *a_int = NIL, *a_float = NIL;
NODE *a_str = NIL, *a_obj = NIL, *a_fptr = NIL, *a_vect;
NODE *obarray = NIL, *s_unbound = NIL;
/* evaluation variables */
NODE ***xlstack = NULL, ***xlstkbase = NULL, ***xlstktop = NULL;
NODE *xlenv = NIL;
/* exception handling variables */
CONTEXT *xlcontext = NULL; /* current exception handler */
NODE *xlvalue = NIL; /* exception value */
/* debugging variables */
int xldebug = 0; /* debug level */
int xltrace = -1; /* trace stack pointer */
NODE **trace_stack = NULL; /* trace stack */
int xlsample = 0; /* control character sample rate */
/* gensym variables */
char gsprefix[STRMAX+1] = { 'G',0 }; /* gensym prefix string */
int gsnumber = 1; /* gensym number */
/* i/o variables */
int prompt = TRUE; /* prompt flag */
int xlplevel = 0; /* paren nesting level */
int xlfsize = 0; /* flat size of current print call */
/* dynamic memory variables */
long total = 0L; /* total memory in use */
int anodes = 0; /* number of nodes to allocate */
int nnodes = 0; /* number of nodes allocated */
int nsegs = 0; /* number of segments allocated */
int nfree = 0; /* number of nodes free */
int gccalls = 0; /* number of gc calls */
struct segment *segs = NULL; /* list of allocated segments */
NODE *fnodes = NIL; /* list of free nodes */
/* object programming variables */
NODE *self = NIL, *class = NIL, *object = NIL;
NODE *new = NIL, *isnew = NIL, *msgcls = NIL, *msgclass = NIL;
/* general purpose string buffer */
char buf[STRMAX+1] = { 0 };
SHAR_EOF
fi # end of overwriting check
if test -f 'xlinit.c'
then
echo shar: will not over-write existing file "'xlinit.c'"
else
cat << \SHAR_EOF > 'xlinit.c'
/* xlinit.c - xlisp initialization module */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* external variables */
extern NODE *true,*s_dot;
extern NODE *s_quote,*s_function,*s_bquote,*s_comma,*s_comat;
extern NODE *s_lambda,*s_macro;
extern NODE *s_stdin,*s_stdout;
extern NODE *s_evalhook,*s_applyhook;
extern NODE *s_tracenable,*s_tlimit,*s_breakenable;
extern NODE *s_car,*s_cdr,*s_nth,*s_get,*s_svalue,*s_splist,*s_aref,*s_eql;
extern NODE *s_rtable,*k_wspace,*k_const,*k_nmacro,*k_tmacro;
extern NODE *k_test,*k_tnot,*k_optional,*k_rest,*k_aux;
extern NODE *a_subr,*a_fsubr;
extern NODE *a_list,*a_sym,*a_int,*a_float,*a_str,*a_obj,*a_fptr,*a_vect;
extern struct fdef ftab[];
/* xlinit - xlisp initialization routine */
xlinit()
{
struct fdef *fptr;
NODE *sym;
/* initialize xlisp (must be in this order) */
xlminit(); /* initialize xldmem.c */
xlsinit(); /* initialize xlsym.c */
xldinit(); /* initialize xldbug.c */
xloinit(); /* initialize xlobj.c */
/* enter the builtin functions */
for (fptr = ftab; fptr->f_name; fptr++)
xlsubr(fptr->f_name,fptr->f_type,fptr->f_fcn);
/* enter operating system specific functions */
osfinit();
/* enter the 't' symbol */
true = xlsenter("T");
setvalue(true,true);
/* enter some important symbols */
s_dot = xlsenter(".");
s_quote = xlsenter("QUOTE");
s_function = xlsenter("FUNCTION");
s_bquote = xlsenter("BACKQUOTE");
s_comma = xlsenter("COMMA");
s_comat = xlsenter("COMMA-AT");
s_lambda = xlsenter("LAMBDA");
s_macro = xlsenter("MACRO");
s_eql = xlsenter("EQL");
/* enter setf place specifiers */
s_car = xlsenter("CAR");
s_cdr = xlsenter("CDR");
s_nth = xlsenter("NTH");
s_get = xlsenter("GET");
s_svalue = xlsenter("SYMBOL-VALUE");
s_splist = xlsenter("SYMBOL-PLIST");
s_aref = xlsenter("AREF");
/* enter the readtable variable and keywords */
s_rtable = xlsenter("*READTABLE*");
k_wspace = xlsenter(":WHITE-SPACE");
k_const = xlsenter(":CONSTITUENT");
k_nmacro = xlsenter(":NMACRO");
k_tmacro = xlsenter(":TMACRO");
xlrinit();
/* enter parameter list keywords */
k_test = xlsenter(":TEST");
k_tnot = xlsenter(":TEST-NOT");
/* enter lambda list keywords */
k_optional = xlsenter("&OPTIONAL");
k_rest = xlsenter("&REST");
k_aux = xlsenter("&AUX");
/* enter *standard-input* and *standard-output* */
s_stdin = xlsenter("*STANDARD-INPUT*");
setvalue(s_stdin,cvfile(stdin));
s_stdout = xlsenter("*STANDARD-OUTPUT*");
setvalue(s_stdout,cvfile(stdout));
/* enter the eval and apply hook variables */
s_evalhook = xlsenter("*EVALHOOK*");
setvalue(s_evalhook,NIL);
s_applyhook = xlsenter("*APPLYHOOK*");
setvalue(s_applyhook,NIL);
/* enter the error traceback and the error break enable flags */
s_tracenable = xlsenter("*TRACENABLE*");
setvalue(s_tracenable,NIL);
s_tlimit = xlsenter("*TRACELIMIT*");
setvalue(s_tlimit,NIL);
s_breakenable = xlsenter("*BREAKENABLE*");
setvalue(s_breakenable,true);
/* enter a copyright notice into the oblist */
sym = xlsenter("**Copyright-1985-by-David-Betz**");
setvalue(sym,true);
/* enter type names */
a_subr = xlsenter(":SUBR");
a_fsubr = xlsenter(":FSUBR");
a_list = xlsenter(":CONS");
a_sym = xlsenter(":SYMBOL");
a_int = xlsenter(":FIXNUM");
a_float = xlsenter(":FLONUM");
a_str = xlsenter(":STRING");
a_obj = xlsenter(":OBJECT");
a_fptr = xlsenter(":FILE");
a_vect = xlsenter(":ARRAY");
}
SHAR_EOF
fi # end of overwriting check
if test -f 'xlio.c'
then
echo shar: will not over-write existing file "'xlio.c'"
else
cat << \SHAR_EOF > 'xlio.c'
/* xlio - xlisp i/o routines */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
#ifdef MEGAMAX
overlay "io"
#endif
/* external variables */
extern NODE ***xlstack;
extern NODE *s_stdin,*s_unbound;
extern int xlfsize;
extern int xlplevel;
extern int xldebug;
extern int prompt;
extern char buf[];
/* xlgetc - get a character from a file or stream */
int xlgetc(fptr)
NODE *fptr;
{
NODE *lptr,*cptr;
FILE *fp;
int ch;
/* check for input from nil */
if (fptr == NIL)
ch = EOF;
/* otherwise, check for input from a stream */
else if (consp(fptr)) {
if ((lptr = car(fptr)) == NIL)
ch = EOF;
else {
if (!consp(lptr) ||
(cptr = car(lptr)) == NIL || !fixp(cptr))
xlfail("bad stream");
if (rplaca(fptr,cdr(lptr)) == NIL)
rplacd(fptr,NIL);
ch = getfixnum(cptr);
}
}
/* otherwise, check for a buffered file character */
else if (ch = getsavech(fptr))
setsavech(fptr,0);
/* otherwise, get a new character */
else {
/* get the file pointer */
fp = getfile(fptr);
/* prompt if necessary */
if (prompt && fp == stdin) {
/* print the debug level */
if (xldebug)
{ sprintf(buf,"%d:",xldebug); stdputstr(buf); }
/* print the nesting level */
if (xlplevel > 0)
{ sprintf(buf,"%d",xlplevel); stdputstr(buf); }
/* print the prompt */
stdputstr("> ");
prompt = FALSE;
}
/* get the character */
if (((ch = osgetc(fp)) == '\n' || ch == EOF) && fp == stdin)
prompt = TRUE;
}
/* return the character */
return (ch);
}
/* docommand - create a nested MS-DOS shell */
#ifdef SYSTEM
docommand()
{
stdputstr("\n[ creating a nested command processor ]\n");
system("COMMAND");
stdputstr("[ returning to XLISP ]\n");
}
#endif
/* xlpeek - peek at a character from a file or stream */
int xlpeek(fptr)
NODE *fptr;
{
NODE *lptr,*cptr;
int ch;
/* check for input from nil */
if (fptr == NIL)
ch = EOF;
/* otherwise, check for input from a stream */
else if (consp(fptr)) {
if ((lptr = car(fptr)) == NIL)
ch = EOF;
else {
if (!consp(lptr) ||
(cptr = car(lptr)) == NIL || !fixp(cptr))
xlfail("bad stream");
ch = getfixnum(cptr);
}
}
/* otherwise, get the next file character and save it */
else
setsavech(fptr,ch = xlgetc(fptr));
/* return the character */
return (ch);
}
/* xlputc - put a character to a file or stream */
xlputc(fptr,ch)
NODE *fptr; int ch;
{
NODE ***oldstk,*lptr;
/* count the character */
xlfsize++;
/* check for output to nil */
if (fptr == NIL)
;
/* otherwise, check for output to a stream */
else if (consp(fptr)) {
oldstk = xlsave(&lptr,(NODE **)NULL);
lptr = consa(NIL);
rplaca(lptr,cvfixnum((FIXNUM)ch));
if (cdr(fptr))
rplacd(cdr(fptr),lptr);
else
rplaca(fptr,lptr);
rplacd(fptr,lptr);
xlstack = oldstk;
}
/* otherwise, output the character to a file */
else
osputc(ch,getfile(fptr));
}
/* xlflush - flush the input buffer */
int xlflush()
{
if (!prompt)
while (xlgetc(getvalue(s_stdin)) != '\n')
;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'xlisp.c'
then
echo shar: will not over-write existing file "'xlisp.c'"
else
cat << \SHAR_EOF > 'xlisp.c'
/* xlisp - a small implementation of lisp with object-oriented programming */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* define the banner line string */
#define BANNER "XLISP version 1.6, Copyright (c) 1985, by David Betz"
/* external variables */
extern NODE *s_stdin,*s_stdout;
extern NODE *s_evalhook,*s_applyhook;
extern int xldebug;
extern NODE *true;
/* main - the main routine */
main(argc,argv)
int argc; char *argv[];
{
CONTEXT cntxt;
NODE *expr;
int i;
/* initialize and print the banner line */
osinit(BANNER);
/* setup initialization error handler */
xlbegin(&cntxt,CF_TOPLEVEL|CF_ERROR,(NODE *) 1);
if (setjmp(cntxt.c_jmpbuf)) {
printf("fatal initialization error\n");
osfinish();
exit(1);
}
/* initialize xlisp */
xlinit();
xlend(&cntxt);
/* reset the error handler */
xlbegin(&cntxt,CF_TOPLEVEL|CF_ERROR,true);
/* load "init.lsp" */
if (setjmp(cntxt.c_jmpbuf) == 0)
xlload("init.lsp",FALSE,FALSE);
/* load any files mentioned on the command line */
#ifndef MEGAMAX
if (setjmp(cntxt.c_jmpbuf) == 0)
for (i = 1; i < argc; i++)
if (!xlload(argv[i],TRUE,FALSE))
xlfail("can't load file");
#endif
/* create a new stack frame */
xlsave(&expr,(NODE **)NULL);
/* main command processing loop */
while (TRUE) {
/* setup the error return */
if (i = setjmp(cntxt.c_jmpbuf)) {
if (i == CF_TOPLEVEL)
stdputstr("[ back to the top level ]\n");
setvalue(s_evalhook,NIL);
setvalue(s_applyhook,NIL);
xldebug = 0;
xlflush();
}
/* read an expression */
if (!xlread(getvalue(s_stdin),&expr,FALSE))
break;
/* evaluate the expression */
expr = xleval(expr);
/* print it */
stdprint(expr);
}
xlend(&cntxt);
osfinish ();
exit (0);
}
/* stdprint - print to standard output */
stdprint(expr)
NODE *expr;
{
xlprint(getvalue(s_stdout),expr,TRUE);
xlterpri(getvalue(s_stdout));
}
/* stdputstr - print a string to standard output */
stdputstr(str)
char *str;
{
xlputstr(getvalue(s_stdout),str);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'xljump.c'
then
echo shar: will not over-write existing file "'xljump.c'"
else
cat << \SHAR_EOF > 'xljump.c'
/* xljump - execution context routines */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* external variables */
extern CONTEXT *xlcontext;
extern NODE *xlvalue;
extern NODE ***xlstack,*xlenv;
extern int xltrace,xldebug;
/* xlbegin - beginning of an execution context */
xlbegin(cptr,flags,expr)
CONTEXT *cptr; int flags; NODE *expr;
{
cptr->c_flags = flags;
cptr->c_expr = expr;
cptr->c_xlstack = xlstack;
cptr->c_xlenv = xlenv;
cptr->c_xltrace = xltrace;
cptr->c_xlcontext = xlcontext;
xlcontext = cptr;
}
/* xlend - end of an execution context */
xlend(cptr)
CONTEXT *cptr;
{
xlcontext = cptr->c_xlcontext;
}
/* xljump - jump to a saved execution context */
xljump(cptr,type,val)
CONTEXT *cptr; int type; NODE *val;
{
/* restore the state */
xlcontext = cptr;
xlstack = xlcontext->c_xlstack;
xlenv = xlcontext->c_xlenv;
xltrace = xlcontext->c_xltrace;
xlvalue = val;
/* call the handler */
longjmp(xlcontext->c_jmpbuf,type);
}
/* xltoplevel - go back to the top level */
xltoplevel()
{
findtarget(CF_TOPLEVEL,"no top level");
}
/* xlcleanup - clean-up after an error */
xlcleanup()
{
findtarget(CF_CLEANUP,"not in a break loop");
}
/* xlcontinue - continue from an error */
xlcontinue()
{
findtarget(CF_CONTINUE,"not in a break loop");
}
/* xlgo - go to a label */
xlgo(label)
NODE *label;
{
CONTEXT *cptr;
NODE *p;
/* find a tagbody context */
for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
if (cptr->c_flags & CF_GO)
for (p = cptr->c_expr; consp(p); p = cdr(p))
if (car(p) == label)
xljump(cptr,CF_GO,p);
xlfail("no target for GO");
}
/* xlreturn - return from a block */
xlreturn(val)
NODE *val;
{
CONTEXT *cptr;
/* find a block context */
for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
if (cptr->c_flags & CF_RETURN)
xljump(cptr,CF_RETURN,val);
xlfail("no target for RETURN");
}
/* xlthrow - throw to a catch */
xlthrow(tag,val)
NODE *tag,*val;
{
CONTEXT *cptr;
/* find a catch context */
for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
if ((cptr->c_flags & CF_THROW) && cptr->c_expr == tag)
xljump(cptr,CF_THROW,val);
xlfail("no target for THROW");
}
/* xlsignal - signal an error */
xlsignal(emsg,arg)
char *emsg; NODE *arg;
{
CONTEXT *cptr;
/* find an error catcher */
for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
if (cptr->c_flags & CF_ERROR) {
if (cptr->c_expr && emsg)
xlerrprint("error",NULL,emsg,arg);
xljump(cptr,CF_ERROR,NIL);
}
xlfail("no target for error");
}
/* findtarget - find a target context frame */
LOCAL findtarget(flag,error)
int flag; char *error;
{
CONTEXT *cptr;
/* find a block context */
for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
if (cptr->c_flags & flag)
xljump(cptr,flag,NIL);
xlabort(error);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'xllist.c'
then
echo shar: will not over-write existing file "'xllist.c'"
else
cat << \SHAR_EOF > 'xllist.c'
/* xllist - xlisp built-in list functions */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
#ifdef MEGAMAX
overlay "overflow"
#endif
/* external variables */
extern NODE ***xlstack;
extern NODE *s_unbound;
extern NODE *true;
/* external routines */
extern int eq(),eql(),equal();
/* forward declarations */
FORWARD NODE *cxr();
FORWARD NODE *nth(),*assoc();
FORWARD NODE *subst(),*sublis(),*map();
FORWARD NODE *cequal();
/* cxr functions */
NODE *xcar(args) NODE *args; { return (cxr(args,"a")); }
NODE *xcdr(args) NODE *args; { return (cxr(args,"d")); }
/* cxxr functions */
NODE *xcaar(args) NODE *args; { return (cxr(args,"aa")); }
NODE *xcadr(args) NODE *args; { return (cxr(args,"da")); }
NODE *xcdar(args) NODE *args; { return (cxr(args,"ad")); }
NODE *xcddr(args) NODE *args; { return (cxr(args,"dd")); }
/* cxxxr functions */
NODE *xcaaar(args) NODE *args; { return (cxr(args,"aaa")); }
NODE *xcaadr(args) NODE *args; { return (cxr(args,"daa")); }
NODE *xcadar(args) NODE *args; { return (cxr(args,"ada")); }
NODE *xcaddr(args) NODE *args; { return (cxr(args,"dda")); }
NODE *xcdaar(args) NODE *args; { return (cxr(args,"aad")); }
NODE *xcdadr(args) NODE *args; { return (cxr(args,"dad")); }
NODE *xcddar(args) NODE *args; { return (cxr(args,"add")); }
NODE *xcdddr(args) NODE *args; { return (cxr(args,"ddd")); }
/* cxxxxr functions */
NODE *xcaaaar(args) NODE *args; { return (cxr(args,"aaaa")); }
NODE *xcaaadr(args) NODE *args; { return (cxr(args,"daaa")); }
NODE *xcaadar(args) NODE *args; { return (cxr(args,"adaa")); }
NODE *xcaaddr(args) NODE *args; { return (cxr(args,"ddaa")); }
NODE *xcadaar(args) NODE *args; { return (cxr(args,"aada")); }
NODE *xcadadr(args) NODE *args; { return (cxr(args,"dada")); }
NODE *xcaddar(args) NODE *args; { return (cxr(args,"adda")); }
NODE *xcadddr(args) NODE *args; { return (cxr(args,"ddda")); }
NODE *xcdaaar(args) NODE *args; { return (cxr(args,"aaad")); }
NODE *xcdaadr(args) NODE *args; { return (cxr(args,"daad")); }
NODE *xcdadar(args) NODE *args; { return (cxr(args,"adad")); }
NODE *xcdaddr(args) NODE *args; { return (cxr(args,"ddad")); }
NODE *xcddaar(args) NODE *args; { return (cxr(args,"aadd")); }
NODE *xcddadr(args) NODE *args; { return (cxr(args,"dadd")); }
NODE *xcdddar(args) NODE *args; { return (cxr(args,"addd")); }
NODE *xcddddr(args) NODE *args; { return (cxr(args,"dddd")); }
/* cxr - common car/cdr routine */
LOCAL NODE *cxr(args,adstr)
NODE *args; char *adstr;
{
NODE *list;
/* get the list */
list = xlmatch(LIST,&args);
xllastarg(args);
/* perform the car/cdr operations */
while (*adstr && consp(list))
list = (*adstr++ == 'a' ? car(list) : cdr(list));
/* make sure the operation succeeded */
if (*adstr && list)
xlfail("bad argument");
/* return the result */
return (list);
}
/* xcons - construct a new list cell */
NODE *xcons(args)
NODE *args;
{
NODE *arg1,*arg2;
/* get the two arguments */
arg1 = xlarg(&args);
arg2 = xlarg(&args);
xllastarg(args);
/* construct a new list element */
return (cons(arg1,arg2));
}
/* xlist - built a list of the arguments */
NODE *xlist(args)
NODE *args;
{
NODE ***oldstk,*arg,*list,*val,*last;
NODE *lptr = NIL;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,&val,(NODE **)NULL);
/* initialize */
arg = args;
/* evaluate and append each argument */
for (last = NIL; arg; last = lptr) {
/* evaluate the next argument */
val = xlarg(&arg);
/* append this argument to the end of the list */
lptr = consa(val);
if (last == NIL)
list = lptr;
else
rplacd(last,lptr);
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the list */
return (list);
}
/* xappend - built-in function append */
NODE *xappend(args)
NODE *args;
{
NODE ***oldstk,*arg,*list,*last,*val,*lptr;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,&last,&val,(NODE **)NULL);
/* initialize */
arg = args;
/* evaluate and append each argument */
while (arg) {
/* evaluate the next argument */
list = xlmatch(LIST,&arg);
/* append each element of this list to the result list */
while (consp(list)) {
/* append this element */
lptr = consa(car(list));
if (last == NIL)
val = lptr;
else
rplacd(last,lptr);
/* save the new last element */
last = lptr;
/* move to the next element */
list = cdr(list);
}
}
/* restore previous stack frame */
xlstack = oldstk;
/* return the list */
return (val);
}
/* xreverse - built-in function reverse */
NODE *xreverse(args)
NODE *args;
{
NODE ***oldstk,*list,*val;
/* create a new stack frame */
oldstk = xlsave(&list,&val,(NODE **)NULL);
/* get the list to reverse */
list = xlmatch(LIST,&args);
xllastarg(args);
/* append each element of this list to the result list */
while (consp(list)) {
/* append this element */
val = cons(car(list),val);
/* move to the next element */
list = cdr(list);
}
/* restore previous stack frame */
xlstack = oldstk;
/* return the list */
return (val);
}
/* xlast - return the last cons of a list */
NODE *xlast(args)
NODE *args;
{
NODE *list;
/* get the list */
list = xlmatch(LIST,&args);
xllastarg(args);
/* find the last cons */
while (consp(list) && cdr(list))
list = cdr(list);
/* return the last element */
return (list);
}
/* xmember - built-in function 'member' */
NODE *xmember(args)
NODE *args;
{
NODE ***oldstk,*x,*list,*fcn,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&x,&list,&fcn,(NODE **)NULL);
/* get the expression to look for and the list */
x = xlarg(&args);
list = xlmatch(LIST,&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* look for the expression */
for (val = NIL; consp(list); list = cdr(list))
if (dotest(x,car(list),fcn) == tresult) {
val = list;
break;
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xassoc - built-in function 'assoc' */
NODE *xassoc(args)
NODE *args;
{
NODE ***oldstk,*x,*alist,*fcn,*pair,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&x,&alist,&fcn,(NODE **)NULL);
/* get the expression to look for and the association list */
x = xlarg(&args);
alist = xlmatch(LIST,&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* look for the expression */
for (val = NIL; consp(alist); alist = cdr(alist))
if ((pair = car(alist)) && consp(pair))
if (dotest(x,car(pair),fcn) == tresult) {
val = pair;
break;
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xsubst - substitute one expression for another */
NODE *xsubst(args)
NODE *args;
{
NODE ***oldstk,*to,*from,*expr,*fcn,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&to,&from,&expr,&fcn,(NODE **)NULL);
/* get the to value, the from value and the expression */
to = xlarg(&args);
from = xlarg(&args);
expr = xlarg(&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* do the substitution */
val = subst(to,from,expr,fcn,tresult);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* subst - substitute one expression for another */
LOCAL NODE *subst(to,from,expr,fcn,tresult)
NODE *to,*from,*expr,*fcn; int tresult;
{
NODE ***oldstk,*carval,*cdrval,*val;
if (dotest(expr,from,fcn) == tresult)
val = to;
else if (consp(expr)) {
oldstk = xlsave(&carval,&cdrval,(NODE **)NULL);
carval = subst(to,from,car(expr),fcn,tresult);
cdrval = subst(to,from,cdr(expr),fcn,tresult);
val = cons(carval,cdrval);
xlstack = oldstk;
}
else
val = expr;
return (val);
}
/* xsublis - substitute using an association list */
NODE *xsublis(args)
NODE *args;
{
NODE ***oldstk,*alist,*expr,*fcn,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&alist,&expr,&fcn,(NODE **)NULL);
/* get the assocation list and the expression */
alist = xlmatch(LIST,&args);
expr = xlarg(&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* do the substitution */
val = sublis(alist,expr,fcn,tresult);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* sublis - substitute using an association list */
LOCAL NODE *sublis(alist,expr,fcn,tresult)
NODE *alist,*expr,*fcn; int tresult;
{
NODE ***oldstk,*carval,*cdrval,*val;
if (val = assoc(expr,alist,fcn,tresult))
val = cdr(val);
else if (consp(expr)) {
oldstk = xlsave(&carval,&cdrval,(NODE **)NULL);
carval = sublis(alist,car(expr),fcn,tresult);
cdrval = sublis(alist,cdr(expr),fcn,tresult);
val = cons(carval,cdrval);
xlstack = oldstk;
}
else
val = expr;
return (val);
}
/* assoc - find a pair in an association list */
LOCAL NODE *assoc(expr,alist,fcn,tresult)
NODE *expr,*alist,*fcn; int tresult;
{
NODE *pair;
for (; consp(alist); alist = cdr(alist))
if ((pair = car(alist)) && consp(pair))
if (dotest(expr,car(pair),fcn) == tresult)
return (pair);
return (NIL);
}
/* xremove - built-in function 'remove' */
NODE *xremove(args)
NODE *args;
{
NODE ***oldstk,*x,*list,*fcn,*val,*p;
NODE *last = NIL;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&x,&list,&fcn,&val,(NODE **)NULL);
/* get the expression to remove and the list */
x = xlarg(&args);
list = xlmatch(LIST,&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* remove matches */
while (consp(list)) {
/* check to see if this element should be deleted */
if (dotest(x,car(list),fcn) != tresult) {
p = consa(car(list));
if (val) rplacd(last,p);
else val = p;
last = p;
}
/* move to the next element */
list = cdr(list);
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the updated list */
return (val);
}
/* dotest - call a test function */
int dotest(arg1,arg2,fcn)
NODE *arg1,*arg2,*fcn;
{
NODE ***oldstk,*args,*val;
/* create a new stack frame */
oldstk = xlsave(&args,(NODE **)NULL);
/* build an argument list */
args = consa(arg1);
rplacd(args,consa(arg2));
/* apply the test function */
val = xlapply(fcn,args);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result of the test */
return (val != NIL);
}
/* xnth - return the nth element of a list */
NODE *xnth(args)
NODE *args;
{
return (nth(args,TRUE));
}
/* xnthcdr - return the nth cdr of a list */
NODE *xnthcdr(args)
NODE *args;
{
return (nth(args,FALSE));
}
/* nth - internal nth function */
LOCAL NODE *nth(args,carflag)
NODE *args; int carflag;
{
NODE *list;
int n;
/* get n and the list */
if ((n = getfixnum(xlmatch(INT,&args))) < 0)
xlfail("bad argument");
if ((list = xlmatch(LIST,&args)) == NIL)
xlfail("bad argument");
xllastarg(args);
/* find the nth element */
while (consp(list) && n--)
list = cdr(list);
/* return the list beginning at the nth element */
return (carflag && consp(list) ? car(list) : list);
}
/* xlength - return the length of a list or string */
NODE *xlength(args)
NODE *args;
{
NODE *arg;
int n;
/* get the list or string */
arg = xlarg(&args);
xllastarg(args);
/* find the length of a list */
if (listp(arg))
for (n = 0; consp(arg); n++)
arg = cdr(arg);
/* find the length of a string */
else if (stringp(arg))
n = strlen(getstring(arg));
/* find the length of a vector */
else if (vectorp(arg))
n = getsize(arg);
/* otherwise, bad argument type */
else
xlerror("bad argument type",arg);
/* return the length */
return (cvfixnum((FIXNUM)n));
}
/* xmapc - built-in function 'mapc' */
NODE *xmapc(args)
NODE *args;
{
return (map(args,TRUE,FALSE));
}
/* xmapcar - built-in function 'mapcar' */
NODE *xmapcar(args)
NODE *args;
{
return (map(args,TRUE,TRUE));
}
/* xmapl - built-in function 'mapl' */
NODE *xmapl(args)
NODE *args;
{
return (map(args,FALSE,FALSE));
}
/* xmaplist - built-in function 'maplist' */
NODE *xmaplist(args)
NODE *args;
{
return (map(args,FALSE,TRUE));
}
/* map - internal mapping function */
LOCAL NODE *map(args,carflag,valflag)
NODE *args; int carflag,valflag;
{
NODE ***oldstk,*fcn,*lists,*arglist,*val,*p,*x,*y;
NODE *last = NIL;
/* create a new stack frame */
oldstk = xlsave(&fcn,&lists,&arglist,&val,(NODE **)NULL);
/* get the function to apply and the first list */
fcn = xlarg(&args);
lists = xlmatch(LIST,&args);
/* save the first list if not saving function values */
if (!valflag)
val = lists;
/* set up the list of argument lists */
lists = consa(lists);
/* get the remaining argument lists */
while (args) {
lists = consd(lists);
rplaca(lists,xlmatch(LIST,&args));
}
/* if the function is a symbol, get its value */
if (symbolp(fcn))
fcn = xleval(fcn);
/* loop through each of the argument lists */
for (;;) {
/* build an argument list from the sublists */
arglist = NIL;
for (x = lists; x && (y = car(x)) && consp(y); x = cdr(x)) {
arglist = consd(arglist);
rplaca(arglist,carflag ? car(y) : y);
rplaca(x,cdr(y));
}
/* quit if any of the lists were empty */
if (x) break;
/* apply the function to the arguments */
if (valflag) {
p = consa(NIL);
if (val) rplacd(last,p);
else val = p;
rplaca(p,xlapply(fcn,arglist));
last = p;
}
else
xlapply(fcn,arglist);
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the last test expression value */
return (val);
}
/* xrplca - replace the car of a list node */
NODE *xrplca(args)
NODE *args;
{
NODE *list,*newcar;
/* get the list and the new car */
if ((list = xlmatch(LIST,&args)) == NIL)
xlfail("bad argument");
newcar = xlarg(&args);
xllastarg(args);
/* replace the car */
rplaca(list,newcar);
/* return the list node that was modified */
return (list);
}
/* xrplcd - replace the cdr of a list node */
NODE *xrplcd(args)
NODE *args;
{
NODE *list,*newcdr;
/* get the list and the new cdr */
if ((list = xlmatch(LIST,&args)) == NIL)
xlfail("bad argument");
newcdr = xlarg(&args);
xllastarg(args);
/* replace the cdr */
rplacd(list,newcdr);
/* return the list node that was modified */
return (list);
}
/* xnconc - destructively append lists */
NODE *xnconc(args)
NODE *args;
{
NODE *list,*val;
NODE *last = NIL;
/* concatenate each argument */
for (val = NIL; args; ) {
/* concatenate this list */
if (list = xlmatch(LIST,&args)) {
/* check for this being the first non-empty list */
if (val)
rplacd(last,list);
else
val = list;
/* find the end of the list */
while (consp(cdr(list)))
list = cdr(list);
/* save the new last element */
last = list;
}
}
/* return the list */
return (val);
}
/* xdelete - built-in function 'delete' */
NODE *xdelete(args)
NODE *args;
{
NODE ***oldstk,*x,*list,*fcn,*last,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&x,&list,&fcn,(NODE **)NULL);
/* get the expression to delete and the list */
x = xlarg(&args);
list = xlmatch(LIST,&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* delete leading matches */
while (consp(list)) {
if (dotest(x,car(list),fcn) != tresult)
break;
list = cdr(list);
}
val = last = list;
/* delete embedded matches */
if (consp(list)) {
/* skip the first non-matching element */
list = cdr(list);
/* look for embedded matches */
while (consp(list)) {
/* check to see if this element should be deleted */
if (dotest(x,car(list),fcn) == tresult)
rplacd(last,cdr(list));
else
last = list;
/* move to the next element */
list = cdr(list);
}
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the updated list */
return (val);
}
/* xatom - is this an atom? */
NODE *xatom(args)
NODE *args;
{
NODE *arg;
arg = xlarg(&args);
xllastarg(args);
return (atom(arg) ? true : NIL);
}
/* xsymbolp - is this an symbol? */
NODE *xsymbolp(args)
NODE *args;
{
NODE *arg;
arg = xlarg(&args);
xllastarg(args);
return (arg == NIL || symbolp(arg) ? true : NIL);
}
/* xnumberp - is this a number? */
NODE *xnumberp(args)
NODE *args;
{
NODE *arg;
arg = xlarg(&args);
xllastarg(args);
return (fixp(arg) || floatp(arg) ? true : NIL);
}
/* xboundp - is this a value bound to this symbol? */
NODE *xboundp(args)
NODE *args;
{
NODE *sym;
sym = xlmatch(SYM,&args);
xllastarg(args);
return (getvalue(sym) == s_unbound ? NIL : true);
}
/* xnull - is this null? */
NODE *xnull(args)
NODE *args;
{
NODE *arg;
arg = xlarg(&args);
xllastarg(args);
return (null(arg) ? true : NIL);
}
/* xlistp - is this a list? */
NODE *xlistp(args)
NODE *args;
{
NODE *arg;
arg = xlarg(&args);
xllastarg(args);
return (listp(arg) ? true : NIL);
}
/* xconsp - is this a cons? */
NODE *xconsp(args)
NODE *args;
{
NODE *arg;
arg = xlarg(&args);
xllastarg(args);
return (consp(arg) ? true : NIL);
}
/* xeq - are these equal? */
NODE *xeq(args)
NODE *args;
{
return (cequal(args,eq));
}
/* xeql - are these equal? */
NODE *xeql(args)
NODE *args;
{
return (cequal(args,eql));
}
/* xequal - are these equal? */
NODE *xequal(args)
NODE *args;
{
return (cequal(args,equal));
}
/* cequal - common eq/eql/equal function */
LOCAL NODE *cequal(args,fcn)
NODE *args; int (*fcn)();
{
NODE *arg1,*arg2;
/* get the two arguments */
arg1 = xlarg(&args);
arg2 = xlarg(&args);
xllastarg(args);
/* compare the arguments */
return ((*fcn)(arg1,arg2) ? true : NIL);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'xlmath.c'
then
echo shar: will not over-write existing file "'xlmath.c'"
else
cat << \SHAR_EOF > 'xlmath.c'
/* xlmath - xlisp builtin arithmetic functions */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#ifdef MEGAMAX
#include <fmath.h>
overlay "math"
#else
#include <math.h>
#endif
/*
* Lattice's math.h include declarations for fabs, so must come before
* xlisp.h
*/
#include "xlisp.h"
/* external variables */
extern NODE *true;
/* forward declarations */
FORWARD NODE *unary();
FORWARD NODE *binary();
FORWARD NODE *predicate();
FORWARD NODE *compare();
/* xadd - builtin function for addition */
NODE *xadd(args)
NODE *args;
{
return (binary(args,'+'));
}
/* xsub - builtin function for subtraction */
NODE *xsub(args)
NODE *args;
{
return (binary(args,'-'));
}
/* xmul - builtin function for multiplication */
NODE *xmul(args)
NODE *args;
{
return (binary(args,'*'));
}
/* xdiv - builtin function for division */
NODE *xdiv(args)
NODE *args;
{
return (binary(args,'/'));
}
/* xrem - builtin function for remainder */
NODE *xrem(args)
NODE *args;
{
return (binary(args,'%'));
}
/* xmin - builtin function for minimum */
NODE *xmin(args)
NODE *args;
{
return (binary(args,'m'));
}
/* xmax - builtin function for maximum */
NODE *xmax(args)
NODE *args;
{
return (binary(args,'M'));
}
/* xexpt - built-in function 'expt' */
NODE *xexpt(args)
NODE *args;
{
return (binary(args,'E'));
}
/* xbitand - builtin function for bitwise and */
NODE *xbitand(args)
NODE *args;
{
return (binary(args,'&'));
}
/* xbitior - builtin function for bitwise inclusive or */
NODE *xbitior(args)
NODE *args;
{
return (binary(args,'|'));
}
/* xbitxor - builtin function for bitwise exclusive or */
NODE *xbitxor(args)
NODE *args;
{
return (binary(args,'^'));
}
/* binary - handle binary operations */
LOCAL NODE *binary(args,fcn)
NODE *args; int fcn;
{
FIXNUM ival,iarg;
FLONUM fval,farg;
NODE *arg;
int imode;
/* get the first argument */
arg = xlarg(&args);
/* set the type of the first argument */
if (fixp(arg)) {
ival = getfixnum(arg);
imode = TRUE;
}
else if (floatp(arg)) {
fval = getflonum(arg);
imode = FALSE;
}
else
xlerror("bad argument type",arg);
/* treat '-' with a single argument as a special case */
if (fcn == '-' && args == NIL)
if (imode)
ival = -ival;
else
fval = -fval;
/* handle each remaining argument */
while (args) {
/* get the next argument */
arg = xlarg(&args);
/* check its type */
if (fixp(arg))
if (imode) iarg = getfixnum(arg);
else farg = (FLONUM)getfixnum(arg);
else if (floatp(arg))
if (imode) { fval = (FLONUM)ival; farg = getflonum(arg); imode = FALSE; }
else farg = getflonum(arg);
else
xlerror("bad argument type",arg);
/* accumulate the result value */
if (imode)
switch (fcn) {
case '+': ival += iarg; break;
case '-': ival -= iarg; break;
case '*': ival *= iarg; break;
case '/': checkizero(iarg); ival /= iarg; break;
case '%': checkizero(iarg); ival %= iarg; break;
case 'M': if (iarg > ival) ival = iarg; break;
case 'm': if (iarg < ival) ival = iarg; break;
case '&': ival &= iarg; break;
case '|': ival |= iarg; break;
case '^': ival ^= iarg; break;
default: badiop();
}
else
switch (fcn) {
case '+': fval += farg; break;
case '-': fval -= farg; break;
case '*': fval *= farg; break;
case '/': checkfzero(farg); fval /= farg; break;
case 'M': if (farg > fval) fval = farg; break;
case 'm': if (farg < fval) fval = farg; break;
case 'E': fval = pow(fval,farg); break;
default: badfop();
}
}
/* return the result */
return (imode ? cvfixnum(ival) : cvflonum(fval));
}
/* checkizero - check for integer division by zero */
checkizero(iarg)
FIXNUM iarg;
{
if (iarg == 0)
xlfail("division by zero");
}
/* checkfzero - check for floating point division by zero */
checkfzero(farg)
FLONUM farg;
{
if (farg == 0.0)
xlfail("division by zero");
}
/* checkfneg - check for square root of a negative number */
checkfneg(farg)
FLONUM farg;
{
if (farg < 0.0)
xlfail("square root of a negative number");
}
/* xbitnot - bitwise not */
NODE *xbitnot(args)
NODE *args;
{
return (unary(args,'~'));
}
/* xabs - builtin function for absolute value */
NODE *xabs(args)
NODE *args;
{
return (unary(args,'A'));
}
/* xadd1 - builtin function for adding one */
NODE *xadd1(args)
NODE *args;
{
return (unary(args,'+'));
}
/* xsub1 - builtin function for subtracting one */
NODE *xsub1(args)
NODE *args;
{
return (unary(args,'-'));
}
/* xsin - built-in function 'sin' */
NODE *xsin(args)
NODE *args;
{
return (unary(args,'S'));
}
/* xcos - built-in function 'cos' */
NODE *xcos(args)
NODE *args;
{
return (unary(args,'C'));
}
/* xtan - built-in function 'tan' */
NODE *xtan(args)
NODE *args;
{
return (unary(args,'T'));
}
/* xexp - built-in function 'exp' */
NODE *xexp(args)
NODE *args;
{
return (unary(args,'E'));
}
/* xsqrt - built-in function 'sqrt' */
NODE *xsqrt(args)
NODE *args;
{
return (unary(args,'R'));
}
/* xfix - built-in function 'fix' */
NODE *xfix(args)
NODE *args;
{
return (unary(args,'I'));
}
/* xfloat - built-in function 'float' */
NODE *xfloat(args)
NODE *args;
{
return (unary(args,'F'));
}
/* xrand - built-in function 'random' */
NODE *xrand(args)
NODE *args;
{
return (unary(args,'R'));
}
/* unary - handle unary operations */
LOCAL NODE *unary(args,fcn)
NODE *args; int fcn;
{
FLONUM fval;
FIXNUM ival;
NODE *arg;
/* get the argument */
arg = xlarg(&args);
xllastarg(args);
/* check its type */
if (fixp(arg)) {
ival = getfixnum(arg);
switch (fcn) {
case '~': ival = ~ival; break;
case 'A': ival = abs(ival); break;
case '+': ival++; break;
case '-': ival--; break;
case 'I': break;
case 'F': return (cvflonum((FLONUM)ival));
case 'R': ival = (FIXNUM)osrand((int)ival); break;
default: badiop();
}
return (cvfixnum(ival));
}
else if (floatp(arg)) {
fval = getflonum(arg);
switch (fcn) {
case 'A': fval = fabs(fval); break;
case '+': fval += 1.0; break;
case '-': fval -= 1.0; break;
case 'S': fval = sin(fval); break;
case 'C': fval = cos(fval); break;
case 'T': fval = tan(fval); break;
case 'E': fval = exp(fval); break;
case 'R': checkfneg(fval); fval = sqrt(fval); break;
case 'I': return (cvfixnum((FIXNUM)fval));
case 'F': break;
default: badfop();
}
return (cvflonum(fval));
}
else
xlerror("bad argument type",arg);
/*NOTREACHED*/
}
/* xminusp - is this number negative? */
NODE *xminusp(args)
NODE *args;
{
return (predicate(args,'-'));
}
/* xzerop - is this number zero? */
NODE *xzerop(args)
NODE *args;
{
return (predicate(args,'Z'));
}
/* xplusp - is this number positive? */
NODE *xplusp(args)
NODE *args;
{
return (predicate(args,'+'));
}
/* xevenp - is this number even? */
NODE *xevenp(args)
NODE *args;
{
return (predicate(args,'E'));
}
/* xoddp - is this number odd? */
NODE *xoddp(args)
NODE *args;
{
return (predicate(args,'O'));
}
/* predicate - handle a predicate function */
LOCAL NODE *predicate(args,fcn)
NODE *args; int fcn;
{
FLONUM fval;
FIXNUM ival;
NODE *arg;
/* get the argument */
arg = xlarg(&args);
xllastarg(args);
/* check the argument type */
if (fixp(arg)) {
ival = getfixnum(arg);
switch (fcn) {
case '-': ival = (ival < 0); break;
case 'Z': ival = (ival == 0); break;
case '+': ival = (ival > 0); break;
case 'E': ival = ((ival & 1) == 0); break;
case 'O': ival = ((ival & 1) != 0); break;
default: badiop();
}
}
else if (floatp(arg)) {
fval = getflonum(arg);
switch (fcn) {
case '-': ival = (fval < 0); break;
case 'Z': ival = (fval == 0); break;
case '+': ival = (fval > 0); break;
default: badfop();
}
}
else
xlerror("bad argument type",arg);
/* return the result value */
return (ival ? true : NIL);
}
/* xlss - builtin function for < */
NODE *xlss(args)
NODE *args;
{
return (compare(args,'<'));
}
/* xleq - builtin function for <= */
NODE *xleq(args)
NODE *args;
{
return (compare(args,'L'));
}
/* equ - builtin function for = */
NODE *xequ(args)
NODE *args;
{
return (compare(args,'='));
}
/* xneq - builtin function for /= */
NODE *xneq(args)
NODE *args;
{
return (compare(args,'#'));
}
/* xgeq - builtin function for >= */
NODE *xgeq(args)
NODE *args;
{
return (compare(args,'G'));
}
/* xgtr - builtin function for > */
NODE *xgtr(args)
NODE *args;
{
return (compare(args,'>'));
}
/* compare - common compare function */
LOCAL NODE *compare(args,fcn)
NODE *args; int fcn;
{
NODE *arg1,*arg2;
FIXNUM icmp;
FLONUM fcmp;
int imode;
/* get the two arguments */
arg1 = xlarg(&args);
arg2 = xlarg(&args);
xllastarg(args);
/* do the compare */
if (stringp(arg1) && stringp(arg2)) {
icmp = strcmp(getstring(arg1),getstring(arg2));
imode = TRUE;
}
else if (fixp(arg1) && fixp(arg2)) {
icmp = getfixnum(arg1) - getfixnum(arg2);
imode = TRUE;
}
else if (floatp(arg1) && floatp(arg2)) {
fcmp = getflonum(arg1) - getflonum(arg2);
imode = FALSE;
}
else if (fixp(arg1) && floatp(arg2)) {
fcmp = (FLONUM)getfixnum(arg1) - getflonum(arg2);
imode = FALSE;
}
else if (floatp(arg1) && fixp(arg2)) {
fcmp = getflonum(arg1) - (FLONUM)getfixnum(arg2);
imode = FALSE;
}
else
xlfail("expecting strings, integers or floats");
/* compute result of the compare */
if (imode)
switch (fcn) {
case '<': icmp = (icmp < 0); break;
case 'L': icmp = (icmp <= 0); break;
case '=': icmp = (icmp == 0); break;
case '#': icmp = (icmp != 0); break;
case 'G': icmp = (icmp >= 0); break;
case '>': icmp = (icmp > 0); break;
}
else
switch (fcn) {
case '<': icmp = (fcmp < 0.0); break;
case 'L': icmp = (fcmp <= 0.0); break;
case '=': icmp = (fcmp == 0.0); break;
case '#': icmp = (fcmp != 0.0); break;
case 'G': icmp = (fcmp >= 0.0); break;
case '>': icmp = (fcmp > 0.0); break;
}
/* return the result */
return (icmp ? true : NIL);
}
/* badiop - bad integer operation */
LOCAL badiop()
{
xlfail("bad integer operation");
}
/* badfop - bad floating point operation */
LOCAL badfop()
{
xlfail("bad floating point operation");
}
SHAR_EOF
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Mod.sources
mailing list