Differences From Artifact [aeb12eeaab91afb4]:
- File
polemy/value.d
- 2010-11-21 14:24:33 - part of checkin [3995a5eb6a] on branch trunk - added iikagen pattern match (user: kinaba) [annotate]
To Artifact [0386a7dd31807f87]:
- File
polemy/value.d
- 2010-11-21 15:48:16 - part of checkin [f86026acb8] on branch trunk - 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 (user: kinaba) [annotate]
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 {