Make your own Lisp
github.com
github.com
/* excerpt from builtin_op function */
while (a->count > 0) {
/* Pop the next element */
lval* y = lval_pop(a, 0);
if (strcmp(op, "+") == 0) { x->num += y->num; }
if (strcmp(op, "-") == 0) { x->num -= y->num; }
if (strcmp(op, "*") == 0) { x->num *= y->num; }
if (strcmp(op, "/") == 0) {
if (y->num == 0) {
lval_del(x); lval_del(y);
x = lval_err("Division By Zero!"); break;
}
x->num /= y->num;
}
lval_del(y);
}
For people who are newbies to programming and newbies to C, this sort of book can provide stimulating activities and motivation. Ultimately they will probably be unsatisfied with their results (but then nobody is ever satisfied with their results no matter what, if they are newbies in programming and C, struggling to make something).One thing that you might be interested in knowing about is that this book uses a few libraries which means you don't end up writing everything from scratch. For example, in the chapter on parsing, the grammar is implemented using a library called MPC (https://github.com/orangeduck/mpc) written by the author himself.
I didn't quite reach till the very end so didn't have a chance to implement Macros (the author does mention them in Chapter 16), so if that's something you can very keen on implementing then you might have to look someplace else.
Shameless self-promotion: I wrote a Lisp interpreter in a single assembly file for Raspberry Pi. It also starts from scratch at an even lower level, to the point of ignoring standard libraries.
https://github.com/marcpaq/arpilisp
I was inspired by jonesforth, which, if you haven't read it, is a beautiful piece of work.
This really makes me want to blow the dust off the RaspberryPi (we all bought one and never used it: admit it) and get this up and running, just to see it working.
dwc */ | sort -n | head
494: examples/
846: docs/
1268: mal/
1464: perl6/
1483: coffee/
1509: io/
1534: racket/
1571: ocaml/
1579: es6/
1621: factor/
Edit1: for better commandEdit2: for formatting
for i in $(make print-IMPLS); do \
s=$(make stats^$i | grep total); \
printf "%-9s %s\n" "$i" "$s"; \
done | sort -n -k2
I made a gist with the current results: https://gist.github.com/kanaka/fdef20f5d0c2e04b97d9106b2f2f2...Haskell, Ruby, Kotlin, Lua, Go, Rust, C, Swift.
Note that this should obviously be taken with a grain of salt: the implementations were created by many different people each with their own style and differing experience levels with the target language. That being said, from my own experience, I think the concision (size) of the implementation often reflects how "Lispy" a language is. Most of the Lisps are in the top half of the list (fewest LOCs). Ruby is often described as very Lisp-like. Factor is one that stands out for me (second after mal itself). Factor also happens to be one of the fastest implementations (for certain microbenchmarks).
Common Lisp, Racket, Clojure, Scheme, etc. are all great choices with decent compilers, interpreters, library ecosystems, editor support, etc.
Seems there's a new pet project Lisp released once a month or so, and none of them add anything interesting over the existing options.
Of course if you have computing to do in a bash script, bash already supports that so there is no real point. A colleague implemented a BASIC inside TECO which may have also been pointless.
Building a Lisp is a great exercise, but I don't need to know every time somebody does it. We might as well have posts about everybody's fizzbuzz...