Diff
Not logged in

Differences From Artifact [4f24d3bd11889ec1]:

To Artifact [84ee94a6f293fac0]:


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)) );