Diff
Not logged in

Differences From Artifact [ac6802f569d2081c]:

To Artifact [b8f99f303d4d3a98]:


2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 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.lex : LexPosition; | 9 import polemy.lex; 10 import std.stdio; < 11 10 > 11 /// Raised when something went wrong in runtime > 12 12 class PolemyRuntimeException : Exception | 13 class RuntimeException : Exception 13 { 14 { > 15 const LexPosition pos; > 16 > 17 this( const LexPosition pos, string msg ) > 18 { super(sprintf!"%s [%s]"(msg, pos)); this.pos = pos; } 14 this(string msg) { super(msg); } | 19 this( string msg ) { super(msg); this.pos = null; } 15 } 20 } > 21 > 22 /// Runtime values of Polemy 16 23 17 abstract class Value 24 abstract class Value 18 { 25 { 19 } 26 } 20 27 21 class UndefinedValue : Value < 22 { < 23 mixin SimpleConstructor; < 24 mixin SimpleCompare; < 25 override string toString() const { return "(undefined)"; } < 26 } < 27 < 28 class IntValue : Value 28 class IntValue : Value 29 { 29 { 30 BigInt data; 30 BigInt data; > 31 31 mixin SimpleConstructor; 32 mixin SimpleConstructor; 32 mixin SimpleCompare; 33 mixin SimpleCompare; 33 override string toString() const { < 34 return std.bigint.toDecimalString(cast(BigInt)data); | 34 override string toString() const { return std.bigint.toDecimalString(cas 35 } < 36 } 35 } 37 36 38 class StrValue : Value 37 class StrValue : Value 39 { 38 { 40 string data; 39 string data; > 40 41 mixin SimpleConstructor; 41 mixin SimpleConstructor; 42 mixin SimpleCompare; 42 mixin SimpleCompare; 43 override string toString() const { return data; } 43 override string toString() const { return data; } 44 } 44 } 45 45 46 class FunValue : Value 46 class FunValue : Value 47 { 47 { 48 Value delegate(immutable LexPosition pos, Value[]) data; 48 Value delegate(immutable LexPosition pos, Value[]) data; > 49 49 mixin SimpleConstructor; 50 mixin SimpleConstructor; 50 Value call(immutable LexPosition pos, Value[] args) { return data(pos,ar | 51 alias data call; 51 override string toString() const { return sprintf!"(function:%s:%s)"(dat 52 override string toString() const { return sprintf!"(function:%s:%s)"(dat 52 } 53 } 53 import std.stdio; < > 54 > 55 /// Layer ID > 56 > 57 alias string Layer; > 58 > 59 /// Context (variable environment) > 60 /// Simlar to prototype chain of ECMAScript etc. > 61 /// But extended with the notion of "Layer" > 62 54 class Context | 63 class Table : Value 55 { 64 { 56 Context parent; | 65 enum Kind {PropagateSet, NotPropagateSet}; 57 Value[string] table; < > 66 58 this(Context parent = null) { this.parent = parent; } | 67 this( Table proto=null, Kind k = Kind.PropagateSet ) > 68 { this.prototype = proto; this.kind = k; } 59 69 60 void add(string i, Value v) | 70 void set(string i, Layer lay, Value v) 61 { 71 { > 72 if( !setIfExist(i, lay, v) ) 62 table[i] = v; | 73 data[i][lay] = v; 63 } 74 } 64 75 65 Value opIndex(string i) | 76 Value get(string i, Layer lay) 66 { 77 { 67 if( i in table ) | 78 if( i in data ) 68 return table[i]; | 79 return data[i][lay]; 69 if( parent is null ) | 80 if( prototype is null ) 70 throw new PolemyRuntimeException(sprintf!"variable %s no | 81 throw new RuntimeException(sprintf!"variable %s not foun 71 return parent[i]; | 82 return prototype.get(i, lay); 72 } 83 } 73 84 74 void opIndexAssign(Value v, string i) | 85 private: > 86 Table prototype; > 87 Kind kind; > 88 Value[Layer][string] data; > 89 > 90 bool setIfExist(string i, Layer lay, Value v) 75 { 91 { 76 if( i in table ) | 92 if( i in data ) > 93 { > 94 data[i][lay] = v; 77 return table[i] = v; | 95 return true; 78 if( parent is null ) < 79 throw new PolemyRuntimeException(sprintf!"variable %s no < > 96 } > 97 if( kind==Kind.PropagateSet && prototype !is null ) > 98 return prototype.setIfExist(i, lay, v); 80 return parent[i] = v; | 99 return false; 81 } 100 } 82 } 101 } > 102 > 103 unittest > 104 { > 105 Table c0 = new Table; > 106 Table c01 = new Table(c0, Table.Kind.NotPropagateSet); > 107 Table c012 = new Table(c01, Table.Kind.PropagateSet); > 108 Table c013 = new Table(c01, Table.Kind.PropagateSet); > 109 > 110 assert_nothrow( c012.set("x", "@val", new IntValue(BigInt(12))) ); > 111 assert_throw!RuntimeException( c013.get("x", "@val") ); > 112 assert_nothrow( c013.set("x", "@val", new IntValue(BigInt(13))) ); > 113 assert_eq( c013.get("x", "@val"), new IntValue(BigInt(13)) ); > 114 assert_eq( c012.get("x", "@val"), new IntValue(BigInt(12)) ); > 115 assert_throw!RuntimeException( c01.get("x", "@val") ); > 116 > 117 assert_nothrow( c01.set("y", "@val", new IntValue(BigInt(1))) ); > 118 assert_eq( c013.get("y", "@val"), new IntValue(BigInt(1)) ); > 119 assert_eq( c012.get("y", "@val"), new IntValue(BigInt(1)) ); > 120 assert_eq( c01.get("y", "@val"), new IntValue(BigInt(1)) ); > 121 > 122 assert_nothrow( c0.set("z", "@val", new IntValue(BigInt(0))) ); > 123 assert_eq( c013.get("z", "@val"), new IntValue(BigInt(0)) ); > 124 assert_eq( c012.get("z", "@val"), new IntValue(BigInt(0)) ); > 125 assert_eq( c01.get("z", "@val"), new IntValue(BigInt(0)) ); > 126 assert_eq( c0.get("z", "@val"), new IntValue(BigInt(0)) ); > 127 > 128 assert_nothrow( c012.set("y", "@val", new IntValue(BigInt(444))) ); > 129 assert_eq( c013.get("y", "@val"), new IntValue(BigInt(444)) ); > 130 assert_eq( c012.get("y", "@val"), new IntValue(BigInt(444)) ); > 131 assert_eq( c01.get("y", "@val"), new IntValue(BigInt(444)) ); > 132 > 133 assert_nothrow( c012.set("z", "@val", new IntValue(BigInt(555))) ); > 134 assert_eq( c013.get("z", "@val"), new IntValue(BigInt(0)) ); > 135 assert_eq( c012.get("z", "@val"), new IntValue(BigInt(555)) ); > 136 assert_eq( c01.get("z", "@val"), new IntValue(BigInt(0)) ); > 137 assert_eq( c0.get("z", "@val"), new IntValue(BigInt(0)) ); > 138 > 139 // [TODO] define the semantics and test @layers > 140 }