annotate types.js @ 100:9db0e3533b23

Some work on parameterized types
author Mike Pavone <pavone@retrodev.com>
date Wed, 08 Aug 2012 09:19:14 -0700
parents b58b19c455ec
children 5d15b91e738a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
1 function anytype() {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
2 anytype.prototype.satisfiedBy = function(type) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
3 return true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
4 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
5 anytype.prototype.str = function(indent) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
6 if (indent === undefined) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
7 indent = '';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
8 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
9 return indent + 'any\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
10 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
11 anytype.prototype.id = 0;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
12 anytype.prototype.callable = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
13 anytype.prototype.replaceParams = function() { return this; };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
14 var any = new anytype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
15
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
16 function typeparam(name, base)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
17 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
18 this.name = name;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
19 this.base = base;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
20 this.callable = base.callable;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
21 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
22 typeparam.prototype.replaceParams = function(paramtypes) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
23 if (!(this.name in paramtypes)) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
24 return this;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
25 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
26 if (!this.base.satisfiedBy(paramtypes[this.name])) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
27 throw new Error('param ' + this.name + ' has base type ' + this.base.str() + ' which is not satisfied by ' + paramtypes[this.name].str());
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
28 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
29 return paramtypes[this.name];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
30 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
31 typeparam.prototype.satisfiedBy = function(type) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
32 return this.base.satisfiedBy(type);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
33 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
34 typeparam.prototype.str = function(indent) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
35 return indent + 'param ' + this.name + '\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
36 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
37
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
38 var nexttypeid = 1;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
39
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
40 function objecttype()
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
41 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
42 this.messages = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
43 this.id = nexttypeid++;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
44 this.typeparams = [];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
45 this.satisfies_cache = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
46 this.satisfies_cache[this.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
47 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
48
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
49 objecttype.prototype.callable = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
50
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
51 objecttype.prototype.addMessage = function(name, type)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
52 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
53 this.messages[name] = type;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
54 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
55
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
56 objecttype.prototype.satisfiedBy = function(type) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
57 if (type.id in this.satisfies_cache) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
58 return this.satisfies_cache[type.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
59 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
60 if (type.lazyinit) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
61 type.lazyinit();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
62 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
63 //temporarily set cache entry to true to prevent infinite recursion
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
64 this.satisfies_cache[type.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
65 var ret = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
66 if (type.messages === undefined) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
67 print('type has no messages');
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
68 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
69 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
70 if (ret) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
71 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
72 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
73 print(msgname, 'missing in type');
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
74 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
75 break;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
76 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
77 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
78 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
79 this.satisfies_cache[type.id] = ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
80 return ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
81 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
82
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
83 objecttype.prototype.str = function(indent) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
84 if (indent === undefined) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
85 indent = '';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
86 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
87 if (indent.length > 6) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
88 return 'max depth reached\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
89 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
90 var newindent = indent + '\t';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
91 var childindent = newindent + '\t'
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
92 var ret = indent + 'objectype {\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
93 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
94 ret += newindent + msgname + ':\n' + this.messages[msgname].str(childindent)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
95 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
96 return ret + indent + '}\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
97 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
98
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
99 objecttype.prototype.replaceParams = function(paramtypes, visited) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
100 if (visited === undefined) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
101 visited = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
102 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
103 if (this.id in visited) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
104 return visited[this.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
105 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
106 var me = visited[this.id] = this.clone();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
107 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
108 me.messages[msgname] = me.messages[msgname].replaceParams(paramtypes, visited);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
109 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
110 return me;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
111 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
112
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
113 objecttype.prototype.clone = function() {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
114 var clone = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
115 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
116 clone.messages[msgname] = this.messages[msgname];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
117 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
118 clone.typeparams = this.typeparams;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
119 return clone;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
120 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
121
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
122 function lambdatype()
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
123 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
124 this.id = nexttypeid++;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
125 this.messages = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
126 this.params = [];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
127 this.paramlu = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
128 this.typeparams = [];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
129 this.returntype = any;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
130 this.satisfies_cache = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
131 this.satisfies_cache[this.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
132 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
133
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
134 lambdatype.prototype.callable = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
135
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
136 lambdatype.prototype.addParam = function(name) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
137 this.paramlu[name] = this.params.length;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
138 this.params.push(any);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
139 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
140
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
141 lambdatype.prototype.paramType = function(name, type) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
142 this.params[this.paramlu[name]] = type;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
143 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
144
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
145 lambdatype.prototype.addMessage = function(name, type)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
146 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
147 this.messages[name] = type;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
148 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
149
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
150 lambdatype.prototype.satisfiedBy = function(type) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
151 if (type.id in this.satisfies_cache) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
152 return this.satisfies_cache[type.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
153 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
154 if (type.lazyinit) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
155 type.lazyinit();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
156 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
157 //temporarily set cache entry to true to prevent infinite recursion
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
158 this.satisfies_cache[type.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
159 var ret = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
160 if (!(type.callable) || this.params.length != type.params.length) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
161 print('type is not callable or param length mismatch');
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
162 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
163 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
164 if (ret) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
165 for (var i in this.params) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
166 if (i >= type.params.length || !this.params[i].satisfiedBy(type.params[i])) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
167 print('param ', i, ' is not satisfied');
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
168 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
169 break;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
170 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
171 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
172 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
173 if (ret) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
174 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
175 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
176 print('message', msgname, 'is not satisfied');
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
177 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
178 break;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
179 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
180 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
181 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
182 ret = ret && this.returntype.satisfiedBy(type.returntype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
183 this.satisfies_cache[type.id] = ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
184 return ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
185 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
186
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
187 lambdatype.prototype.str = function(indent) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
188 if (indent === undefined) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
189 indent = '';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
190 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
191 if (indent.length > 6) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
192 return 'max depth reached\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
193 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
194 var newindent = indent + '\t';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
195 var childindent = newindent + '\t'
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
196 var ret = indent + 'lambdatype {\n' + newindent + 'params: {\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
197 for (var i = 0; i < this.params.length; i++) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
198 ret += childindent + i + ':\n' + this.params[i].str(childindent + '\t');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
199 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
200 ret += newindent + '}\n' + newindent + 'returntype:\n' + this.returntype.str(childindent);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
201
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
202 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
203 ret += newindent + msgname + ':\n' + this.messages[msgname].str(childindent)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
204 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
205 return ret + indent + '}\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
206 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
207
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
208 lambdatype.prototype.replaceParams = function(paramtypes, visited) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
209 if (visited === undefined) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
210 visited = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
211 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
212 if (this.id in visited) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
213 return visited[this.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
214 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
215 var me = visited[this.id] = this.clone();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
216 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
217 me.messages[msgname] = me.messages[msgname].replaceParams(paramtypes, visited);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
218 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
219 return me;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
220 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
221
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
222 lambdatype.prototype.clone = function() {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
223 var clone = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
224 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
225 clone.messages[msgname] = this.messages[msgname];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
226 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
227 clone.paramlu = this.paramlu;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
228 clone.params = this.params.slice(0, this.params.length);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
229 clone.returntype = this.returntype;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
230 clone.typeparams = this.typeparams;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
231 return clone;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
232 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
233
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
234 function uniontype(a, b)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
235 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
236 this.a = a;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
237 this.b = b;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
238 this.id = nexttypeid++;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
239 this.satisfies_cache = null;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
240 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
241
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
242 uniontype.prototype.lazyinit = function() {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
243 if (this.satisfies_cache == null) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
244 this.satisfies_cache = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
245 this.satisfies_cache[this.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
246 this.messages = {};
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
247 if (this.a.messages !== undefined && this.b.messages !== undefined) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
248 for (var msgname in this.a.messages) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
249 if (msgname in this.b.messages) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
250 this.messages[msgname] = mkunion(this.a.messages[msgname], this.b.messages[msgname]);
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
251 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
252 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
253 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
254 this.callable = false;
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
255 if (this.a.callable && this.b.callable && this.a.params.length == this.b.params.length) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
256 this.callable = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
257 this.params = [];
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
258 for (var i = 0; i < this.a.params.length; i++) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
259 this.params.push(mkunion(this.a.params[i], this.b.params[i]));
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
260 }
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
261 this.returntype = mkunion(this.a.returntype, this.b.returntype);
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
262 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
263 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
264 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
265
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
266 uniontype.prototype.satisfiedBy = function(type)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
267 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
268 this.lazyinit();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
269 if (type.id in this.satisfies_cache) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
270 return this.satisfies_cache[type.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
271 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
272 this.satisfies_cache[type.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
273 var ret = this.a.satisfiedBy(type) || this.b.satisfiedBy(type);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
274 this.satisfies_cache[type.id] = ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
275 return ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
276 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
277
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
278 uniontype.prototype.str = function(indent)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
279 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
280 if (indent === undefined) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
281 indent = '';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
282 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
283 if (indent.length > 6) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
284 return 'max depth reached\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
285 }
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
286 return indent + 'Union {\n\t' + indent + this.a.str(indent+'\t') + '\t' + indent + this.b.str(indent+'\t') + indent + '}\n';
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
287 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
288
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
289 uniontype.prototype.replaceParams = function(paramtypes, visited) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
290 if (visited === undefined) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
291 visited = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
292 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
293 if (this.id in visited) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
294 return visited[this.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
295 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
296 var me = visited[this.id] = this.clone();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
297 me.a = me.a.replaceParams(paramtypes, visited);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
298 me.b = me.b.replaceParams(paramtypes, visited);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
299 return me;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
300 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
301
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
302 uniontype.prototype.clone = function() {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
303 return new uniontype(this.a, this.b);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
304 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
305
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
306
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
307 function mkunion(a, b)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
308 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
309 //if b is a subtype of a, then a | b is equivalent to a
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
310 if (a.satisfiedBy(b)) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
311 return a;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
312 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
313 //if a is a subtype of b, then a | b is equivalent to b
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
314 if (b.satisfiedBy(a)) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
315 return b;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
316 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
317 return new uniontype(a, b);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
318 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
319
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
320 function withtparams(type, params)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
321 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
322 this.type = type;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
323 this.params = params;
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
324 this.replaced = false;
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
325 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
326
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
327 withtparams.prototype = {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
328 satisfiedBy: function(type) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
329 this.lazyinit();
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
330 return this.type.satisfiedBy(type);
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
331 },
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
332 str: function(indent) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
333 if (indent === undefined) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
334 indent = '';
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
335 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
336 if (indent.length > 6) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
337 return 'max depth reached\n';
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
338 }
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
339 return this.type.str(indent) + indent + '<' + this.params.map(function(p) { return p.str(indent); }).join(', ') + '>';
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
340 },
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
341 replaceParams: function(paramtypes) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
342 var replaced = false;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
343 for (var i in this.params) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
344 var newp = this.params[i].replaceParams(paramtypes);
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
345 if (newp != this.params[i]) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
346 replaced = true;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
347 this.params[i] = newp;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
348 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
349 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
350 return this;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
351 },
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
352 lazyinit: function() {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
353 if (!this.replaced) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
354 var childptypes = {};
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
355 for (var i in this.type.typeparams) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
356 print(this.type.typeparams[i], 'is', this.params[i].str());
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
357 childptypes[this.type.typeparams[i]] = this.params[i]
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
358 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
359 this.type = this.type.replaceParams(childptypes, {});
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
360 this.replaced = true;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
361 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
362 },
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
363 get messages() {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
364 this.lazyinit();
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
365 return this.type.messages;
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
366 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
367 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
368
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
369 function typetest()
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
370 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
371 var foo = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
372 var msgtype = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
373 msgtype.addParam('fo');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
374 msgtype.returntype = foo;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
375 foo.addMessage('bar', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
376 var baz = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
377 var msgtype2 = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
378 msgtype2.addParam('fo');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
379 msgtype2.paramType('fo', foo);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
380 msgtype2.returntype = baz;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
381 baz.addMessage('bar', msgtype2);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
382 baz.addMessage('qux', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
383 var shizzle = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
384 shizzle.addMessage('bar', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
385 shizzle.addMessage('boo', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
386 return {foo: foo, baz: baz, shizzle: shizzle};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
387 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
388
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
389 function paramtypetest()
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
390 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
391 var empty = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
392 var tlnode = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
393 tlnode.typeparams = ['T'];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
394 var t = new typeparam('T', any);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
395 var q = new typeparam('Q', any);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
396 var head = new lambdatype();
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
397 head.returntype = t;
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
398 tlnode.addMessage('head', head);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
399 var tail = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
400 var econs = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
401 econs.addParam('val');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
402 econs.typeparams = ['Q'];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
403 econs.paramType('val', q);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
404 econs.returntype = new withtparams(tlnode, [q]);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
405 empty.addMessage('cons', econs);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
406 tail.returntype = new uniontype(new withtparams(tlnode, [t]), empty);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
407 tlnode.addMessage('tail', tail);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
408 var cons = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
409 cons.addParam('val');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
410 cons.paramType('val', t);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
411 cons.returntype = new withtparams(tlnode, [t]);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
412 tlnode.addMessage('cons', cons);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
413 return {empty: empty, tlnode: tlnode};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
414 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
415