8de5b49cdf 2010-11-09 kinaba: /** b0d8d7875b 2010-11-08 kinaba: * Authors: k.inaba b0d8d7875b 2010-11-08 kinaba: * License: NYSL 0.9982 http://www.kmonos.net/nysl/ b0d8d7875b 2010-11-08 kinaba: * b0d8d7875b 2010-11-08 kinaba: * Runtime data structures for Polemy programming language. b0d8d7875b 2010-11-08 kinaba: */ b0d8d7875b 2010-11-08 kinaba: module polemy.value; b0d8d7875b 2010-11-08 kinaba: import polemy._common; aa770610d3 2010-11-08 kinaba: import polemy.lex; b0d8d7875b 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: /// Raised when something went wrong in runtime aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: class RuntimeException : Exception b0d8d7875b 2010-11-08 kinaba: { aa770610d3 2010-11-08 kinaba: const LexPosition pos; aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: this( const LexPosition pos, string msg ) 8de5b49cdf 2010-11-09 kinaba: { super(sprintf!"%s at [%s]"(msg, pos)); this.pos = pos; } b0d8d7875b 2010-11-08 kinaba: } aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: /// Runtime values of Polemy b0d8d7875b 2010-11-08 kinaba: b0d8d7875b 2010-11-08 kinaba: abstract class Value b0d8d7875b 2010-11-08 kinaba: { b0d8d7875b 2010-11-08 kinaba: } b0d8d7875b 2010-11-08 kinaba: b0d8d7875b 2010-11-08 kinaba: class IntValue : Value b0d8d7875b 2010-11-08 kinaba: { b0d8d7875b 2010-11-08 kinaba: BigInt data; aa770610d3 2010-11-08 kinaba: b0d8d7875b 2010-11-08 kinaba: mixin SimpleConstructor; b0d8d7875b 2010-11-08 kinaba: mixin SimpleCompare; aa770610d3 2010-11-08 kinaba: override string toString() const { return std.bigint.toDecimalString(cast(BigInt)data); } b0d8d7875b 2010-11-08 kinaba: } b0d8d7875b 2010-11-08 kinaba: b0d8d7875b 2010-11-08 kinaba: class StrValue : Value b0d8d7875b 2010-11-08 kinaba: { b0d8d7875b 2010-11-08 kinaba: string data; aa770610d3 2010-11-08 kinaba: b0d8d7875b 2010-11-08 kinaba: mixin SimpleConstructor; b0d8d7875b 2010-11-08 kinaba: mixin SimpleCompare; b0d8d7875b 2010-11-08 kinaba: override string toString() const { return data; } b0d8d7875b 2010-11-08 kinaba: } b0d8d7875b 2010-11-08 kinaba: b0d8d7875b 2010-11-08 kinaba: class FunValue : Value b0d8d7875b 2010-11-08 kinaba: { b0d8d7875b 2010-11-08 kinaba: Value delegate(immutable LexPosition pos, Value[]) data; aa770610d3 2010-11-08 kinaba: b0d8d7875b 2010-11-08 kinaba: mixin SimpleConstructor; aa770610d3 2010-11-08 kinaba: alias data call; b0d8d7875b 2010-11-08 kinaba: override string toString() const { return sprintf!"(function:%s:%s)"(data.ptr,data.funcptr); } b0d8d7875b 2010-11-08 kinaba: } aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: /// Layer ID aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: alias string Layer; aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: /// Context (variable environment) aa770610d3 2010-11-08 kinaba: /// Simlar to prototype chain of ECMAScript etc. aa770610d3 2010-11-08 kinaba: /// But extended with the notion of "Layer" aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: class Table : Value b0d8d7875b 2010-11-08 kinaba: { aa770610d3 2010-11-08 kinaba: enum Kind {PropagateSet, NotPropagateSet}; aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: this( Table proto=null, Kind k = Kind.PropagateSet ) aa770610d3 2010-11-08 kinaba: { this.prototype = proto; this.kind = k; } aa770610d3 2010-11-08 kinaba: 8de5b49cdf 2010-11-09 kinaba: void set(string i, Layer lay, Value v, in LexPosition pos=null) aa770610d3 2010-11-08 kinaba: { 8de5b49cdf 2010-11-09 kinaba: if( setIfExist(i, lay, v) ) 8de5b49cdf 2010-11-09 kinaba: return; 8de5b49cdf 2010-11-09 kinaba: data[i][lay] = v; aa770610d3 2010-11-08 kinaba: } b0d8d7875b 2010-11-08 kinaba: 8de5b49cdf 2010-11-09 kinaba: Value get(string i, Layer lay, in LexPosition pos=null) b0d8d7875b 2010-11-08 kinaba: { aa770610d3 2010-11-08 kinaba: if( i in data ) aa770610d3 2010-11-08 kinaba: return data[i][lay]; aa770610d3 2010-11-08 kinaba: if( prototype is null ) 8de5b49cdf 2010-11-09 kinaba: throw new RuntimeException(pos, sprintf!"variable %s not found"(i)); aa770610d3 2010-11-08 kinaba: return prototype.get(i, lay); b0d8d7875b 2010-11-08 kinaba: } b0d8d7875b 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: private: aa770610d3 2010-11-08 kinaba: Table prototype; aa770610d3 2010-11-08 kinaba: Kind kind; aa770610d3 2010-11-08 kinaba: Value[Layer][string] data; b0d8d7875b 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: bool setIfExist(string i, Layer lay, Value v) b0d8d7875b 2010-11-08 kinaba: { aa770610d3 2010-11-08 kinaba: if( i in data ) aa770610d3 2010-11-08 kinaba: { aa770610d3 2010-11-08 kinaba: data[i][lay] = v; aa770610d3 2010-11-08 kinaba: return true; aa770610d3 2010-11-08 kinaba: } aa770610d3 2010-11-08 kinaba: if( kind==Kind.PropagateSet && prototype !is null ) aa770610d3 2010-11-08 kinaba: return prototype.setIfExist(i, lay, v); aa770610d3 2010-11-08 kinaba: return false; b0d8d7875b 2010-11-08 kinaba: } aa770610d3 2010-11-08 kinaba: } aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: unittest aa770610d3 2010-11-08 kinaba: { aa770610d3 2010-11-08 kinaba: Table c0 = new Table; aa770610d3 2010-11-08 kinaba: Table c01 = new Table(c0, Table.Kind.NotPropagateSet); aa770610d3 2010-11-08 kinaba: Table c012 = new Table(c01, Table.Kind.PropagateSet); aa770610d3 2010-11-08 kinaba: Table c013 = new Table(c01, Table.Kind.PropagateSet); aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: assert_nothrow( c012.set("x", "@val", new IntValue(BigInt(12))) ); aa770610d3 2010-11-08 kinaba: assert_throw!RuntimeException( c013.get("x", "@val") ); aa770610d3 2010-11-08 kinaba: assert_nothrow( c013.set("x", "@val", new IntValue(BigInt(13))) ); aa770610d3 2010-11-08 kinaba: assert_eq( c013.get("x", "@val"), new IntValue(BigInt(13)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c012.get("x", "@val"), new IntValue(BigInt(12)) ); aa770610d3 2010-11-08 kinaba: assert_throw!RuntimeException( c01.get("x", "@val") ); aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: assert_nothrow( c01.set("y", "@val", new IntValue(BigInt(1))) ); aa770610d3 2010-11-08 kinaba: assert_eq( c013.get("y", "@val"), new IntValue(BigInt(1)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c012.get("y", "@val"), new IntValue(BigInt(1)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c01.get("y", "@val"), new IntValue(BigInt(1)) ); aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: assert_nothrow( c0.set("z", "@val", new IntValue(BigInt(0))) ); aa770610d3 2010-11-08 kinaba: assert_eq( c013.get("z", "@val"), new IntValue(BigInt(0)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c012.get("z", "@val"), new IntValue(BigInt(0)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c01.get("z", "@val"), new IntValue(BigInt(0)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c0.get("z", "@val"), new IntValue(BigInt(0)) ); aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: assert_nothrow( c012.set("y", "@val", new IntValue(BigInt(444))) ); aa770610d3 2010-11-08 kinaba: assert_eq( c013.get("y", "@val"), new IntValue(BigInt(444)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c012.get("y", "@val"), new IntValue(BigInt(444)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c01.get("y", "@val"), new IntValue(BigInt(444)) ); aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: assert_nothrow( c012.set("z", "@val", new IntValue(BigInt(555))) ); aa770610d3 2010-11-08 kinaba: assert_eq( c013.get("z", "@val"), new IntValue(BigInt(0)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c012.get("z", "@val"), new IntValue(BigInt(555)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c01.get("z", "@val"), new IntValue(BigInt(0)) ); aa770610d3 2010-11-08 kinaba: assert_eq( c0.get("z", "@val"), new IntValue(BigInt(0)) ); aa770610d3 2010-11-08 kinaba: aa770610d3 2010-11-08 kinaba: // [TODO] define the semantics and test @layers b0d8d7875b 2010-11-08 kinaba: }