separate forHScript() and forMacroEval()

This commit is contained in:
2021-11-10 11:37:16 -07:00
parent 5c7287bdff
commit 2eb24a8c3f
3 changed files with 26 additions and 12 deletions

View File

@@ -374,7 +374,7 @@ class Helpers {
static var parser = new Parser();
static function compileTimeHScript(exp:ReaderExp, k:KissState) {
var hscriptExp = mapForInterp(k.forHScript().convert(exp));
var hscriptExp = mapForInterp(k.forMacroEval().convert(exp));
var code = hscriptExp.toString(); // tink_macro to the rescue
#if macrotest
Prelude.print("Compile-time hscript: " + code);

View File

@@ -14,6 +14,7 @@ import kiss.Macros;
import kiss.CompileError;
import kiss.cloner.Cloner;
using kiss.Kiss;
using kiss.Helpers;
using kiss.Reader;
using tink.MacroApi;
@@ -372,27 +373,37 @@ class Kiss {
return expr;
}
static function disableMacro(copy:KissState, m:String, reason:String) {
copy.macros[m] = (wholeExp:ReaderExp, exps, k) -> {
var b = wholeExp.expBuilder();
b.callSymbol("throw", [b.str('$m is unavailable in macros because $reason')]);
};
}
// Return an identical Kiss State, but without type annotations or wrapping list expressions as kiss.List constructor calls.
public static function forHScript(k:KissState):KissState {
var copy = new Cloner().clone(k);
copy.hscript = true;
// disallow macros that will error when run in hscript:
function disableMacro(m:String, reason:String) {
copy.macros[m] = (wholeExp:ReaderExp, exps, k) -> {
var b = wholeExp.expBuilder();
b.callSymbol("throw", [b.str('$m is unavailable in macros because $reason')]);
};
}
disableMacro(copy, "ifLet", "hscript doesn't support pattern-matching");
disableMacro(copy, "whenLet", "hscript doesn't support pattern-matching");
disableMacro(copy, "unlessLet", "hscript doesn't support pattern-matching");
disableMacro("set", "you don't want your macros to be stateful");
disableMacro("ifLet", "hscript doesn't support pattern-matching");
disableMacro("whenLet", "hscript doesn't support pattern-matching");
disableMacro("unlessLet", "hscript doesn't support pattern-matching");
copy.macros["cast"] = (wholeExp:ReaderExp, exps, k) -> {
exps[0];
};
return copy;
}
public static function forMacroEval(k:KissState): KissState {
var copy = k.forHScript();
// Disable macros that will cause problems in macro evaluation:
disableMacro(copy, "set", "you don't want your macros to be stateful");
return copy;
}
// Return an identical Kiss State, but without wrapping list expressions as kiss.List constructor calls.
public static function withoutListWrapping(k:KissState) {
var copy = new Cloner().clone(k);

View File

@@ -9,6 +9,7 @@ import kiss.Reader;
import kiss.Stream;
using tink.MacroApi;
using kiss.Kiss;
#end
import haxe.Json;
@@ -132,7 +133,9 @@ class Main {
var k = Kiss.defaultKissState();
k.wrapListExps = false;
var pretty = args.indexOf("--pretty") != -1;
k.hscript = args.indexOf("--hscript") != -1;
if (args.indexOf("--hscript") != -1)
k = k.forHScript();
function print(s:String) {
if (!pretty)