Diff
Not logged in

Differences From Artifact [197c2cfb75326106]:

To Artifact [bc3c32f1d9aafc10]:


256 256 override Table definitionContext() { return defCtx; } 257 257 258 258 this(Fun ast, Table defCtx) { this.ast=ast; this.defCtx=defCtx; } 259 259 override string toString() const 260 260 { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } 261 261 override int opCmp(Object rhs) { 262 262 if(auto r = cast(UserDefinedFunValue)rhs) { 263 - auto a = cast(void*)this.ast; 264 - auto b = cast(void*)r.ast; 265 - if(a<b) return -1; 266 - if(a>b) return +1; // [TODO] avoid using pointer value... 267 - return this.defCtx.opCmp(r.defCtx); 263 + if(auto c = typeid(void*).compare(cast(void*)ast, cast(void*)r.ast)) 264 + return c; 265 + if(auto c = typeid(void*).compare(cast(void*)defCtx, cast(void*)r.defCtx)) 266 + return c; 267 + return 0;// [TODO] avoid using pointer value... 268 268 } 269 269 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r)); 270 270 throw genex!RuntimeException("comparison with value and something other"); 271 271 } 272 - mixin SimpleToHash; 272 + override hash_t toHash() { 273 + return (cast(hash_t)cast(void*)ast) + (cast(hash_t)cast(void*)defCtx); 274 + } 273 275 274 - AST afterMacroAST; 276 + AST macroCache; 277 + static class MemokeyType 278 + { 279 + void* a; Layer b; Tuple!(string,Layer,Value)[] c; 280 + hash_t toHash() { 281 + hash_t h = structuralHash(a) + structuralHash(b); 282 + foreach(e; c) 283 + h += structuralHash(e[0])+structuralHash(e[1])+structuralHash(e[2]); 284 + return h; 285 + } 286 + mixin SimpleToString; 287 + mixin SimpleConstructor; 288 + mixin SimpleCompareWithoutToHash; 289 + } 290 + static Tuple!(Value,int)[MemokeyType] memo; 291 + 275 292 override Value invoke(Layer lay, Table ctx, LexPosition pos) 276 293 { 277 294 if( isASTLayer(lay) ) 278 295 return eval(ast.funbody, lay, ctx); 279 - if( afterMacroAST is null ) 296 + 297 + auto nonMemoizedRun = (){ 298 + if( macroCache is null ) 299 + { 300 + auto va = macroAndEval(e.funbody, lay, ctx); 301 + macroCache = va[1]; 302 + return va[0]; 303 + } 304 + else 305 + return eval(macroCache, lay, ctx); 306 + }; 307 + 308 + if( !isUserDefinedLayer(lay) ) 309 + return nonMemoizedRun(); 310 + 311 + MemokeyType memokey = new MemokeyType(cast(void*)ast, lay, ctx.direct_entries()); 312 + 313 + if(auto p = memokey in memo) 280 314 { 281 - auto va = macroAndEval(e.funbody, lay, ctx); 282 - afterMacroAST = va[1]; 283 - return va[0]; 315 + (*p)[1] ++; 316 + return (*p)[0]; 284 317 } 285 318 else 286 - return eval(afterMacroAST, lay, ctx); 319 + memo[memokey] = tuple(lift(new UndefinedValue, lay, ctx, pos), 0); 320 + 321 + Value r = nonMemoizedRun(); 322 + 323 + int touched = memo[memokey][1]; 324 + memo[memokey] = tuple(r, 12345678); 325 + //if(touched) {DBG("rerun :: ",r);r = nonMemoizedRun();} // twice!! 326 + return r; 287 327 } 288 328 } 289 329 return new UserDefinedFunValue(e,ctx); 290 330 } 291 331 292 332 public: 293 333 /// Add primitive function to the global context ................................................................................ 300 340 301 341 override string toString() { return sprintf!"(native:%x)"(dg.funcptr); } 302 342 override int opCmp(Object rhs) { 303 343 if(auto r = cast(NativeFunValue)rhs) return typeid(typeof(dg)).compare(&dg,&r.dg); 304 344 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r)); 305 345 throw genex!RuntimeException("comparison with value and something other"); 306 346 } 307 - mixin SimpleToHash; 347 + override hash_t toHash() const { 348 + return typeid(dg).getHash(&dg); 349 + } 308 350 309 351 R delegate(T) dg; 310 352 Parameter[] params_data; 311 353 312 354 this(R delegate(T) dg) 313 355 { 314 356 this.dg = dg;