Можно строить выражения с помощью ручной генерации абстрактного синтаксического дерева. Например, код для генерации выражения let a = 40 + 2:
Генерировать большие функции с использованием ExprXXX-кирпичиков утомительно, поэтому можно использовать макрос quote, который трансформирует переданное в него выражение в синтаксическое дерево этого выражения:
В случае, если какую-либо часть выражения нужно сделать изменяемой, можно воспользовать макросом apply_template:
Недавно в язык была добавлена фича по упрощению генерации правил переписываний выражений — expression reification (аналогичная фича из haxe). Её можно описать как DSL для задания правил переписывания выражений в шаблонах. Теперь генерацию того же самого выражения можно описать так:
В таком виде строчка шаблона всё ещё остаётся похожим на сам код, который будет сгенерирован этим шаблоном, а не на синтаксическое дерево или таблицу с описанием правил. Пример на все поддерживаемые правила реификации выражений - reification.das.
Переписанная кодо-генерированная функция инициализации структуры с использованием реификации получается где-то вдвое короче и проще:
Макрос qmacro_expr позволяет вставить сгенерированное выражение в текущий блок, а не генерировать новый блок. reduce - функция из стандартной библиотеки functional, позволяющая произвольным образом свернуть массив выражений с помощью функтора. reduce_while — её дописанная версия, позволяющая задать предикат остановки свёртки выражения по условию. qmacro_function — макрос для генерации сигнатуры функции и её определения
Получившаяся функция инициализации аналогична той, которая генерировалась в предыдущей заметке: