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 * 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;
12 13
13 /// Runtime values of Polemy 14 /// Runtime values of Polemy
14 15
15 abstract class Value 16 abstract class Value
16 { 17 {
> 18 override bool opEquals(Object rhs) { return 0==opCmp(rhs); }
17 } 19 }
18 20
19 /// 21 ///
20 class IntValue : Value 22 class IntValue : Value
21 { 23 {
22 BigInt data; 24 BigInt data;
23 25
> 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)da
> 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(
> 34 throw genex!RuntimeException(LexPosition.dummy, "comparison with
> 35 }
24 mixin SimpleClass; | 36 mixin SimpleToHash;
25 override string toString() const { return std.bigint.toDecimalString(cas <
26 } 37 }
27 38
28 /// 39 ///
29 class StrValue : Value 40 class StrValue : Value
30 { 41 {
31 string data; 42 string data;
32 43
33 mixin SimpleClass; | 44 mixin SimpleConstructor;
34 override string toString() const { return data; } 45 override string toString() const { return data; }
> 46 override int opCmp(Object rhs) {
> 47 if(auto r = cast(StrValue)rhs) return typeid(string).compare(&da
> 48 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(
> 49 throw genex!RuntimeException(LexPosition.dummy, "comparison with
> 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 override string toString() const { return "<undefined>"; } 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(
> 62 throw genex!RuntimeException(LexPosition.dummy, "comparison with
> 63 }
> 64 mixin SimpleToHash;
42 } 65 }
43 <
44 66
45 /// 67 ///
46 abstract class FunValue : Value 68 abstract class FunValue : Value
47 { 69 {
48 const(Parameter[]) params(); 70 const(Parameter[]) params();
49 Table definitionContext(); 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 /// Context (variable environment) 75 /// Context (variable environment)
54 /// Simlar to prototype chain of ECMAScript etc. 76 /// Simlar to prototype chain of ECMAScript etc.
55 /// But extended with the notion of "Layer" 77 /// But extended with the notion of "Layer"
56 78
57 class Table : Value 79 class Table : Value
................................................................................................................................................................................
334 } 356 }
335 357
336 Table fromPos(LexPosition pos) 358 Table fromPos(LexPosition pos)
337 { 359 {
338 Table t = new Table; 360 Table t = new Table;
339 if( pos !is null ) { 361 if( pos !is null ) {
340 t.set("filename", ValueLayer, new StrValue(pos.filename)); 362 t.set("filename", ValueLayer, new StrValue(pos.filename));
341 t.set("lineno", ValueLayer, new IntValue(BigInt(pos.lineno))); | 363 t.set("lineno", ValueLayer, new IntValue(pos.lineno));
342 t.set("column", ValueLayer, new IntValue(BigInt(pos.column))); | 364 t.set("column", ValueLayer, new IntValue(pos.column));
343 } else { 365 } else {
344 t.set("filename", ValueLayer, new StrValue("nullpos")); 366 t.set("filename", ValueLayer, new StrValue("nullpos"));
345 t.set("lineno", ValueLayer, new IntValue(BigInt(0))); | 367 t.set("lineno", ValueLayer, new IntValue(0));
346 t.set("column", ValueLayer, new IntValue(BigInt(0))); | 368 t.set("column", ValueLayer, new IntValue(0));
347 } 369 }
348 return t; 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(".")[
> 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 }