Earlier quoted context omitted.
Since this is written in assembly is it much faster than a C version since this one can manage its own stack frames and stack variables and such? I always imagined that’s the case and that a lisp implemented fully in assembly would be the trick to a super fast lisp that can complete with Go.
LISP was created a long time ago. Assembly was the weapon of choice. Thinking Machines, Symbolics and Macsyma might already say: We did that. But, uh, no.
Lisp in fewer than 200 lines of C
91–100 of 108 posts
Re: Lisp in fewer than 200 lines of C
#92Earlier quoted context omitted.
That still evaluates x twice, which can also be a source of bugs. I usually take one of two approaches: either decide that this is a weekend hack and using the macros whenever the expansion isn't obvious in my head is a sign of too much complexity, or use this GCC extension: #define is_space(x) ({ typeof(x) y = x; y == ' ' || y = '\n'; }) (Or in this case, turn it into an actual function and let the compiler figure o…
GCC extensions make my brain hurt :( Should just use C++ at that point: template bool is_space(const T & x) { return x == ‘ ‘ || x == ‘\n’; }
Re: Lisp in fewer than 200 lines of C
#93Awesome article, thanks for that. As someone who almost never even looks at C code, this was very understandable with the inline comments. What's the reason for using macros instead of real functions? Is this an optimization because macros get inlined at compile time? Does this really bring a lot of value?
In this particular case, none whatsoever. It’s egregious abuse of macros.
Re: Lisp in fewer than 200 lines of C
#94After reading Peter Norvig's post about a lisp implementation [0], I decided to write one in Python. I got something working in 65 lines [1] [0] http://norvig.com/lispy.html [1] https://gist.github.com/jmikkola/b7c6c644dff1c07891c698f0a52...
Re: Lisp in fewer than 200 lines of C
#95If you like this, you might like Lisp interpreter written in assembly in a single file. It is one of the best commented code ever written imo. https://github.com/marcpaq/arpilisp
Someone once suggested to me the easiest way to "bootstrap the world" is to write a Forth implementation in assembly, and then write your Lisp in Forth.
and their opinion was that it was easier to do the lisp than it was to do the FORTH. Although right now they are trying to improve their C Compiler prototype https://github.com/oriansj/M2-Planet before they convert it to assembly
Re: Lisp in fewer than 200 lines of C
#96Toward the end of `print_obj()`, we see: if (is_pair(cdr(ob))) { printf(" "); print_obj(cdr(ob), 0); } How could this `if` statement ever evaluate to false? We already verified that `cdr(ob) != 0`, and the CDR can never be a plain old string, so isn't this `if` superfluous?
Nope. It still can be an atom. Only if it's a pair (i.e. a cons with two cells, not just one) it prints the next.
Re: Lisp in fewer than 200 lines of C
#97Re: Lisp in fewer than 200 lines of C
#98Really cool! A more complete implementation in 1000 lines of C for getting started: http://www.buildyourownlisp.com
Re: Lisp in fewer than 200 lines of C
#99Re: Lisp in fewer than 200 lines of C
#100Earlier quoted context omitted.
I found none of these particularly difficult. (I've never attempted 3. or 5. though.) Functional values, however, are difficult. They work effortlessly in interpreted code, but in compiled code you're faced with the upwards funarg problem: https://en.wikipedia.org/wiki/Funarg_problem#Upwards_funarg_... A solution is needed if you want lazy evaluation.
> They work effortlessly in interpreted code, but in compiled code you're faced with the upwards funarg problem No it's not about interpreted or compiled. It's about using the native stack or a heap for stack frames. Compiled code and interpreters can both use either, so that's orthogonal.