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