kissCache
This commit is contained in:
@@ -58,7 +58,9 @@ typedef KissState = {
|
||||
macroVars:Map<String, Dynamic>,
|
||||
collectedBlocks:Map<String, Array<ReaderExp>>,
|
||||
inStaticFunction:Bool,
|
||||
typeHints:Array<Var>
|
||||
typeHints:Array<Var>,
|
||||
conversionStack:Array<ReaderExp>,
|
||||
stateChanged:Bool
|
||||
};
|
||||
#end
|
||||
|
||||
@@ -168,6 +170,8 @@ class Kiss {
|
||||
collectedBlocks: new Map(),
|
||||
inStaticFunction: false,
|
||||
typeHints: [],
|
||||
conversionStack: [],
|
||||
stateChanged: false
|
||||
};
|
||||
|
||||
k.doc = (form:String, minArgs:Null<Int>, maxArgs:Null<Int>, expectedForm = "", doc = "") -> {
|
||||
@@ -413,8 +417,27 @@ class Kiss {
|
||||
}
|
||||
|
||||
static var macroUsed = false;
|
||||
|
||||
static var expCache:haxe.DynamicAccess<String> = null;
|
||||
static var cacheFile = ".kissCache.json";
|
||||
static var cacheThreshold = 0.2;
|
||||
public static function readerExpToHaxeExpr(exp:ReaderExp, k:KissState):Expr {
|
||||
#if kissCache
|
||||
if (expCache == null) {
|
||||
expCache = if (sys.FileSystem.exists(cacheFile)) {
|
||||
haxe.Json.parse(File.getContent(cacheFile));
|
||||
} else {
|
||||
{};
|
||||
}
|
||||
}
|
||||
var str = Reader.toString(exp.def);
|
||||
if (expCache.exists(str)) {
|
||||
return Context.parse(expCache[str], Helpers.macroPos(exp));
|
||||
}
|
||||
#end
|
||||
|
||||
if (k.conversionStack.length == 0) k.stateChanged = false;
|
||||
k.conversionStack.push(exp);
|
||||
|
||||
var macros = k.macros;
|
||||
var fieldForms = k.fieldForms;
|
||||
var specialForms = k.specialForms;
|
||||
@@ -437,6 +460,7 @@ class Kiss {
|
||||
|
||||
var none = EBlock([]).withMacroPosOf(exp);
|
||||
|
||||
var startTime = haxe.Timer.stamp();
|
||||
var expr = switch (exp.def) {
|
||||
case None:
|
||||
none;
|
||||
@@ -455,6 +479,7 @@ class Kiss {
|
||||
var field = fieldForms[ff](exp, args.copy(), k);
|
||||
k.fieldList.push(field);
|
||||
k.fieldDict[field.name] = field;
|
||||
k.stateChanged = true;
|
||||
none; // Field forms are no-ops
|
||||
case CallExp({pos: _, def: Symbol(mac)}, args) if (macros.exists(mac)):
|
||||
checkNumArgs(mac);
|
||||
@@ -516,8 +541,13 @@ class Kiss {
|
||||
default:
|
||||
throw KissError.fromExp(exp, 'conversion not implemented');
|
||||
};
|
||||
#if test
|
||||
// Sys.println(expr.toString()); // For very fine-grained codegen inspection--slows compilation a lot.
|
||||
var conversionTime = haxe.Timer.stamp() - startTime;
|
||||
k.conversionStack.pop();
|
||||
#if kissCache
|
||||
if (conversionTime > cacheThreshold && !k.stateChanged) {
|
||||
expCache[str] = expr.toString();
|
||||
File.saveContent(cacheFile, haxe.Json.stringify(expCache));
|
||||
}
|
||||
#end
|
||||
|
||||
return expr;
|
||||
|
@@ -410,6 +410,7 @@ class Macros {
|
||||
|
||||
k.doc("defmacro", 3, null, '(defMacro <name> [<args...>] <body...>)');
|
||||
macros["defmacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
var name = switch (exps[0].def) {
|
||||
case Symbol(name): name;
|
||||
default: throw KissError.fromExp(exps[0], "macro name should be a symbol");
|
||||
@@ -528,6 +529,7 @@ class Macros {
|
||||
|
||||
k.doc("undefmacro", 1, 1, '(undefMacro <name>)');
|
||||
macros["undefmacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
var name = switch (exps[0].def) {
|
||||
case Symbol(name): name;
|
||||
default: throw KissError.fromExp(exps[0], "macro name should be a symbol");
|
||||
@@ -540,6 +542,7 @@ class Macros {
|
||||
|
||||
k.doc("defreadermacro", 3, null, '(defReaderMacro <optional &start> <"<startingString>" or [<startingStrings...>]> [<streamArgName>] <body...>)');
|
||||
macros["defreadermacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
|
||||
// reader macros declared in the form (defreadermacro &start ...) will only be applied
|
||||
// at the beginning of lines
|
||||
@@ -610,6 +613,7 @@ class Macros {
|
||||
|
||||
k.doc("undefreadermacro", 1, 1, '(undefReaderMacro <optional &start> ["<startingString>" or <startingStrings...>])');
|
||||
macros["undefreadermacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
// reader macros undeclared in the form (undefReaderMacro &start ...) will be removed from the table
|
||||
// for reader macros that must be at the beginning of lines
|
||||
// at the beginning of lines
|
||||
@@ -663,6 +667,7 @@ class Macros {
|
||||
|
||||
k.doc("defalias", 2, 2, "(defAlias <<&call or &ident> whenItsThis> <makeItThis>)");
|
||||
macros["defalias"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
var name = getAliasName(k, exps[0], "defAlias");
|
||||
|
||||
aliasMap[name] = exps[1].def;
|
||||
@@ -672,6 +677,7 @@ class Macros {
|
||||
|
||||
k.doc("undefalias", 1, 1, "(undefAlias <<&call or &ident> alias>)");
|
||||
macros["undefalias"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
var name = getAliasName(k, exps[0], "undefAlias");
|
||||
|
||||
aliasMap.remove(name);
|
||||
@@ -896,6 +902,7 @@ class Macros {
|
||||
|
||||
k.doc("defMacroVar", 2, 2, "(defMacroVar <name> <value>)");
|
||||
macros["defMacroVar"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
var name = exps[0].symbolNameValue();
|
||||
|
||||
k.macroVars[name] = Helpers.runAtCompileTimeDynamic(exps[1], k);
|
||||
@@ -905,6 +912,7 @@ class Macros {
|
||||
|
||||
k.doc("setMacroVar",2, 2, "(setMacroVar <name> <value>)");
|
||||
macros["setMacroVar"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
var name = exps[0].symbolName().withPosOf(exps[0]);
|
||||
var b = wholeExp.expBuilder();
|
||||
|
||||
@@ -913,6 +921,7 @@ class Macros {
|
||||
|
||||
k.doc("defMacroFunction", 3, null, "(defMacroFunction <name> [<args>] <body...>)");
|
||||
macros["defMacroFunction"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
k.stateChanged = true;
|
||||
var b = wholeExp.expBuilder();
|
||||
var name = exps[0].symbolNameValue();
|
||||
var lambdaExp = b.callSymbol("lambda", [exps[1]].concat(exps.slice(2)));
|
||||
|
Reference in New Issue
Block a user