Check-in [f86026acb8]
Not logged in
Overview
SHA1 Hash:f86026acb8636d5b302809e88477a8321c43ed62
Date: 2010-11-22 00:48:16
User: kinaba
Comment:macro cache and automemoization reloaded. auto re-run implemented. but automemo and autorerun is currently disabled. we need Table.opCmp... we also need to think more about the memoization
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 [c85d31e67d8ceb4b] to [9a9618fb0277f966].

105 105 return f.invoke(pos, lay, ctx); 106 106 } 107 107 throw genex!RuntimeException(pos, "tried to call non-function"); 108 108 } 109 109 110 110 Value lift(in LexPosition pos, Value v, Layer lay, Table callerCtx) 111 111 { 112 + // functions are automatically lifterd 113 + if( cast(FunValue) v ) 114 + return v; 115 + 112 116 // similar to invoke Function, but with only one argument bound to ValueLayer 113 117 Value _f = callerCtx.get(lay, SystemLayer, pos); 114 118 if(auto f = cast(FunValue)_f) 115 119 { 116 120 Table ctx = new Table(f.definitionContext(), Table.Kind.NotPropagateSet); 117 121 auto ps = f.params(); 118 122 if( ps.length != 1 ) ................................................................................ 151 155 else // rise 152 156 return lift(e.pos,v,lay,ctx); 153 157 }, 154 158 (VarExpression e) 155 159 { 156 160 if( lay == ValueLayer ) 157 161 return ctx.get(e.name, lay, e.pos); 158 - try { 162 + if( ctx.has(e.name, lay, e.pos) ) 159 163 return ctx.get(e.name, lay, e.pos); 160 - } catch( Throwable ) { // [TODO] more precise... 164 + else 161 165 return lift(e.pos, ctx.get(e.name, ValueLayer, e.pos), lay, ctx); 162 - } 163 166 }, 164 167 (LayExpression e) 165 168 { 166 169 if( e.layer == MacroLayer ) 167 170 return macroEval(e.expr, ctx, false); 168 171 else 169 172 return eval(e.expr, ctx, true, e.layer); ................................................................................ 180 183 }, 181 184 (FuncallExpression e) 182 185 { 183 186 return invokeFunction(e.pos, eval(e.fun, ctx, true, lay), e.args, ctx, lay); 184 187 }, 185 188 (FunLiteral e) 186 189 { 187 - Value[Value[]][Layer] memo; 188 - AST macroMemo = null; // cache 189 - 190 - // funvalue need not be rised 191 - // no, need to be rised !! suppose @t(fib)("int") 192 190 return new UserDefinedFunValue(e, ctx); 193 191 }, 194 192 delegate Value (AST e) 195 193 { 196 194 throw genex!RuntimeException(e.pos, sprintf!"Unknown Kind of Expression %s"(typeid(e))); 197 195 } 198 196 ); ................................................................................ 237 235 t.set("pos", theLayer, pos); 238 236 t.set("is", theLayer, new StrValue("int")); 239 237 t.set("data", theLayer, new IntValue(e.data)); 240 238 return t; 241 239 }, 242 240 (VarExpression e) 243 241 { 244 - try { 242 + if( ctx.has(e.name, MacroLayer, e.pos) ) 245 243 return ctx.get(e.name, MacroLayer, e.pos); 246 - } catch( Throwable ) {// [TODO] more precies... 244 + else { 247 245 Table t = new Table; 248 246 t.set("pos", theLayer, pos); 249 247 t.set("is", theLayer, new StrValue("var")); 250 248 t.set("name", theLayer, new StrValue(e.name)); 251 249 return cast(Value)t; 252 250 } 253 251 },

Modified polemy/value.d from [aeb12eeaab91afb4] to [0386a7dd31807f87].

47 47 { 48 48 const(Parameter[]) params(); 49 49 Table definitionContext(); 50 50 Value invoke(in LexPosition pos, Layer lay, Table ctx); 51 51 } 52 52 53 53 import polemy.eval; // circular... 54 +version = MacroCache; 55 +//version = AutoMemoization; 56 +//version = AutoRerun; 54 57 55 58 /// 56 59 class UserDefinedFunValue : FunValue 57 60 { 58 61 FunLiteral ast; 59 62 Table defCtx; 63 + 64 + this(FunLiteral ast, Table defCtx) { this.ast=ast; this.defCtx=defCtx; } 65 + override string toString() const { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } 66 + override bool opEquals(Object rhs_) const /// member-by-member equality 67 + { 68 + if( auto rhs = cast(typeof(this))rhs_ ) 69 + return this.ast==rhs.ast && this.defCtx==rhs.defCtx; 70 + assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 71 + } 72 + override hash_t toHash() const /// member-by-member hash 73 + { 74 + return typeid(this.ast).getHash(&this.ast) + typeid(this.defCtx).getHash(&this.defCtx); 75 + } 76 + override int opCmp(Object rhs_) /// member-by-member compare 77 + { 78 + if( auto rhs = cast(typeof(this))rhs_ ) 79 + { 80 + if(auto i = this.ast.opCmp(rhs.ast)) 81 + return i; 82 + return this.defCtx.opCmp(rhs.defCtx); 83 + } 84 + assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 85 + } 86 + 87 + private AST preprocessed_funbody; 88 + private Value[Value[]][Layer] memo; 89 + 60 90 override const(Parameter[]) params() { return ast.params; } 61 91 override Table definitionContext() { return defCtx; } 62 92 override Value invoke(in LexPosition pos, Layer lay, Table ctx) 63 93 { 64 94 // TODO: only auto raised ones need memo? no? 65 - // auto memoization 66 -/* 67 - if( lay != ValueLayer && lay != MacroLayer ) 95 + // how can we integrate re-run ?? 96 + version(AutoMemoization) 68 97 { 69 - if( auto memolay = lay in memo ) 70 - if( auto pv = args in *memolay ) 71 - return *pv; 72 - memo[lay][args] = lift(e.pos,new UndValue,lay,ctx); 98 + Value[] memokey; 99 + if( lay != ValueLayer && lay != MacroLayer ) 100 + { 101 + foreach(i,p; ast.params) 102 + memokey ~= ctx.get(p.name, lay); // lay? 103 + if( auto memolay = lay in memo ) 104 + if( auto pv = memokey in *memolay ) 105 + return *pv; 106 + memo[lay][memokey] = lift(ast.pos,new UndValue,lay,ctx); 107 + } 73 108 } 74 109 75 -*/ 76 110 // @macro run!!! 77 111 if( lay == MacroLayer ) 78 112 return macroEval(ast.funbody, ctx, false); 79 -/*TODO memo*/ AST macroMemo; 80 - if( macroMemo is null ) { 81 - // .prototype!, forced macro cannot access parameters 82 - ctx.kill = true; scope(exit)ctx.kill=false; 83 - auto tbl = macroEval(ast.funbody, ctx, true); 84 - macroMemo = tableToAST(ValueLayer,tbl); 113 + 114 + version(MacroCache) { 115 + if( preprocessed_funbody is null ) { 116 + // .prototype!, forced macro cannot access parameters 117 + ctx.kill = true; scope(exit)ctx.kill=false; 118 + preprocessed_funbody = tableToAST(ValueLayer,macroEval(ast.funbody, ctx, true)); 119 + } 120 + } else { 121 + if( preprocessed_funbody is null ) { 122 + // .prototype!, forced macro cannot access parameters 123 + ctx.kill = true; scope(exit)ctx.kill=false; 124 + preprocessed_funbody = tableToAST(ValueLayer,macroEval(ast.funbody, ctx, true)); 125 + } 85 126 } 86 - auto v = eval(macroMemo, ctx, true, lay); 87 127 88 - //auto v = eval(e.funbody, ctxNeo, true, lay); 89 - // auto memoization 90 -// if( lay != ValueLayer && lay != MacroLayer ) 91 -// memo[lay][args] = v; 128 + auto v = eval(preprocessed_funbody, ctx, true, lay); 129 + version(AutoMemoization) 130 + { 131 + if( lay != ValueLayer && lay != MacroLayer ) 132 + { 133 + memo[lay][memokey] = v; 134 + version(AutoReRun) 135 + memo[lay][memokey] = eval(preprocessed_funbody, ctx, true, lay); // re-Run!! 136 + } 137 + } 92 138 return v; 93 139 } 94 - 95 - mixin SimpleClass; 96 - override string toString() const { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } 97 140 } 98 141 99 142 /// 100 143 abstract class NativeFunValue : FunValue 101 144 { 102 145 Parameter[] params_data; 103 146 override const(Parameter[]) params() { return params_data; } ................................................................................ 167 210 } 168 211 169 212 Value get(string i, Layer lay, in LexPosition pos=null) 170 213 { 171 214 if( i in data ) { 172 215 // [TODO] consider forwarding to proto also in this case 173 216 if( lay !in data[i] ) 174 - throw genex!RuntimeException(pos, sprintf!"variable %s is not set in layer %s"(i,lay)); 217 + throw genex!RuntimeException(pos, sprintf!"'%s' is not set in layer %s"(i,lay)); 175 218 if(kill) 176 - throw genex!RuntimeException(pos, sprintf!"variable %s is killed in macro"(i)); 219 + throw genex!RuntimeException(pos, sprintf!"'%s' is killed in macro"(i)); 177 220 return data[i][lay]; 178 221 } 179 222 if( prototype is null ) 180 - throw new RuntimeException(pos, sprintf!"variable %s not found"(i)); 223 + throw new RuntimeException(pos, sprintf!"'%s' not found"(i)); 181 224 return prototype.get(i, lay, pos); 182 225 } 183 226 184 227 T access(T,S...)( Layer lay, string path, S rest ) 185 228 { 186 229 static if( rest.length == 0 ) 187 230 {

Modified sample/pattern.pmy from [683a8d961c6525cd] to [3044d19024152b10].

15 15 { 16 16 case( lst ) 17 17 when( {car:x, cdr:{car: y, cdr:z}} ) { {car: x+y, cdr: adjSum(z)} } 18 18 when( {car:x, cdr:{}} ) { {car: x, cdr: {}} } 19 19 when( {} ) { {} } 20 20 }; 21 21 22 -var xs = fromTo(1,11); 22 +var xs = fromTo(1,101); 23 23 24 24 print( xs ); 25 25 print( length(xs) ); 26 26 print( adjSum(xs) ); 27 27 print( length(adjSum(xs)) );

Modified sample/type.pmy from [c9a55d8e7b3293ae] to [ed44c7901d3c5853].

3 3 else { if( _isstr(x) ) { "str" } 4 4 else { if( _isfun(x) ) { x } 5 5 else { if( _isundefined(x) ) { "undefined" } 6 6 else { "any" }}}} 7 7 }; 8 8 9 9 def binop(a,b,c) { 10 - fun(x,y){@v( 10 + fun(x,y){@value( 11 11 if( @type(x)=="undefined" || @type(y)=="undefined" ) { "undefined" } else { 12 12 if( @type(x)==a && @type(y)==b ) { c } else { "error" } 13 13 } 14 14 )} 15 15 }; 16 16 17 17 @type "+" = binop("int", "int", "int"); ................................................................................ 19 19 @type "<" = binop("int", "int", "int"); 20 20 @type ">" = binop("int", "int", "int"); 21 21 22 22 def mergeType(a,b) { 23 23 if( a == "undefined" ) { if(b=="undefined"){"error"}else{b} } else { a } 24 24 }; 25 25 26 -@type "if" = fun(c,t,e) {@v( 26 +@type "if" = fun(c,t,e) {@value( 27 27 if(@type(c)=="int" ) { mergeType(@type(t()), @type(e())) } else { "error" } 28 28 )};