Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site mit-eddie.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!jfw From: jfw@mit-eddie.UUCP (John Woods) Newsgroups: net.sources Subject: Dave Betz' XLISP 1.2 (The Real Thing) Part 2/5 Message-ID: <3546@mit-eddie.UUCP> Date: Sat, 2-Feb-85 16:51:55 EST Article-I.D.: mit-eddi.3546 Posted: Sat Feb 2 16:51:55 1985 Date-Received: Sun, 3-Feb-85 11:26:16 EST Distribution: net.sources Organization: MIT, Cambridge, MA Lines: 1652 [ Replace this line with your bug ] Here is part two of the Newest XLISP 1.2 posting. echo extract with sh, not csh echo x XLFIO.C cat > XLFIO.C << '!Funky!Stuff!' /* xlfio.c - xlisp file i/o */ #ifdef AZTEC #include "stdio.h" #else #include #include #endif #include "xlisp.h" /* external variables */ extern struct node *s_stdin,*s_stdout; extern struct node *xlstack; extern int xlfsize; /* external routines */ extern FILE *fopen(); /* local variables */ static char buf[STRMAX+1]; /* forward declarations */ FORWARD struct node *printit(); FORWARD struct node *flatsize(); FORWARD struct node *explode(); FORWARD struct node *makesym(); FORWARD struct node *openit(); FORWARD struct node *getfile(); /* xread - read an expression */ struct node *xread(args) struct node *args; { struct node *oldstk,fptr,eof,*val; /* create a new stack frame */ oldstk = xlsave(&fptr,&eof,NULL); /* get file pointer and eof value */ fptr.n_ptr = (args ? getfile(&args) : s_stdin->n_symvalue); eof.n_ptr = (args ? xlarg(&args) : NULL); xllastarg(args); /* read an expression */ if (!xlread(fptr.n_ptr,&val)) val = eof.n_ptr; /* restore the previous stack frame */ xlstack = oldstk; /* return the expression */ return (val); } /* xprint - builtin function 'print' */ struct node *xprint(args) struct node *args; { return (printit(args,TRUE,TRUE)); } /* xprin1 - builtin function 'prin1' */ struct node *xprin1(args) struct node *args; { return (printit(args,TRUE,FALSE)); } /* xprinc - builtin function princ */ struct node *xprinc(args) struct node *args; { return (printit(args,FALSE,FALSE)); } /* xterpri - terminate the current print line */ struct node *xterpri(args) struct node *args; { struct node *fptr; /* get file pointer */ fptr = (args ? getfile(&args) : s_stdout->n_symvalue); xllastarg(args); /* terminate the print line and return nil */ xlterpri(fptr); return (NULL); } /* printit - common print function */ LOCAL struct node *printit(args,pflag,tflag) struct node *args; int pflag,tflag; { struct node *oldstk,fptr,val; /* create a new stack frame */ oldstk = xlsave(&fptr,&val,NULL); /* get expression to print and file pointer */ val.n_ptr = xlarg(&args); fptr.n_ptr = (args ? getfile(&args) : s_stdout->n_symvalue); xllastarg(args); /* print the value */ xlprint(fptr.n_ptr,val.n_ptr,pflag); /* terminate the print line if necessary */ if (tflag) xlterpri(fptr.n_ptr); /* restore the previous stack frame */ xlstack = oldstk; /* return the result */ return (val.n_ptr); } /* xflatsize - compute the size of a printed representation using prin1 */ struct node *xflatsize(args) struct node *args; { return (flatsize(args,TRUE)); } /* xflatc - compute the size of a printed representation using princ */ struct node *xflatc(args) struct node *args; { return (flatsize(args,FALSE)); } /* flatsize - compute the size of a printed expression */ LOCAL struct node *flatsize(args,pflag) struct node *args; int pflag; { struct node *oldstk,val; /* create a new stack frame */ oldstk = xlsave(&val,NULL); /* get the expression */ val.n_ptr = xlarg(&args); xllastarg(args); /* print the value to compute its size */ xlfsize = 0; xlprint(NULL,val.n_ptr,pflag); /* restore the previous stack frame */ xlstack = oldstk; /* return the length of the expression */ val.n_ptr = newnode(INT); val.n_ptr->n_int = xlfsize; return (val.n_ptr); } /* xexplode - explode an expression */ struct node *xexplode(args) struct node *args; { return (explode(args,TRUE)); } /* xexplc - explode an expression using princ */ struct node *xexplc(args) struct node *args; { return (explode(args,FALSE)); } /* explode - internal explode routine */ LOCAL struct node *explode(args,pflag) struct node *args; int pflag; { struct node *oldstk,val,strm; /* create a new stack frame */ oldstk = xlsave(&val,&strm,NULL); /* get the expression */ val.n_ptr = xlarg(&args); xllastarg(args); /* create a stream */ strm.n_ptr = newnode(LIST); /* print the value into the stream */ xlprint(strm.n_ptr,val.n_ptr,pflag); /* restore the previous stack frame */ xlstack = oldstk; /* return the list of characters */ return (strm.n_ptr->n_listvalue); } /* ximplode - implode a list of characters into an expression */ struct node *ximplode(args) struct node *args; { return (makesym(args,TRUE)); } /* xmaknam - implode a list of characters into an uninterned symbol */ struct node *xmaknam(args) struct node *args; { return (makesym(args,FALSE)); } /* makesym - internal implode routine */ LOCAL struct node *makesym(args,intflag) struct node *args; int intflag; { struct node *list,*val; char *p; /* get the list */ list = xlarg(&args); xllastarg(args); /* assemble the symbol's pname */ for (p = buf; list && list->n_type == LIST; list = list->n_listnext) { if ((val = list->n_listvalue) == NULL || val->n_type != INT) xlfail("bad character list"); if ((int)(p - buf) < STRMAX) *p++ = val->n_int; } *p = 0; /* create a symbol */ val = (intflag ? xlenter(buf,DYNAMIC) : xlmakesym(buf,DYNAMIC)); /* return the symbol */ return (val); } /* xopeni - open an input file */ struct node *xopeni(args) struct node *args; { return (openit(args,"r")); } /* xopeno - open an output file */ struct node *xopeno(args) struct node *args; { return (openit(args,"w")); } /* openit - common file open routine */ LOCAL struct node *openit(args,mode) struct node *args; char *mode; { struct node *fname,*val; FILE *fp; /* get the file name */ fname = xlmatch(STR,&args); xllastarg(args); /* try to open the file */ if ((fp = fopen(fname->n_str,mode)) != NULL) { val = newnode(FPTR); val->n_fp = fp; val->n_savech = 0; } else val = NULL; /* return the file pointer */ return (val); } /* xclose - close a file */ struct node *xclose(args) struct node *args; { struct node *fptr; /* get file pointer */ fptr = xlmatch(FPTR,&args); xllastarg(args); /* make sure the file exists */ if (fptr->n_fp == NULL) xlfail("file not open"); /* close the file */ fclose(fptr->n_fp); fptr->n_fp = NULL; /* return nil */ return (NULL); } /* xrdchar - read a character from a file */ struct node *xrdchar(args) struct node *args; { struct node *fptr,*val; int ch; /* get file pointer */ fptr = (args ? getfile(&args) : s_stdin->n_symvalue); xllastarg(args); /* get character and check for eof */ if ((ch = xlgetc(fptr)) == EOF) val = NULL; else { val = newnode(INT); val->n_int = ch; } /* return the character */ return (val); } /* xpkchar - peek at a character from a file */ struct node *xpkchar(args) struct node *args; { struct node *flag,*fptr,*val; int ch; /* peek flag and get file pointer */ flag = (args ? xlarg(&args) : NULL); fptr = (args ? getfile(&args) : s_stdin->n_symvalue); 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); /* check for eof */ if (ch == EOF) val = NULL; else { val = newnode(INT); val->n_int = ch; } /* return the character */ return (val); } /* xwrchar - write a character to a file */ struct node *xwrchar(args) struct node *args; { struct node *fptr,*chr; /* get the character and file pointer */ chr = xlmatch(INT,&args); fptr = (args ? getfile(&args) : s_stdout->n_symvalue); xllastarg(args); /* put character to the file */ xlputc(fptr,chr->n_int); /* return the character */ return (chr); } /* xreadline - read a line from a file */ struct node *xreadline(args) struct node *args; { struct node *oldstk,fptr,str; char *p,*sptr; int len,ch; /* create a new stack frame */ oldstk = xlsave(&fptr,&str,NULL); /* get file pointer */ fptr.n_ptr = (args ? getfile(&args) : s_stdin->n_symvalue); xllastarg(args); /* make a string node */ str.n_ptr = newnode(STR); str.n_ptr->n_strtype = DYNAMIC; /* get character and check for eof */ len = 0; p = buf; while ((ch = xlgetc(fptr.n_ptr)) != EOF && ch != '\n') { /* check for buffer overflow */ if ((int)(p - buf) == STRMAX) { *p = 0; sptr = stralloc(len + STRMAX); *sptr = 0; if (len) { strcpy(sptr,str.n_ptr->n_str); strfree(str.n_ptr->n_str); } str.n_ptr->n_str = sptr; strcat(sptr,buf); len += STRMAX; p = buf; } /* store the character */ *p++ = ch; } /* check for end of file */ if (len == 0 && p == buf && ch == EOF) { xlstack = oldstk; return (NULL); } /* append the last substring */ *p = 0; sptr = stralloc(len + (int)(p - buf)); *sptr = 0; if (len) { strcpy(sptr,str.n_ptr->n_str); strfree(str.n_ptr->n_str); } str.n_ptr->n_str = sptr; strcat(sptr,buf); /* restore the previous stack frame */ xlstack = oldstk; /* return the string */ return (str.n_ptr); } /* getfile - get a file or stream */ LOCAL struct node *getfile(pargs) struct node **pargs; { struct node *arg; /* get a file or stream (cons) or nil */ if (arg = xlarg(pargs)) { if (arg->n_type == FPTR) { if (arg->n_fp == NULL) xlfail("file closed"); } else if (arg->n_type != LIST) xlfail("bad file or stream"); } return (arg); } !Funky!Stuff! echo x XLFIO.C cat > XLFIO.C << '!Funky!Stuff!' /* xlfio.c - xlisp file i/o */ #ifdef AZTEC #include "stdio.h" #else #include #include #endif #include "xlisp.h" /* external variables */ extern struct node *s_stdin,*s_stdout; extern struct node *xlstack; extern int xlfsize; /* external routines */ extern FILE *fopen(); /* local variables */ static char buf[STRMAX+1]; /* forward declarations */ FORWARD struct node *printit(); FORWARD struct node *flatsize(); FORWARD struct node *explode(); FORWARD struct node *makesym(); FORWARD struct node *openit(); FORWARD struct node *getfile(); /* xread - read an expression */ struct node *xread(args) struct node *args; { struct node *oldstk,fptr,eof,*val; /* create a new stack frame */ oldstk = xlsave(&fptr,&eof,NULL); /* get file pointer and eof value */ fptr.n_ptr = (args ? getfile(&args) : s_stdin->n_symvalue); eof.n_ptr = (args ? xlarg(&args) : NULL); xllastarg(args); /* read an expression */ if (!xlread(fptr.n_ptr,&val)) val = eof.n_ptr; /* restore the previous stack frame */ xlstack = oldstk; /* return the expression */ return (val); } /* xprint - builtin function 'print' */ struct node *xprint(args) struct node *args; { return (printit(args,TRUE,TRUE)); } /* xprin1 - builtin function 'prin1' */ struct node *xprin1(args) struct node *args; { return (printit(args,TRUE,FALSE)); } /* xprinc - builtin function princ */ struct node *xprinc(args) struct node *args; { return (printit(args,FALSE,FALSE)); } /* xterpri - terminate the current print line */ struct node *xterpri(args) struct node *args; { struct node *fptr; /* get file pointer */ fptr = (args ? getfile(&args) : s_stdout->n_symvalue); xllastarg(args); /* terminate the print line and return nil */ xlterpri(fptr); return (NULL); } /* printit - common print function */ LOCAL struct node *printit(args,pflag,tflag) struct node *args; int pflag,tflag; { struct node *oldstk,fptr,val; /* create a new stack frame */ oldstk = xlsave(&fptr,&val,NULL); /* get expression to print and file pointer */ val.n_ptr = xlarg(&args); fptr.n_ptr = (args ? getfile(&args) : s_stdout->n_symvalue); xllastarg(args); /* print the value */ xlprint(fptr.n_ptr,val.n_ptr,pflag); /* terminate the print line if necessary */ if (tflag) xlterpri(fptr.n_ptr); /* restore the previous stack frame */ xlstack = oldstk; /* return the result */ return (val.n_ptr); } /* xflatsize - compute the size of a printed representation using prin1 */ struct node *xflatsize(args) struct node *args; { return (flatsize(args,TRUE)); } /* xflatc - compute the size of a printed representation using princ */ struct node *xflatc(args) struct node *args; { return (flatsize(args,FALSE)); } /* flatsize - compute the size of a printed expression */ LOCAL struct node *flatsize(args,pflag) struct node *args; int pflag; { struct node *oldstk,val; /* create a new stack frame */ oldstk = xlsave(&val,NULL); /* get the expression */ val.n_ptr = xlarg(&args); xllastarg(args); /* print the value to compute its size */ xlfsize = 0; xlprint(NULL,val.n_ptr,pflag); /* restore the previous stack frame */ xlstack = oldstk; /* return the length of the expression */ val.n_ptr = newnode(INT); val.n_ptr->n_int = xlfsize; return (val.n_ptr); } /* xexplode - explode an expression */ struct node *xexplode(args) struct node *args; { return (explode(args,TRUE)); } /* xexplc - explode an expression using princ */ struct node *xexplc(args) struct node *args; { return (explode(args,FALSE)); } /* explode - internal explode routine */ LOCAL struct node *explode(args,pflag) struct node *args; int pflag; { struct node *oldstk,val,strm; /* create a new stack frame */ oldstk = xlsave(&val,&strm,NULL); /* get the expression */ val.n_ptr = xlarg(&args); xllastarg(args); /* create a stream */ strm.n_ptr = newnode(LIST); /* print the value into the stream */ xlprint(strm.n_ptr,val.n_ptr,pflag); /* restore the previous stack frame */ xlstack = oldstk; /* return the list of characters */ return (strm.n_ptr->n_listvalue); } /* ximplode - implode a list of characters into an expression */ struct node *ximplode(args) struct node *args; { return (makesym(args,TRUE)); } /* xmaknam - implode a list of characters into an uninterned symbol */ struct node *xmaknam(args) struct node *args; { return (makesym(args,FALSE)); } /* makesym - internal implode routine */ LOCAL struct node *makesym(args,intflag) struct node *args; int intflag; { struct node *list,*val; char *p; /* get the list */ list = xlarg(&args); xllastarg(args); /* assemble the symbol's pname */ for (p = buf; list && list->n_type == LIST; list = list->n_listnext) { if ((val = list->n_listvalue) == NULL || val->n_type != INT) xlfail("bad character list"); if ((int)(p - buf) < STRMAX) *p++ = val->n_int; } *p = 0; /* create a symbol */ val = (intflag ? xlenter(buf,DYNAMIC) : xlmakesym(buf,DYNAMIC)); /* return the symbol */ return (val); } /* xopeni - open an input file */ struct node *xopeni(args) struct node *args; { return (openit(args,"r")); } /* xopeno - open an output file */ struct node *xopeno(args) struct node *args; { return (openit(args,"w")); } /* openit - common file open routine */ LOCAL struct node *openit(args,mode) struct node *args; char *mode; { struct node *fname,*val; FILE *fp; /* get the file name */ fname = xlmatch(STR,&args); xllastarg(args); /* try to open the file */ if ((fp = fopen(fname->n_str,mode)) != NULL) { val = newnode(FPTR); val->n_fp = fp; val->n_savech = 0; } else val = NULL; /* return the file pointer */ return (val); } /* xclose - close a file */ struct node *xclose(args) struct node *args; { struct node *fptr; /* get file pointer */ fptr = xlmatch(FPTR,&args); xllastarg(args); /* make sure the file exists */ if (fptr->n_fp == NULL) xlfail("file not open"); /* close the file */ fclose(fptr->n_fp); fptr->n_fp = NULL; /* return nil */ return (NULL); } /* xrdchar - read a character from a file */ struct node *xrdchar(args) struct node *args; { struct node *fptr,*val; int ch; /* get file pointer */ fptr = (args ? getfile(&args) : s_stdin->n_symvalue); xllastarg(args); /* get character and check for eof */ if ((ch = xlgetc(fptr)) == EOF) val = NULL; else { val = newnode(INT); val->n_int = ch; } /* return the character */ return (val); } /* xpkchar - peek at a character from a file */ struct node *xpkchar(args) struct node *args; { struct node *flag,*fptr,*val; int ch; /* peek flag and get file pointer */ flag = (args ? xlarg(&args) : NULL); fptr = (args ? getfile(&args) : s_stdin->n_symvalue); 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); /* check for eof */ if (ch == EOF) val = NULL; else { val = newnode(INT); val->n_int = ch; } /* return the character */ return (val); } /* xwrchar - write a character to a file */ struct node *xwrchar(args) struct node *args; { struct node *fptr,*chr; /* get the character and file pointer */ chr = xlmatch(INT,&args); fptr = (args ? getfile(&args) : s_stdout->n_symvalue); xllastarg(args); /* put character to the file */ xlputc(fptr,chr->n_int); /* return the character */ return (chr); } /* xreadline - read a line from a file */ struct node *xreadline(args) struct node *args; { struct node *oldstk,fptr,str; char *p,*sptr; int len,ch; /* create a new stack frame */ oldstk = xlsave(&fptr,&str,NULL); /* get file pointer */ fptr.n_ptr = (args ? getfile(&args) : s_stdin->n_symvalue); xllastarg(args); /* make a string node */ str.n_ptr = newnode(STR); str.n_ptr->n_strtype = DYNAMIC; /* get character and check for eof */ len = 0; p = buf; while ((ch = xlgetc(fptr.n_ptr)) != EOF && ch != '\n') { /* check for buffer overflow */ if ((int)(p - buf) == STRMAX) { *p = 0; sptr = stralloc(len + STRMAX); *sptr = 0; if (len) { strcpy(sptr,str.n_ptr->n_str); strfree(str.n_ptr->n_str); } str.n_ptr->n_str = sptr; strcat(sptr,buf); len += STRMAX; p = buf; } /* store the character */ *p++ = ch; } /* check for end of file */ if (len == 0 && p == buf && ch == EOF) { xlstack = oldstk; return (NULL); } /* append the last substring */ *p = 0; sptr = stralloc(len + (int)(p - buf)); *sptr = 0; if (len) { strcpy(sptr,str.n_ptr->n_str); strfree(str.n_ptr->n_str); } str.n_ptr->n_str = sptr; strcat(sptr,buf); /* restore the previous stack frame */ xlstack = oldstk; /* return the string */ return (str.n_ptr); } /* getfile - get a file or stream */ LOCAL struct node *getfile(pargs) struct node **pargs; { struct node *arg; /* get a file or stream (cons) or nil */ if (arg = xlarg(pargs)) { if (arg->n_type == FPTR) { if (arg->n_fp == NULL) xlfail("file closed"); } else if (arg->n_type != LIST) xlfail("bad file or stream"); } return (arg); } !Funky!Stuff! echo x XLFTAB.C cat > XLFTAB.C << '!Funky!Stuff!' /* xlftab.c - xlisp function table */ #ifdef AZTEC #include "stdio.h" #else #include #endif #include "xlisp.h" /* external functions */ extern struct node *xeval(),*xapply(),*xfuncall(),*xquote(), *xset(),*xsetq(),*xdefun(),*xndefun(), *xgensym(),*xintern(),*xsymname(),*xsymplist(), *xget(),*xputprop(),*xremprop(), *xcar(),*xcaar(),*xcadr(),*xcdr(),*xcdar(),*xcddr(), *xcons(),*xlist(),*xappend(),*xreverse(),*xlast(),*xnth(),*xnthcdr(), *xmember(),*xmemq(),*xassoc(),*xassq(),*xsubst(),*xsublis(),*xlength(), *xmapcar(),*xmaplist(), *xrplca(),*xrplcd(),*xnconc(),*xdelete(),*xdelq(), *xatom(),*xsymbolp(),*xnumberp(),*xboundp(),*xnull(),*xlistp(),*xconsp(), *xeq(),*xequal(), *xcond(),*xand(),*xor(),*xlet(),*xif(),*xprogn(), *xwhile(),*xrepeat(), *xadd(),*xsub(),*xmul(),*xdiv(),*xrem(),*xminus(),*xmin(),*xmax(),*xabs(), *xadd1(),*xsub1(),*xbitand(),*xbitior(),*xbitxor(),*xbitnot(), *xlss(),*xleq(),*xeql(),*xneq(),*xgeq(),*xgtr(), *xstrlen(),*xstrcat(),*xsubstr(),*xascii(),*xchr(),*xatoi(),*xitoa(), *xread(),*xprint(),*xprin1(),*xprinc(),*xterpri(), *xflatsize(),*xflatc(),*xexplode(),*xexplc(),*ximplode(),*xmaknam(), *xopeni(),*xopeno(),*xclose(),*xrdchar(),*xpkchar(),*xwrchar(),*xreadline(), *xload(),*xgc(),*xexpand(),*xalloc(),*xmem(),*xtype(),*xexit(); struct fdef ftab[] = { /* evaluator functions */ "eval", SUBR, xeval, "apply", SUBR, xapply, "funcall", SUBR, xfuncall, "quote", FSUBR, xquote, /* symbol functions */ "set", SUBR, xset, "setq", FSUBR, xsetq, "defun", FSUBR, xdefun, "ndefun", FSUBR, xndefun, "gensym", SUBR, xgensym, "intern", SUBR, xintern, "symbol-name", SUBR, xsymname, "symbol-plist", SUBR, xsymplist, "get", SUBR, xget, "putprop", SUBR, xputprop, "remprop", SUBR, xremprop, /* list functions */ "car", SUBR, xcar, "caar", SUBR, xcaar, "cadr", SUBR, xcadr, "cdr", SUBR, xcdr, "cdar", SUBR, xcdar, "cddr", SUBR, xcddr, "cons", SUBR, xcons, "list", SUBR, xlist, "append", SUBR, xappend, "reverse", SUBR, xreverse, "last", SUBR, xlast, "nth", SUBR, xnth, "nthcdr", SUBR, xnthcdr, "member", SUBR, xmember, "memq", SUBR, xmemq, "assoc", SUBR, xassoc, "assq", SUBR, xassq, "subst", SUBR, xsubst, "sublis", SUBR, xsublis, "length", SUBR, xlength, "mapcar", SUBR, xmapcar, "maplist", SUBR, xmaplist, /* destructive list functions */ "rplaca", SUBR, xrplca, "rplacd", SUBR, xrplcd, "nconc", SUBR, xnconc, "delete", SUBR, xdelete, "delq", SUBR, xdelq, /* 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, "eq", SUBR, xeq, "equal", SUBR, xequal, /* control functions */ "cond", FSUBR, xcond, "and", FSUBR, xand, "or", FSUBR, xor, "let", FSUBR, xlet, "if", FSUBR, xif, "progn", FSUBR, xprogn, "while", FSUBR, xwhile, "repeat", FSUBR, xrepeat, /* arithmetic functions */ "+", SUBR, xadd, "-", SUBR, xsub, "*", SUBR, xmul, "/", SUBR, xdiv, "1+", SUBR, xadd1, "1-", SUBR, xsub1, "rem", SUBR, xrem, "minus", SUBR, xminus, "min", SUBR, xmin, "max", SUBR, xmax, "abs", SUBR, xabs, /* 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, xeql, "/=", SUBR, xneq, ">=", SUBR, xgeq, ">", SUBR, xgtr, /* string functions */ "strlen", SUBR, xstrlen, "strcat", SUBR, xstrcat, "substr", SUBR, xsubstr, "ascii", SUBR, xascii, "chr", SUBR, xchr, "atoi", SUBR, xatoi, "itoa", SUBR, xitoa, /* I/O functions */ "read", SUBR, xread, "print", SUBR, xprint, "prin1", SUBR, xprin1, "princ", SUBR, xprinc, "terpri", SUBR, xterpri, "flatsize", SUBR, xflatsize, "flatc", SUBR, xflatc, "explode", SUBR, xexplode, "explodec", SUBR, xexplc, "implode", SUBR, ximplode, "maknam", SUBR, xmaknam, /* 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, "readline", SUBR, xreadline, /* system functions */ "load", SUBR, xload, "gc", SUBR, xgc, "expand", SUBR, xexpand, "alloc", SUBR, xalloc, "mem", SUBR, xmem, "type", SUBR, xtype, "exit", SUBR, xexit, 0 }; !Funky!Stuff! echo x XLINIT.C cat > XLINIT.C << '!Funky!Stuff!' /* xlinit.c - xlisp initialization module */ #ifdef AZTEC #include "stdio.h" #else #include #endif #include "xlisp.h" /* global variables */ struct node *true; struct node *s_quote; struct node *s_lambda,*s_nlambda; struct node *s_stdin,*s_stdout; struct node *s_tracenable; struct node *k_rest,*k_aux; struct node *a_subr; struct node *a_fsubr; struct node *a_list; struct node *a_sym; struct node *a_int; struct node *a_str; struct node *a_obj; struct node *a_fptr; /* external variables */ extern struct fdef ftab[]; /* xlinit - xlisp initialization routine */ xlinit() { struct fdef *fptr; struct node *sym; /* initialize xlisp (must be in this order) */ xlminit(); /* initialize xldmem.c */ xlsinit(); /* initialize xlsym.c */ xleinit(); /* initialize xleval.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 the 't' symbol */ true = xlsenter("t"); true->n_symvalue = true; /* enter some important symbols */ s_quote = xlsenter("quote"); s_lambda = xlsenter("lambda"); s_nlambda = xlsenter("nlambda"); k_rest = xlsenter("&rest"); k_aux = xlsenter("&aux"); /* enter *standard-input* and *standard-output* */ s_stdin = xlsenter("*standard-input*"); s_stdin->n_symvalue = newnode(FPTR); s_stdin->n_symvalue->n_fp = stdin; s_stdin->n_symvalue->n_savech = 0; s_stdout = xlsenter("*standard-output*"); s_stdout->n_symvalue = newnode(FPTR); s_stdout->n_symvalue->n_fp = stdout; s_stdout->n_symvalue->n_savech = 0; /* enter the error traceback enable flag */ s_tracenable = xlsenter("*tracenable*"); s_tracenable->n_symvalue = true; /* enter a copyright notice into the oblist */ sym = xlsenter("**Copyright-1984-by-David-Betz**"); sym->n_symvalue = true; /* enter type names */ a_subr = xlsenter("SUBR"); a_fsubr = xlsenter("FSUBR"); a_list = xlsenter("LIST"); a_sym = xlsenter("SYM"); a_int = xlsenter("INT"); a_str = xlsenter("STR"); a_obj = xlsenter("OBJ"); a_fptr = xlsenter("FPTR"); } !Funky!Stuff! echo x XLIO.C cat > XLIO.C << '!Funky!Stuff!' /* xlio - xlisp i/o routines */ #ifdef AZTEC #include "stdio.h" #else #include #endif #include "xlisp.h" /* global variables */ int xlplevel=0; int xlfsize=0; /* external variables */ extern struct node *xlstack; extern struct node *s_stdin; /* local variables */ static int prompt=TRUE; /* xlgetc - get a character from a file or stream */ int xlgetc(fptr) struct node *fptr; { struct node *lptr,*cptr; FILE *fp; int ch; /* check for input from nil */ if (fptr == NULL) ch = EOF; /* otherwise, check for input from a stream */ else if (fptr->n_type == LIST) { if ((lptr = fptr->n_listvalue) == NULL) ch = EOF; else { if (lptr->n_type != LIST || (cptr = lptr->n_listvalue) == NULL || cptr->n_type != INT) xlfail("bad stream"); if ((fptr->n_listvalue = lptr->n_listnext) == NULL) fptr->n_listnext = NULL; ch = cptr->n_int; } } /* otherwise, check for a buffered file character */ else if (ch = fptr->n_savech) fptr->n_savech = 0; /* otherwise, get a new character */ else { /* get the file pointer */ fp = fptr->n_fp; /* prompt if necessary */ if (prompt && fp == stdin) { if (xlplevel > 0) printf("%d> ",xlplevel); else printf("> "); prompt = FALSE; } /* get the character */ if ((ch = getc(fp)) == '\n' && fp == stdin) prompt = TRUE; /* check for input abort */ if (fp == stdin && ch == '\007') { putchar('\n'); xlfail("input aborted"); } } /* return the character */ return (ch); } /* xlpeek - peek at a character from a file or stream */ int xlpeek(fptr) struct node *fptr; { struct node *lptr,*cptr; int ch; /* check for input from nil */ if (fptr == NULL) ch = EOF; /* otherwise, check for input from a stream */ else if (fptr->n_type == LIST) { if ((lptr = fptr->n_listvalue) == NULL) ch = EOF; else { if (lptr->n_type != LIST || (cptr = lptr->n_listvalue) == NULL || cptr->n_type != INT) xlfail("bad stream"); ch = cptr->n_int; } } /* otherwise, get the next file character and save it */ else ch = fptr->n_savech = xlgetc(fptr); /* return the character */ return (ch); } /* xlputc - put a character to a file or stream */ xlputc(fptr,ch) struct node *fptr; int ch; { struct node *oldstk,lptr; /* count the character */ xlfsize++; /* check for output to nil */ if (fptr == NULL) ; /* otherwise, check for output to a stream */ else if (fptr->n_type == LIST) { oldstk = xlsave(&lptr,NULL); lptr.n_ptr = newnode(LIST); lptr.n_ptr->n_listvalue = newnode(INT); lptr.n_ptr->n_listvalue->n_int = ch; if (fptr->n_listnext) fptr->n_listnext->n_listnext = lptr.n_ptr; else fptr->n_listvalue = lptr.n_ptr; fptr->n_listnext = lptr.n_ptr; xlstack = oldstk; } /* otherwise, output the character to a file */ else putc(ch,fptr->n_fp); } /* xlflush - flush the input buffer */ int xlflush() { if (!prompt) while (xlgetc(s_stdin->n_symvalue) != '\n') ; } !Funky!Stuff! echo x XLISP.C cat > XLISP.C << '!Funky!Stuff!' /* xlisp - a small subset of lisp */ #ifdef AZTEC #include "stdio.h" #include "setjmp.h" #else #include #include #endif #include "xlisp.h" /* global variables */ jmp_buf *xljmpbuf; jmp_buf topjmpbuf; /* external variables */ extern struct node *xlenv; extern struct node *xlstack; extern struct node *s_stdin,*s_stdout; /* main - the main routine */ main(argc,argv) int argc; char *argv[]; { struct node expr; int i; /* print the banner line */ printf("XLISP version 1.2\n"); /* setup the error handler context buffer */ xljmpbuf = topjmpbuf; /* setup initialization error handler */ if (setjmp(xljmpbuf)) { printf("fatal initialization error\n"); exit(); } /* initialize xlisp */ xlinit(); /* load "init.lsp" */ if (setjmp(xljmpbuf) == 0) xlload("init"); /* load any files mentioned on the command line */ if (setjmp(xljmpbuf) == 0) for (i = 1; i < argc; i++) { printf("[ loading \"%s\" ]\n",argv[i]); if (!xlload(argv[i])) xlfail("can't load file"); } /* main command processing loop */ while (TRUE) { /* setup the error return */ setjmp(xljmpbuf); /* free any previous expression and leftover context */ xlstack = xlenv = NULL; /* create a new stack frame */ xlsave(&expr,NULL); /* read an expression */ if (!xlread(s_stdin->n_symvalue,&expr.n_ptr)) break; /* evaluate the expression */ expr.n_ptr = xleval(expr.n_ptr); /* print it */ xlprint(s_stdout->n_symvalue,expr.n_ptr,TRUE); xlterpri(s_stdout->n_symvalue); } } !Funky!Stuff! echo x XLISP.H cat > XLISP.H << '!Funky!Stuff!' /* xlisp - a small subset of lisp */ /* system specific definitions */ /* NNODES number of nodes to allocate in each request */ /* TDEPTH trace stack depth */ /* FORWARD type of a forward declaration (usually "") */ /* LOCAL type of a local function (usually "static") */ /* for the Computer Innovations compiler */ #ifdef CI #define NNODES 1000 #define TDEPTH 500 #endif /* for the CPM68K compiler */ #ifdef CPM68K #define NNODES 1000 #define TDEPTH 500 #define LOCAL #undef NULL #define NULL (char *)0 #endif /* for the DeSmet compiler */ #ifdef DESMET #define NNODES 1000 #define TDEPTH 500 #define LOCAL #define getc(fp) getcx(fp) #define EOF -1 #endif /* for the VAX-11 C compiler */ #ifdef vms #define NNODES 2000 #define TDEPTH 1000 #endif /* for the DECUS C compiler */ #ifdef decus #define NNODES 200 #define TDEPTH 100 #define FORWARD extern #endif /* for unix compilers */ #ifdef unix #define NNODES 200 #define TDEPTH 100 #endif /* for the AZTEC C compiler */ #ifdef AZTEC #define NNODES 200 #define TDEPTH 100 #define getc(fp) getcx(fp) #define putc(ch,fp) aputc(ch,fp) #define malloc alloc #define strchr index #endif /* default important definitions */ #ifndef NNODES #define NNODES 200 #endif #ifndef TDEPTH #define TDEPTH 100 #endif #ifndef FORWARD #define FORWARD #endif #ifndef LOCAL #define LOCAL static #endif /* useful definitions */ #define TRUE 1 #define FALSE 0 /* program limits */ #define STRMAX 100 /* maximum length of a string constant */ /* node types */ #define FREE 0 #define SUBR 1 #define FSUBR 2 #define LIST 3 #define SYM 4 #define INT 5 #define STR 6 #define OBJ 7 #define FPTR 8 /* node flags */ #define MARK 1 #define LEFT 2 /* string types */ #define DYNAMIC 0 #define STATIC 1 /* symbol structure */ struct xsym { struct node *xsy_plist; /* symbol plist - points to (name.plist) */ struct node *xsy_value; /* the current value */ }; /* subr/fsubr node structure */ struct xsubr { struct node *(*xsu_subr)(); /* pointer to an internal routine */ }; /* list node structure */ struct xlist { struct node *xl_value; /* value at this node */ struct node *xl_next; /* next node */ }; /* integer node structure */ struct xint { int xi_int; /* integer value */ }; /* string node structure */ struct xstr { int xst_type; /* string type */ char *xst_str; /* string pointer */ }; /* object node structure */ struct xobj { struct node *xo_obclass; /* class of object */ struct node *xo_obdata; /* instance data */ }; /* file pointer node structure */ struct xfptr { FILE *xf_fp; /* the file pointer */ int xf_savech; /* lookahead character for input files */ }; /* shorthand macros for accessing node substructures */ /* symbol node */ #define n_symplist n_info.n_xsym.xsy_plist #define n_symvalue n_info.n_xsym.xsy_value /* subr/fsubr node */ #define n_subr n_info.n_xsubr.xsu_subr /* list node (and message node and binding node) */ #define n_listvalue n_info.n_xlist.xl_value #define n_listnext n_info.n_xlist.xl_next #define n_msg n_info.n_xlist.xl_value #define n_msgcode n_info.n_xlist.xl_next #define n_bndsym n_info.n_xlist.xl_value #define n_bndvalue n_info.n_xlist.xl_next #define n_left n_info.n_xlist.xl_value #define n_right n_info.n_xlist.xl_next #define n_ptr n_info.n_xlist.xl_value /* integer node */ #define n_int n_info.n_xint.xi_int /* string node */ #define n_str n_info.n_xstr.xst_str #define n_strtype n_info.n_xstr.xst_type /* object node */ #define n_obclass n_info.n_xobj.xo_obclass #define n_obdata n_info.n_xobj.xo_obdata /* file pointer node */ #define n_fp n_info.n_xfptr.xf_fp #define n_savech n_info.n_xfptr.xf_savech /* node structure */ struct node { char n_type; /* type of node */ char n_flags; /* flag bits */ union { /* value */ struct xsym n_xsym; /* symbol node */ struct xsubr n_xsubr; /* subr/fsubr node */ struct xlist n_xlist; /* list node */ struct xint n_xint; /* integer node */ struct xstr n_xstr; /* string node */ struct xobj n_xobj; /* object node */ struct xfptr n_xfptr; /* file pointer node */ } n_info; }; /* function table entry structure */ struct fdef { char *f_name; int f_type; struct node *(*f_fcn)(); }; /* external procedure declarations */ extern struct node *xleval(); /* evaluate an expression */ extern struct node *xlapply(); /* apply a function to arguments */ extern struct node *xlevlist(); /* evaluate a list of arguments */ extern struct node *xlarg(); /* fetch an argument */ extern struct node *xlevarg(); /* fetch and evaluate an argument */ extern struct node *xlmatch(); /* fetch an typed argument */ extern struct node *xlevmatch(); /* fetch and evaluate a typed arg */ extern struct node *xlsend(); /* send a message to an object */ extern struct node *xlenter(); /* enter a symbol */ extern struct node *xlsenter(); /* enter a symbol with a static pname */ extern struct node *xlintern(); /* intern a symbol */ extern struct node *xlmakesym(); /* make an uninterned symbol */ extern struct node *xlsave(); /* generate a stack frame */ extern struct node *xlobsym(); /* find an object's class or instance variable */ extern struct node *xlgetprop(); /* get the value of a property */ extern char *xlsymname(); /* get the print name of a symbol */ extern struct node *newnode(); /* allocate a new node */ extern char *stralloc(); /* allocate string space */ extern char *strsave(); /* make a safe copy of a string */ !Funky!Stuff! exit 0 -- John Woods, Charles River Data Systems decvax!frog!john, mit-eddie!jfw, JFW%mit-ccc@MIT-XX When your puppy goes off in another room, is it because of the explosive charge?