Check-in [552d43f567]
Not logged in
Overview
SHA1 Hash:552d43f567ce52df465842efab311a605af70d31
Date: 2010-11-26 15:46:09
User: kinaba
Comment:one-by-one M&E memoizer
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified polemy/eval.d from [56f0a662740b0906] to [1c0a1caee00496c7].

9 9 import polemy.failure; 10 10 import polemy.ast; 11 11 import polemy.parse; 12 12 import polemy.value; 13 13 import polemy.layer; 14 14 import polemy.value; 15 15 import polemy.valueconv; 16 +import std.signals; 16 17 17 18 /// Objects for maitaining global environment and evaluation of expression on it 18 19 class Evaluator 19 20 { 20 21 public: 21 22 /// Initialize evaluator with empty context 22 23 this() { theContext = new Table; } 23 24 24 25 /// Evaluate the AST 25 26 Value evalAST(AST e) 26 27 { 27 - return macroAndEval(e, ValueLayer, theContext, OverwriteCtx)[0]; 28 + AST[void*] mandeCache; 29 + return macroAndEval(e, ValueLayer, theContext, OverwriteCtx, mandeCache)[0]; 28 30 } 29 31 30 32 /// Evaluate the string 31 33 Value evalString(S,T...)(S str, T fn_ln_cn) 32 34 { 33 35 return evalAST(parseString(str,fn_ln_cn)); 34 36 } ................................................................................ 152 154 } 153 155 } 154 156 155 157 private: 156 158 // little little bit incremental macro defining version. 157 159 // enables @macro foo(x)=... in ... foo ..., only at the top level of the 158 160 // interpreter and functions. better than nothing :P 159 - Tuple!(Value,AST) macroAndEval( AST e_, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 161 + Tuple!(Value,AST) macroAndEval( AST e_, Layer lay, Table ctx, bool overwriteCtx 162 + , ref AST[void*] mandeCache) // [TODO] avoid assuming non-moving GC 160 163 { 161 164 assert( !isASTLayer(lay) ); 162 165 163 166 AST decodeAST(Value v, LexPosition pos) 164 167 { 165 168 // [TODO] more informative error message 166 169 return polemy2d!(AST)(v, pos); 167 170 } 168 171 169 172 if(auto e = cast(Let)e_) 170 173 { 171 - AST ai = decodeAST(eval(e.init, RawMacroLayer, ctx), e.init.pos); 174 + void* key = cast(void*)e.init; 175 + AST ai; 176 + if(auto p = key in mandeCache) 177 + ai = *p; 178 + else { 179 + ai = decodeAST(eval(e.init, RawMacroLayer, ctx), e.init.pos); 180 + mandeCache[key] = ai; 181 + } 172 182 Value vi = eval(ai, lay, ctx); 173 183 174 184 if( !overwriteCtx ) 175 185 ctx = new Table(ctx, Table.Kind.NotPropagateSet); 176 186 string theLayer = e.layer.empty ? lay : e.layer; 177 187 ctx.set(e.name, theLayer, vi); 178 188 179 - auto ave = macroAndEval( e.expr, lay, ctx, OverwriteCtx ); 189 + auto ave = macroAndEval( e.expr, lay, ctx, OverwriteCtx, mandeCache ); 180 190 AST a = new Let(e.pos, e.name, e.layer, ai, ave[1]); 181 191 return tuple(ave[0], a); 182 192 } 183 193 else 184 194 { 185 - AST a = decodeAST(eval(e_, RawMacroLayer, ctx), e_.pos); 186 - Value v = eval(a, lay, ctx); 195 + void* key = cast(void*)e_; 196 + AST a; 197 + if(auto p = key in mandeCache) 198 + a = *p; 199 + else { 200 + a = decodeAST(eval(e_, RawMacroLayer, ctx), e_.pos); 201 + mandeCache[key] = a; 202 + } 203 + Value v = eval(a, lay, ctx, overwriteCtx); 187 204 return tuple(v, a); 188 205 } 189 206 } 190 207 191 208 private: 192 209 string getNameIfPossible(AST e) 193 210 { ................................................................................ 271 288 throw genex!RuntimeException("comparison with value and something other"); 272 289 } 273 290 override hash_t toHash() { 274 291 return (cast(hash_t)cast(void*)ast) + (cast(hash_t)cast(void*)defCtx); 275 292 } 276 293 277 294 AST macroCache; 295 + AST[void*] mandeCache; 278 296 static class MemokeyType 279 297 { 280 298 void* a; Layer b; Tuple!(string,Layer,Value)[] c; 281 299 hash_t toHash() { 282 300 hash_t h = structuralHash(a) + structuralHash(b); 283 301 foreach(e; c) 284 302 h += structuralHash(e[0])+structuralHash(e[1])+structuralHash(e[2]); ................................................................................ 294 312 { 295 313 if( isASTLayer(lay) ) 296 314 return eval(ast.funbody, lay, ctx); 297 315 298 316 auto nonMemoizedRun = (){ 299 317 if( macroCache is null ) 300 318 { 301 - auto va = macroAndEval(e.funbody, lay, ctx); 319 + auto va = macroAndEval(e.funbody, lay, ctx, CascadeCtx, mandeCache); 302 320 macroCache = va[1]; 303 321 return va[0]; 304 322 } 305 323 else 306 324 return eval(macroCache, lay, ctx); 307 325 }; 308 326 ................................................................................ 466 484 assert_nothrow( e.evalString(`case 1 when 1: 2`) ); 467 485 468 486 // this is a shorthand for 469 487 // @macro x = fun(){} in @macro(x) 470 488 // so it is ok to fail, but it is really incovenient on REPL 471 489 assert_nothrow( e.evalString(`@macro x=fun(){}`) ); 472 490 } 473 - 474 -/* 475 -unittest 476 -{ 477 - assert_eq( evalString(`var fac = fun(x){ 478 - if(x) 479 - { x*fac(x-1); } 480 - else 481 - { 1; }; 482 - }; 483 - fac(10);`).val, new IntValue(BigInt(10*9*8*5040))); 484 - assert_eq( evalString(`var fib = fun(x){ 485 - if(x<2) 486 - { 1; } 487 - else 488 - { fib(x-1) + fib(x-2); }; 489 - }; 490 - fib(5);`).val, new IntValue(BigInt(8))); 491 -} 492 -unittest 493 -{ 494 - assert_eq( evalString(`@@t = fun(x){x+1}; @t(123)`).val, new IntValue(BigInt(124)) ); 495 - // there was a bug that declaration in the first line of function definition 496 - // cannot be recursive 497 - assert_nothrow( evalString(`def foo() { 498 - def bar(y) { if(y<1) {0} else {bar(0)} }; 499 - bar(1) 500 -}; foo()`) ); 501 -} 502 -*/