ProceduralMacros
Macros for Macaulay2, written in Macaulay2: code that writes code before it runs. Inspired by Rust’s procedural macros, and still very much an experiment.
needsPackage "ProceduralMacros"
runSource ///
$defineRecord PackageRelease(makePackageRelease; releaseName, releaseVersion) $
///
turns into
PackageRelease = new Type of BasicList
makePackageRelease = (releaseName, releaseVersion) -> new PackageRelease from {releaseName, releaseVersion}
releaseName = value -> value#0
releaseVersion = value -> value#1
expandSource shows the expansion without running it. Two macros come built in:
defineRecord and inferReturns (which adds return types it can work out).
Your own
Declarative, a pattern and a template:
declMacro("double", "'e", "2 * ('e)")
'x is a metavariable, 'x:Number a typed one, '{…}+ repeats.
Or procedural, a function from the parsed input (a token tree from M2’s own parse) to new
tokens:
installMacro("myMacro", ts -> ...)
For bigger things there are typed syntax-tree views with visitors and folds, and
visualizeTree when you’re lost.
Install
installPackage "ProceduralMacros"
Needs M2 1.26.05+ (the first one with parse).
Watch out
load/needsdon’t expand macros, so usevalue openIn "file.m2"- templates don’t add parentheses for you
- the API will change
Prefer Rust? m2-syn does macros with a typed tree and quote-style templates.