Differences From Artifact [b6c76b48bfdecce6]:
- File
polemy/value.d
- 2010-11-23 09:36:27 - part of checkin [b97bd4f713] on branch trunk - automatic AST to table encoder (user: kinaba) [annotate]
To Artifact [6d85ee04f34c61b7]:
- File
polemy/value.d
- 2010-11-23 10:09:03 - part of checkin [36c517dfc4] on branch trunk - refactored d-value and polemy-value conversion (user: kinaba) [annotate]
5 * Runtime data structures for Polemy programming language. 5 * Runtime data structures for Polemy programming language.
6 */ 6 */
7 module polemy.value; 7 module polemy.value;
8 import polemy._common; 8 import polemy._common;
9 import polemy.failure; 9 import polemy.failure;
10 import polemy.ast; 10 import polemy.ast;
11 import polemy.layer; 11 import polemy.layer;
12 import std.string; <
13 12
14 /// Runtime values of Polemy 13 /// Runtime values of Polemy
15 14
16 abstract class Value 15 abstract class Value
17 { 16 {
18 override bool opEquals(Object rhs) { return 0==opCmp(rhs); } 17 override bool opEquals(Object rhs) { return 0==opCmp(rhs); }
19 } 18 }
20 19
21 /// 20 ///
22 class IntValue : Value 21 class IntValue : Value
23 { 22 {
24 BigInt data; 23 BigInt data;
25 24
> 25 this(bool n) { this.data = n?1:0; }
26 this(int n) { this.data = n; } 26 this(int n) { this.data = n; }
27 this(long n) { this.data = n; } 27 this(long n) { this.data = n; }
28 this(BigInt n) { this.data = n; } 28 this(BigInt n) { this.data = n; }
29 this(string n) { this.data = BigInt(n); } 29 this(string n) { this.data = BigInt(n); }
30 override string toString() const { return toDecimalString(cast(BigInt)da 30 override string toString() const { return toDecimalString(cast(BigInt)da
31 override int opCmp(Object rhs) { 31 override int opCmp(Object rhs) {
32 if(auto r = cast(IntValue)rhs) return data.opCmp(r.data); 32 if(auto r = cast(IntValue)rhs) return data.opCmp(r.data);
................................................................................................................................................................................
216 assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) ); 216 assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) );
217 assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) ); 217 assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) );
218 assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) ); 218 assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) );
219 assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) ); 219 assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) );
220 220
221 // [TODO] define the semantics and test @layers 221 // [TODO] define the semantics and test @layers
222 } 222 }
223 <
224 immutable(LexPosition) extractPos( Table t ) <
225 { <
226 Layer theLayer = ValueLayer; <
227 if(auto tt = t.access!Table(theLayer, "pos")) <
228 { <
229 auto fn = tt.access!StrValue(theLayer, "filename"); <
230 auto ln = tt.access!IntValue(theLayer, "lineno"); <
231 auto cl = tt.access!IntValue(theLayer, "column"); <
232 if(fn !is null && ln !is null && cl !is null) <
233 return new immutable(LexPosition)(fn.data,cast(int)ln.da <
234 } <
235 return null; <
236 } <
237 <
238 Value[] tableAsConsList( Layer theLayer, Table t ) <
239 { <
240 Value[] result; <
241 while(t) <
242 if(auto v = t.access!Value(theLayer, "car")) <
243 { <
244 result ~= v; <
245 t = t.access!Table(theLayer, "cdr"); <
246 } <
247 else <
248 break; <
249 return result; <
250 } <
251 <
252 AST[] tableToASTList( Layer theLayer, Table t ) <
253 { <
254 AST[] result; <
255 foreach(v; tableAsConsList(theLayer, t)) <
256 if(auto t = cast(Table)v) <
257 result ~= tableToAST(theLayer,t); <
258 else <
259 throw genex!RuntimeException(cast(LexPosition)null, "Inv <
260 return result; <
261 } <
262 <
263 AST tableToAST( Layer theLayer, Value vvvv ) <
264 { <
265 Table t = cast(Table)vvvv; <
266 if( t is null ) <
267 throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST <
268 <
269 auto nodeType = t.access!StrValue(theLayer, "is"); <
270 if( nodeType is null ) <
271 throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST <
272 auto pos = extractPos(t); <
273 switch(nodeType.data) <
274 { <
275 case "int": <
276 if(auto v = t.access!IntValue(theLayer, "data")) <
277 return new Int(pos, v.data); <
278 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
279 case "str": <
280 if(auto v = t.access!StrValue(theLayer, "data")) <
281 return new Str(pos, v.data); <
282 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
283 case "var": <
284 if(auto v = t.access!StrValue(theLayer, "name")) <
285 return new Var(pos, v.data); <
286 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
287 case "lay": <
288 if(auto v = t.access!StrValue(theLayer, "layer")) <
289 if(auto e = t.access!Table(theLayer, "expr")) <
290 return new Lay(pos, v.data, tableToAST(theLayer, <
291 else <
292 throw genex!RuntimeException(cast(LexPosition)nu <
293 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
294 case "let": <
295 if(auto n = t.access!StrValue(theLayer, "name")) <
296 if(auto e = t.access!Table(theLayer, "init")) <
297 if(auto b = t.access!Table(theLayer, "expr")) <
298 { <
299 string nn = n.data; <
300 auto ee = tableToAST(theLayer, e); <
301 auto bb = tableToAST(theLayer, b); <
302 Layer lay=""; <
303 if(auto l = t.access!StrValue(theLayer, "layer")) <
304 lay = l.data; <
305 return new Let(pos, nn, lay, ee, bb); <
306 } <
307 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
308 case "app": <
309 if(auto f = t.access!Table(theLayer, "fun")) <
310 if(auto a = t.access!Table(theLayer, "args")) <
311 return new App(pos, tableToAST(theLayer,f), tableToASTLi <
312 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
313 case "fun": <
314 if(auto p = t.access!Table(theLayer, "params")) <
315 if(auto b = t.access!Table(theLayer, "funbody")) <
316 { <
317 Parameter[] ps; <
318 foreach(v; tableAsConsList(theLayer, p)) <
319 { <
320 if(auto tt = cast(Table)v) <
321 if(auto ss = tt.access!StrValue(theLayer, "name" <
322 if(auto ll = tt.access!Table(theLayer, "layers") <
323 { <
324 Layer[] ls; <
325 foreach(lll; tableAsConsList(theLayer, l <
326 if(auto l = cast(StrValue)lll) <
327 ls ~= l.data; <
328 else <
329 throw genex!RuntimeExcep <
330 ps ~= new Parameter(ss.data, ls); <
331 continue; <
332 } <
333 else <
334 { <
335 Layer[] emp; <
336 ps ~= new Parameter(ss.data, emp); <
337 continue; <
338 } <
339 throw genex!RuntimeException(cast(LexPosition)nu <
340 } <
341 auto bb = tableToAST(theLayer, b); <
342 return new Fun(pos,ps,bb); <
343 } <
344 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST <
345 default: <
346 throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Inv <
347 } <
348 } <
349 <
350 Table makeCons(Value a, Value d) <
351 { <
352 Table t = new Table; <
353 t.set("car", ValueLayer, a); <
354 t.set("cdr", ValueLayer, d); <
355 return t; <
356 } <
357 <
358 Table fromPos(LexPosition pos) <
359 { <
360 Table t = new Table; <
361 if( pos !is null ) { <
362 t.set("filename", ValueLayer, new StrValue(pos.filename)); <
363 t.set("lineno", ValueLayer, new IntValue(pos.lineno)); <
364 t.set("column", ValueLayer, new IntValue(pos.column)); <
365 } else { <
366 t.set("filename", ValueLayer, new StrValue("nullpos")); <
367 t.set("lineno", ValueLayer, new IntValue(0)); <
368 t.set("column", ValueLayer, new IntValue(0)); <
369 } <
370 return t; <
371 } <
372 <
373 /// Convert AST to Table so that it can be used in Polemy <
374 /// TODO: generalize to DValue2PolemyValue <
375 <
376 Value ast2table(T)(T e, Value delegate(AST) rec) <
377 { <
378 assert( typeid(e) == typeid(T) ); <
379 <
380 static if(is(T==BigInt) || is(T==long) || is(T==int)) <
381 return new IntValue(e); <
382 else <
383 static if(is(T==string)) <
384 return new StrValue(e); <
385 else <
386 static if(is(T S : S[])) <
387 { <
388 Table lst = new Table; <
389 foreach_reverse(a; e) <
390 static if(is(S : AST)) <
391 lst = makeCons(rec(a), lst); <
392 else <
393 lst = makeCons(ast2table(a,rec), lst); <
394 return lst; <
395 } <
396 else <
397 static if(is(T : AST)) <
398 { <
399 auto t = new Table; <
400 t.set("pos", ValueLayer, fromPos(e.pos)); <
401 t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[ <
402 foreach(i,m; e.tupleof) <
403 static if(is(typeof(m) : AST)) <
404 t.set(e.tupleof[i].stringof[2..$], ValueLayer, r <
405 else <
406 t.set(e.tupleof[i].stringof[2..$], ValueLayer, a <
407 return t; <
408 } <
409 else <
410 static if(is(T == class)) <
411 { <
412 auto t = new Table; <
413 foreach(i,m; e.tupleof) <
414 static if(is(typeof(m) : AST)) <
415 t.set(e.tupleof[i].stringof[2..$], ValueLayer, r <
416 else <
417 t.set(e.tupleof[i].stringof[2..$], ValueLayer, a <
418 return t; <
419 } <
420 else <
421 static assert(false, "unknown type <"~T.stringof~"> during AST e <
422 } <