Megalextoria
Retro computing and gaming, sci-fi books, tv and movies and other geeky stuff.

Home » Archive » net.micro.atari » xlisp (PART 5 of 6)
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
xlisp (PART 5 of 6) [message #282783] Sat, 18 January 1986 15:03
bammi is currently offline  bammi
Messages: 27
Registered: January 1986
Karma: 0
Junior Member
Article-I.D.: cwruecmp.1383
Posted: Sat Jan 18 15:03:26 1986
Date-Received: Mon, 20-Jan-86 05:23:26 EST
Organization: CWRU Dept. Computer Eng., Cleveland, OH
Lines: 2150


#!/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:
#	xlftab2.c
#	xlglob.c
#	xlinit.c
#	xlio.c
#	xlisp.c
#	xljump.c
#	xllist.c
#	xlmath.c
# This archive created: Sat Jan 18 14:32:27 1986
# By:	Jwahar R. Bammi ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'xlftab2.c'" '(2614 characters)'
if test -f 'xlftab2.c'
then
	echo shar: over-writing existing file "'xlftab2.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xlftab2.c'
X/* xlftab2.c - xlisp function table - part 2 */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include "xlisp.h"
X
X/* external functions */
Xextern NODE
X    *xfix(),*xfloat(),
X    *xadd(),*xsub(),*xmul(),*xdiv(),*xrem(),*xmin(),*xmax(),*xabs(),
X    *xadd1(),*xsub1(),*xbitand(),*xbitior(),*xbitxor(),*xbitnot(),
X    *xsin(),*xcos(),*xtan(),*xexpt(),*xexp(),*xsqrt(),
X    *xlss(),*xleq(),*xequ(),*xneq(),*xgeq(),*xgtr(),
X    *xstrcat(),*xsubstr(),*xstring(),*xchar(),
X    *xread(),*xprint(),*xprin1(),*xprinc(),*xterpri(),
X    *xflatsize(),*xflatc(),
X    *xopeni(),*xopeno(),*xclose(),*xrdchar(),*xpkchar(),*xwrchar(),*xreadline(),
X    *xload(),*xgc(),*xexpand(),*xalloc(),*xmem(),*xtype(),*xexit(),
X    *xpeek(),*xpoke(),*xaddressof();
X
X/* the function table */
Xstruct fdef ftab2[] = {
X
X	/* arithmetic functions */
X{	"TRUNCATE",	SUBR,	xfix		},
X{	"FLOAT",	SUBR,	xfloat		},
X{	"+",		SUBR,	xadd		},
X{	"-",		SUBR,	xsub		},
X{	"*",		SUBR,	xmul		},
X{	"/",		SUBR,	xdiv		},
X{	"1+",		SUBR,	xadd1		},
X{	"1-",		SUBR,	xsub1		},
X{	"REM",		SUBR,	xrem		},
X{	"MIN",		SUBR,	xmin		},
X{	"MAX",		SUBR,	xmax		},
X{	"ABS",		SUBR,	xabs		},
X{	"SIN",		SUBR,	xsin		},
X{	"COS",		SUBR,	xcos		},
X{	"TAN",		SUBR,	xtan		},
X{	"EXPT",		SUBR,	xexpt		},
X{	"EXP",		SUBR,	xexp		},
X{	"SQRT",		SUBR,	xsqrt		},
X
X	/* bitwise logical functions */
X{	"BIT-AND",	SUBR,	xbitand		},
X{	"BIT-IOR",	SUBR,	xbitior		},
X{	"BIT-XOR",	SUBR,	xbitxor		},
X{	"BIT-NOT",	SUBR,	xbitnot		},
X
X	/* numeric comparison functions */
X{	"<",		SUBR,	xlss		},
X{	"<=",		SUBR,	xleq		},
X{	"=",		SUBR,	xequ		},
X{	"/=",		SUBR,	xneq		},
X{	">=",		SUBR,	xgeq		},
X{	">",		SUBR,	xgtr		},
X
X	/* string functions */
X{	"STRCAT",	SUBR,	xstrcat		},
X{	"SUBSTR",	SUBR,	xsubstr		},
X{	"STRING",	SUBR,	xstring		},
X{	"CHAR",		SUBR,	xchar		},
X
X	/* I/O functions */
X{	"READ",		SUBR,	xread		},
X{	"PRINT",	SUBR,	xprint		},
X{	"PRIN1",	SUBR,	xprin1		},
X{	"PRINC",	SUBR,	xprinc		},
X{	"TERPRI",	SUBR,	xterpri		},
X{	"FLATSIZE",	SUBR,	xflatsize	},
X{	"FLATC",	SUBR,	xflatc		},
X
X	/* file I/O functions */
X{	"OPENI",	SUBR,	xopeni		},
X{	"OPENO",	SUBR,	xopeno		},
X{	"CLOSE",	SUBR,	xclose		},
X{	"READ-CHAR",	SUBR,	xrdchar		},
X{	"PEEK-CHAR",	SUBR,	xpkchar		},
X{	"WRITE-CHAR",	SUBR,	xwrchar		},
X{	"READ-LINE",	SUBR,	xreadline	},
X
X	/* system functions */
X{	"LOAD",		SUBR,	xload		},
X{	"GC",		SUBR,	xgc		},
X{	"EXPAND",	SUBR,	xexpand		},
X{	"ALLOC",	SUBR,	xalloc		},
X{	"MEM",		SUBR,	xmem		},
X{	"TYPE-OF",	SUBR,	xtype		},
X{	"EXIT",		SUBR,	xexit		},
X{	"PEEK",		SUBR,	xpeek		},
X{	"POKE",		SUBR,	xpoke		},
X{	"ADDRESS-OF",	SUBR,	xaddressof	},
X
X{	0					}
X};
SHAR_EOF
if test 2614 -ne "`wc -c 'xlftab2.c'`"
then
	echo shar: error transmitting "'xlftab2.c'" '(should have been 2614 characters)'
fi
echo shar: extracting "'xlglob.c'" '(2197 characters)'
if test -f 'xlglob.c'
then
	echo shar: over-writing existing file "'xlglob.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xlglob.c'
X/* xlglobals - xlisp global variables */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include "xlisp.h"
X
X/* symbols */
XNODE *true = NIL;
XNODE *s_quote = NIL, *s_function = NIL;
XNODE *s_bquote = NIL, *s_comma = NIL, *s_comat = NIL;
XNODE *s_evalhook = NIL, *s_applyhook = NIL;
XNODE *s_lambda = NIL, *s_macro = NIL;
XNODE *s_stdin = NIL, *s_stdout = NIL;
XNODE *s_tracenable = NIL, *s_tlimit = NIL, *s_breakenable = NIL;
XNODE *s_car = NIL, *s_cdr = NIL;
XNODE *s_get = NIL, *s_svalue = NIL, *s_splist = NIL;
XNODE *s_eql = NIL, *k_test = NIL, *k_tnot = NIL;
XNODE *k_optional = NIL, *k_rest = NIL, *k_aux = NIL;
XNODE *a_subr = NIL, *a_fsubr = NIL;
XNODE *a_list = NIL, *a_sym = NIL, *a_int = NIL, *a_float = NIL;
XNODE *a_str = NIL, *a_obj = NIL, *a_fptr = NIL;
XNODE *oblist = NIL, *keylist = NIL, *s_unbound = NIL;
X
X/* evaluation variables */
XNODE *xlstack = NIL;
XNODE *xlenv = NIL;
X
X/* exception handling variables */
XCONTEXT *xlcontext = NULL;	/* current exception handler */
XNODE *xlvalue = NIL;		/* exception value */
X
X/* debugging variables */
Xint xldebug = 0;		/* debug level */
Xint xltrace = -1;		/* trace stack pointer */
XNODE **trace_stack = NULL;	/* trace stack */
X
X/* gensym variables */
Xchar gsprefix[STRMAX+1] = { 'G',0 };	/* gensym prefix string */
Xint gsnumber = 1;		/* gensym number */
X
X/* i/o variables */
Xint xlplevel = 0;		/* prompt nesting level */
Xint xlfsize = 0;		/* flat size of current print call */
Xint prompt = TRUE;		/* input prompt flag */
X
X/* dynamic memory variables */
Xlong total = 0L;		/* total memory in use */
Xint anodes = 0;			/* number of nodes to allocate */
Xint nnodes = 0;			/* number of nodes allocated */
Xint nsegs = 0;			/* number of segments allocated */
Xint nfree = 0;			/* number of nodes free */
Xint gccalls = 0;		/* number of gc calls */
Xstruct segment *segs = NULL;	/* list of allocated segments */
XNODE *fnodes = NIL;		/* list of free nodes */
X
X/* object programming variables */
XNODE *self = NIL, *class = NIL, *object = NIL;
XNODE *new = NIL, *isnew = NIL, *msgcls = NIL, *msgclass = NIL;
Xint varcnt = 0;
X
X/* general purpose string buffer */
Xchar buf[STRMAX+1] = { 0 };
SHAR_EOF
if test 2197 -ne "`wc -c 'xlglob.c'`"
then
	echo shar: error transmitting "'xlglob.c'" '(should have been 2197 characters)'
fi
echo shar: extracting "'xlinit.c'" '(3534 characters)'
if test -f 'xlinit.c'
then
	echo shar: over-writing existing file "'xlinit.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xlinit.c'
X/* xlinit.c - xlisp initialization module */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include "xlisp.h"
X
X/* external variables */
Xextern NODE *true;
Xextern NODE *s_quote,*s_function,*s_bquote,*s_comma,*s_comat;
Xextern NODE *s_lambda,*s_macro;
Xextern NODE *s_stdin,*s_stdout;
Xextern NODE *s_evalhook,*s_applyhook;
Xextern NODE *s_tracenable,*s_tlimit,*s_breakenable;
Xextern NODE *s_car,*s_cdr,*s_get,*s_svalue,*s_splist,*s_eql;
Xextern NODE *k_test,*k_tnot,*k_optional,*k_rest,*k_aux;
Xextern NODE *a_subr,*a_fsubr;
Xextern NODE *a_list,*a_sym,*a_int,*a_float,*a_str,*a_obj,*a_fptr;
Xextern struct fdef ftab1[],ftab2[];
X
X/* xlinit - xlisp initialization routine */
Xxlinit()
X{
X    struct fdef *fptr;
X    NODE *sym;
X
X    /* initialize xlisp (must be in this order) */
X    xlminit();	/* initialize xldmem.c */
X    xlsinit();	/* initialize xlsym.c */
X    xldinit();	/* initialize xldbug.c */
X    xloinit();	/* initialize xlobj.c */
X
X    /* enter the builtin functions */
X    for (fptr = ftab1; fptr->f_name; fptr++)
X	xlsubr(fptr->f_name,fptr->f_type,fptr->f_fcn);
X    for (fptr = ftab2; fptr->f_name; fptr++)
X	xlsubr(fptr->f_name,fptr->f_type,fptr->f_fcn);
X#ifdef CPM68K
X    xlginit();
X#endif
X#ifdef MEGAMAX
X    macfinit();
X#endif
X
X    /* enter the 't' symbol */
X    true = xlsenter("T");
X    true->n_symvalue = true;
X
X    /* enter some important symbols */
X    s_quote	= xlsenter("QUOTE");
X    s_function	= xlsenter("FUNCTION");
X    s_bquote	= xlsenter("BACKQUOTE");
X    s_comma	= xlsenter("COMMA");
X    s_comat	= xlsenter("COMMA-AT");
X    s_lambda	= xlsenter("LAMBDA");
X    s_macro	= xlsenter("MACRO");
X    s_eql	= xlsenter("EQL");
X
X    /* enter setf place specifiers */
X    s_car	= xlsenter("CAR");
X    s_cdr	= xlsenter("CDR");
X    s_get	= xlsenter("GET");
X    s_svalue	= xlsenter("SYMBOL-VALUE");
X    s_splist	= xlsenter("SYMBOL-PLIST");
X
X    /* enter parameter list keywords */
X    k_test	= xlsenter(":TEST");
X    k_tnot	= xlsenter(":TEST-NOT");
X
X    /* enter lambda list keywords */
X    k_optional	= xlsenter("&OPTIONAL");
X    k_rest	= xlsenter("&REST");
X    k_aux	= xlsenter("&AUX");
X
X    /* enter *standard-input* and *standard-output* */
X    s_stdin = xlsenter("*STANDARD-INPUT*");
X    s_stdin->n_symvalue = newnode(FPTR);
X    s_stdin->n_symvalue->n_fp = stdin;
X    s_stdin->n_symvalue->n_savech = 0;
X    s_stdout = xlsenter("*STANDARD-OUTPUT*");
X    s_stdout->n_symvalue = newnode(FPTR);
X    s_stdout->n_symvalue->n_fp = stdout;
X    s_stdout->n_symvalue->n_savech = 0;
X
X    /* enter the eval and apply hook variables */
X    s_evalhook = xlsenter("*EVALHOOK*");
X    s_evalhook->n_symvalue = NIL;
X    s_applyhook = xlsenter("*APPLYHOOK*");
X    s_applyhook->n_symvalue = NIL;
X
X    /* enter the error traceback and the error break enable flags */
X    s_tracenable = xlsenter("*TRACENABLE*");
X    s_tracenable->n_symvalue = NIL;
X    s_tlimit = xlsenter("*TRACELIMIT*");
X    s_tlimit->n_symvalue = NIL;
X    s_breakenable = xlsenter("*BREAKENABLE*");
X    s_breakenable->n_symvalue = true;
X
X    /* enter a copyright notice into the oblist */
X    sym = xlsenter("**Copyright-1985-by-David-Betz**");
X    sym->n_symvalue = true;
X
X    /* enter type names */
X    a_subr	= xlsenter(":SUBR");
X    a_fsubr	= xlsenter(":FSUBR");
X    a_list	= xlsenter(":CONS");
X    a_sym	= xlsenter(":SYMBOL");
X    a_int	= xlsenter(":FIXNUM");
X    a_float	= xlsenter(":FLONUM");
X    a_str	= xlsenter(":STRING");
X    a_obj	= xlsenter(":OBJECT");
X    a_fptr	= xlsenter(":FILE");
X}
SHAR_EOF
if test 3534 -ne "`wc -c 'xlinit.c'`"
then
	echo shar: error transmitting "'xlinit.c'" '(should have been 3534 characters)'
fi
echo shar: extracting "'xlio.c'" '(3109 characters)'
if test -f 'xlio.c'
then
	echo shar: over-writing existing file "'xlio.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xlio.c'
X/* xlio - xlisp i/o routines */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include "xlisp.h"
X
X#ifdef MEGAMAX
Xoverlay "io"
X#endif
X
X/* external variables */
Xextern int xlplevel;
Xextern int xlfsize;
Xextern NODE *xlstack;
Xextern NODE *s_stdin;
Xextern int xldebug;
Xextern int prompt;
Xextern char buf[];
X
X/* xlgetc - get a character from a file or stream */
Xint xlgetc(fptr)
X  NODE *fptr;
X{
X    NODE *lptr,*cptr;
X    FILE *fp;
X    int ch;
X
X    /* check for input from nil */
X    if (fptr == NIL)
X	ch = EOF;
X
X    /* otherwise, check for input from a stream */
X    else if (consp(fptr)) {
X	if ((lptr = car(fptr)) == NIL)
X	    ch = EOF;
X	else {
X	    if (!consp(lptr) ||
X		(cptr = car(lptr)) == NIL || !fixp(cptr))
X		xlfail("bad stream");
X	    if (rplaca(fptr,cdr(lptr)) == NIL)
X		rplacd(fptr,NIL);
X	    ch = cptr->n_int;
X	}
X    }
X
X    /* otherwise, check for a buffered file character */
X    else if (ch = fptr->n_savech)
X	fptr->n_savech = 0;
X
X    /* otherwise, get a new character */
X    else {
X
X	/* get the file pointer */
X	fp = fptr->n_fp;
X
X	/* prompt if necessary */
X	if (prompt && fp == stdin) {
X
X	    /* print the debug level */
X	    if (xldebug)
X		{ sprintf(buf,"%d:",xldebug); stdputstr(buf); }
X
X	    /* print the nesting level */
X	    if (xlplevel > 0)
X		{ sprintf(buf,"%d",xlplevel); stdputstr(buf); }
X
X	    /* print the prompt */
X	    stdputstr("> ");
X	    prompt = FALSE;
X	}
X
X	/* get the character */
X	if (((ch = getc(fp)) == '\n' || ch == EOF) && fp == stdin)
X	    prompt = TRUE;
X
X	/* check for input abort */
X	if (fp == stdin && ch == '\007') {
X	    putchar('\n');
X	    xlabort("input aborted");
X	}
X    }
X
X    /* return the character */
X    return (ch);
X}
X
X/* xlpeek - peek at a character from a file or stream */
Xint xlpeek(fptr)
X  NODE *fptr;
X{
X    NODE *lptr,*cptr;
X    int ch;
X
X    /* check for input from nil */
X    if (fptr == NIL)
X	ch = EOF;
X
X    /* otherwise, check for input from a stream */
X    else if (consp(fptr)) {
X	if ((lptr = car(fptr)) == NIL)
X	    ch = EOF;
X	else {
X	    if (!consp(lptr) ||
X		(cptr = car(lptr)) == NIL || !fixp(cptr))
X		xlfail("bad stream");
X	    ch = cptr->n_int;
X	}
X    }
X
X    /* otherwise, get the next file character and save it */
X    else
X	ch = fptr->n_savech = xlgetc(fptr);
X
X    /* return the character */
X    return (ch);
X}
X
X/* xlputc - put a character to a file or stream */
Xxlputc(fptr,ch)
X  NODE *fptr; int ch;
X{
X    NODE *oldstk,lptr;
X
X    /* count the character */
X    xlfsize++;
X
X    /* check for output to nil */
X    if (fptr == NIL)
X	;
X
X    /* otherwise, check for output to a stream */
X    else if (consp(fptr)) {
X	oldstk = xlsave(&lptr,NULL);
X	lptr.n_ptr = newnode(LIST);
X	rplaca(lptr.n_ptr,cvfixnum((FIXNUM)ch));
X	if (cdr(fptr))
X	    rplacd(cdr(fptr),lptr.n_ptr);
X	else
X	    rplaca(fptr,lptr.n_ptr);
X	rplacd(fptr,lptr.n_ptr);
X	xlstack = oldstk;
X    }
X
X    /* otherwise, output the character to a file */
X    else
X	putc(ch,fptr->n_fp);
X}
X
X/* xlflush - flush the input buffer */
Xint xlflush()
X{
X    if (!prompt)
X	while (xlgetc(getvalue(s_stdin)) != '\n')
X	    ;
X}
SHAR_EOF
if test 3109 -ne "`wc -c 'xlio.c'`"
then
	echo shar: error transmitting "'xlio.c'" '(should have been 3109 characters)'
fi
echo shar: extracting "'xlisp.c'" '(2176 characters)'
if test -f 'xlisp.c'
then
	echo shar: over-writing existing file "'xlisp.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xlisp.c'
X/* xlisp - an small version of lisp that supports object-oriented programming */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include "xlisp.h"
X
X/* define the banner line string */
X#define BANNER	"XLISP version 1.5b, Copyright (c) 1985, by David Betz"
X
X/* external variables */
Xextern NODE *s_stdin,*s_stdout;
Xextern NODE *s_evalhook,*s_applyhook;
Xextern NODE *true;
X
X/* main - the main routine */
Xmain(argc,argv)
X  int argc; char *argv[];
X{
X    char fname[50];
X    CONTEXT cntxt;
X    NODE expr;
X    int i;
X
X    /* print the banner line */
X#ifdef MEGAMAX
X    macinit(BANNER);
X#else
X    printf("%s\n",BANNER);
X#endif
X
X    /* setup initialization error handler */
X    xlbegin(&cntxt,CF_ERROR,(NODE *) 1);
X    if (setjmp(cntxt.c_jmpbuf)) {
X	printf("fatal initialization error\n");
X	exit();
X    }
X
X    /* initialize xlisp */
X    xlinit();
X    xlend(&cntxt);
X
X    /* reset the error handler */
X    xlbegin(&cntxt,CF_ERROR,true);
X
X    /* load "init.lsp" */
X    if (setjmp(cntxt.c_jmpbuf) == 0)
X#ifndef INITPATH
X	xlload("init.lsp",FALSE,FALSE);
X#else
X	xlload(INITPATH,FALSE,FALSE);
X#endif
X
X    /* load any files mentioned on the command line */
X#ifndef MEGAMAX
X    if (setjmp(cntxt.c_jmpbuf) == 0)
X	for (i = 1; i < argc; i++) {
X	    sprintf(fname,"%s.lsp",argv[i]);
X	    if (!xlload(fname,TRUE,FALSE))
X		xlfail("can't load file");
X	}
X#endif
X
X    /* create a new stack frame */
X    xlsave(&expr,NULL);
X
X    /* main command processing loop */
X    while (TRUE) {
X
X	/* setup the error return */
X	if (setjmp(cntxt.c_jmpbuf)) {
X	    setvalue(s_evalhook,NIL);
X	    setvalue(s_applyhook,NIL);
X	    xlflush();
X	}
X
X	/* read an expression */
X	if (!xlread(getvalue(s_stdin),&expr.n_ptr))
X	    break;
X
X	/* evaluate the expression */
X	expr.n_ptr = xleval(expr.n_ptr);
X
X	/* print it */
X	stdprint(expr.n_ptr);
X    }
X    xlend(&cntxt);
X}
X
X/* stdprint - print to standard output */
Xstdprint(expr)
X  NODE *expr;
X{
X    xlprint(getvalue(s_stdout),expr,TRUE);
X    xlterpri(getvalue(s_stdout));
X}
X
X/* stdputstr - print a string to standard output */
Xstdputstr(str)
X  char *str;
X{
X    xlputstr(getvalue(s_stdout),str);
X}
X
SHAR_EOF
if test 2176 -ne "`wc -c 'xlisp.c'`"
then
	echo shar: error transmitting "'xlisp.c'" '(should have been 2176 characters)'
fi
echo shar: extracting "'xljump.c'" '(2937 characters)'
if test -f 'xljump.c'
then
	echo shar: over-writing existing file "'xljump.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xljump.c'
X/* xljump - execution context routines */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include "xlisp.h"
X
X/* external variables */
Xextern CONTEXT *xlcontext;
Xextern NODE *xlvalue;
Xextern NODE *xlstack,*xlenv;
Xextern int xltrace,xldebug;
X
X/* xlbegin - beginning of an execution context */
Xxlbegin(cptr,flags,expr)
X  CONTEXT *cptr; int flags; NODE *expr;
X{
X    cptr->c_flags = flags;
X    cptr->c_expr = expr;
X    cptr->c_xlstack = xlstack;
X    cptr->c_xlenv = xlenv;
X    cptr->c_xltrace = xltrace;
X    cptr->c_xlcontext = xlcontext;
X    xlcontext = cptr;
X}
X
X/* xlend - end of an execution context */
Xxlend(cptr)
X  CONTEXT *cptr;
X{
X    xlcontext = cptr->c_xlcontext;
X}
X
X/* xljump - jump to a saved execution context */
Xxljump(cptr,type,val)
X  CONTEXT *cptr; int type; NODE *val;
X{
X    /* restore the state */
X    xlcontext = cptr;
X    xlstack = xlcontext->c_xlstack;
X    xlenv = xlcontext->c_xlenv;
X    xltrace = xlcontext->c_xltrace;
X    xlvalue = val;
X
X    /* call the handler */
X    longjmp(xlcontext->c_jmpbuf,type);
X}
X
X/* xlcleanup - clean-up after an error */
Xxlcleanup()
X{
X    CONTEXT *cptr;
X
X    /* find a block context */
X    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
X	if (cptr->c_flags & CF_CLEANUP)
X	    xljump(cptr,CF_CLEANUP,NIL);
X    xlfail("not in a break loop");
X}
X
X/* xlcontinue - continue from an error */
Xxlcontinue()
X{
X    CONTEXT *cptr;
X
X    /* find a block context */
X    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
X	if (cptr->c_flags & CF_CONTINUE)
X	    xljump(cptr,CF_CONTINUE,NIL);
X    xlfail("not in a break loop");
X}
X
X/* xlgo - go to a label */
Xxlgo(label)
X  NODE *label;
X{
X    CONTEXT *cptr;
X    NODE *p;
X
X    /* find a tagbody context */
X    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
X	if (cptr->c_flags & CF_GO)
X	    for (p = cptr->c_expr; consp(p); p = cdr(p))
X		if (car(p) == label)
X		    xljump(cptr,CF_GO,p);
X    xlfail("no target for GO");
X}
X
X/* xlreturn - return from a block */
Xxlreturn(val)
X  NODE *val;
X{
X    CONTEXT *cptr;
X
X    /* find a block context */
X    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
X	if (cptr->c_flags & CF_RETURN)
X	    xljump(cptr,CF_RETURN,val);
X    xlfail("no target for RETURN");
X}
X
X/* xlthrow - throw to a catch */
Xxlthrow(tag,val)
X  NODE *tag,*val;
X{
X    CONTEXT *cptr;
X
X    /* find a catch context */
X    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
X	if ((cptr->c_flags & CF_THROW) && cptr->c_expr == tag)
X	    xljump(cptr,CF_THROW,val);
X    xlfail("no target for THROW");
X}
X
X/* xlsignal - signal an error */
Xxlsignal(emsg,arg)
X  char *emsg; NODE *arg;
X{
X    CONTEXT *cptr;
X
X    /* find an error catcher */
X    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
X	if (cptr->c_flags & CF_ERROR) {
X	    if (cptr->c_expr)
X		xlerrprint("error",NULL,emsg,arg);
X	    xljump(cptr,CF_ERROR,NIL);
X	}
X    xlfail("no target for error");
X}
SHAR_EOF
if test 2937 -ne "`wc -c 'xljump.c'`"
then
	echo shar: error transmitting "'xljump.c'" '(should have been 2937 characters)'
fi
echo shar: extracting "'xllist.c'" '(18035 characters)'
if test -f 'xllist.c'
then
	echo shar: over-writing existing file "'xllist.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xllist.c'
X/* xllist - xlisp built-in list functions */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include "xlisp.h"
X
X#ifdef MEGAMAX
Xoverlay "overflow"
X#endif
X
X/* external variables */
Xextern NODE *xlstack;
Xextern NODE *s_unbound;
Xextern NODE *true;
X
X/* external routines */
Xextern int eq(),eql(),equal();
X
X/* forward declarations */
XFORWARD NODE *cxr();
XFORWARD NODE *nth(),*assoc();
XFORWARD NODE *subst(),*sublis(),*map();
XFORWARD NODE *cequal();
X
X/* xcar - return the car of a list */
XNODE *xcar(args)
X  NODE *args;
X{
X    return (cxr(args,"a"));
X}
X
X/* xcdr - return the cdr of a list */
XNODE *xcdr(args)
X  NODE *args;
X{
X    return (cxr(args,"d"));
X}
X
X/* xcaar - return the caar of a list */
XNODE *xcaar(args)
X  NODE *args;
X{
X    return (cxr(args,"aa"));
X}
X
X/* xcadr - return the cadr of a list */
XNODE *xcadr(args)
X  NODE *args;
X{
X    return (cxr(args,"da"));
X}
X
X/* xcdar - return the cdar of a list */
XNODE *xcdar(args)
X  NODE *args;
X{
X    return (cxr(args,"ad"));
X}
X
X/* xcddr - return the cddr of a list */
XNODE *xcddr(args)
X  NODE *args;
X{
X    return (cxr(args,"dd"));
X}
X
X/* cxr - common car/cdr routine */
XLOCAL NODE *cxr(args,adstr)
X  NODE *args; char *adstr;
X{
X    NODE *list;
X
X    /* get the list */
X    list = xlmatch(LIST,&args);
X    xllastarg(args);
X
X    /* perform the car/cdr operations */
X    while (*adstr && consp(list))
X	list = (*adstr++ == 'a' ? car(list) : cdr(list));
X
X    /* make sure the operation succeeded */
X    if (*adstr && list)
X	xlfail("bad argument");
X
X    /* return the result */
X    return (list);
X}
X
X/* xcons - construct a new list cell */
XNODE *xcons(args)
X  NODE *args;
X{
X    NODE *arg1,*arg2,*val;
X
X    /* get the two arguments */
X    arg1 = xlarg(&args);
X    arg2 = xlarg(&args);
X    xllastarg(args);
X
X    /* construct a new list element */
X    val = newnode(LIST);
X    rplaca(val,arg1);
X    rplacd(val,arg2);
X
X    /* return the list */
X    return (val);
X}
X
X/* xlist - built a list of the arguments */
XNODE *xlist(args)
X  NODE *args;
X{
X    NODE *oldstk,arg,list,val,*last,*lptr;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&arg,&list,&val,NULL);
X
X    /* initialize */
X    arg.n_ptr = args;
X
X    /* evaluate and append each argument */
X    for (last = NIL; arg.n_ptr != NIL; last = lptr) {
X
X	/* evaluate the next argument */
X	val.n_ptr = xlarg(&arg.n_ptr);
X
X	/* append this argument to the end of the list */
X	lptr = newnode(LIST);
X	if (last == NIL)
X	    list.n_ptr = lptr;
X	else
X	    rplacd(last,lptr);
X	rplaca(lptr,val.n_ptr);
X    }
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the list */
X    return (list.n_ptr);
X}
X
X/* xappend - built-in function append */
XNODE *xappend(args)
X  NODE *args;
X{
X    NODE *oldstk,arg,list,last,val,*lptr;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&arg,&list,&last,&val,NULL);
X
X    /* initialize */
X    arg.n_ptr = args;
X
X    /* evaluate and append each argument */
X    while (arg.n_ptr) {
X
X	/* evaluate the next argument */
X	list.n_ptr = xlmatch(LIST,&arg.n_ptr);
X
X	/* append each element of this list to the result list */
X	while (consp(list.n_ptr)) {
X
X	    /* append this element */
X	    lptr = newnode(LIST);
X	    if (last.n_ptr == NIL)
X		val.n_ptr = lptr;
X	    else
X		rplacd(last.n_ptr,lptr);
X	    rplaca(lptr,car(list.n_ptr));
X
X	    /* save the new last element */
X	    last.n_ptr = lptr;
X
X	    /* move to the next element */
X	    list.n_ptr = cdr(list.n_ptr);
X	}
X    }
X
X    /* restore previous stack frame */
X    xlstack = oldstk;
X
X    /* return the list */
X    return (val.n_ptr);
X}
X
X/* xreverse - built-in function reverse */
XNODE *xreverse(args)
X  NODE *args;
X{
X    NODE *oldstk,list,val,*lptr;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&list,&val,NULL);
X
X    /* get the list to reverse */
X    list.n_ptr = xlmatch(LIST,&args);
X    xllastarg(args);
X
X    /* append each element of this list to the result list */
X    while (consp(list.n_ptr)) {
X
X	/* append this element */
X	lptr = newnode(LIST);
X	rplaca(lptr,car(list.n_ptr));
X	rplacd(lptr,val.n_ptr);
X	val.n_ptr = lptr;
X
X	/* move to the next element */
X	list.n_ptr = cdr(list.n_ptr);
X    }
X
X    /* restore previous stack frame */
X    xlstack = oldstk;
X
X    /* return the list */
X    return (val.n_ptr);
X}
X
X/* xlast - return the last cons of a list */
XNODE *xlast(args)
X  NODE *args;
X{
X    NODE *list;
X
X    /* get the list */
X    list = xlmatch(LIST,&args);
X    xllastarg(args);
X
X    /* find the last cons */
X    while (consp(list) && cdr(list))
X	list = cdr(list);
X
X    /* return the last element */
X    return (list);
X}
X
X/* xmember - built-in function 'member' */
XNODE *xmember(args)
X  NODE *args;
X{
X    NODE *oldstk,x,list,fcn,*val;
X    int tresult;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&x,&list,&fcn,NULL);
X
X    /* get the expression to look for and the list */
X    x.n_ptr = xlarg(&args);
X    list.n_ptr = xlmatch(LIST,&args);
X    xltest(&fcn.n_ptr,&tresult,&args);
X    xllastarg(args);
X
X    /* look for the expression */
X    for (val = NIL; consp(list.n_ptr); list.n_ptr = cdr(list.n_ptr))
X	if (dotest(x.n_ptr,car(list.n_ptr),fcn.n_ptr) == tresult) {
X	    val = list.n_ptr;
X	    break;
X	}
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the result */
X    return (val);
X}
X
X/* xassoc - built-in function 'assoc' */
XNODE *xassoc(args)
X  NODE *args;
X{
X    NODE *oldstk,x,alist,fcn,*pair,*val;
X    int tresult;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&x,&alist,&fcn,NULL);
X
X    /* get the expression to look for and the association list */
X    x.n_ptr = xlarg(&args);
X    alist.n_ptr = xlmatch(LIST,&args);
X    xltest(&fcn.n_ptr,&tresult,&args);
X    xllastarg(args);
X
X    /* look for the expression */
X    for (val = NIL; consp(alist.n_ptr); alist.n_ptr = cdr(alist.n_ptr))
X	if ((pair = car(alist.n_ptr)) && consp(pair))
X	    if (dotest(x.n_ptr,car(pair),fcn.n_ptr) == tresult) {
X		val = pair;
X		break;
X	    }
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the result */
X    return (val);
X}
X
X/* xsubst - substitute one expression for another */
XNODE *xsubst(args)
X  NODE *args;
X{
X    NODE *oldstk,to,from,expr,fcn,*val;
X    int tresult;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&to,&from,&expr,&fcn,NULL);
X
X    /* get the to value, the from value and the expression */
X    to.n_ptr = xlarg(&args);
X    from.n_ptr = xlarg(&args);
X    expr.n_ptr = xlarg(&args);
X    xltest(&fcn.n_ptr,&tresult,&args);
X    xllastarg(args);
X
X    /* do the substitution */
X    val = subst(to.n_ptr,from.n_ptr,expr.n_ptr,fcn.n_ptr,tresult);
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the result */
X    return (val);
X}
X
X/* subst - substitute one expression for another */
XLOCAL NODE *subst(to,from,expr,fcn,tresult)
X  NODE *to,*from,*expr,*fcn; int tresult;
X{
X    NODE *oldstk,carval,cdrval,*val;
X
X    if (dotest(expr,from,fcn) == tresult)
X	val = to;
X    else if (consp(expr)) {
X	oldstk = xlsave(&carval,&cdrval,NULL);
X	carval.n_ptr = subst(to,from,car(expr),fcn,tresult);
X	cdrval.n_ptr = subst(to,from,cdr(expr),fcn,tresult);
X	val = newnode(LIST);
X	rplaca(val,carval.n_ptr);
X	rplacd(val,cdrval.n_ptr);
X	xlstack = oldstk;
X    }
X    else
X	val = expr;
X    return (val);
X}
X
X/* xsublis - substitute using an association list */
XNODE *xsublis(args)
X  NODE *args;
X{
X    NODE *oldstk,alist,expr,fcn,*val;
X    int tresult;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&alist,&expr,&fcn,NULL);
X
X    /* get the assocation list and the expression */
X    alist.n_ptr = xlmatch(LIST,&args);
X    expr.n_ptr = xlarg(&args);
X    xltest(&fcn.n_ptr,&tresult,&args);
X    xllastarg(args);
X
X    /* do the substitution */
X    val = sublis(alist.n_ptr,expr.n_ptr,fcn.n_ptr,tresult);
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the result */
X    return (val);
X}
X
X/* sublis - substitute using an association list */
XLOCAL NODE *sublis(alist,expr,fcn,tresult)
X  NODE *alist,*expr,*fcn; int tresult;
X{
X    NODE *oldstk,carval,cdrval,*val;
X
X    if (val = assoc(expr,alist,fcn,tresult))
X	val = cdr(val);
X    else if (consp(expr)) {
X	oldstk = xlsave(&carval,&cdrval,NULL);
X	carval.n_ptr = sublis(alist,car(expr),fcn,tresult);
X	cdrval.n_ptr = sublis(alist,cdr(expr),fcn,tresult);
X	val = newnode(LIST);
X	rplaca(val,carval.n_ptr);
X	rplacd(val,cdrval.n_ptr);
X	xlstack = oldstk;
X    }
X    else
X	val = expr;
X    return (val);
X}
X
X/* assoc - find a pair in an association list */
XLOCAL NODE *assoc(expr,alist,fcn,tresult)
X  NODE *expr,*alist,*fcn; int tresult;
X{
X    NODE *pair;
X
X    for (; consp(alist); alist = cdr(alist))
X	if ((pair = car(alist)) && consp(pair))
X	    if (dotest(expr,car(pair),fcn) == tresult)
X		return (pair);
X    return (NIL);
X}
X
X/* xremove - built-in function 'remove' */
XNODE *xremove(args)
X  NODE *args;
X{
X    NODE *oldstk,x,list,fcn,val,*p,*last;
X    int tresult;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&x,&list,&fcn,&val,NULL);
X
X    /* get the expression to remove and the list */
X    x.n_ptr = xlarg(&args);
X    list.n_ptr = xlmatch(LIST,&args);
X    xltest(&fcn.n_ptr,&tresult,&args);
X    xllastarg(args);
X
X    /* remove matches */
X    while (consp(list.n_ptr)) {
X
X	/* check to see if this element should be deleted */
X	if (dotest(x.n_ptr,car(list.n_ptr),fcn.n_ptr) != tresult) {
X	    p = newnode(LIST);
X	    rplaca(p,car(list.n_ptr));
X	    if (val.n_ptr) rplacd(last,p);
X	    else val.n_ptr = p;
X	    last = p;
X	}
X
X	/* move to the next element */
X	list.n_ptr = cdr(list.n_ptr);
X    }
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the updated list */
X    return (val.n_ptr);
X}
X
X/* dotest - call a test function */
Xint dotest(arg1,arg2,fcn)
X  NODE *arg1,*arg2,*fcn;
X{
X    NODE *oldstk,args,*val;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&args,NULL);
X
X    /* build an argument list */
X    args.n_ptr = newnode(LIST);
X    rplaca(args.n_ptr,arg1);
X    rplacd(args.n_ptr,newnode(LIST));
X    rplaca(cdr(args.n_ptr),arg2);
X
X    /* apply the test function */
X    val = xlapply(fcn,args.n_ptr);
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the result of the test */
X    return (val != NIL);
X}
X
X/* xnth - return the nth element of a list */
XNODE *xnth(args)
X  NODE *args;
X{
X    return (nth(args,TRUE));
X}
X
X/* xnthcdr - return the nth cdr of a list */
XNODE *xnthcdr(args)
X  NODE *args;
X{
X    return (nth(args,FALSE));
X}
X
X/* nth - internal nth function */
XLOCAL NODE *nth(args,carflag)
X  NODE *args; int carflag;
X{
X    NODE *list;
X    int n;
X
X    /* get n and the list */
X    if ((n = xlmatch(INT,&args)->n_int) < 0)
X	xlfail("bad argument");
X    if ((list = xlmatch(LIST,&args)) == NIL)
X	xlfail("bad argument");
X    xllastarg(args);
X
X    /* find the nth element */
X    while (consp(list) && n--)
X	list = cdr(list);
X
X    /* return the list beginning at the nth element */
X    return (carflag && consp(list) ? car(list) : list);
X}
X
X/* xlength - return the length of a list or string */
XNODE *xlength(args)
X  NODE *args;
X{
X    NODE *arg;
X    int n;
X
X    /* get the list or string */
X    arg = xlarg(&args);
X    xllastarg(args);
X
X    /* find the length of a list */
X    if (listp(arg))
X	for (n = 0; consp(arg); n++)
X	    arg = cdr(arg);
X
X    /* find the length of a string */
X    else if (stringp(arg))
X	n = strlen(arg->n_str);
X
X    /* otherwise, bad argument type */
X    else
X	xlerror("bad argument type",arg);
X
X    /* return the length */
X    return (cvfixnum((FIXNUM)n));
X}
X
X/* xmapc - built-in function 'mapc' */
XNODE *xmapc(args)
X  NODE *args;
X{
X    return (map(args,TRUE,FALSE));
X}
X
X/* xmapcar - built-in function 'mapcar' */
XNODE *xmapcar(args)
X  NODE *args;
X{
X    return (map(args,TRUE,TRUE));
X}
X
X/* xmapl - built-in function 'mapl' */
XNODE *xmapl(args)
X  NODE *args;
X{
X    return (map(args,FALSE,FALSE));
X}
X
X/* xmaplist - built-in function 'maplist' */
XNODE *xmaplist(args)
X  NODE *args;
X{
X    return (map(args,FALSE,TRUE));
X}
X
X/* map - internal mapping function */
XLOCAL NODE *map(args,carflag,valflag)
X  NODE *args; int carflag,valflag;
X{
X    NODE *oldstk,fcn,lists,arglist,val,*last,*p,*x,*y;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&fcn,&lists,&arglist,&val,NULL);
X
X    /* get the function to apply and the first list */
X    fcn.n_ptr = xlarg(&args);
X    lists.n_ptr = xlmatch(LIST,&args);
X
X    /* save the first list if not saving function values */
X    if (!valflag)
X	val.n_ptr = lists.n_ptr;
X
X    /* set up the list of argument lists */
X    p = newnode(LIST);
X    rplaca(p,lists.n_ptr);
X    lists.n_ptr = p;
X
X    /* get the remaining argument lists */
X    while (args) {
X	p = newnode(LIST);
X	rplacd(p,lists.n_ptr);
X	lists.n_ptr = p;
X	rplaca(p,xlmatch(LIST,&args));
X    }
X
X    /* if the function is a symbol, get its value */
X    if (symbolp(fcn.n_ptr))
X	fcn.n_ptr = xleval(fcn.n_ptr);
X
X    /* loop through each of the argument lists */
X    for (;;) {
X
X	/* build an argument list from the sublists */
X	arglist.n_ptr = NIL;
X	for (x = lists.n_ptr; x && (y = car(x)) && consp(y); x = cdr(x)) {
X	    p = newnode(LIST);
X	    rplacd(p,arglist.n_ptr);
X	    arglist.n_ptr = p;
X	    rplaca(p,carflag ? car(y) : y);
X	    rplaca(x,cdr(y));
X	}
X
X	/* quit if any of the lists were empty */
X	if (x) break;
X
X	/* apply the function to the arguments */
X	if (valflag) {
X	    p = newnode(LIST);
X	    if (val.n_ptr) rplacd(last,p);
X	    else val.n_ptr = p;
X	    rplaca(p,xlapply(fcn.n_ptr,arglist.n_ptr));
X	    last = p;
X	}
X	else
X	    xlapply(fcn.n_ptr,arglist.n_ptr);
X    }
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the last test expression value */
X    return (val.n_ptr);
X}
X
X/* xrplca - replace the car of a list node */
XNODE *xrplca(args)
X  NODE *args;
X{
X    NODE *list,*newcar;
X
X    /* get the list and the new car */
X    if ((list = xlmatch(LIST,&args)) == NIL)
X	xlfail("bad argument");
X    newcar = xlarg(&args);
X    xllastarg(args);
X
X    /* replace the car */
X    rplaca(list,newcar);
X
X    /* return the list node that was modified */
X    return (list);
X}
X
X/* xrplcd - replace the cdr of a list node */
XNODE *xrplcd(args)
X  NODE *args;
X{
X    NODE *list,*newcdr;
X
X    /* get the list and the new cdr */
X    if ((list = xlmatch(LIST,&args)) == NIL)
X	xlfail("bad argument");
X    newcdr = xlarg(&args);
X    xllastarg(args);
X
X    /* replace the cdr */
X    rplacd(list,newcdr);
X
X    /* return the list node that was modified */
X    return (list);
X}
X
X/* xnconc - destructively append lists */
XNODE *xnconc(args)
X  NODE *args;
X{
X    NODE *list,*last,*val;
X
X    /* concatenate each argument */
X    for (val = NIL; args; ) {
X
X	/* concatenate this list */
X	if (list = xlmatch(LIST,&args)) {
X
X	    /* check for this being the first non-empty list */
X	    if (val)
X		rplacd(last,list);
X	    else
X		val = list;
X
X	    /* find the end of the list */
X	    while (consp(cdr(list)))
X		list = cdr(list);
X
X	    /* save the new last element */
X	    last = list;
X	}
X    }
X
X    /* return the list */
X    return (val);
X}
X
X/* xdelete - built-in function 'delete' */
XNODE *xdelete(args)
X  NODE *args;
X{
X    NODE *oldstk,x,list,fcn,*last,*val;
X    int tresult;
X
X    /* create a new stack frame */
X    oldstk = xlsave(&x,&list,&fcn,NULL);
X
X    /* get the expression to delete and the list */
X    x.n_ptr = xlarg(&args);
X    list.n_ptr = xlmatch(LIST,&args);
X    xltest(&fcn.n_ptr,&tresult,&args);
X    xllastarg(args);
X
X    /* delete leading matches */
X    while (consp(list.n_ptr)) {
X	if (dotest(x.n_ptr,car(list.n_ptr),fcn.n_ptr) != tresult)
X	    break;
X	list.n_ptr = cdr(list.n_ptr);
X    }
X    val = last = list.n_ptr;
X
X    /* delete embedded matches */
X    if (consp(list.n_ptr)) {
X
X	/* skip the first non-matching element */
X	list.n_ptr = cdr(list.n_ptr);
X
X	/* look for embedded matches */
X	while (consp(list.n_ptr)) {
X
X	    /* check to see if this element should be deleted */
X	    if (dotest(x.n_ptr,car(list.n_ptr),fcn.n_ptr) == tresult)
X		rplacd(last,cdr(list.n_ptr));
X	    else
X		last = list.n_ptr;
X
X	    /* move to the next element */
X	    list.n_ptr = cdr(list.n_ptr);
X 	}
X    }
X
X    /* restore the previous stack frame */
X    xlstack = oldstk;
X
X    /* return the updated list */
X    return (val);
X}
X
X/* xatom - is this an atom? */
XNODE *xatom(args)
X  NODE *args;
X{
X    NODE *arg;
X    arg = xlarg(&args);
X    xllastarg(args);
X    return (atom(arg) ? true : NIL);
X}
X
X/* xsymbolp - is this an symbol? */
XNODE *xsymbolp(args)
X  NODE *args;
X{
X    NODE *arg;
X    arg = xlarg(&args);
X    xllastarg(args);
X    return (arg == NIL || symbolp(arg) ? true : NIL);
X}
X
X/* xnumberp - is this a number? */
XNODE *xnumberp(args)
X  NODE *args;
X{
X    NODE *arg;
X    arg = xlarg(&args);
X    xllastarg(args);
X    return (fixp(arg) || floatp(arg) ? true : NIL);
X}
X
X/* xboundp - is this a value bound to this symbol? */
XNODE *xboundp(args)
X  NODE *args;
X{
X    NODE *sym;
X    sym = xlmatch(SYM,&args);
X    xllastarg(args);
X    return (xlxgetvalue(sym) == s_unbound ? NIL : true);
X}
X
X/* xnull - is this null? */
XNODE *xnull(args)
X  NODE *args;
X{
X    NODE *arg;
X    arg = xlarg(&args);
X    xllastarg(args);
X    return (null(arg) ? true : NIL);
X}
X
X/* xlistp - is this a list? */
XNODE *xlistp(args)
X  NODE *args;
X{
X    NODE *arg;
X    arg = xlarg(&args);
X    xllastarg(args);
X    return (listp(arg) ? true : NIL);
X}
X
X/* xconsp - is this a cons? */
XNODE *xconsp(args)
X  NODE *args;
X{
X    NODE *arg;
X    arg = xlarg(&args);
X    xllastarg(args);
X    return (consp(arg) ? true : NIL);
X}
X
X/* xeq - are these equal? */
XNODE *xeq(args)
X  NODE *args;
X{
X    return (cequal(args,eq));
X}
X
X/* xeql - are these equal? */
XNODE *xeql(args)
X  NODE *args;
X{
X    return (cequal(args,eql));
X}
X
X/* xequal - are these equal? */
XNODE *xequal(args)
X  NODE *args;
X{
X    return (cequal(args,equal));
X}
X
X/* cequal - common eq/eql/equal function */
XLOCAL NODE *cequal(args,fcn)
X  NODE *args; int (*fcn)();
X{
X    NODE *arg1,*arg2;
X
X    /* get the two arguments */
X    arg1 = xlarg(&args);
X    arg2 = xlarg(&args);
X    xllastarg(args);
X
X    /* compare the arguments */
X    return ((*fcn)(arg1,arg2) ? true : NIL);
X}
SHAR_EOF
if test 18035 -ne "`wc -c 'xllist.c'`"
then
	echo shar: error transmitting "'xllist.c'" '(should have been 18035 characters)'
fi
echo shar: extracting "'xlmath.c'" '(10134 characters)'
if test -f 'xlmath.c'
then
	echo shar: over-writing existing file "'xlmath.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xlmath.c'
X/* xlmath - xlisp builtin arithmetic functions */
X/*	Copyright (c) 1985, by David Michael Betz
X	All Rights Reserved
X	Permission is granted for unrestricted non-commercial use	*/
X
X#include 
X#include "xlisp.h"
X
X#ifdef MEGAMAX
Xoverlay "math"
X#endif
X
X/* external variables */
Xextern NODE *xlstack;
Xextern NODE *true;
X
X/* forward declarations */
XFORWARD NODE *unary();
XFORWARD NODE *binary();
XFORWARD NODE *predicate();
XFORWARD NODE *compare();
X
X/* xadd - builtin function for addition */
XNODE *xadd(args)
X  NODE *args;
X{
X    return (binary(args,'+'));
X}
X
X/* xsub - builtin function for subtraction */
XNODE *xsub(args)
X  NODE *args;
X{
X    return (binary(args,'-'));
X}
X
X/* xmul - builtin function for multiplication */
XNODE *xmul(args)
X  NODE *args;
X{
X    return (binary(args,'*'));
X}
X
X/* xdiv - builtin function for division */
XNODE *xdiv(args)
X  NODE *args;
X{
X    return (binary(args,'/'));
X}
X
X/* xrem - builtin function for remainder */
XNODE *xrem(args)
X  NODE *args;
X{
X    return (binary(args,'%'));
X}
X
X/* xmin - builtin function for minimum */
XNODE *xmin(args)
X  NODE *args;
X{
X    return (binary(args,'m'));
X}
X
X/* xmax - builtin function for maximum */
XNODE *xmax(args)
X  NODE *args;
X{
X    return (binary(args,'M'));
X}
X
X/* xexpt - built-in function 'expt' */
XNODE *xexpt(args)
X  NODE *args;
X{
X    return (binary(args,'E'));
X}
X
X/* xbitand - builtin function for bitwise and */
XNODE *xbitand(args)
X  NODE *args;
X{
X    return (binary(args,'&'));
X}
X
X/* xbitior - builtin function for bitwise inclusive or */
XNODE *xbitior(args)
X  NODE *args;
X{
X    return (binary(args,'|'));
X}
X
X/* xbitxor - builtin function for bitwise exclusive or */
XNODE *xbitxor(args)
X  NODE *args;
X{
X    return (binary(args,'^'));
X}
X
X/* binary - handle binary operations */
XLOCAL NODE *binary(args,fcn)
X  NODE *args; int fcn;
X{
X    FIXNUM ival,iarg;
X    FLONUM fval,farg;
X    NODE *arg;
X    int imode;
X
X    /* get the first argument */
X    arg = xlarg(&args);
X
X    /* set the type of the first argument */
X    if (fixp(arg)) {
X	ival = arg->n_int;
X	imode = TRUE;
X    }
X    else if (floatp(arg)) {
X	fval = arg->n_float;
X	imode = FALSE;
X    }
X    else
X	xlerror("bad argument type",arg);
X
X    /* treat '-' with a single argument as a special case */
X    if (fcn == '-' && args == NIL)
X	if (imode)
X	    ival = -ival;
X	else
X	    fval = -fval;
X
X    /* handle each remaining argument */
X    while (args) {
X
X	/* get the next argument */
X	arg = xlarg(&args);
X
X	/* check its type */
X	if (fixp(arg))
X	    if (imode) iarg = arg->n_int;
X	    else farg = (FLONUM)arg->n_int;
X	else if (floatp(arg))
X	    if (imode) { fval = (FLONUM)ival; farg = arg->n_float; imode = FALSE; }
X	    else farg = arg->n_float;
X	else
X	    xlerror("bad argument type",arg);
X
X	/* accumulate the result value */
X	if (imode)
X	    switch (fcn) {
X	    case '+':	ival += iarg; break;
X	    case '-':	ival -= iarg; break;
X	    case '*':	ival *= iarg; break;
X	    case '/':	checkizero(iarg); ival /= iarg; break;
X	    case '%':	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 '&':	ival &= iarg; break;
X	    case '|':	ival |= iarg; break;
X	    case '^':	ival ^= iarg; break;
X	    default:	badiop();
X	    }
X	else
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    }
X
X    /* return the result */
X    return (imode ? cvfixnum(ival) : cvflonum(fval));
X}
X
X/* checkizero - check for integer division by zero */
Xcheckizero(iarg)
X  FIXNUM iarg;
X{
X    if (iarg == 0)
X	xlfail("division by zero");
X}
X
X/* checkfzero - check for floating point division by zero */
Xcheckfzero(farg)
X  FLONUM 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  FLONUM farg;
X{
X    if (farg < 0.0)
X	xlfail("square root of a negative number");
X}
X
X/* xbitnot - bitwise not */
XNODE *xbitnot(args)
X  NODE *args;
X{
X    return (unary(args,'~'));
X}
X
X/* xabs - builtin function for absolute value */
XNODE *xabs(args)
X  NODE *args;
X{
X    return (unary(args,'A'));
X}
X
X/* xadd1 - builtin function for adding one */
XNODE *xadd1(args)
X  NODE *args;
X{
X    return (unary(args,'+'));
X}
X
X/* xsub1 - builtin function for subtracting one */
XNODE *xsub1(args)
X  NODE *args;
X{
X    return (unary(args,'-'));
X}
X
X/* xsin - built-in function 'sin' */
XNODE *xsin(args)
X  NODE *args;
X{
X    return (unary(args,'S'));
X}
X
X/* xcos - built-in function 'cos' */
XNODE *xcos(args)
X  NODE *args;
X{
X    return (unary(args,'C'));
X}
X
X/* xtan - built-in function 'tan' */
XNODE *xtan(args)
X  NODE *args;
X{
X    return (unary(args,'T'));
X}
X
X/* xexp - built-in function 'exp' */
XNODE *xexp(args)
X  NODE *args;
X{
X    return (unary(args,'E'));
X}
X
X/* xsqrt - built-in function 'sqrt' */
XNODE *xsqrt(args)
X  NODE *args;
X{
X    return (unary(args,'R'));
X}
X
X/* xfix - built-in function 'fix' */
XNODE *xfix(args)
X  NODE *args;
X{
X    return (unary(args,'I'));
X}
X
X/* xfloat - built-in function 'float' */
XNODE *xfloat(args)
X  NODE *args;
X{
X    return (unary(args,'F'));
X}
X
X/* unary - handle unary operations */
XLOCAL NODE *unary(args,fcn)
X  NODE *args; int fcn;
X{
X    FLONUM fval;
X    FIXNUM ival;
X    NODE *arg;
X
X    /* get the argument */
X    arg = xlarg(&args);
X    xllastarg(args);
X
X    /* check its type */
X    if (fixp(arg)) {
X	ival = arg->n_int;
X	switch (fcn) {
X	case '~':	ival = ~ival; break;
X	case 'A':	ival = abs(ival); break;
X	case '+':	ival++; break;
X	case '-':	ival--; break;
X	case 'I':	break;
X	case 'F':	return (cvflonum((FLONUM)ival));
X	default:	badiop();
X	}
X	return (cvfixnum(ival));
X    }
X    else if (floatp(arg)) {
X	fval = arg->n_float;
X	switch (fcn) {
X	case 'A':	fval = fabs(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 'E':	fval = exp(fval); break;
X	case 'R':	checkfneg(fval); fval = sqrt(fval); break;
X	case 'I':	return (cvfixnum((FIXNUM)fval));
X	case 'F':	break;
X	default:	badfop();
X	}
X	return (cvflonum(fval));
X    }
X    else
X	xlerror("bad argument type",arg);
X}
X
X/* xminusp - is this number negative? */
XNODE *xminusp(args)
X  NODE *args;
X{
X    return (predicate(args,'-'));
X}
X
X/* xzerop - is this number zero? */
XNODE *xzerop(args)
X  NODE *args;
X{
X    return (predicate(args,'Z'));
X}
X
X/* xplusp - is this number positive? */
XNODE *xplusp(args)
X  NODE *args;
X{
X    return (predicate(args,'+'));
X}
X
X/* xevenp - is this number even? */
XNODE *xevenp(args)
X  NODE *args;
X{
X    return (predicate(args,'E'));
X}
X
X/* xoddp - is this number odd? */
XNODE *xoddp(args)
X  NODE *args;
X{
X    return (predicate(args,'O'));
X}
X
X/* predicate - handle a predicate function */
XLOCAL NODE *predicate(args,fcn)
X  NODE *args; int fcn;
X{
X    FLONUM fval;
X    FIXNUM ival;
X    NODE *arg;
X
X    /* get the argument */
X    arg = xlarg(&args);
X    xllastarg(args);
X
X    /* check the argument type */
X    if (fixp(arg)) {
X	ival = arg->n_int;
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 = arg->n_float;
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	xlerror("bad argument type",arg);
X
X    /* return the result value */
X    return (ival ? true : NIL);
X}
X
X/* xlss - builtin function for < */
XNODE *xlss(args)
X  NODE *args;
X{
X    return (compare(args,'<'));
X}
X
X/* xleq - builtin function for <= */
XNODE *xleq(args)
X  NODE *args;
X{
X    return (compare(args,'L'));
X}
X
X/* equ - builtin function for = */
XNODE *xequ(args)
X  NODE *args;
X{
X    return (compare(args,'='));
X}
X
X/* xneq - builtin function for /= */
XNODE *xneq(args)
X  NODE *args;
X{
X    return (compare(args,'#'));
X}
X
X/* xgeq - builtin function for >= */
XNODE *xgeq(args)
X  NODE *args;
X{
X    return (compare(args,'G'));
X}
X
X/* xgtr - builtin function for > */
XNODE *xgtr(args)
X  NODE *args;
X{
X    return (compare(args,'>'));
X}
X
X/* compare - common compare function */
XLOCAL NODE *compare(args,fcn)
X  NODE *args; int fcn;
X{
X    NODE *arg1,*arg2;
X    FIXNUM icmp;
X    FLONUM fcmp;
X    int imode;
X
X    /* get the two arguments */
X    arg1 = xlarg(&args);
X    arg2 = xlarg(&args);
X    xllastarg(args);
X
X    /* do the compare */
X    if (stringp(arg1) && stringp(arg2)) {
X	icmp = strcmp(arg1->n_str,arg2->n_str);
X	imode = TRUE;
X    }
X    else if (fixp(arg1) && fixp(arg2)) {
X	icmp = arg1->n_int - arg2->n_int;
X	imode = TRUE;
X    }
X    else if (floatp(arg1) && floatp(arg2)) {
X	fcmp = arg1->n_float - arg2->n_float;
X	imode = FALSE;
X    }
X    else if (fixp(arg1) && floatp(arg2)) {
X	fcmp = (FLONUM)arg1->n_int - arg2->n_float;
X	imode = FALSE;
X    }
X    else if (floatp(arg1) && fixp(arg2)) {
X	fcmp = arg1->n_float - (FLONUM)arg2->n_int;
X	imode = FALSE;
X    }
X    else
X	xlfail("expecting strings, integers or floats");
X
X    /* compute result of the compare */
X    if (imode)
X	switch (fcn) {
X	case '<':	icmp = (icmp < 0); break;
X	case 'L':	icmp = (icmp <= 0); break;
X	case '=':	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    else
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 '#':	icmp = (fcmp != 0.0); break;
X	case 'G':	icmp = (fcmp >= 0.0); break;
X	case '>':	icmp = (fcmp > 0.0); break;
X	}
X
X    /* return the result */
X    return (icmp ? true : NIL);
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}
SHAR_EOF
if test 10134 -ne "`wc -c 'xlmath.c'`"
then
	echo shar: error transmitting "'xlmath.c'" '(should have been 10134 characters)'
fi
#	End of shell archive
exit 0

-- 
					Jwahar R. Bammi
			       Usenet:  .....!decvax!cwruecmp!bammi
			        CSnet:  bammi@case
				 Arpa:  bammi%case@csnet-relay
			   CompuServe:  71515,155
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: xlisp (PART 4 of 6)
Next Topic: xlisp (PART 6 of 6)
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Apr 24 04:09:24 EDT 2024

Total time taken to generate the page: 0.01338 seconds