macro that allows collecting expressions throughout a file

This commit is contained in:
2021-11-01 16:52:22 -04:00
parent 270487501b
commit 5a7e88158a
2 changed files with 36 additions and 2 deletions

View File

@@ -39,7 +39,8 @@ typedef KissState = {
fieldDict:Map<String, Field>,
loadingDirectory:String,
hscript:Bool,
macroVars:Map<String, Dynamic>
macroVars:Map<String, Dynamic>,
collectedBlocks:Map<String, Array<ReaderExp>>
};
class Kiss {
@@ -111,7 +112,8 @@ class Kiss {
fieldDict: new Map(),
loadingDirectory: "",
hscript: false,
macroVars: new Map()
macroVars: new Map(),
collectedBlocks: new Map()
};
return k;
@@ -154,6 +156,7 @@ class Kiss {
if (kissFile == null) {
kissFile = classPath.withoutDirectory().withoutExtension().withExtension("kiss");
}
//trace('kiss build $kissFile');
return _try(() -> {
if (k == null)

View File

@@ -839,6 +839,37 @@ class Macros {
b.callSymbol("object", objectExps);
}
// Macro for triggering collection of expressions throughout a Kiss file, to inject them later with collectedBlocks
macros["collectBlocks"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
wholeExp.checkNumArgs(1, 2, "(collectBlocks <block symbol> <?expression to inline instead of the blocks>)");
var blockName = try {
exps[0].symbolNameValue();
} catch (notSymbolError:String) {
throw CompileError.fromExp(wholeExp, notSymbolError);
}
k.collectedBlocks[blockName] = [];
// TODO some assertion that the coder hasn't defined over another macro (also should apply to defMacro)
macros[blockName] = (wholeExp:ReaderExp, innerExps:Array<ReaderExp>, k:KissState) -> {
k.collectedBlocks[blockName] = k.collectedBlocks[blockName].concat(innerExps);
if (exps.length > 1) exps[1] else null;
};
null;
};
macros["collectedBlocks"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
wholeExp.checkNumArgs(1, 1, "(collectedBlocks <block symbol>)");
var blockName = try {
exps[0].symbolNameValue();
} catch (notSymbolError:String) {
throw CompileError.fromExp(wholeExp, notSymbolError);
}
var b = wholeExp.expBuilder();
if (!k.collectedBlocks.exists(blockName)) {
throw CompileError.fromExp(wholeExp, 'no blocks for $blockName were collected. Try adding (collectBlocks ${blockName}) at the start of the file.');
}
b.begin(k.collectedBlocks[blockName]);
};
macros["clamp"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
wholeExp.checkNumArgs(2, 3, "(clamp <expr> <min or null> <?max or null>)");
var b = wholeExp.expBuilder();