sources-request@mirror.UUCP (08/13/86)
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