Differences From Artifact [4f24d3bd11889ec1]:
- File
polemy/eval.d
- 2010-11-20 12:57:15 - part of checkin [3f6f41b558] on branch trunk - ast - table conversion (NOT AT ALL TESTED) (user: kinaba) [annotate]
To Artifact [84ee94a6f293fac0]:
- File
polemy/eval.d
- 2010-11-20 14:04:44 - part of checkin [8e3db9ef20] on branch trunk - macro worked! (user: kinaba) [annotate]
123 123 return (cast(FunValue)ctx.get(lay, "(system)", e.pos)).call(e.pos, "@v",
124 124 [ctx.get(e.var, "@v", e.pos)]
125 125 );
126 126 }
127 127 },
128 128 (LayeredExpression e)
129 129 {
130 - return eval(e.expr, ctx, false, e.lay);
130 + if( e.lay == "@macro" )
131 + return macroEval(e.expr, ctx, false);
132 + else
133 + return eval(e.expr, ctx, false, e.lay);
131 134 },
132 135 (LetExpression e)
133 136 {
134 137 // for letrec, we need this, but should avoid overwriting????
135 138 // ctx.set(e.var, "@v", new UndefinedValue, e.pos);
136 139 Value v = eval(e.init, ctx, true, lay);
137 140 if(splitCtx)
................................................................................
149 152 return f.call(e.pos, lay, args);
150 153 }
151 154 throw genex!RuntimeException(e.pos, "Non-funcion is applied");
152 155 },
153 156 (FunLiteral e)
154 157 {
155 158 Value[Value[]][Layer] memo;
159 + AST macroMemo = null; // cache
156 160
157 161 // funvalue need not be rised
158 162 // no, need to be rised !! suppose @t(fib)("int")
159 163 return new FunValue(delegate Value(immutable LexPosition pos, string lay, Value[] args){
160 164 // TODO: only auto raised ones need memo? no?
161 165 // auto memoization
162 - if( lay != "@v" )
166 + if( lay != "@v" && lay != "@macro" )
163 167 {
164 168 if( auto memolay = lay in memo )
165 169 if( auto pv = args in *memolay )
166 170 return *pv;
167 171 memo[lay][args] = (cast(FunValue)ctx.get(lay, "(system)", e.pos)).call(e.pos, "@v",
168 172 [new UndValue]
169 173 );
................................................................................
171 175
172 176 if( e.params.length != args.length )
173 177 throw genex!RuntimeException(e.pos, sprintf!"Argument Number Mismatch (%d required but %d given)"
174 178 (e.params.length, args.length));
175 179 Table ctxNeo = new Table(ctx, Table.Kind.NotPropagateSet);
176 180 foreach(i,p; e.params)
177 181 ctxNeo.set(p.name, lay, args[i]);
178 - auto v = eval(e.funbody, ctxNeo, true, lay);
182 +
183 + // @macro run!!!
184 + if( lay == "@macro" )
185 + return macroEval(e.funbody, ctxNeo, false);
186 + if( macroMemo is null )
187 + macroMemo = tableToAST("@v",macroEval(e.funbody, ctxNeo, true));
188 + auto v = eval(macroMemo, ctxNeo, true, lay);
189 +
190 + //auto v = eval(e.funbody, ctxNeo, true, lay);
179 191 // auto memoization
180 - if( lay != "@v" )
192 + if( lay != "@v" && lay != "@macro" )
181 193 memo[lay][args] = v;
182 194 return v;
183 195 });
184 196 },
185 197 delegate Value (AST e)
186 198 {
187 199 throw genex!RuntimeException(e.pos, sprintf!"Unknown Kind of Expression %s"(typeid(e)));
................................................................................
213 225 t.set("pos", theLayer, pos);
214 226 t.set("is", theLayer, new StrValue("int"));
215 227 t.set("data", theLayer, new IntValue(e.data));
216 228 return t;
217 229 },
218 230 (VarExpression e)
219 231 {
220 - Table t = new Table;
221 - t.set("pos", theLayer, pos);
222 - t.set("is", theLayer, new StrValue("var"));
223 - t.set("name", theLayer, new StrValue(e.var));
224 - return t;
232 + try {
233 + return ctx.get(e.var, "@macro", e.pos);
234 + } catch( Throwable ) {// [TODO] more precies...
235 + Table t = new Table;
236 + t.set("pos", theLayer, pos);
237 + t.set("is", theLayer, new StrValue("var"));
238 + t.set("name", theLayer, new StrValue(e.var));
239 + return cast(Value)t;
240 + }
225 241 },
226 242 (LayeredExpression e)
227 243 {
228 244 if( AlwaysMacro )
229 245 {
230 246 Table t = new Table;
231 247 t.set("pos", theLayer, pos);
232 248 t.set("is", theLayer, new StrValue("lay"));
249 + t.set("layer", theLayer, new StrValue(e.lay));
233 250 t.set("expr", theLayer, macroEval(e.expr,ctx,AlwaysMacro));
234 251 return cast(Value)t;
235 252 }
236 253 else
237 254 {
238 255 return eval(e.expr, ctx, true, e.lay);
239 256 }
................................................................................
246 263 t.set("name", theLayer, new StrValue(e.var));
247 264 t.set("init", theLayer, macroEval(e.init,ctx,AlwaysMacro));
248 265 t.set("expr", theLayer, macroEval(e.expr,ctx,AlwaysMacro));
249 266 return t;
250 267 },
251 268 (FuncallExpression e)
252 269 {
253 - // [TODO] @macro invokation!!!!
254 - // if e.fun is varname and its ctx[@macro] is set, switch to usual eval
270 + Value _f = macroEval(e.fun,ctx,AlwaysMacro);
271 +
272 + // copy & pase from normal eval
273 + // [TODO] sync with @layerd parameters.
274 + if( auto f = cast(FunValue)_f ) {
275 + Value[] args;
276 + foreach(a; e.args)
277 + args ~= macroEval(a, ctx, AlwaysMacro);
278 + return f.call(e.pos, "@macro", args); // explicit @macro is the best???
279 + }
280 +
255 281 Table t = new Table;
256 282 t.set("pos", theLayer, pos);
257 283 t.set("is", theLayer, new StrValue("app"));
258 - t.set("fun", theLayer, macroEval(e.fun,ctx,AlwaysMacro));
284 + t.set("fun", theLayer, _f);
259 285 Table args = new Table;
260 286 foreach_reverse(a; e.args) {
261 287 Table cons = new Table;
262 288 cons.set("car",theLayer,macroEval(a,ctx,AlwaysMacro));
263 289 cons.set("cdr",theLayer,args);
264 290 args = cons;
265 291 }
266 292 t.set("arg", theLayer, args);
267 - return t;
293 + return cast(Value)t;
268 294 },
269 295 (FunLiteral e)
270 296 {
271 297 Table t = new Table;
272 298 t.set("pos", theLayer, pos);
273 299 t.set("is", theLayer, new StrValue("fun"));
274 300 t.set("body", theLayer, macroEval(e.funbody,ctx,AlwaysMacro));
................................................................................
339 365 fac(10);`).val, new IntValue(BigInt(10*9*8*5040)));
340 366 assert_eq( evalString(`var fib = fun(x){
341 367 if(x<2)
342 368 { 1; }
343 369 else
344 370 { fib(x-1) + fib(x-2); };
345 371 };
346 - fib(10);`).val, new IntValue(BigInt(89)));
372 + fib(5);`).val, new IntValue(BigInt(8)));
347 373 }
348 374
349 375 unittest
350 376 {
351 377 assert_throw!Throwable( evalString(`@@s(x){x}; @s "+"=fun(x,y){x-y};@s(1+2)`) );
352 378 assert_eq( evalString(`@@s(x){x}; @s "+"=fun(x,y){x-y};1+2`).val, new IntValue(BigInt(3)) );
353 379 assert_eq( evalString(`@@s(x){x}; @s "+"=fun(x,y){@v(@s(x)-@s(y))};1+2`).val, new IntValue(BigInt(3)) );