toby@gargoyle.UChicago.UUCP (Toby Harness) (08/02/84)
> From: ksbc@hirst1.UUCP > When I try to build xlisp, both under unix III and 4.1 I get an error msg > from xldmem.c > line 31: illegal zero sized structure : sgnodes > this is part od the definition of struct segment which reads:- > struct node sg_nodes[]; > Anybody got any advice how to get round this:- 4.1 lets me get away with a > warning, and xlisp seems to work:- however III wants it to be fatal. I am posting this reply because I think it may be useful to other readers, and because I wish to offer some other comments about xlisp. Note also that I will not use many "diffs", as I have changed around a fair bit of code. I will assume that everyone has read and installed the bug fixes already posted. To address the question above first: The portable C complier, and hence most compliers derived from it (and evidently the sys iii complier), won`t swallow such things as "struct node sg_nodes[]" -- they don`t make syntactic (or is that lexical? whatever) sense. There was some discussion of this in net.lang.c not that long ago, under the label "open-ended structures". In any case, the thing you SHOULD do is change this empty structure to a pointer to a structure, i.e. "struct node sg_nodes[]" to "struct node *sg_nodes". I say "should" because this is the most portable way; you might be able to get away with "struct node sg_nodes[1]". If you do it the portable way, you will then have change how memory is allocated for this structure (that is, struct segment). Fortunately this is done in only one place, in addseg, also in xldmem.c (around line 324). Change if ((newseg = (struct segment *) calloc(1,ALLOCSIZE)) != NULL) { to if((newseg = (struct segment *) calloc(1, sizeof(struct segment))) != NULL && (newseg->sg_nodes = (struct node *) calloc(anodes, sizeof(struct node))) != NULL) { Another portable problem will be with xlsave in xleval.c Xlsave is passed a variable number of arguments throughout the xlisp code, but it makes (ok then, the programmer made) some simple assumptions on how it would recieve those arguments. The following fix will only be useful to you if you are fortunate enough to have <varargs.h>. First, include a "#define VARARGS" under the "#ifdef unix" in xlisp.h (I am assuming that varargs is only available to unix sites), then, of course, you will have to put "#include <varargs.h>" under the "#ifdef unix" at the top of xleval.c. Finally, change xlsave to read: #ifdef VARARGS struct node *xlsave(va_alist) va_dcl { va_list argptr; struct node *n, *oldstk; oldstk = xlstack; /* Save old stack pointer */ va_start(argptr) for(n = va_arg(argptr, struct node *); n != NULL; n = va_arg(argptr, struct node *)) { n->n_type = LIST; n->n_listvalue = NULL; n->n_listnext = xlstack; xlstack = n; } va_end(argptr); return(oldstk); /* Return old stack pointer */ } #else struct node *xlsave(n) ... #endif (NOTE: the style above is that of the original source, not mine) A word about reals: I would think most people would want them, and I see no reason why they are defined only for the CI-86 compiler when certainly (for example) every unix C compiler I have seen supports floats. If you do "#define REALS" in xlisp.h, you will have to make the following changes in xllist.c to get the subr "type" to handle them properly. Add #ifdef REALS static struct node *a_real; #endif to the "local variables" section near the top of the file. Then add #ifdef REALS case REAL: return (a_real); #endif to the switch in "type" (around line 140). And finally put #ifdef REALS a_real = xlenter("REAL"); #endif along with the other "xlenter"`s in "xllinit" at the end of the file. With all of that, xlisp seems to work. There are some problems with argument binding that I know of, specificly where the expers created with defun seem to act like fexpers. Some expers that bomb out leave values bound to their arguments as well. I would be interrested in seeing true fexpers, and for that matter, macros and lexpers, if anyone is up to it. I DO realize that xlisp was never intended to be a full implementation of lisp, but as it is the only lisp running on this machine .... Included below is "xlunix.c", which is a group of utilities designed to make xlisp more interactive with unix, and the documentation page (to be tacked on to xlisp.doc) describing them. They were written by me, and are in the public domain. If you wish to use these functions, you will need to install the following (edited) diffs in xlisp.c: 2d1 < 25a25 > #include <signal.h> /* TH*/ 35a36,38 > #ifdef unix /* TH*/ > static jmp_buf ljmp; > #else 36a40 > #endif 69a78,82 > #ifdef unix /* this has to occur after 'xltin' if > * reading of '.xlisprc is to work TH*/ > xluninit(); > #endif > 74a88,93 > #ifdef unix /* TH*/ > signal(SIGCLD, SIG_IGN); /* don`t worry when children die */ > /* as created from "system" and "shell" */ > #endif > 76a96,98 > #ifdef unix > signal(SIGINT, xlintr); /* trap interrupts TH*/ > #endif 100c122,130 < longjmp(ljmp); --- > /*longjmp(ljmp); TH*/ > longjmp(ljmp, 1); > } > > > xlintr() /* TH*/ > { > puts("\nintr"); > xlabort(); Note that the signal catching, while not necessary, provides for resonable interrupt servicing. xlunix.c follows------------------------------------------------ /* xlunix - xlisp unix support routines */ /* note that it is assumed through-out this file * that "unix" is defined. This file was written * by Toby Harness (changes in other files marked * by 'TH') */ #include <stdio.h> #include <xlisp.h> /* external functions */ extern char *getenv(); extern char *strchr(); extern int xlfin(); /* global vars */ extern char **environ; /* local vars */ static struct node *true; /************************************ * sys - execute "system" command * ************************************/ static struct node *sys(args) struct node *args; { struct node *cmd; cmd = xlevmatch(STR,&args); xllastarg(args); return( (system(cmd->n_str) == 0) ? true : NULL); } /************************************ * shell - escape to lower shell * ************************************/ /* this really should pick SHELL from the * bound vars (see bind_env) */ static struct node *shell(args) struct node *args; { static char *shnam = NULL; int fstatus; xllastarg(args); if(shnam == NULL && (shnam = getenv("SHELL")) == NULL) shnam = "/bin/sh"; if(fork() == 0) { execl(shnam, shnam, 0); puts("cannot exec shell"); } else wait(&fstatus); return( (fstatus == 0) ? true : NULL); } /**************************************** * bind_env - bind enviornment to atoms * ****************************************/ static bind_env() { int i; char *cp; for(i = 0; environ[i] != NULL; i++) { cp = strchr(environ[i], '='); *cp = '\0'; xlsvar(environ[i], cp+1); *cp = '='; } } /******************************** * cd - change working directory * ********************************/ static struct node *cd(args) struct node *args; { struct node *cdir, *val; cdir = xlevmatch(STR, &args); xllastarg(args); return( (chdir(cdir->n_str) == 0) ? true : NULL); } /****************************************** * readrc - read in ".xlisprc" in HOME dir * ******************************************/ static int readrc() { char rcnam[128]; strcpy(rcnam, getenv("HOME")); strcat(rcnam, "/.xlisprc"); if(access(rcnam, 04) == 0) xlfin(rcnam); } /****************************************** * xluninit - unix initialization routine * *******************************************/ xluninit() { bind_env(); true = xlenter("t"); xlsubr("system", sys); xlsubr("sh", shell); xlsubr("cd", cd); readrc(); } xlisp.doc.a follows-------------------------------------------- XLISP: An Experimental Object Oriented Language Page 20 FUNCTIONS Unix utility functions (local additions): (cd <expr>) CHANGE DIRECTORY <expr> string expression returns t if successful, else nil (sh) ESCAPE TO SHELL returns t if exit status is 0, else nil (system <expr>) EXECUTE COMMAND IN A UNIX SHELL <expr> string expression to be executed returns t if exit status is 0, else nil In addition to these functions, all the environmental variables have been defined and bound to a string representation of their contents, e.g. if TERM=hp then `(print TERM)' would print "hp". The file ".xlisprc" in the user`s home directory, if it exists, is read-in on start up if no arguments are given. If an argument is given, it is assumed to be a filename and is read-in in place of any ".xlisprc" file. Sorry for the length of this. I hope it has been of some help. Toby Harness Ogburn/Stouffer Center, University of Chicago ...ihnp4!gargoyle!toby
ksbc@hirst1.UUCP (08/08/84)
When I try to build xlisp, both under unix III and 4.1 I get an error msg from xldmem.c line 31: illegal zero sized structure : sgnodes this is part od the deffinition of struct segment which reads:- struct node sg_nodes[]; Anybody got any advice how to get round this:- 4.1 lets me get away with a warning, and xlisp seems to work:- however III wants it to be fatal.
jfw@mit-eddie.UUCP (John Woods) (08/11/84)
You mentioned wondering about fexprs and lexprs in XLISP. I have modified (heavily) XLISP to have SUBRs and FSUBRs as well as EXPRs and FEXPRs. In fact, Creeping featurism has been rampant on my terminal. MACROs are scheduled next, now that I have property lists going. When I think I have something reasonable, I will post a note about the results -- people who are really interested can send me mail at decvax!frog!john, genrad!mit-eddie!jfw, or JFW@MIT-XX (for ARPA types). Fun Fun Fun!! John Woods, Charles River Data Systems, Framingham MA decvax!frog!john, genrad!mit-eddie!jfw, JFW@MIT-XX