Differences From Artifact [8d6e708eceba536a]:
- File
polemy/eval.d
- 2010-11-26 07:42:38 - part of checkin [f7e9e77316] on branch trunk - introduced "..." expression, and replaced the pattern match failure with this. (user: kinaba) [annotate]
To Artifact [10da2d7378e56ec4]:
- File
polemy/eval.d
- 2010-11-26 15:13:58 - part of checkin [6760e0dd02] on branch trunk - evaluator refactoring done. x6 speed up. (user: kinaba) [annotate]
21 public: 21 public:
22 /// Initialize evaluator with empty context 22 /// Initialize evaluator with empty context
23 this() { theContext = new Table; } 23 this() { theContext = new Table; }
24 24
25 /// Evaluate the AST 25 /// Evaluate the AST
26 Value evalAST(AST e) 26 Value evalAST(AST e)
27 { 27 {
28 AST[void*] mandeCache; <
29 return macroAndEval(e, ValueLayer, theContext, OverwriteCtx, man | 28 return macroAndEval(e, ValueLayer, theContext, OverwriteCtx);
30 } 29 }
31 30
32 /// Evaluate the string 31 /// Evaluate the string
33 Value evalString(S,T...)(S str, T fn_ln_cn) 32 Value evalString(S,T...)(S str, T fn_ln_cn)
34 { 33 {
35 return evalAST(parseString(str,fn_ln_cn)); 34 return evalAST(parseString(str,fn_ln_cn));
36 } 35 }
................................................................................................................................................................................
48 } 47 }
49 48
50 private: 49 private:
51 Table theContext; 50 Table theContext;
52 51
53 enum : bool { CascadeCtx=false, OverwriteCtx=true }; 52 enum : bool { CascadeCtx=false, OverwriteCtx=true };
54 53
55 Value eval( AST e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) | 54 LayerEval getLayerEvaluator(Layer lay)
56 { 55 {
57 // dynamic-overload-resolution-pattern: modify here | 56 if( lay == ValueLayer )
58 enum funName = "eval"; | 57 return new ValueLayerEval;
59 alias TypeTuple!(e,lay,ctx,overwriteCtx) params; | 58 if( lay == RawMacroLayer )
60 <
> 59 return new RawMacroLayerEval;
61 // dynamic-overload-resolution-pattern: dispatch | 60 if( lay == MacroLayer )
62 alias typeof(__traits(getOverloads, this, funName)) ovTypes; | 61 return new MacroLayerEval;
63 alias staticMap!(firstParam, ovTypes) fstTypes; | 62 return new UserDefinedLayerEval(lay);
64 alias DerivedToFront!(fstTypes) fstTypes_sorted; <
65 foreach(i, T; fstTypes_sorted) <
66 static if( is(T == typeof(params[0])) ) {} else if( auto <
67 return __traits(getOverloads, this, funName)[i]( <
68 <
69 // dynamic-overload-resolution-pattern: default behavior <
70 assert(false, text("eval() for ",typeid(e)," [",e.pos,"] is not <
71 } 63 }
72 64
73 Value eval( Str e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) | 65 abstract class LayerEval
74 { <
75 if( isASTLayer(lay) ) <
76 return ast2table(e, (AST e){return eval(e,lay,ctx);}); <
77 if( isUserDefinedLayer(lay) ) <
78 return lift(new StrValue(e.data), lay, ctx, e.pos); <
79 return new StrValue(e.data); <
80 } <
81 <
82 Value eval( Int e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) <
83 { 66 {
84 if( isASTLayer(lay) ) | 67 /// Concrete layers should implement these
85 return ast2table(e, (AST e){return eval(e,lay,ctx);}); | 68 Layer currentLayer();
86 if( isUserDefinedLayer(lay) ) | 69 Value eval_( Die e, Table ctx, bool ctxMod );///
87 return lift(new IntValue(e.data), lay, ctx, e.pos); | 70 Value eval_( Str e, Table ctx, bool ctxMod );///
88 return new IntValue(e.data); | 71 Value eval_( Int e, Table ctx, bool ctxMod );///
> 72 Value eval_( Var e, Table ctx, bool ctxMod );///
> 73 Value eval_( Lay e, Table ctx, bool ctxMod );///
> 74 Value eval_( Let e, Table ctx, bool ctxMod );///
> 75 Value eval_( App e, Table ctx, bool ctxMod );///
> 76 Value eval_( Fun e, Table ctx, bool ctxMod );///
89 } | 77
> 78 /// dynamic-overload-resolution
> 79 Value eval( AST e, Table ctx, bool ctxMod )
90 | 80 {
91 Value eval( Var e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) <
> 81 enum funName = "eval_"; // modify here t
> 82 alias TypeTuple!(e,ctx,ctxMod) params; // modify here t
92 { | 83
93 if( isASTLayer(lay) ) <
94 if( isMacroLayer(lay) && ctx.has(e.name,MacroLayer) ) <
95 return ctx.get(e.name, MacroLayer, e.pos); <
> 84 alias typeof(__traits(getOverloads, this, funName)) ovTy
> 85 alias staticMap!(firstParam, ovTypes) fstTy
> 86 alias DerivedToFront!(fstTypes) fstTypes_sor
> 87 foreach(i, T; fstTypes_sorted)
> 88 static if( is(T == typeof(params[0])) ) {} else
> 89 return __traits(getOverloads, this, funN
> 90
> 91 // modify here to customize the default behavior
> 92 assert(false, text("eval() for ",typeid(e)," [",e.pos,"]
> 93 }
> 94
> 95 ///
> 96 Value invokeFunction(Value _f, AST[] args, Table ctx, LexPositio
> 97 {
> 98 if(auto f = cast(FunValue)_f)
> 99 {
> 100 Table newCtx = new Table(f.definitionContext(),
> 101 foreach(i,p; f.params())
> 102 if( p.layers.empty ) {
> 103 Value v = this.eval(args[i], ctx
> 104 if(v is null) v = ast2table(args
> 105 newCtx.set(p.name, currentLayer(
> 106 }
96 else | 107 else
97 return ast2table(e, (AST e){return eval(e,lay,ct <
98 if( isUserDefinedLayer(lay) && !ctx.has(e.name, lay) ) <
99 return lift(ctx.get(e.name, ValueLayer, e.pos), lay, ctx <
100 return ctx.get(e.name, lay, e.pos); <
> 108 foreach(argLay; p.layers) {
> 109 Layer ll = argLay;
> 110 if( isMacroLayer(argLay)
> 111 ll = RawMacroLay
> 112 Value v = getLayerEvalua
> 113 if(v is null) v = ast2ta
> 114 newCtx.set(p.name, argLa
101 } | 115 }
> 116 scope _ = new PushCallStack(pos, callstackmsg);
> 117 return f.invoke(currentLayer(), newCtx, pos);
102 | 118 }
103 Value eval( App e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) <
> 119 throw genex!RuntimeException(pos, text("tried to call no
> 120 }
104 { | 121
105 Value f = eval( e.fun, lay, ctx ); <
106 if( isASTLayer(lay) ) { <
> 122 ///
> 123 Value lift(Value v, Table ctx, LexPosition pos)
> 124 {
> 125 Layer lay = currentLayer();
> 126
> 127 // functions are automatically lifterd
> 128 if( cast(FunValue) v )
> 129 return v;
> 130
> 131 if( !ctx.has(lay, LiftLayer) )
> 132 throw genex!RuntimeException(pos, "lift function
> 133
> 134 // similar to invokeFunction, but with only one argument
> 135 auto _f = ctx.get(lay, LiftLayer, pos);
107 auto ff = cast(FunValue)f; | 136 if(auto f = cast(FunValue)_f)
108 if( ff !is null && isMacroLayer(lay) ) <
109 return invokeFunction(ff, e.args, lay, ctx, e.po <
> 137 {
> 138 Table newCtx = new Table(f.definitionContext(),
> 139 auto ps = f.params();
> 140 if( ps.length != 1 )
> 141 throw genex!RuntimeException(pos,
> 142 text("lift function for", lay, "
> 143 if( ps[0].layers.length==0 || ps[0].layers.lengt
> 144 {
> 145 newCtx.set(ps[0].name, ValueLayer, v);
> 146 scope _ = new PushCallStack(pos, lay);
> 147 return f.invoke(ValueLayer, newCtx, pos)
> 148 }
110 else | 149 else
111 return ast2table(e, (AST e){return eval(e,lay,ct <
> 150 throw genex!RuntimeException(pos,
> 151 text("lift function for", lay, "
112 } | 152 }
113 return invokeFunction(f, e.args, lay, ctx, e.pos, getNameIfPossi <
> 153 throw genex!RuntimeException(pos,
> 154 text("non-function ", _f, " is registered as the
> 155 }
114 } 156 }
115 157
116 Value eval( Fun e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) | 158 /// Evaluator for standard @value semantics
117 { <
118 if( isASTLayer(lay) ) <
119 { <
120 // need this for correct scoping (outer scope macro vari <
121 Table newCtx = new Table(ctx, Table.Kind.NotPropagateSet <
122 foreach(p; e.params) <
123 newCtx.set(p.name, NoopLayer, null); <
124 return ast2table(e, (AST e){return eval(e,lay,newCtx);}) <
125 } <
126 else <
127 return createNewFunction(e, ctx); <
128 } <
129 <
130 Value eval( Lay e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) <
> 159 class ValueLayerEval : LayerEval
131 { 160 {
132 if( isNoLayerChangeLayer(lay) ) | 161 override Layer currentLayer()
133 return ast2table(e, (AST e){return eval(e,lay,ctx);}); <
> 162 {
134 else | 163 return ValueLayer;
135 return eval(e.expr, e.layer, ctx); <
136 } | 164 }
> 165 override Value eval_( Die e, Table ctx, bool ctxMod )
137 | 166 {
138 Value eval( Let e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) | 167 throw genex!RuntimeException(e.pos, "undefined case");
> 168 }
> 169 override Value eval_( Str e, Table ctx, bool ctxMod )
139 { | 170 {
140 Table newCtx = overwriteCtx ? ctx : new Table(ctx, Table.Kind.No <
141 if( isASTLayer(lay) ) <
> 171 return new StrValue(e.data);
> 172 }
> 173 override Value eval_( Int e, Table ctx, bool ctxMod )
> 174 {
> 175 return new IntValue(e.data);
> 176 }
> 177 override Value eval_( Var e, Table ctx, bool ctxMod )
> 178 {
> 179 return ctx.get(e.name, currentLayer(), e.pos);
> 180 }
> 181 override Value eval_( Lay e, Table ctx, bool ctxMod )
> 182 {
> 183 auto le = getLayerEvaluator(e.layer);
> 184 auto v = le.eval(e.expr,ctx,CascadeCtx);
> 185 if( (v is null) && (cast(MacroLayerEval)le !is null) )
142 return ast2table(e, (AST ee){ | 186 return ast2table(e.expr);
143 // need this for correct scoping (outer scope ma <
144 if(e.name!="_" && ee is e.expr) <
145 newCtx.set(e.name, NoopLayer, null); <
146 return eval(ee,lay,newCtx); <
147 }); <
148 else | 187 else
> 188 return v;
> 189 }
> 190 override Value eval_( Let e, Table ctx, bool ctxMod )
149 { | 191 {
150 Value ri = eval(e.init, lay, newCtx); <
> 192 Table newCtx = ctxMod ? ctx : new Table(ctx, Table.Kind.
> 193 Value ri = this.eval(e.init, newCtx, CascadeCtx);
151 if(e.name!="_") 194 if(e.name!="_")
152 newCtx.set(e.name, e.layer.empty ? lay : e.layer | 195 newCtx.set(e.name, e.layer.empty ? currentLayer(
153 return eval(e.expr, lay, newCtx, OverwriteCtx); | 196 return this.eval(e.expr, newCtx, OverwriteCtx);
> 197 }
> 198 override Value eval_( App e, Table ctx, bool ctxMod )
> 199 {
> 200 Value f = this.eval( e.fun, ctx, CascadeCtx );
> 201 return this.invokeFunction(f, e.args, ctx, e.pos, getNam
> 202 }
> 203 override Value eval_( Fun e, Table ctx, bool ctxMod )
> 204 {
> 205 return createNewFunction(e, ctx);
154 } 206 }
155 } 207 }
156 208
157 Value eval( Die e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) | 209 /// Evaluator for user-defined layer
> 210 class UserDefinedLayerEval : ValueLayerEval
158 { 211 {
159 if( isMacroLayer(lay) ) | 212 Layer layerID;
160 return ast2table(e, (AST e){return eval(e,lay,ctx);}); | 213 mixin SimpleConstructor;
161 if( isUserDefinedLayer(lay) ) <
> 214
> 215 override Layer currentLayer()
> 216 {
> 217 return layerID;
> 218 }
> 219 override Value eval_( Die e, Table ctx, bool ctxMod )
> 220 {
162 return new UndefinedValue; 221 return new UndefinedValue;
163 throw genex!RuntimeException(e.pos, "undefined case"); <
> 222 }
> 223 override Value eval_( Str e, Table ctx, bool ctxMod )
> 224 {
> 225 return this.lift(new StrValue(e.data), ctx, e.pos);
> 226 }
> 227 override Value eval_( Int e, Table ctx, bool ctxMod )
> 228 {
> 229 return this.lift(new IntValue(e.data), ctx, e.pos);
> 230 }
> 231 override Value eval_( Var e, Table ctx, bool ctxMod )
> 232 {
> 233 if( ctx.has(e.name, currentLayer()) )
> 234 return ctx.get(e.name, currentLayer());
> 235 return this.lift(ctx.get(e.name, ValueLayer, e.pos), ctx
> 236 }
164 } 237 }
165 238
166 private: | 239 // Convention!!
167 // little little bit incremental macro defining version. | 240 // returns null if never used macro-like feature
168 // enables @macro foo(x)=... in ... foo ..., only at the top level of th | 241 class MacroLayerEval : LayerEval
169 // interpreter and functions. better than nothing :P <
170 Tuple!(Value,AST) macroAndEval( AST e_, Layer lay, Table ctx, bool overw <
171 , ref AST[void*] mandeCache) // [TODO] avoid assuming non-moving <
172 { 242 {
173 assert( !isASTLayer(lay) ); | 243 override Layer currentLayer()
174 | 244 {
175 AST decodeAST(Value v, LexPosition pos) | 245 return MacroLayer;
> 246 }
> 247 override Value eval_( Die e, Table ctx, bool ctxMod )
> 248 {
> 249 return null;
> 250 }
> 251 override Value eval_( Str e, Table ctx, bool ctxMod )
> 252 {
> 253 return null;
> 254 }
> 255 override Value eval_( Int e, Table ctx, bool ctxMod )
> 256 {
> 257 return null;
> 258 }
> 259 override Value eval_( Var e, Table ctx, bool ctxMod )
> 260 {
> 261 if( ctx.has(e.name, currentLayer()) )
> 262 return ctx.get(e.name, currentLayer(), e.pos);
> 263 else
> 264 return null;
> 265 }
> 266 override Value eval_( Lay e, Table ctx, bool ctxMod )
176 { 267 {
177 // [TODO] more informative error message | 268 auto le = getLayerEvaluator(e.layer);
178 return polemy2d!(AST)(v, pos); | 269 return le.eval(e.expr,ctx,CascadeCtx);
179 } 270 }
180 <
181 if(auto e = cast(Let)e_) <
> 271 override Value eval_( Let e, Table ctx, bool ctxMod )
182 { 272 {
183 void* key = cast(void*)e.init; <
184 AST ai; <
185 if(auto p = key in mandeCache) <
186 ai = *p; <
187 else { <
188 ai = decodeAST(eval(e.init, RawMacroLayer, ctx), <
189 mandeCache[key] = ai; <
190 } <
191 Value vi = eval(ai, lay, ctx); <
192 <
193 if( !overwriteCtx ) <
194 ctx = new Table(ctx, Table.Kind.NotPropagateSet) | 273 Table newCtx = ctxMod ? ctx : new Table(ctx, Table.Kind.
195 string theLayer = e.layer.empty ? lay : e.layer; <
> 274 Value ai = this.eval(e.init, newCtx, CascadeCtx);
196 ctx.set(e.name, theLayer, vi); | 275 newCtx.set(e.name, NoopLayer, null);
197 <
198 auto ave = macroAndEval( e.expr, lay, ctx, OverwriteCtx, <
199 AST a = new Let(e.pos, e.name, e.layer, ai, ave[1]); <
> 276 Value ae = this.eval(e.expr, newCtx, OverwriteCtx);
> 277 if( ai is null && ae is null )
200 return tuple(ave[0], a); | 278 return null;
> 279 if( ai is null ) ai = ast2table(e.init);
> 280 if( ae is null ) ae = ast2table(e.expr);
> 281 return ast2table(e, delegate Value (AST _){
> 282 if(_ is e.init) { return ai; }
> 283 if(_ is e.expr) { return ae; }
> 284 assert(false);
> 285 });
201 } 286 }
202 else | 287 override Value eval_( App e, Table ctx, bool ctxMod )
203 { 288 {
204 void* key = cast(void*)e_; | 289 Value f = this.eval( e.fun, ctx, CascadeCtx );
205 AST a; | 290 if(auto ff = cast(FunValue)f)
206 if(auto p = key in mandeCache) | 291 return this.invokeFunction(ff, e.args, ctx, e.po
207 a = *p; <
208 else { 292 else {
209 a = decodeAST(eval(e_, RawMacroLayer, ctx), e_.p | 293 bool allNull = (f is null);
210 mandeCache[key] = a; | 294 Value[] vas;
> 295 foreach(a; e.args) {
> 296 Value va = this.eval(a, ctx, CascadeCtx)
> 297 if(va !is null) allNull = false;
> 298 vas ~= va;
> 299 }
> 300 if( allNull )
> 301 return null;
> 302 return ast2table(e, delegate Value (AST _){
> 303 if(_ is e.fun) return (f is null ? ast2t
> 304 foreach(i,a; e.args) if(_ is a) return (
> 305 assert(false);
> 306 });
211 } 307 }
212 Value v = eval(a, lay, ctx, overwriteCtx); <
> 308 }
> 309 override Value eval_( Fun e, Table ctx, bool ctxMod )
> 310 {
> 311 Table newCtx = new Table(ctx, Table.Kind.NotPropagateSet
> 312 foreach(p; e.params)
> 313 newCtx.set(p.name, NoopLayer, null);
> 314 Value af = this.eval(e.funbody, newCtx, CascadeCtx);
> 315 if( af is null )
213 return tuple(v, a); | 316 return null;
> 317 return ast2table(e, (AST _){if(_ is e.funbody)return af;
> 318 }
> 319 }
> 320
> 321 class RawMacroLayerEval : MacroLayerEval
> 322 {
> 323 override Value eval_( Lay e, Table ctx, bool ctxMod )
> 324 {
> 325 Value ae = this.eval(e.expr, ctx, CascadeCtx);
> 326 return ae is null ? null
> 327 : ast2table(e, delegate Value (AST _){if(_ is e.e
> 328 }
> 329 }
> 330
> 331 private:
> 332 Value macroAndEval( AST e_, Layer lay, Table ctx, bool ctxMod )
> 333 {
> 334 assert( !isASTLayer(lay) );
> 335 if(auto e = cast(Let)e_)
> 336 {
> 337 Value vai = getLayerEvaluator(RawMacroLayer).eval(e.init
> 338 AST ai = (vai is null ? e.init : polemy2d!(AST)(vai, e.p
> 339
> 340 if( !ctxMod )
> 341 ctx = new Table(ctx, Table.Kind.NotPropagateSet)
> 342
> 343 Value vi = getLayerEvaluator(lay).eval(ai, ctx, CascadeC
> 344 string theLayer = e.layer.empty ? lay : e.layer;
> 345 ctx.set(e.name, theLayer, vi);
> 346
> 347 return macroAndEval( e.expr, lay, ctx, OverwriteCtx );
> 348 }
> 349 else
> 350 {
> 351 Value va = getLayerEvaluator(RawMacroLayer).eval(e_, ctx
> 352 AST a = (va is null ? e_ : polemy2d!(AST)(va, e_.pos));
> 353 return getLayerEvaluator(lay).eval(a, ctx, ctxMod);
214 } 354 }
215 } 355 }
216 356
217 private: 357 private:
218 string getNameIfPossible(AST e) 358 string getNameIfPossible(AST e)
219 { 359 {
220 if(auto v = cast(Var)e) 360 if(auto v = cast(Var)e)
221 return v.name; 361 return v.name;
222 return ""; 362 return "";
223 } 363 }
224 364
225 Value invokeFunction(Value _f, AST[] args, Layer lay, Table ctx, LexPosi <
226 { <
227 if(auto f = cast(FunValue)_f) <
228 { <
229 Table newCtx = new Table(f.definitionContext(), Table.Ki <
230 foreach(i,p; f.params()) <
231 if( p.layers.empty ) <
232 newCtx.set(p.name, isMacroLayer(lay)?Mac <
233 else <
234 foreach(argLay; p.layers) <
235 if( lay!=MacroLayer && isMacroLa <
236 newCtx.set(p.name, argLa <
237 else <
238 newCtx.set(p.name, argLa <
239 scope _ = new PushCallStack(pos, callstackmsg); <
240 return f.invoke(isMacroLayer(lay)?MacroLayer:lay, newCtx <
241 } <
242 throw genex!RuntimeException(pos, text("tried to call non-functi <
243 } <
244 <
245 Value lift(Value v, Layer lay, Table ctx, LexPosition pos) <
246 { <
247 assert( !isASTLayer(lay), "lift to the @macro layer should never <
248 <
249 // functions are automatically lifterd <
250 if( cast(FunValue) v ) <
251 return v; <
252 <
253 if( !ctx.has(lay, LiftLayer) ) <
254 throw genex!RuntimeException(pos, "lift function for "~l <
255 <
256 // similar to invokeFunction, but with only one argument bound t <
257 auto _f = ctx.get(lay, LiftLayer, pos); <
258 if(auto f = cast(FunValue)_f) <
259 { <
260 Table newCtx = new Table(f.definitionContext(), Table.Ki <
261 auto ps = f.params(); <
262 if( ps.length != 1 ) <
263 throw genex!RuntimeException(pos, <
264 text("lift function for", lay, " must ta <
265 if( ps[0].layers.length==0 || ps[0].layers.length==1 && <
266 { <
267 newCtx.set(ps[0].name, ValueLayer, v); <
268 scope _ = new PushCallStack(pos, lay); <
269 return f.invoke(ValueLayer, newCtx, pos); <
270 } <
271 else <
272 throw genex!RuntimeException(pos, <
273 text("lift function for", lay, " must ta <
274 } <
275 throw genex!RuntimeException(pos, <
276 text("non-function ", _f, " is registered as the lift fu <
277 } <
278 <
279 Value createNewFunction(Fun e, Table ctx) 365 Value createNewFunction(Fun e, Table ctx)
280 { 366 {
281 class UserDefinedFunValue : FunValue 367 class UserDefinedFunValue : FunValue
282 { 368 {
283 Fun ast; 369 Fun ast;
284 Table defCtx; 370 Table defCtx;
285 override const(Parameter[]) params() { return ast.params 371 override const(Parameter[]) params() { return ast.params
................................................................................................................................................................................
318 mixin SimpleConstructor; 404 mixin SimpleConstructor;
319 mixin SimpleCompareWithoutToHash; 405 mixin SimpleCompareWithoutToHash;
320 } 406 }
321 static Tuple!(Value,int)[MemokeyType] memo; 407 static Tuple!(Value,int)[MemokeyType] memo;
322 408
323 override Value invoke(Layer lay, Table ctx, LexPosition 409 override Value invoke(Layer lay, Table ctx, LexPosition
324 { 410 {
325 if( isASTLayer(lay) ) | 411 if( isASTLayer(lay) ) {
326 return eval(ast.funbody, lay, ctx); | 412 Value v = getLayerEvaluator(lay).eval(as
> 413 if( v is null ) v = ast2table(ast.funbod
> 414 return v;
327 | 415 }
> 416 return macroAndEval(ast.funbody, lay, ctx, Casca
> 417 /*
328 auto nonMemoizedRun = (){ 418 auto nonMemoizedRun = (){
329 if( macroCache is null ) 419 if( macroCache is null )
330 { 420 {
331 auto va = macroAndEval(e.funbody 421 auto va = macroAndEval(e.funbody
332 macroCache = va[1]; 422 macroCache = va[1];
333 return va[0]; 423 return va[0];
334 } 424 }
................................................................................................................................................................................
351 441
352 Value r = nonMemoizedRun(); 442 Value r = nonMemoizedRun();
353 443
354 int touched = memo[memokey][1]; 444 int touched = memo[memokey][1];
355 memo[memokey] = tuple(r, 12345678); 445 memo[memokey] = tuple(r, 12345678);
356 //if(touched) {DBG("rerun :: ",r);r = nonMemoize 446 //if(touched) {DBG("rerun :: ",r);r = nonMemoize
357 return r; 447 return r;
> 448 */
358 } 449 }
359 } 450 }
360 return new UserDefinedFunValue(e,ctx); 451 return new UserDefinedFunValue(e,ctx);
361 } 452 }
362 453
363 public: 454 public:
364 /// Add primitive function to the global context 455 /// Add primitive function to the global context