https://en.wikipedia.org/wiki/Ratfor
Similarly I've written awk programs that write shell scripts (guilty pleasure), Python programs that write AVR-8 assembly, toolkits to write Java ASTs with static imports like
@Test
public void buildAList() {
var stream = callBuild(callAdd(callAdd(callAdd(callBuilder(), Literal.of(7)),
Literal.of(11)),Literal.of(15)));
var expr = callToList(stream);
var l = expr.evaluateRT();
assertEquals(3,l.size());
assertEquals(7, l.get(0));
assertEquals(11, l.get(1));
assertEquals(15, l.get(2));
}
and evaluate with a tree-walking interpreter or use as a code generator in maven, do transformations on the ASTs, etc.There are many paths to metaprogramming but the Lisp family leads in putting it on your fingertips. Once you learn those methods you can apply them in the trashiest programming languages, but I think often people miss the point.