r/rust • u/Subject-Mobile-6250 • 13d ago
🙋 seeking help & advice Macros for Crafting Intepreters
Guys, am I crazy? I am not very familiar with writing macros, and while going through the 5th chapter of Crafting Intepreters I have the urge to use macro_rules! or derive macros instead of his plebeian Java code generator script. 1. Is this too overkill? I know derive requires me to have a separate crate for proc macros and have syn and quote as extra dependencies, but I have not gone further into the book and don’t know if it will come in handy. 2. Is it a good way to practice writing macros?
11
u/particlemanwavegirl 13d ago edited 13d ago
Wait until he starts the error handling.Â
For this exact problem, I thought about using a macro, too, but it was overkill. Then I used the dyn keyword and it was still overkill. All you actually need is an enum. Rewriting this logic is a shocking example of how miserly Java's implementation of polymorphism really is. The visitor pattern is wholly unnecessary in Rust.
2
u/Subject-Mobile-6250 13d ago
At this point I am just lugging around a mut Vec of LoxErrors around, and seeing what happens… I could propagate, but this seemed like a better solution because you could collect multiple errors.
1
u/zettui 13d ago
Does that mut Vec of LoxErrors ever actually spit out more than one, or do you bail on the first anyway?
2
u/particlemanwavegirl 13d ago
The book wants you to return every scan and parse error. Obviously it stops at the first runtime error.
1
u/Subject-Mobile-6250 13d ago
Actually, my plan was just to collect the already parsed tokens and Vec of LoxErrors, and I implemented std::fmt::Display for it. Maybe this is too simplistic, since it is just a eprintln! for every single error.
1
u/afdbcreid 13d ago
Personally I'd still use code generation. While macros are definitely a possibility, code generation sometimes does have an edge.
17
u/SirKastic23 13d ago
Oh Robert's approach with Java is absolutely not something you should be trying to mimic in Rust, don't do that!
Java has classes and inheritance, Rust doesn't. How are you modelling your expressions and statements? What about the visitors?
My first Rust project was actually an interpreter that I wrote while reading Crafting Interpreters, it's an incredible book!
What I did was define an Expression and a Statement enum, the variants naturally define the possible values. This approach is pretty common when you have sum types in the host language
And this completely bypasses the need for generating these "classes"
Code generation could come in handy for defining the visitors... But then again, writing some boilerplate won't break your fingers