bobg+@andrew.cmu.edu (Robert Steven Glickstein) (06/01/89)
> Excerpts from ext.nn.comp.lang.c: 30-May-89 Tiny Lisp written in C Dr. > Roy@willow.Caltech.E (483) > Does anyone know of a public domain lisp interpreter, written > in a high-level language, preferably C, which can control > an application like this? And now for the monthly ELI posting. I am the author of the Andrew System embedded lisp from CMU (called ELI [Embedded Lisp Interpreter]). It is written in very portable C and is available on the X11R3 distribution which can be ftp'd from expo.lcs.mit.edu (Internet: 18.30.0.212) in the file "/contrib/eli-dist.tar". It implements an "extended subset" of Common Lisp, and is currently in use as a filtering language for the Andrew Message System. It is a fairly stable if not utterly robust package, but when you buy into ELI, you will also be among the first to know about its upcoming successor, ELSIE (the "Embedded Lisp [Scheme] Interpreter, 'ELSIE'"), which will be even smaller and faster than ELI and which will not be an "extended subset" of anything; it will be a proper superset of the Revised^4 Report on Scheme, complete with a Lisp compatability module and tons of other wonderful features such as dynamic loading and user-defined types. If you are interested in discussing ELI or ELSIE, or indeed any other part of the Andrew system, please check out comp.soft-sys.andrew or subscribe to the mailing list "info-andrew" by sending mail to "info-andrew-request@andrew.cmu.edu". If you are unable to ftp from expo.lcs.mit.edu, send me mail and I can mail you the ELI distribution. Let me know if I can send anyone any more information. ============== Bob Glickstein ITC Database Group Information Technology Center Carnegie Mellon University Pittsburgh, PA ==============
mayer@hplabsz.HPL.HP.COM (Niels Mayer) (06/09/89)
I recently checked out the new version of ELI on expo.lcs.mit.edu by Bob Glickstein to find out whether any of the bugs I have found had been fixed. They weren't unfortunately.... here's some previous postiungs I've made about ELI bugs, just so that you can know to avoid these problems with ELI. ELI is a nifty package, and I'm not trying to denigrate BobG's work. I just wanted to inform y'all of existing bugs in ELI before y'all go off and waste your precious time tracking down anomalous behavior in ELI. ------- Forwarded Messages To: info-andrew@andrew.cmu.edu Subject: BGLISP/ELI -- question, contribution, bugs, and "features" Organization: Hewlett-Packard Labs, Software Technology Lab, Palo Alto, CA. X-Mailer: mh6.6 Date: Tue, 22 Nov 88 01:08:07 PST Message-ID: <610.596192887@hplnpm> From: Niels P. Mayer <mayer@hplnpm> Here are some bugs I've found using ELI/bglisp as released in the X11r3 tape (under contrib/toolkits/andrew/overhead/eli/). I'm running on a HP9000s350 under HPUX 6.2. An aside -- Are any of you out there using FLAMES and/or ELI/bglisp in your applications? I'd love to hear what sort of mail processing you're doing with FLAMES, and what kinds of user-customizable applications you've dreamed up using ELI. Also, I'd like to hear reports of ELI's reliability, scalability, speed, etc. Me? I'm using ELI to build a "widget interpreter" using the HP Xwidgets. The widget iterpreter will be part of a hybrid lisp/c development platform for a highly customizable CSCW/mail system that I'm prototyping. It will NOT be based on AMS/FLAMES, though I might steal EZ for displaying/editing multimedia messages. Oh, and I also have added a few useful primitives to ELI -- lisp interfaces to the unix subroutines popen(3S), pclose(3S), fopen(3S), fclose(3S), fgets(3S), fputs(3S), and fscanf(3S). Anybody want these? And finally, here's da bugs -- anybody got a fix? - ------------------------------------------------------------------------------ (1) I found this bug in "let", while tracking down a misfeature in "do" (see (2) below): (setq a 666) (progn (printf "before let a = %S\n" a) (let ((a 3)) (progn (printf "in let, before setq, a = %S\n" a) (setq a 5) (printf "in let, after setq, a = %S\n" a) ) ) (printf "after let, a = %S\n" a) ) Evaling the above two expressions gives the following results. > BGLisp> (666) > BGLisp> before let a = 666 > in let, before setq, a = 3 > in let, after setq, a = 3 > after let, a = 5 > (T) In other words, the setq within the let is being bound to the "a" outside of the scope of the let. This pretty much makes "let" and "let*" useless for creating local variables, since you can never change their values. - ------------------------------------------------------------------------------ (2) The reason why I tried out what "let" was doing is because a simple test program I was writing using "do" was failing for totally unexpected reasons. The documentation for the "do" and "do*" functions indicates that local variables of "do" retain their initializer values while in the do loop unless a step value is given. Although this goes against all usages of "do" that I've come across in the other dialects of lisp i've used, I figured I could get by with a construct like the following in order to allow variables declared in "do"'s varlist to act as local temporary variables (as if declared in a "let" block just outside of the "do"): (do ((i 0 i)) (<test> <return>) <body> ) Unfortunately, we see the same error here as we did in "let" above, namely that if I try to do a (setq i 2) in <body>, I won't be setting the i that was locally bound in "do". Within the scope of "do", variable i will always stay at 0. Ok, fine, so I figured that bglisp's "do" local variables insist on getting set and altered through the <init> and <step> expressions in the varlist. So I tried putting the local variables that need to be setq'd inside a "let" that wraps the "do": (let ((j 0)) (do ((i 0 (+ i 1))) ((equal j 100) j) (progn (setq j i) (printf "%S\n" j)) )) The result is of course an infinite loop, with bglisp printing out "0\n" until I ^C it. The reason for the behaviour is mentioned in (1) above. Granted, the above is a contrived example that needn't be written the way it is to achieve the desired effect. It is really just a simplification of a problem I was having with a more complicated procedure that required the ability to set and use local variables within the <body> of the "do". - ------------------------------------------------------------------------------ (3) The following is probably less of a "bug" and more of a "feature" of bglisp, eli. However, it will certainly cause much confusion for those that know some of the well-known dialects of lisp such as common lisp, maclisp, franzlisp, gnuemacs-lisp, etc: All the lisps I've come across that take a <body> expression, such as "do", "let", "cond", "defun", etc, allow <body> to be a sequence of expressions. In bglisp/eli forces you to wrap any such sequence of expressions in a progn as in the example above. Is this perhaps because bglisp is derived from Gosling's mocklisp? - -- Niels "tomorrow -- we'll work on closures and continuations! :-)" Mayer. ------- Message 2 To: Robert Steven Glickstein <bobg+@andrew.cmu.edu> Subject: Eli Bug? Organization: Hewlett-Packard Labs, Software Technology Lab, Palo Alto, CA. X-Mailer: mh6.6 Date: Sun, 27 Nov 88 18:39:48 PST Message-ID: <7574.596687988@hplnpm> From: Niels P. Mayer <mayer@hplnpm> I've gotten part of my "widget interpreter" (WINTERP) working using Eli, and I think I may have found some memory allocation problems caused by reading or evaling long strings. to reproduce the problem, try the following: create a file "foo.l" containing (setq a "1234567890....." ) where "1234567890....." is really a >512 character string. Startup bglisp and do (read "foo.l") Follow that by some other operation like (+ 1 1) On my system in bglisp, it will print out some character right after the CRLF following (+ 1 1), for example: BGLisp> (read "foo.l") ("12345678901234567890123456789012345678901234567890123456789012345678901234567 8901234567890123456789012345678901234567890123456789012345678901234567890123456 7890123456789012345678901234567890123456789012345678901234567890123456789012345 6789012345678901234561234567890123456789012345678901234567890123456789012345678 9012345678901234567890123456789012345678901234567890123456789012345678901234567 8901234567890123456789012345678901234567890123456789012345678901234567890123456 7890123456789012345678901234567890123456") BGLisp> (+ 1 1) 9 BGLisp> 2 In this case, a spurious "9" was printed out, indicating that something strange is going on. In bglisp, this problem doesn't seem to cause any core dumps, and it's hard for me to say what data is getting corrupted. However, in my widget interpreter, the problem isn't so benign, since I always get a core dump the next time an X Event is processed, or the next time WINTERP accepts a socket connection from a widget interpreter client (lisp input to ELI in WINTERP comes from a socket...). After many hours of tracking down false leads in my server/client code, I finally arrived upon the problem caused by long strings being loaded. Any ideas on what's going wrong? Also, do you have any suggestions for fixing the let/setq bug mentioned in my info-andrew note? Given the proper guidance, I'd be willing to help fix bugs in Eli. I'm knee-deep in the code as is, and I need to fix the let/setq problem before I start writing any serious applications with the widget interpreter. Thanks, - -- Niels. ------- Comment on Above Message by Niels Mayer: The above bug is caused by a LEX limitation: from the lex manpage: > WARNINGS > > The token buffer in the program built by lex is of fixed > length, > > yytext[YYLMAX] > > where YYLMAX is defined to be 200 characters. Overflow of > this array is not detected in the lex.yy.c program. The value of "200" seems to correspond to the breakpoint in tokenlength around which I was noticing strange behaviour, and indeed, in elil.c i find > # define YYLMAX 200 A workaround to the problem of reading in long strings is to use strcat instead of "veryveryverylongstring......" use (strcat "very" "very" "very" "long" "string" "...") ------- Message 3 Date: Sat, 8 Apr 89 01:07:38 -0500 (CDT) From: Bill Janssen <janssen%titan.sw.MCC.COM@mcc.com> To: info-andrew-bugs@andrew.cmu.edu, info-andrew@andrew.cmu.edu Subject: bug in eli "and" [from the help entry for eli-functions:] > The following standard Common LISP primitives are supported in eli. They > should work exactly as they're supposed to work in Common LISP, and hence are > not explained here. Consult a Common LISP manual for an explanation: The "and" function in eli is documented to work as CommonLisp "and" does, but it doesn't. CL: (and t "foo") => "foo" ELI: (and t "foo") => t I imagine this is also true for "or". Bill ------- Message 4 Date: Sat, 8 Apr 89 01:12:17 -0500 (CDT) From: Bill Janssen <janssen%titan.sw.MCC.COM@mcc.com> To: info-andrew-bugs@andrew.cmu.edu, info-andrew@andrew.cmu.edu Subject: bug in eli "cond" "cond" is documented to work like the "cond" in CommonLisp, but it doesn't. CL: (cond ((boundp 'a) (+ 2 3) (+ 3 4)) (t nil)) => nil ELI: (cond ((boundp 'a) (+ 2 3) (+ 3 4)) (t nil)) => *error* where "*error*" indicates that the interpreter doesn't like the syntax of the first cond clause. Bill ------- Message 5 Date: Sat, 8 Apr 89 01:16:07 -0500 (CDT) From: Bill Janssen <janssen%titan.sw.MCC.COM@mcc.com> To: info-andrew-bugs@andrew.cmu.edu, info-andrew@andrew.cmu.edu Subject: bug in ELI "let" and "let*" The ELI functions "let" and "let*" are documented to work as their CommonLisp version do. They don't. In CommonLisp, both let and let* establish an implicit progn, so that a number of forms can be evaluated sequentially in the body of the let. The value of the last form evaluated is returned as the value of the let. ELI only allows one form in its "let". Bill ------- End of Forwarded Messages