Now that I have finally gotten my <code>
and multi-line code (in the form of a <pre>
set up in a manner that is to my liking, I can properly write a first entry about a Lisp (the programming language). This entry is the first in what will hopefully become a series of entries about said Lisp.
The Lisp which I wish to briefly introduce is one of my own creation. Ideally from a user's perspective, it will appear to function similar to a modern Scheme dialect, though I have not read much of the code of any extant Scheme (and certainly not at any depth which would give me an understanding of what was happening in the code). This Lisp is the personal project toward which I am currently directing most of my energies; at the time of this writing it is just over 2200 lines of C and counting. There is currently a single basic data structure upon which all user-accessible types are implemented. The layout of this data structure (which I am calling an atom
) is reproduced below.
typedef struct atom { uint16_t type; uint16_t flags; uint32_t refs; void *car; void *cdr; } atom_t;
There are currently several large issues which require me to address before I can write all of the builtin functions which I desire; most notably, the (reference-counting) garbage collector seems to be collecting some objects before another part of the code is done with them, resulting in hard-to-trace segmentation faults caused by malloc()
trying to write to "dirty" memory. To address this, I am working on writing a set()
function to handle setting the car
and cdr
fields of atom
structures. This function will ensure that all required reference count changes occur properly. I have duplicated the function below.
uint32_t atom_set(atom_t **ap, atom_t *a) { if (*ap != nil && *ap != undef) { if (*ap == a) return (*ap)->refs; (*ap)->refs--; if ((*ap)->refs == 0) atom_final(*ap); } *ap = a; if (a != nil && a != undef) { a->refs++; return a->refs; } return 0; }
I hope to set up a publicly-viewable Git repository containing this project in the near future, but for now I am content to hack on it in my spare time until I fix the [probably] GC-induced segfaults. After that issue is resolved, the remaining builtin functions can be written and the project will become much more interesting. I would also like to be able to create a function like Scheme's call-with-current-continuation
(also known as call/cc
), but that will require some deeper thinking (and more understanding of what it does and how it works on my part) after the reference counting/GC bug(s) is/are fixed.
That's all for now. I am open to questions about this program, but it may be wise to wait until I have written more about it/worked on it more and made the code publicly-accessible. Until then, contact information is where it usually is.