Diff
Not logged in

Differences From Artifact [19366410c0eeb209]:

To Artifact [b6c76b48bfdecce6]:


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 +}