Mercurial > repos > tabletprog
comparison types.js @ 101:5d15b91e738a
Fix paramerized types. Remove debug print calls.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 09 Aug 2012 08:09:14 -0700 |
parents | 9db0e3533b23 |
children | 92ff9630897a |
comparison
equal
deleted
inserted
replaced
100:9db0e3533b23 | 101:5d15b91e738a |
---|---|
62 } | 62 } |
63 //temporarily set cache entry to true to prevent infinite recursion | 63 //temporarily set cache entry to true to prevent infinite recursion |
64 this.satisfies_cache[type.id] = true; | 64 this.satisfies_cache[type.id] = true; |
65 var ret = true; | 65 var ret = true; |
66 if (type.messages === undefined) { | 66 if (type.messages === undefined) { |
67 print('type has no messages'); | |
68 ret = false; | 67 ret = false; |
69 } | 68 } |
70 if (ret) { | 69 if (ret) { |
71 for (var msgname in this.messages) { | 70 for (var msgname in this.messages) { |
72 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) { | 71 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) { |
73 print(msgname, 'missing in type'); | |
74 ret = false; | 72 ret = false; |
75 break; | 73 break; |
76 } | 74 } |
77 } | 75 } |
78 } | 76 } |
156 } | 154 } |
157 //temporarily set cache entry to true to prevent infinite recursion | 155 //temporarily set cache entry to true to prevent infinite recursion |
158 this.satisfies_cache[type.id] = true; | 156 this.satisfies_cache[type.id] = true; |
159 var ret = true; | 157 var ret = true; |
160 if (!(type.callable) || this.params.length != type.params.length) { | 158 if (!(type.callable) || this.params.length != type.params.length) { |
161 print('type is not callable or param length mismatch'); | |
162 ret = false; | 159 ret = false; |
163 } | 160 } |
164 if (ret) { | 161 if (ret) { |
165 for (var i in this.params) { | 162 for (var i in this.params) { |
166 if (i >= type.params.length || !this.params[i].satisfiedBy(type.params[i])) { | 163 if (i >= type.params.length || !this.params[i].satisfiedBy(type.params[i])) { |
167 print('param ', i, ' is not satisfied'); | |
168 ret = false; | 164 ret = false; |
169 break; | 165 break; |
170 } | 166 } |
171 } | 167 } |
172 } | 168 } |
173 if (ret) { | 169 if (ret) { |
174 for (var msgname in this.messages) { | 170 for (var msgname in this.messages) { |
175 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) { | 171 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) { |
176 print('message', msgname, 'is not satisfied'); | |
177 ret = false; | 172 ret = false; |
178 break; | 173 break; |
179 } | 174 } |
180 } | 175 } |
181 } | 176 } |
211 } | 206 } |
212 if (this.id in visited) { | 207 if (this.id in visited) { |
213 return visited[this.id]; | 208 return visited[this.id]; |
214 } | 209 } |
215 var me = visited[this.id] = this.clone(); | 210 var me = visited[this.id] = this.clone(); |
216 for (var msgname in this.messages) { | 211 for (var msgname in me.messages) { |
217 me.messages[msgname] = me.messages[msgname].replaceParams(paramtypes, visited); | 212 me.messages[msgname] = me.messages[msgname].replaceParams(paramtypes, visited); |
218 } | 213 } |
214 for (var i in me.params) { | |
215 me.params[i] = me.params[i].replaceParams(paramtypes, visited); | |
216 } | |
217 me.returntype = me.returntype.replaceParams(paramtypes, visited); | |
219 return me; | 218 return me; |
220 }; | 219 }; |
221 | 220 |
222 lambdatype.prototype.clone = function() { | 221 lambdatype.prototype.clone = function() { |
223 var clone = new lambdatype(); | 222 var clone = new lambdatype(); |
237 this.b = b; | 236 this.b = b; |
238 this.id = nexttypeid++; | 237 this.id = nexttypeid++; |
239 this.satisfies_cache = null; | 238 this.satisfies_cache = null; |
240 } | 239 } |
241 | 240 |
242 uniontype.prototype.lazyinit = function() { | 241 uniontype.prototype = { |
243 if (this.satisfies_cache == null) { | 242 lazyinit: function() { |
244 this.satisfies_cache = {}; | 243 if (this.satisfies_cache == null) { |
245 this.satisfies_cache[this.id] = true; | 244 this.satisfies_cache = {}; |
246 this.messages = {}; | 245 this.satisfies_cache[this.id] = true; |
247 if (this.a.messages !== undefined && this.b.messages !== undefined) { | 246 this._messages = {}; |
248 for (var msgname in this.a.messages) { | 247 if (this.a.messages !== undefined && this.b.messages !== undefined) { |
249 if (msgname in this.b.messages) { | 248 for (var msgname in this.a.messages) { |
250 this.messages[msgname] = mkunion(this.a.messages[msgname], this.b.messages[msgname]); | 249 if (msgname in this.b.messages) { |
250 this._messages[msgname] = mkunion(this.a.messages[msgname], this.b.messages[msgname]); | |
251 } | |
251 } | 252 } |
252 } | 253 } |
253 } | 254 this._callable = false; |
254 this.callable = false; | 255 if (this.a.callable && this.b.callable && this.a.params.length == this.b.params.length) { |
255 if (this.a.callable && this.b.callable && this.a.params.length == this.b.params.length) { | 256 this._callable = true; |
256 this.callable = true; | 257 this._params = []; |
257 this.params = []; | 258 for (var i = 0; i < this.a.params.length; i++) { |
258 for (var i = 0; i < this.a.params.length; i++) { | 259 this._params.push(mkunion(this.a.params[i], this.b.params[i])); |
259 this.params.push(mkunion(this.a.params[i], this.b.params[i])); | 260 } |
260 } | 261 this._returntype = mkunion(this.a.returntype, this.b.returntype); |
261 this.returntype = mkunion(this.a.returntype, this.b.returntype); | 262 } |
262 } | 263 } |
263 } | 264 }, |
264 }; | 265 satisfiedBy: function(type) |
265 | 266 { |
266 uniontype.prototype.satisfiedBy = function(type) | 267 this.lazyinit(); |
267 { | 268 if (type.id in this.satisfies_cache) { |
268 this.lazyinit(); | 269 return this.satisfies_cache[type.id]; |
269 if (type.id in this.satisfies_cache) { | 270 } |
270 return this.satisfies_cache[type.id]; | 271 this.satisfies_cache[type.id] = true; |
271 } | 272 var ret = this.a.satisfiedBy(type) || this.b.satisfiedBy(type); |
272 this.satisfies_cache[type.id] = true; | 273 this.satisfies_cache[type.id] = ret; |
273 var ret = this.a.satisfiedBy(type) || this.b.satisfiedBy(type); | 274 return ret; |
274 this.satisfies_cache[type.id] = ret; | 275 }, |
275 return ret; | 276 str: function(indent) |
276 }; | 277 { |
277 | 278 if (indent === undefined) { |
278 uniontype.prototype.str = function(indent) | 279 indent = ''; |
279 { | 280 } |
280 if (indent === undefined) { | 281 if (indent.length > 6) { |
281 indent = ''; | 282 return 'max depth reached\n'; |
282 } | 283 } |
283 if (indent.length > 6) { | 284 return indent + 'Union {\n\t' + indent + this.a.str(indent+'\t') + '\t' + indent + this.b.str(indent+'\t') + indent + '}\n'; |
284 return 'max depth reached\n'; | 285 }, |
285 } | 286 replaceParams: function(paramtypes, visited) { |
286 return indent + 'Union {\n\t' + indent + this.a.str(indent+'\t') + '\t' + indent + this.b.str(indent+'\t') + indent + '}\n'; | 287 if (visited === undefined) { |
287 }; | 288 visited = {}; |
288 | 289 } |
289 uniontype.prototype.replaceParams = function(paramtypes, visited) { | 290 if (this.id in visited) { |
290 if (visited === undefined) { | 291 return visited[this.id]; |
291 visited = {}; | 292 } |
292 } | 293 var me = visited[this.id] = this.clone(); |
293 if (this.id in visited) { | 294 me.a = me.a.replaceParams(paramtypes, visited); |
294 return visited[this.id]; | 295 me.b = me.b.replaceParams(paramtypes, visited); |
295 } | 296 return me; |
296 var me = visited[this.id] = this.clone(); | 297 }, |
297 me.a = me.a.replaceParams(paramtypes, visited); | 298 clone: function() { |
298 me.b = me.b.replaceParams(paramtypes, visited); | 299 return new uniontype(this.a, this.b); |
299 return me; | 300 }, |
300 }; | 301 get messages() { |
301 | 302 this.lazyinit(); |
302 uniontype.prototype.clone = function() { | 303 return this._messages; |
303 return new uniontype(this.a, this.b); | 304 }, |
305 get params() { | |
306 this.lazyinit(); | |
307 return this._params; | |
308 }, | |
309 get returntype() { | |
310 this.lazyinit(); | |
311 return this._returntype; | |
312 }, | |
313 get callable() { | |
314 this.lazyinit(); | |
315 return this._callable; | |
316 } | |
304 }; | 317 }; |
305 | 318 |
306 | 319 |
307 function mkunion(a, b) | 320 function mkunion(a, b) |
308 { | 321 { |
351 }, | 364 }, |
352 lazyinit: function() { | 365 lazyinit: function() { |
353 if (!this.replaced) { | 366 if (!this.replaced) { |
354 var childptypes = {}; | 367 var childptypes = {}; |
355 for (var i in this.type.typeparams) { | 368 for (var i in this.type.typeparams) { |
356 print(this.type.typeparams[i], 'is', this.params[i].str()); | |
357 childptypes[this.type.typeparams[i]] = this.params[i] | 369 childptypes[this.type.typeparams[i]] = this.params[i] |
358 } | 370 } |
359 this.type = this.type.replaceParams(childptypes, {}); | 371 this.type = this.type.replaceParams(childptypes, {}); |
360 this.replaced = true; | 372 this.replaced = true; |
361 } | 373 } |