Differences From Artifact [19366410c0eeb209]:
- File
polemy/value.d
- 2010-11-23 07:42:13 - part of checkin [6ac127ddd0] on branch trunk - new evaluator (user: kinaba) [annotate]
To 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]
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.failure;
10 10 import polemy.ast;
11 11 import polemy.layer;
12 +import std.string;
12 13
13 14 /// Runtime values of Polemy
14 15
15 16 abstract class Value
16 17 {
18 + override bool opEquals(Object rhs) { return 0==opCmp(rhs); }
17 19 }
18 20
19 21 ///
20 22 class IntValue : Value
21 23 {
22 24 BigInt data;
23 25
24 - mixin SimpleClass;
25 - override string toString() const { return std.bigint.toDecimalString(cast(BigInt)data); }
26 + this(int n) { this.data = n; }
27 + this(long n) { this.data = n; }
28 + this(BigInt n) { this.data = n; }
29 + this(string n) { this.data = BigInt(n); }
30 + override string toString() const { return toDecimalString(cast(BigInt)data); }
31 + override int opCmp(Object rhs) {
32 + if(auto r = cast(IntValue)rhs) return data.opCmp(r.data);
33 + if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r));
34 + throw genex!RuntimeException(LexPosition.dummy, "comparison with value and somithing other");
35 + }
36 + mixin SimpleToHash;
26 37 }
27 38
28 39 ///
29 40 class StrValue : Value
30 41 {
31 42 string data;
32 43
33 - mixin SimpleClass;
44 + mixin SimpleConstructor;
34 45 override string toString() const { return data; }
46 + override int opCmp(Object rhs) {
47 + if(auto r = cast(StrValue)rhs) return typeid(string).compare(&data, &r.data);
48 + if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r));
49 + throw genex!RuntimeException(LexPosition.dummy, "comparison with value and somithing other");
50 + }
51 + mixin SimpleToHash;
35 52 }
36 53
37 54 ///
38 -class UndValue : Value
55 +class UndefinedValue : Value
39 56 {
40 - mixin SimpleClass;
57 + mixin SimpleConstructor;
41 58 override string toString() const { return "<undefined>"; }
59 + override int opCmp(Object rhs) {
60 + if(auto r = cast(StrValue)rhs) return 0;
61 + if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r));
62 + throw genex!RuntimeException(LexPosition.dummy, "comparison with value and somithing other");
63 + }
64 + mixin SimpleToHash;
42 65 }
43 -
44 66
45 67 ///
46 68 abstract class FunValue : Value
47 69 {
48 70 const(Parameter[]) params();
49 71 Table definitionContext();
50 - Value invoke(LexPosition pos, Layer lay, Table ctx);
72 + Value invoke(Layer lay, Table ctx, LexPosition pos);
51 73 }
52 74
53 75 /// Context (variable environment)
54 76 /// Simlar to prototype chain of ECMAScript etc.
55 77 /// But extended with the notion of "Layer"
56 78
57 79 class Table : Value
................................................................................
334 356 }
335 357
336 358 Table fromPos(LexPosition pos)
337 359 {
338 360 Table t = new Table;
339 361 if( pos !is null ) {
340 362 t.set("filename", ValueLayer, new StrValue(pos.filename));
341 - t.set("lineno", ValueLayer, new IntValue(BigInt(pos.lineno)));
342 - t.set("column", ValueLayer, new IntValue(BigInt(pos.column)));
363 + t.set("lineno", ValueLayer, new IntValue(pos.lineno));
364 + t.set("column", ValueLayer, new IntValue(pos.column));
343 365 } else {
344 366 t.set("filename", ValueLayer, new StrValue("nullpos"));
345 - t.set("lineno", ValueLayer, new IntValue(BigInt(0)));
346 - t.set("column", ValueLayer, new IntValue(BigInt(0)));
367 + t.set("lineno", ValueLayer, new IntValue(0));
368 + t.set("column", ValueLayer, new IntValue(0));
347 369 }
348 370 return t;
349 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(".")[$-1].tolower()));
402 + foreach(i,m; e.tupleof)
403 + static if(is(typeof(m) : AST))
404 + t.set(e.tupleof[i].stringof[2..$], ValueLayer, rec(m));
405 + else
406 + t.set(e.tupleof[i].stringof[2..$], ValueLayer, ast2table(m,rec));
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, rec(m));
416 + else
417 + t.set(e.tupleof[i].stringof[2..$], ValueLayer, ast2table(m,rec));
418 + return t;
419 + }
420 + else
421 + static assert(false, "unknown type <"~T.stringof~"> during AST encoding");
422 +}