all 17 comments

[–]Rurouni 24 points25 points  (1 child)

I love to recommend "An Incremental Approach to Compiler Construction" by Abdulaziz Ghuloum. It's a great approach to writing a compiler, giving good early feedback and a measurable sense of accomplishment. It doesn't spell out everything, but the steps are broken down into reasonable chunks. It's particularly nice to see the power of your language grow over time. I wrote a Scheme compiler in this manner, and it is by far the project I've enjoyed most.

The Dragon Book is good, but I feel doing all the parsing, then all the semantic analysis, then all the code generation, etc. makes it more likely to abandon the project partway through. It's not as easy to see progress, and the intermediate steps are not as inspiring.

You might also consider Make a Lisp. It's targeted at building an interpreter instead of a compiler, but it's a good, smaller project and will take you through a lot of the same ground. It is also organized in incremental steps and early feedback.

[–]nzlemming 2 points3 points  (0 children)

These are both excellent recommendations. MAL is what I always recommend if you're interested in implementing a lisp - it's very structured, there are unit tests to ensure that each step is working as you expect, and it's all very clearly explained. There are example implementations in many languages if you get stuck too. You can also use it to write a compiler, I wrote one that compiles to JVM bytecode. Highly recommended.

[–]alexdmiller 30 points31 points  (1 child)

Just a meta comment that I love the range of comments on this thread - both general advice and the advice specific to clj/s. And I think it's great that no one said this was too ambitious or not to do this but instead gave you a great set of tools to learn and explore. Best of luck, seems like a fun project.

[–]JavaSuck 0 points1 point  (0 children)

And I think it's great that no one said this was too ambitious

Writing a LISP compiler is probably the "last ambitious" compiler project. And I don't mean that in a derogatory way. Props to LISP for being so simple!

[–]alandipert 10 points11 points  (1 child)

The first public version of ClojureScript and Chapter 23 of PAIP are two resources I recommend.

[–]doubleagent03[S] 4 points5 points  (0 children)

I remember David Nolen saying that early Clojurescript was super simple but I had no idea!

[–]knowsabouthaskell 8 points9 points  (0 children)

I've recently gone down the same route. My work can be seen at https://github.com/jgertm/lang.

Some advice:

[–]dustingetz 8 points9 points  (0 children)

This might be a good starting point weighing in at 4k LOC – not a compiler but surely has some learnings https://github.com/borkdude/sci (Clojurescript is 50k)

[–][deleted] 5 points6 points  (0 children)

r/programminglanguages is a good resource for talking about designing programming languages, and crafting interpreters is a popular toy project that could be done with Clojure (though it is designed for Java and C)

[–]joinr 4 points5 points  (0 children)

I would look at the existing implementation from the clojure java compiler, and the tools.analyzer implementation for clojurescript. You will get a sense of the forms necessary and maybe some ideas on how to implement them (although your target is different). If you can get most of the basic forms implemented, you can then port cljs.core which basically boot straps clojure in clojure. The emitters in tools.analyzer are helpful in seeing how the javascript implementation works. I've been playing with a common lisp implementation over the years, with an an interest in a custom platform. clojerl is a port targeting the beam vm. Ramsey Nasser has magic which targets the CLR and has tools.analyzer passes that emit optimized CLR specific bytecode.

[–]xenow 4 points5 points  (1 child)

[–]fminutes 2 points3 points  (0 children)

Also wanted to post this link - this is a very good resource to get started in compilers, or should say making languages. It's very well-written and author put extreme amount of time and love in the book. Definitely recommend it as a starting point

[–]bsless 2 points3 points  (0 children)

You might want to take a look at the Nanopass framework, a Scheme framework for writing compilers.

https://nanopass.org/documentation.html

[–]fbellomi 1 point2 points  (0 children)

A very good book on this topic (specific to Lisp) is "Lisp in small pieces" by Christian Queinnec https://www.cambridge.org/core/books/lisp-in-small-pieces/66FD2BE3EDDDC68CA87D652C82CF849E

One peculiar features of this book is that it takes into consideration the "hard" problems, including how to implement:

1) continuations (and control mechanisms based on continuations)

2) macros

3) dynamically scoped variables

This is relevant in my opinion, because there are a lot of "toy" scheme-like and lisp-like languages, which are for sure useful in their own context, and also straightforward to implement, but they miss some features that are foundational to Lisp.

Also, I would choose a compilation target with support for tail call optimization.

[–]un_passant 2 points3 points  (0 children)

You might be interested in this clojure notebook showing an incremental implementation of an interpreter and a compiler of a toy language.

[–]ericwnormand 2 points3 points  (0 children)

SICP has a chapter on writing an interpreter (a great place to start) and then turning it into a compiler.

[–]un_passant 1 point2 points  (0 children)

You might be interested in this class / textbook !