Find a Lisp reader in C

clisp

I have a Lisp reader written in Java that I'm thinking of translating into C. (Or perhaps C++.) It's a fairly complete and useful hack, so the main issue is doing the dynamic-storage allocation in a language without garbage collection. If someone has already thought this through I'd rather borrow their code than figure it out myself. (C is not my favorite language.)

Of course, having a Lisp reader makes no sense unless you're planning to do something with the things you read, so perhaps I should have phrased the question, Where do I find a simple Lisp core written in C?, but in my experience the hardest unavoidable part of writing a Lisp (somewhat surprisingly) is the reader. Plus, I don't want to have a garbage collector; I'm anticipating an application where the list structures will be freed more or less by hand.

Best Answer

Gary Knott's Interpreting Lisp is very nice. You may also try others, like Jim Mayfield's Lisp. There are probably lots of little Lisps out there...

You mentioned that you don't like C. Maybe you'd like Haskell -- in which case you could try "Write yourself a Scheme in 48 hours", an interesting tutorial (you get to write a Scheme interpreter in Haskell).

Update: I know that a Lisper would hardly feel comfortable using Haskell, but hey, it's much more comfortable than C (at least for me)! Besides that, HAskell has a good FFI, so it should be easy to use the Haskell-made Lisp-reader as a C-compatible library.

Update 2: If you want to use XLisp, as suggested by another user, you will probably need src/xlread.c (863 lines) and include/xlisp.h (1379 lines) -- but I could be wrong...

Update 3: If you use Gary Knott's Lisp (one single C file with 942 lines), the function signature is int32 sread(void). This would be my choie if I didn't need anything fancy (like read macros) or highly optimized (there is a PDF paper that describes how the code is implemented, so you won't have to find your way in a labyrinth). The documentation for the function is:

This procedure scans an input string g using a lexical token scanning
routine, e(), where e() returns
                    1 if the token is '('
                    2 if the token is '''
                    3 if the token is '.'
                    4 if the token is ')'   or a typed pointer d to an
atom or number stored in row ptrv(d) in   the atom or number tables.
Due to the typecode (8 or 9) of d, d is a negative 32-bit integer.  The
token found by e() is stripped from the front of g.

SREAD constructs an S-expression and returns a typed pointer to it as
its result.

See that Gary's Lisp is old and you'll need to change it so it compiles. Instead of including linuxenv.h, include:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

Also, it does not work in 64-bit machines (the documentation of sread should tell you why...)

Update 4: There's also the Scheme implementations by Nils Holm (there are books describing the internals)