Diff
Not logged in

Differences From Artifact [6d85ee04f34c61b7]:

To Artifact [43e26264d772abeb]:


75 /// Context (variable environment) 75 /// Context (variable environment) 76 /// Simlar to prototype chain of ECMAScript etc. 76 /// Simlar to prototype chain of ECMAScript etc. 77 /// But extended with the notion of "Layer" 77 /// But extended with the notion of "Layer" 78 78 79 class Table : Value 79 class Table : Value 80 { 80 { 81 enum Kind {PropagateSet, NotPropagateSet}; 81 enum Kind {PropagateSet, NotPropagateSet}; 82 bool kill = false; // to refactor < 83 82 84 this( Table proto=null, Kind k = Kind.PropagateSet ) 83 this( Table proto=null, Kind k = Kind.PropagateSet ) 85 { this.prototype = proto; this.kind = k; } 84 { this.prototype = proto; this.kind = k; } 86 85 87 void set(string i, Layer lay, Value v, LexPosition pos=null) | 86 void set(string i, Layer lay, Value v) 88 { 87 { 89 if( setIfExist(i, lay, v) ) 88 if( setIfExist(i, lay, v) ) 90 return; 89 return; 91 data[i][lay] = v; 90 data[i][lay] = v; 92 } 91 } 93 92 94 bool has(string i, Layer lay) const 93 bool has(string i, Layer lay) const 95 { 94 { 96 if( i in data ) { | 95 if( i in data ) 97 if( lay !in data[i] ) | 96 return !!(lay in data[i]); 98 return false; < 99 if(kill) < 100 return false; < 101 return true; < 102 } < 103 if( prototype is null ) 97 if( prototype is null ) 104 return false; 98 return false; 105 return prototype.has(i, lay); 99 return prototype.has(i, lay); 106 } 100 } 107 101 108 Value get(string i, Layer lay, LexPosition pos=null) 102 Value get(string i, Layer lay, LexPosition pos=null) 109 { 103 { 110 if( i in data ) { 104 if( i in data ) { 111 // [TODO] consider forwarding to proto also in this case 105 // [TODO] consider forwarding to proto also in this case 112 if( lay !in data[i] ) 106 if( lay !in data[i] ) 113 throw genex!RuntimeException(pos, sprintf!"'%s' | 107 throw genex!RuntimeException(pos, sprintf!"'%s' 114 if(kill) < 115 throw genex!RuntimeException(pos, sprintf!"'%s' < 116 return data[i][lay]; 108 return data[i][lay]; 117 } 109 } 118 if( prototype is null ) 110 if( prototype is null ) 119 throw new RuntimeException(pos, sprintf!"'%s' not found" | 111 throw genex!RuntimeException(pos, sprintf!"'%s' not foun 120 return prototype.get(i, lay, pos); 112 return prototype.get(i, lay, pos); 121 } 113 } 122 114 123 T access(T,S...)( Layer lay, string path, S rest ) 115 T access(T,S...)( Layer lay, string path, S rest ) 124 { 116 { 125 static if( rest.length == 0 ) 117 static if( rest.length == 0 ) 126 { 118 { ................................................................................................................................................................................ 155 { 147 { 156 result ~= " / "; 148 result ~= " / "; 157 result ~= prototype.toStringWithoutParen(); 149 result ~= prototype.toStringWithoutParen(); 158 } 150 } 159 return result; 151 return result; 160 } 152 } 161 153 162 string toString() const | 154 string toString() 163 { 155 { > 156 if( isList() ) > 157 return text(toList()); 164 return "{" ~ toStringWithoutParen() ~ "}"; 158 return "{" ~ toStringWithoutParen() ~ "}"; 165 } 159 } > 160 > 161 public: > 162 /// Is this an empty table? > 163 bool empty() > 164 { > 165 return data.length==0 && (prototype is null || prototype.empty); > 166 } > 167 > 168 /// Can be seen as a cons-list? > 169 bool isList() > 170 { > 171 Table t = this; > 172 while(t.has("car", ValueLayer) && t.has("cdr", ValueLayer)) > 173 if(auto tt = cast(Table)t.get("cdr", ValueLayer)) > 174 t = tt; > 175 else > 176 return false; > 177 return t.empty; > 178 } > 179 > 180 /// Regard table as a cons-list and convert to an array > 181 Value[] toList() > 182 { > 183 Value[] result; > 184 Table t = this; > 185 while(t.has("car", ValueLayer) && t.has("cdr", ValueLayer)) > 186 { > 187 result ~= t.get("car", ValueLayer); > 188 if(auto tt = cast(Table)t.get("cdr", ValueLayer)) > 189 t = tt; > 190 else > 191 throw genex!RuntimeException("this table is not > 192 } > 193 if( t.empty ) > 194 return result; > 195 throw genex!RuntimeException("this table is not a cons-list"); > 196 } 166 197 167 private: 198 private: 168 Table prototype; 199 Table prototype; 169 Kind kind; 200 Kind kind; 170 Value[Layer][string] data; 201 Value[Layer][string] data; 171 202 172 bool setIfExist(string i, Layer lay, Value v) 203 bool setIfExist(string i, Layer lay, Value v) ................................................................................................................................................................................ 185 unittest 216 unittest 186 { 217 { 187 Table c0 = new Table; 218 Table c0 = new Table; 188 Table c01 = new Table(c0, Table.Kind.NotPropagateSet); 219 Table c01 = new Table(c0, Table.Kind.NotPropagateSet); 189 Table c012 = new Table(c01, Table.Kind.PropagateSet); 220 Table c012 = new Table(c01, Table.Kind.PropagateSet); 190 Table c013 = new Table(c01, Table.Kind.PropagateSet); 221 Table c013 = new Table(c01, Table.Kind.PropagateSet); 191 222 192 assert_nothrow( c012.set("x", ValueLayer, new IntValue(BigInt(12))) ); | 223 assert_nothrow( c012.set("x", ValueLayer, new IntValue(12)) ); 193 assert_throw!RuntimeException( c013.get("x", ValueLayer) ); 224 assert_throw!RuntimeException( c013.get("x", ValueLayer) ); 194 assert_nothrow( c013.set("x", ValueLayer, new IntValue(BigInt(13))) ); | 225 assert_nothrow( c013.set("x", ValueLayer, new IntValue(13)) ); 195 assert_eq( c013.get("x", ValueLayer), new IntValue(BigInt(13)) ); | 226 assert_eq( c013.get("x", ValueLayer), new IntValue(13) ); 196 assert_eq( c012.get("x", ValueLayer), new IntValue(BigInt(12)) ); | 227 assert_eq( c012.get("x", ValueLayer), new IntValue(12) ); 197 assert_throw!RuntimeException( c01.get("x", ValueLayer) ); 228 assert_throw!RuntimeException( c01.get("x", ValueLayer) ); 198 229 199 assert_nothrow( c01.set("y", ValueLayer, new IntValue(BigInt(1))) ); | 230 assert_nothrow( c01.set("y", ValueLayer, new IntValue(1)) ); 200 assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(1)) ); | 231 assert_eq( c013.get("y", ValueLayer), new IntValue(1) ); 201 assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(1)) ); | 232 assert_eq( c012.get("y", ValueLayer), new IntValue(1) ); 202 assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(1)) ); | 233 assert_eq( c01.get("y", ValueLayer), new IntValue(1) ); > 234 > 235 assert_nothrow( c0.set("z", ValueLayer, new IntValue(0)) ); > 236 assert_eq( c013.get("z", ValueLayer), new IntValue(0) ); > 237 assert_eq( c012.get("z", ValueLayer), new IntValue(0) ); > 238 assert_eq( c01.get("z", ValueLayer), new IntValue(0) ); > 239 assert_eq( c0.get("z", ValueLayer), new IntValue(0) ); 203 240 204 assert_nothrow( c0.set("z", ValueLayer, new IntValue(BigInt(0))) ); | 241 assert_nothrow( c012.set("y", ValueLayer, new IntValue(444)) ); 205 assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 242 assert_eq( c013.get("y", ValueLayer), new IntValue(444) ); 206 assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(0)) ); < 207 assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 243 assert_eq( c012.get("y", ValueLayer), new IntValue(444) ); 208 assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 244 assert_eq( c01.get("y", ValueLayer), new IntValue(444) ); 209 245 210 assert_nothrow( c012.set("y", ValueLayer, new IntValue(BigInt(444))) ); < 211 assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(444)) ); < 212 assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(444)) ); < 213 assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(444)) ); < 214 < 215 assert_nothrow( c012.set("z", ValueLayer, new IntValue(BigInt(555))) ); | 246 assert_nothrow( c012.set("z", ValueLayer, new IntValue(555)) ); 216 assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 247 assert_eq( c013.get("z", ValueLayer), new IntValue(0) ); 217 assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) ); | 248 assert_eq( c012.get("z", ValueLayer), new IntValue(555) ); 218 assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 249 assert_eq( c01.get("z", ValueLayer), new IntValue(0) ); 219 assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 250 assert_eq( c0.get("z", ValueLayer), new IntValue(0) ); 220 251 221 // [TODO] define the semantics and test @layers 252 // [TODO] define the semantics and test @layers 222 } 253 }