Differences From Artifact [6d85ee04f34c61b7]:
- File
polemy/value.d
- 2010-11-23 10:09:03 - part of checkin [36c517dfc4] on branch trunk - refactored d-value and polemy-value conversion (user: kinaba) [annotate]
To Artifact [43e26264d772abeb]:
- File
polemy/value.d
- 2010-11-23 13:55:15 - part of checkin [2134cd44cc] on branch trunk - further clean-up for polemy2d (user: kinaba) [annotate]
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 }