The macro-dsl in https://scattered-thoughts.net/writing/imp-simple-interprete... is cool too, haven't tried doing something like that in the language-processing tools I've made in Rust in the past, but might now that I see that it doesn't end up (immediately) sucking.
EDIT: Also very nice to see a language intro with both a bunch of examples, including a comparison to a better-known language with a similar model, and denotational semantics.