Really I would love to know how parse context sensitive stuff like typedef which will have "switched" syntax for some tokens. Would like to know things like "hoisting" in C++, where you can you the class and struct after the code inside the function too, but I just find it hard to describe them in rigorous formal language and grammar.
Hacky solution for PEG such as adding a context stack requires careful management of the entry/exit point, but the more fundamental problem is that you still can't "switch" syntax, or you have to add all possible syntax combination depending on the numbers of such stacks. I believe persistent data structure and transactional data structure would help but I just couldn't find a formalism for that.
Another possible solution is the usage of functional parsers (e.g.: [0]) and making use of some form of the ‘do’ notation. Each step makes its result available to all subsequent parsers.
In case anyone finds it useful, we (CodeCrafters) built a coding challenge as a companion to this book. The official repository for the book made this very easy to do since it has tests for each individual chapter.
I've found this book to be a good way to learn a new language, because it forces you to do a bit of reading about various language features and patterns to create equivalent implementations. For languages that lack some of the features in Java, it can be tricky to learn how to apply similar patterns, but that's half the fun (for me).
It's a great book, I bought the paper version first, but man it was too big and heavy for my liking, ended up buying a digital copy; much more practical for notes and search...
although I keep getting lost somewhere in the mountain :)
I also recommend munificent's other book about game programming patterns. Both are fun to read.
Sometimes I get the spine guillotined off and replaced with a ring binding. Any print shop can do it for you, and you just lose the gutter plus a little margin. Easier to work with at a desk, and you can even split into two "books" if you feel it necessary.
But that's only for books I don't want to keep, and Crafting Interpreters is definitely a keeper...
The visitor pattern is very common in programming language implementations. I've seen it in the Rust compiler, in the Java Compiler, in the Go compiler and in the Roslyn C# compiler. Also used extensively in JetBrains' IDEs.
What do you have against this pattern? Or what is a better alternative?
Reading this book brought me a better understanding of "the expression problem" and the use of the visitor pattern as its solution. This led me to (finally) grok the use of Class _Heirarchy_ Inheritance[0] as a solution not requiring visitors. In Newspeak[1], classes can contain nested classes, so when you subclass a class, you inherit the nested classes as well. This blog post discusses the same feature affording Free Object Algebras [2].
I love this book! I do wish there was a new edition that updated the version of Java used in the tree-walk interpreter. There's been some additions to the language, like sealed classes and exhaustive switches, that could really benefit the implementation.
30 comments
[ 3.9 ms ] story [ 55.9 ms ] thread2020 with 777 points: https://news.ycombinator.com/item?id=22788738
2024 with 607 points: https://news.ycombinator.com/item?id=40950235
Hacky solution for PEG such as adding a context stack requires careful management of the entry/exit point, but the more fundamental problem is that you still can't "switch" syntax, or you have to add all possible syntax combination depending on the numbers of such stacks. I believe persistent data structure and transactional data structure would help but I just couldn't find a formalism for that.
I know it's no solace to you, but Rust and Go don't even have this problem Afaik, and it's avoidable by careful consideration.
[0] https://hackage.haskell.org/package/parsec
Link: https://app.codecrafters.io/courses/interpreter/overview
although I keep getting lost somewhere in the mountain :)
I also recommend munificent's other book about game programming patterns. Both are fun to read.
But that's only for books I don't want to keep, and Crafting Interpreters is definitely a keeper...
Here are is a new LUA interpreter implemented in Python:
https://github.com/rhulha/MoonPie
And here is a new language:
https://github.com/rhulha/EasyScript
What do you have against this pattern? Or what is a better alternative?
[0] https://blog.bracha.org/primordialsoup.html?snapshot=Amplefo... [1]https://newspeaklanguage.org [2]https://blog.bracha.org/primordialsoup.html?snapshot=Amplefo...
I hope we get to see "Add a type checker to Lox" sequel
https://github.com/codr7/shi
And perhaps this for those leaning towards C:
https://github.com/codr7/hacktical-c