Diff
Not logged in

Differences From Artifact [dc69a053821951bd]:

To Artifact [6fa9c2c94c01b274]:


18 } 18 } 19 19 20 /// 20 /// 21 class IntValue : Value 21 class IntValue : Value 22 { 22 { 23 BigInt data; 23 BigInt data; 24 24 25 this(bool n) { this.data = n?1:0; } | 25 this(bool n) { this.data = n?1:0; } 26 this(int n) { this.data = n; } | 26 this(int n) { this.data = n; } 27 this(long n) { this.data = n; } | 27 this(long n) { this.data = n; } 28 this(BigInt n) { this.data = n; } 28 this(BigInt n) { this.data = n; } 29 this(string n) { this.data = BigInt(n); } 29 this(string n) { this.data = BigInt(n); } 30 override string toString() const { return toDecimalString(cast(BigInt)da 30 override string toString() const { return toDecimalString(cast(BigInt)da 31 override int opCmp(Object rhs) { 31 override int opCmp(Object rhs) { 32 if(auto r = cast(IntValue)rhs) return data.opCmp(r.data); 32 if(auto r = cast(IntValue)rhs) return data.opCmp(r.data); 33 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( 33 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid( 34 throw genex!RuntimeException("comparison with value and somithin 34 throw genex!RuntimeException("comparison with value and somithin ................................................................................................................................................................................ 79 class Table : Value 79 class Table : Value 80 { 80 { 81 enum Kind {PropagateSet, NotPropagateSet}; 81 enum Kind {PropagateSet, NotPropagateSet}; 82 82 83 this( Table proto=null, Kind k = Kind.PropagateSet ) 83 this( Table proto=null, Kind k = Kind.PropagateSet ) 84 { this.prototype = proto; this.kind = k; } 84 { this.prototype = proto; this.kind = k; } 85 85 > 86 /// Set the value v to the index i of layer lay 86 void set(string i, Layer lay, Value v) 87 void set(string i, Layer lay, Value v) 87 { 88 { 88 if( setIfExist(i, lay, v) ) 89 if( setIfExist(i, lay, v) ) 89 return; 90 return; 90 data[i][lay] = v; 91 data[i][lay] = v; 91 } 92 } 92 93 > 94 /// True if index i has value in layer lay 93 bool has(string i, Layer lay) const 95 bool has(string i, Layer lay) const 94 { 96 { 95 if( i in data ) 97 if( i in data ) 96 return !!(lay in data[i]); 98 return !!(lay in data[i]); 97 if( prototype is null ) 99 if( prototype is null ) 98 return false; 100 return false; 99 return prototype.has(i, lay); 101 return prototype.has(i, lay); 100 } 102 } 101 103 > 104 /// Return the value of index i at layer lay. Throws if it is not set 102 Value get(string i, Layer lay, LexPosition pos=null) 105 Value get(string i, Layer lay, LexPosition pos=null) 103 { 106 { 104 if( i in data ) { 107 if( i in data ) { 105 // [TODO] consider forwarding to proto also in this case 108 // [TODO] consider forwarding to proto also in this case 106 if( lay !in data[i] ) 109 if( lay !in data[i] ) 107 throw genex!RuntimeException(pos, sprintf!"'%s' 110 throw genex!RuntimeException(pos, sprintf!"'%s' 108 return data[i][lay]; 111 return data[i][lay]; 109 } 112 } 110 if( prototype is null ) 113 if( prototype is null ) 111 throw genex!RuntimeException(pos, sprintf!"'%s' not foun 114 throw genex!RuntimeException(pos, sprintf!"'%s' not foun 112 return prototype.get(i, lay, pos); 115 return prototype.get(i, lay, pos); 113 } 116 } 114 117 > 118 /// t.access!T(lay,a,b,...) returns t.get(a,lay).get(b,lay).... if exist > 119 /// and has type T. Returns null otherwise 115 T access(T,S...)( Layer lay, string path, S rest ) 120 T access(T,S...)( Layer lay, string path, S rest ) 116 { 121 { 117 static if( rest.length == 0 ) 122 static if( rest.length == 0 ) 118 { 123 { 119 if( this.has(path, lay) ) 124 if( this.has(path, lay) ) 120 return cast(T) this.get(path, lay); 125 return cast(T) this.get(path, lay); 121 } 126 } ................................................................................................................................................................................ 123 { 128 { 124 if(auto next = this.access!Table(lay,path)) 129 if(auto next = this.access!Table(lay,path)) 125 return next.access!T(lay,rest); 130 return next.access!T(lay,rest); 126 } 131 } 127 return null; 132 return null; 128 } 133 } 129 134 130 string toStringWithoutParen() const < 131 { < 132 string result; < 133 bool first = true; < 134 foreach(k, l2d; data) < 135 foreach(l,d; l2d) < 136 { < 137 if(first) first=false; else result~=", "; < 138 result ~= k; < 139 if( l.empty ) < 140 result ~= "(emptylayer)"; < 141 else if( l != ValueLayer ) < 142 result ~= l; < 143 result ~= ":"; < 144 result ~= text(cast(Value)d); < 145 } < 146 if( prototype !is null ) < 147 { < 148 result ~= " / "; < 149 result ~= prototype.toStringWithoutParen(); < 150 } < 151 return result; < 152 } < 153 < 154 string toString() < 155 { < 156 if( isList() ) < 157 return text(toList()); < 158 return "{" ~ toStringWithoutParen() ~ "}"; < 159 } < 160 < 161 public: < 162 /// Is this an empty table? 135 /// Is this an empty table? 163 bool empty() 136 bool empty() 164 { 137 { 165 return data.length==0 && (prototype is null || prototype.empty); 138 return data.length==0 && (prototype is null || prototype.empty); 166 } 139 } 167 140 168 /// Can be seen as a cons-list? 141 /// Can be seen as a cons-list? ................................................................................................................................................................................ 190 else 163 else 191 throw genex!RuntimeException("this table is not 164 throw genex!RuntimeException("this table is not 192 } 165 } 193 if( t.empty ) 166 if( t.empty ) 194 return result; 167 return result; 195 throw genex!RuntimeException("this table is not a cons-list"); 168 throw genex!RuntimeException("this table is not a cons-list"); 196 } 169 } > 170 > 171 /// Get the list of direct entries ignoring prototypes in sorted order > 172 Tuple!(string,Layer,Value)[] direct_entries() > 173 { > 174 Tuple!(string,Layer,Value)[] arr; > 175 foreach(k, l2d; data) > 176 foreach(l,d; l2d) > 177 arr ~= tuple(k,l,d); > 178 arr.sort(); > 179 return arr; > 180 } > 181 > 182 /// Get the whole list of observable entries in unspecified order > 183 Tuple!(string,Layer,Value)[] entries() > 184 { > 185 bool[string] hidden; > 186 Tuple!(string,Layer,Value)[] arr; > 187 enumerateEntries(hidden, arr); > 188 return arr; > 189 } > 190 > 191 private void enumerateEntries( ref bool[string] hidden, ref Tuple!(strin > 192 { > 193 foreach(k, l2d; data) > 194 if( k !in hidden ) > 195 { > 196 foreach(l,d; l2d) > 197 arr ~= tuple(k,l,d); > 198 hidden[k] = true; > 199 } > 200 if(prototype !is null) > 201 prototype.enumerateEntries(hidden, arr); > 202 } > 203 > 204 override string toString() > 205 { > 206 if( isList() ) > 207 return text(toList()); > 208 return "{" ~ toStringWithoutParen() ~ "}"; > 209 } > 210 > 211 override int opCmp(Object rhs) > 212 { > 213 if(auto r = cast(Table)rhs) { > 214 Tuple!(string,Layer,Value)[] ls = this.entries(); > 215 Tuple!(string,Layer,Value)[] rs = r.entries(); > 216 if( ls.length != rs.length ) > 217 return (ls.length < rs.length ? -1 : +1); > 218 ls.sort(); > 219 rs.sort(); > 220 foreach(i,_; ls) > 221 if(auto c = ls[i].opCmp(rs[i])) > 222 return c; > 223 return 0; > 224 } > 225 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r)) > 226 throw genex!RuntimeException("comparison with value and somithin > 227 } > 228 > 229 override hash_t toHash() > 230 { > 231 Tuple!(string,Layer,Value)[] ls = this.entries(); > 232 ls.sort(); > 233 hash_t h; > 234 foreach(e; ls) > 235 h += structuralHash(e[0])+structuralHash(e[1])+structura > 236 return h; > 237 } 197 238 198 private: 239 private: 199 Table prototype; 240 Table prototype; 200 Kind kind; 241 Kind kind; 201 Value[Layer][string] data; 242 Value[Layer][string] data; > 243 > 244 string toStringWithoutParen() const > 245 { > 246 string result; > 247 bool first = true; > 248 foreach(k, l2d; data) > 249 foreach(l,d; l2d) > 250 { > 251 if(first) first=false; else result~=", "; > 252 result ~= k; > 253 if( l.empty ) > 254 result ~= "(emptylayer)"; > 255 else if( l != ValueLayer ) > 256 result ~= l; > 257 result ~= ":"; > 258 result ~= text(cast(Value)d); > 259 } > 260 if( prototype !is null ) > 261 { > 262 result ~= " / "; > 263 result ~= prototype.toStringWithoutParen(); > 264 } > 265 return result; > 266 } 202 267 203 bool setIfExist(string i, Layer lay, Value v) 268 bool setIfExist(string i, Layer lay, Value v) 204 { 269 { 205 if( i in data ) 270 if( i in data ) 206 { 271 { 207 data[i][lay] = v; 272 data[i][lay] = v; 208 return true; 273 return true;