Diff
Not logged in

Differences From Artifact [19366410c0eeb209]:

To Artifact [b6c76b48bfdecce6]:


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 }