Diff
Not logged in

Differences From Artifact [aeb12eeaab91afb4]:

To Artifact [0386a7dd31807f87]:


47 47 { 48 48 const(Parameter[]) params(); 49 49 Table definitionContext(); 50 50 Value invoke(in LexPosition pos, Layer lay, Table ctx); 51 51 } 52 52 53 53 import polemy.eval; // circular... 54 +version = MacroCache; 55 +//version = AutoMemoization; 56 +//version = AutoRerun; 54 57 55 58 /// 56 59 class UserDefinedFunValue : FunValue 57 60 { 58 61 FunLiteral ast; 59 62 Table defCtx; 63 + 64 + this(FunLiteral ast, Table defCtx) { this.ast=ast; this.defCtx=defCtx; } 65 + override string toString() const { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } 66 + override bool opEquals(Object rhs_) const /// member-by-member equality 67 + { 68 + if( auto rhs = cast(typeof(this))rhs_ ) 69 + return this.ast==rhs.ast && this.defCtx==rhs.defCtx; 70 + assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 71 + } 72 + override hash_t toHash() const /// member-by-member hash 73 + { 74 + return typeid(this.ast).getHash(&this.ast) + typeid(this.defCtx).getHash(&this.defCtx); 75 + } 76 + override int opCmp(Object rhs_) /// member-by-member compare 77 + { 78 + if( auto rhs = cast(typeof(this))rhs_ ) 79 + { 80 + if(auto i = this.ast.opCmp(rhs.ast)) 81 + return i; 82 + return this.defCtx.opCmp(rhs.defCtx); 83 + } 84 + assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 85 + } 86 + 87 + private AST preprocessed_funbody; 88 + private Value[Value[]][Layer] memo; 89 + 60 90 override const(Parameter[]) params() { return ast.params; } 61 91 override Table definitionContext() { return defCtx; } 62 92 override Value invoke(in LexPosition pos, Layer lay, Table ctx) 63 93 { 64 94 // TODO: only auto raised ones need memo? no? 65 - // auto memoization 66 -/* 67 - if( lay != ValueLayer && lay != MacroLayer ) 95 + // how can we integrate re-run ?? 96 + version(AutoMemoization) 68 97 { 69 - if( auto memolay = lay in memo ) 70 - if( auto pv = args in *memolay ) 71 - return *pv; 72 - memo[lay][args] = lift(e.pos,new UndValue,lay,ctx); 98 + Value[] memokey; 99 + if( lay != ValueLayer && lay != MacroLayer ) 100 + { 101 + foreach(i,p; ast.params) 102 + memokey ~= ctx.get(p.name, lay); // lay? 103 + if( auto memolay = lay in memo ) 104 + if( auto pv = memokey in *memolay ) 105 + return *pv; 106 + memo[lay][memokey] = lift(ast.pos,new UndValue,lay,ctx); 107 + } 73 108 } 74 109 75 -*/ 76 110 // @macro run!!! 77 111 if( lay == MacroLayer ) 78 112 return macroEval(ast.funbody, ctx, false); 79 -/*TODO memo*/ AST macroMemo; 80 - if( macroMemo is null ) { 81 - // .prototype!, forced macro cannot access parameters 82 - ctx.kill = true; scope(exit)ctx.kill=false; 83 - auto tbl = macroEval(ast.funbody, ctx, true); 84 - macroMemo = tableToAST(ValueLayer,tbl); 113 + 114 + version(MacroCache) { 115 + if( preprocessed_funbody is null ) { 116 + // .prototype!, forced macro cannot access parameters 117 + ctx.kill = true; scope(exit)ctx.kill=false; 118 + preprocessed_funbody = tableToAST(ValueLayer,macroEval(ast.funbody, ctx, true)); 119 + } 120 + } else { 121 + if( preprocessed_funbody is null ) { 122 + // .prototype!, forced macro cannot access parameters 123 + ctx.kill = true; scope(exit)ctx.kill=false; 124 + preprocessed_funbody = tableToAST(ValueLayer,macroEval(ast.funbody, ctx, true)); 125 + } 85 126 } 86 - auto v = eval(macroMemo, ctx, true, lay); 87 127 88 - //auto v = eval(e.funbody, ctxNeo, true, lay); 89 - // auto memoization 90 -// if( lay != ValueLayer && lay != MacroLayer ) 91 -// memo[lay][args] = v; 128 + auto v = eval(preprocessed_funbody, ctx, true, lay); 129 + version(AutoMemoization) 130 + { 131 + if( lay != ValueLayer && lay != MacroLayer ) 132 + { 133 + memo[lay][memokey] = v; 134 + version(AutoReRun) 135 + memo[lay][memokey] = eval(preprocessed_funbody, ctx, true, lay); // re-Run!! 136 + } 137 + } 92 138 return v; 93 139 } 94 - 95 - mixin SimpleClass; 96 - override string toString() const { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } 97 140 } 98 141 99 142 /// 100 143 abstract class NativeFunValue : FunValue 101 144 { 102 145 Parameter[] params_data; 103 146 override const(Parameter[]) params() { return params_data; } ................................................................................ 167 210 } 168 211 169 212 Value get(string i, Layer lay, in LexPosition pos=null) 170 213 { 171 214 if( i in data ) { 172 215 // [TODO] consider forwarding to proto also in this case 173 216 if( lay !in data[i] ) 174 - throw genex!RuntimeException(pos, sprintf!"variable %s is not set in layer %s"(i,lay)); 217 + throw genex!RuntimeException(pos, sprintf!"'%s' is not set in layer %s"(i,lay)); 175 218 if(kill) 176 - throw genex!RuntimeException(pos, sprintf!"variable %s is killed in macro"(i)); 219 + throw genex!RuntimeException(pos, sprintf!"'%s' is killed in macro"(i)); 177 220 return data[i][lay]; 178 221 } 179 222 if( prototype is null ) 180 - throw new RuntimeException(pos, sprintf!"variable %s not found"(i)); 223 + throw new RuntimeException(pos, sprintf!"'%s' not found"(i)); 181 224 return prototype.get(i, lay, pos); 182 225 } 183 226 184 227 T access(T,S...)( Layer lay, string path, S rest ) 185 228 { 186 229 static if( rest.length == 0 ) 187 230 {