Diff
Not logged in

Differences From Artifact [dc69a053821951bd]:

To Artifact [6fa9c2c94c01b274]:


18 18 } 19 19 20 20 /// 21 21 class IntValue : Value 22 22 { 23 23 BigInt data; 24 24 25 - this(bool n) { this.data = n?1:0; } 26 - this(int n) { this.data = n; } 27 - this(long n) { this.data = n; } 25 + this(bool n) { this.data = n?1:0; } 26 + this(int n) { this.data = n; } 27 + this(long n) { this.data = n; } 28 28 this(BigInt n) { this.data = n; } 29 29 this(string n) { this.data = BigInt(n); } 30 30 override string toString() const { return toDecimalString(cast(BigInt)data); } 31 31 override int opCmp(Object rhs) { 32 32 if(auto r = cast(IntValue)rhs) return data.opCmp(r.data); 33 33 if(auto r = cast(Value)rhs) return typeid(this).opCmp(typeid(r)); 34 34 throw genex!RuntimeException("comparison with value and somithing other"); ................................................................................ 79 79 class Table : Value 80 80 { 81 81 enum Kind {PropagateSet, NotPropagateSet}; 82 82 83 83 this( Table proto=null, Kind k = Kind.PropagateSet ) 84 84 { this.prototype = proto; this.kind = k; } 85 85 86 + /// Set the value v to the index i of layer lay 86 87 void set(string i, Layer lay, Value v) 87 88 { 88 89 if( setIfExist(i, lay, v) ) 89 90 return; 90 91 data[i][lay] = v; 91 92 } 92 93 94 + /// True if index i has value in layer lay 93 95 bool has(string i, Layer lay) const 94 96 { 95 97 if( i in data ) 96 98 return !!(lay in data[i]); 97 99 if( prototype is null ) 98 100 return false; 99 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 105 Value get(string i, Layer lay, LexPosition pos=null) 103 106 { 104 107 if( i in data ) { 105 108 // [TODO] consider forwarding to proto also in this case 106 109 if( lay !in data[i] ) 107 110 throw genex!RuntimeException(pos, sprintf!"'%s' is not set in %s layer"(i,lay)); 108 111 return data[i][lay]; 109 112 } 110 113 if( prototype is null ) 111 114 throw genex!RuntimeException(pos, sprintf!"'%s' not found in %s layer"(i,lay)); 112 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 exists 119 + /// and has type T. Returns null otherwise 115 120 T access(T,S...)( Layer lay, string path, S rest ) 116 121 { 117 122 static if( rest.length == 0 ) 118 123 { 119 124 if( this.has(path, lay) ) 120 125 return cast(T) this.get(path, lay); 121 126 } ................................................................................ 123 128 { 124 129 if(auto next = this.access!Table(lay,path)) 125 130 return next.access!T(lay,rest); 126 131 } 127 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 135 /// Is this an empty table? 163 136 bool empty() 164 137 { 165 138 return data.length==0 && (prototype is null || prototype.empty); 166 139 } 167 140 168 141 /// Can be seen as a cons-list? ................................................................................ 190 163 else 191 164 throw genex!RuntimeException("this table is not a cons-list"); 192 165 } 193 166 if( t.empty ) 194 167 return result; 195 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!(string,Layer,Value)[] arr ) 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 somithing other"); 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])+structuralHash(e[2]); 236 + return h; 237 + } 197 238 198 239 private: 199 240 Table prototype; 200 241 Kind kind; 201 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 268 bool setIfExist(string i, Layer lay, Value v) 204 269 { 205 270 if( i in data ) 206 271 { 207 272 data[i][lay] = v; 208 273 return true;