Differences From Artifact [ca0ab118700475a8]:
- File
polemy/eval.d
- 2010-11-23 10:09:03 - part of checkin [36c517dfc4] on branch trunk - refactored d-value and polemy-value conversion (user: kinaba) [annotate]
To Artifact [a7c677ad83621b47]:
- File
polemy/eval.d
- 2010-11-23 13:55:15 - part of checkin [2134cd44cc] on branch trunk - further clean-up for polemy2d (user: kinaba) [annotate]
98 98 }
99 99
100 100 Value eval( App e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx )
101 101 {
102 102 Value f = eval( e.fun, lay, ctx );
103 103 if( isMacroishLayer(lay) )
104 104 if( auto ff = cast(FunValue)f )
105 - return invokeFunction(ff, e.args, MacroLayer, ctx, e.pos);
105 + return invokeFunction(ff, e.args, MacroLayer, ctx, e.pos, getNameIfPossible(e.fun));
106 106 else
107 107 return ast2table(e, (AST e){return eval(e,lay,ctx);});
108 - return invokeFunction(f, e.args, lay, ctx, e.pos);
108 + return invokeFunction(f, e.args, lay, ctx, e.pos, getNameIfPossible(e.fun));
109 109 }
110 110
111 111 Value eval( Fun e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx )
112 112 {
113 113 if( isMacroishLayer(lay) )
114 114 return ast2table(e, (AST e){return eval(e,lay,ctx);});
115 115 else
................................................................................
137 137 string theLayer = e.layer.empty ? lay : e.layer; // neutral layer
138 138 ctx.set(e.name, theLayer, ri);
139 139 return eval(e.expr, lay, ctx, OverwriteCtx);
140 140 }
141 141 }
142 142
143 143 private:
144 - Value invokeFunction(Value _f, AST[] args, Layer lay, Table ctx, LexPosition pos=null)
144 + string getNameIfPossible(AST e)
145 + {
146 + if(auto v = cast(Var)e)
147 + return v.name;
148 + return "";
149 + }
150 +
151 + Value invokeFunction(Value _f, AST[] args, Layer lay, Table ctx, LexPosition pos, string callstackmsg)
145 152 {
146 153 if(auto f = cast(FunValue)_f)
147 154 {
148 155 Table newCtx = new Table(f.definitionContext(), Table.Kind.NotPropagateSet);
149 156 foreach(i,p; f.params())
150 157 if( p.layers.empty )
151 158 newCtx.set(p.name, (lay==RawMacroLayer ? MacroLayer : lay), eval(args[i], lay, ctx));
152 159 else
153 160 foreach(argLay; p.layers)
154 161 newCtx.set(p.name, argLay, eval(args[i], argLay, ctx));
162 + scope _ = new PushCallStack(pos, callstackmsg);
155 163 return f.invoke(lay==RawMacroLayer ? MacroLayer : lay, newCtx, pos);
156 164 }
157 165 throw genex!RuntimeException(pos, text("tried to call non-function: ",_f));
158 166 }
159 167
160 - Value lift(Value v, Layer lay, Table ctx, LexPosition pos=null)
168 + Value lift(Value v, Layer lay, Table ctx, LexPosition pos)
161 169 {
162 - assert( !isMacroishLayer(lay), "lift to the @macro layer should not happen" );
170 + assert( !isMacroishLayer(lay), "lift to the @macro layer should never happen" );
163 171
164 172 // functions are automatically lifterd
165 173 if( cast(FunValue) v )
166 174 return v;
167 175
168 - // similar to invoke Function, but with only one argument bound to ValueLayer
169 - if(auto f = cast(FunValue)ctx.get(lay, SystemLayer, pos))
176 + if( !ctx.has(lay, SystemLayer) )
177 + throw genex!RuntimeException(pos, "lift function for "~lay~" is not registered" );
178 +
179 + // similar to invokeFunction, but with only one argument bound to ValueLayer
180 + auto _f = ctx.get(lay, SystemLayer, pos);
181 + if(auto f = cast(FunValue)_f)
170 182 {
171 183 Table newCtx = new Table(f.definitionContext(), Table.Kind.NotPropagateSet);
172 184 auto ps = f.params();
173 185 if( ps.length != 1 )
174 - throw genex!RuntimeException(pos, "lift function must take exactly one argument at "~ValueLayer~" layer");
186 + throw genex!RuntimeException(pos,
187 + text("lift function for", lay, " must take exactly one argument of ", ValueLayer));
175 188 if( ps[0].layers.length==0 || ps[0].layers.length==1 && ps[0].layers[0]==ValueLayer )
176 189 {
177 190 newCtx.set(ps[0].name, ValueLayer, v);
191 + scope _ = new PushCallStack(pos, lay);
178 192 return f.invoke(ValueLayer, newCtx, pos);
179 193 }
180 194 else
181 - throw genex!RuntimeException(pos, "lift function must take exactly one argument at "~ValueLayer~" layer");
195 + throw genex!RuntimeException(pos,
196 + text("lift function for", lay, " must take exactly one argument of ", ValueLayer));
182 197 }
183 - throw genex!RuntimeException(pos, "tried to call non-function");
198 + throw genex!RuntimeException(pos,
199 + text("non-function ", _f, " is registered as the lift function for ", lay));
184 200 }
185 201
186 202 Value createNewFunction(Fun e, Table ctx)
187 203 {
188 204 class UserDefinedFunValue : FunValue
189 205 {
190 206 Fun ast;
................................................................................
215 231 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_)));
216 232 }
217 233
218 234 override Value invoke(Layer lay, Table ctx, LexPosition pos)
219 235 {
220 236 if( lay == MacroLayer )
221 237 return eval(ast.funbody, lay, ctx);
222 - if( afterMacroAST is null )
223 - afterMacroAST = tableToAST(ValueLayer, eval(e.funbody, RawMacroLayer, ctx));
224 - return eval(afterMacroAST, lay, ctx);
238 + try {
239 + if( afterMacroAST is null )
240 + afterMacroAST = polemy2d!(AST)(eval(e.funbody, RawMacroLayer, ctx), pos);
241 + return eval(afterMacroAST, lay, ctx);
242 + } catch( RuntimeException e ) {
243 + throw e.pos is null ? new RuntimeException(pos, e.msg, e.file, e.line, e.next) : e;
244 + }
225 245 }
226 246
227 247 AST afterMacroAST;
228 248 }
229 249 return new UserDefinedFunValue(e,ctx);
230 250 }
231 251