Differences From Artifact [a4c75e644b34fb64]:
- File
polemy/value.d
- 2010-11-20 09:20:03 - part of checkin [515502e8d1] on branch trunk - table get, init, ask expressions addded (user: kinaba) [annotate]
To Artifact [10fa9090c50cdaf9]:
- File
polemy/value.d
- 2010-11-20 12:57:15 - part of checkin [3f6f41b558] on branch trunk - ast - table conversion (NOT AT ALL TESTED) (user: kinaba) [annotate]
3 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
4 4 *
5 5 * Runtime data structures for Polemy programming language.
6 6 */
7 7 module polemy.value;
8 8 import polemy._common;
9 9 import polemy.lex;
10 +import polemy.ast;
10 11
11 12 /// Raised when something went wrong in runtime
12 13
13 14 class RuntimeException : Exception
14 15 {
15 16 mixin ExceptionWithPosition;
16 17 }
................................................................................
129 130 throw genex!RuntimeException(pos, sprintf!"variable %s is not set in layer %s"(i,lay));
130 131 return data[i][lay];
131 132 }
132 133 if( prototype is null )
133 134 throw new RuntimeException(pos, sprintf!"variable %s not found"(i));
134 135 return prototype.get(i, lay, pos);
135 136 }
137 +
138 + T access(T,S...)( Layer lay, string path, S rest )
139 + {
140 + static if( rest.length == 0 )
141 + {
142 + if( this.has(path, lay) )
143 + return cast(T) this.get(path, lay);
144 + }
145 + else
146 + {
147 + if(auto next = this.access!Table(lay,path))
148 + return next.access!T(lay,rest);
149 + }
150 + return null;
151 + }
136 152
137 153 private:
138 154 Table prototype;
139 155 Kind kind;
140 156 Value[Layer][string] data;
141 157
142 158 bool setIfExist(string i, Layer lay, Value v)
................................................................................
186 202 assert_eq( c013.get("z", "@v"), new IntValue(BigInt(0)) );
187 203 assert_eq( c012.get("z", "@v"), new IntValue(BigInt(555)) );
188 204 assert_eq( c01.get("z", "@v"), new IntValue(BigInt(0)) );
189 205 assert_eq( c0.get("z", "@v"), new IntValue(BigInt(0)) );
190 206
191 207 // [TODO] define the semantics and test @layers
192 208 }
209 +
210 +immutable(LexPosition) extractPos( Table t )
211 +{
212 + Layer theLayer = "@v";
213 + if(auto tt = t.access!Table(theLayer, "pos"))
214 + {
215 + auto fn = tt.access!StrValue(theLayer, "filename");
216 + auto ln = tt.access!IntValue(theLayer, "lineno");
217 + auto cl = tt.access!IntValue(theLayer, "column");
218 + if(fn !is null && ln !is null && cl !is null)
219 + return new immutable(LexPosition)(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt);
220 + }
221 + return null;
222 +}
223 +
224 +Value[] tableAsConsList( Layer theLayer, Table t )
225 +{
226 + Value[] result;
227 + while(t)
228 + if(auto v = t.access!Value(theLayer, "car"))
229 + {
230 + result ~= v;
231 + t = t.access!Table(theLayer, "cdr");
232 + }
233 + else
234 + break;
235 + return result;
236 +}
237 +
238 +AST[] tableToASTList( Layer theLayer, Table t )
239 +{
240 + AST[] result;
241 + foreach(v; tableAsConsList(theLayer, t))
242 + if(auto t = cast(Table)v)
243 + result ~= tableToAST(theLayer,t);
244 + else
245 + throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST (non-table in cons-list)");
246 + return result;
247 +}
248 +
249 +AST tableToAST( Layer theLayer, Table t )
250 +{
251 + auto nodeType = t.access!StrValue(theLayer, "is");
252 + if( nodeType is null )
253 + throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST {is:(not string)}");
254 + auto pos = extractPos(t);
255 + switch(nodeType.data)
256 + {
257 + case "int":
258 + if(auto v = t.access!IntValue(theLayer, "data"))
259 + return new IntLiteral(pos, v.data);
260 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"int", data:(not int)}`);
261 + case "str":
262 + if(auto v = t.access!StrValue(theLayer, "data"))
263 + return new StrLiteral(pos, v.data);
264 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"str", data:(not string)}`);
265 + case "var":
266 + if(auto v = t.access!StrValue(theLayer, "name"))
267 + return new VarExpression(pos, v.data);
268 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"var", name:(not string)}`);
269 + case "lay":
270 + if(auto v = t.access!StrValue(theLayer, "layer"))
271 + if(auto e = t.access!Table(theLayer, "expr"))
272 + return new LayeredExpression(pos, v.data, tableToAST(theLayer,e));
273 + else
274 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", expr:(not table)}`);
275 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"lay", layer:(not string)}`);
276 + case "let":
277 + if(auto n = t.access!StrValue(theLayer, "name"))
278 + if(auto e = t.access!Table(theLayer, "init"))
279 + if(auto b = t.access!Table(theLayer, "expr"))
280 + {
281 + string nn = n.data;
282 + auto ee = tableToAST(theLayer, e);
283 + auto bb = tableToAST(theLayer, b);
284 + Layer lay="";
285 + if(auto l = t.access!StrValue(theLayer, "layer"))
286 + lay = l.data;
287 + return new LetExpression(pos, nn, lay, ee, bb);
288 + }
289 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"let", name:"???", init:"???", expr:"???"}`);
290 + case "app":
291 + if(auto f = t.access!Table(theLayer, "fun"))
292 + if(auto a = t.access!Table(theLayer, "arg"))
293 + return new FuncallExpression(pos, tableToAST(theLayer,f), tableToASTList(theLayer,a));
294 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"app", fun:???, arg:???}`);
295 + case "fun":
296 + if(auto p = t.access!Table(theLayer, "param"))
297 + if(auto b = t.access!Table(theLayer, "body"))
298 + {
299 + Parameter[] ps;
300 + foreach(v; tableAsConsList(theLayer, p))
301 + {
302 + if(auto tt = cast(Table)v)
303 + if(auto ss = tt.access!StrValue(theLayer, "name"))
304 + if(auto ll = tt.access!Table(theLayer, "layer"))
305 + {
306 + Layer[] ls;
307 + foreach(lll; tableAsConsList(theLayer, ll))
308 + if(auto l = cast(StrValue)lll)
309 + ls ~= l.data;
310 + else
311 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {bad fun params}`);
312 + ps ~= new Parameter(ss.data, ls);
313 + continue;
314 + }
315 + else
316 + {
317 + Layer[] emp;
318 + ps ~= new Parameter(ss.data, emp);
319 + }
320 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {bad fun params}`);
321 + }
322 + auto bb = tableToAST(theLayer, b);
323 + return new FunLiteral(pos,ps,bb);
324 + }
325 + throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST {is:"fun", param:???, body:???}`);
326 + default:
327 + throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Invalid AST {is: "%s"} unknown`(nodeType.data));
328 + }
329 +}