Differences From Artifact [197c2cfb75326106]:
- File
polemy/eval.d
- 2010-11-24 13:22:04 - part of checkin [f9c31f3cd8] on branch trunk - Fixed the null dereference bug when directly wrote "case 1 when 2: 3" in REPL. It was due to null LexPosition in the AST. Now AST.pos !is null is an invariant of AST. (user: kinaba) [annotate]
To Artifact [bc3c32f1d9aafc10]:
- File
polemy/eval.d
- 2010-11-24 17:44:58 - part of checkin [b993a8ad16] on branch trunk - auto memo and re-run feature of non @value/@macro layers re-re-re-implemented. (user: kinaba) [annotate]
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;