annotate types.js @ 251:2557ce4e671f

Fix a couple of compiler bugs. topenv was getting initialized in multiple places. This resulted in multiple copies of modules getting created which caused problems for macro expansion. Additionally, arguments were not being marked as declared during code generation so assigning to an argument that was not closed over generated invalid C code.
author Michael Pavone <pavone@retrodev.com>
date Fri, 11 Apr 2014 22:29:32 -0700
parents 09b65b364927
children
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 //temporarily set cache entry to true to prevent infinite recursion
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
61 this.satisfies_cache[type.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
62 var ret = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
63 if (type.messages === undefined) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
64 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
65 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
66 if (ret) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
67 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
68 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
69 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
70 break;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
71 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
72 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
73 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
74 this.satisfies_cache[type.id] = ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
75 return ret;
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 objecttype.prototype.str = function(indent) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
79 if (indent === undefined) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
80 indent = '';
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 if (indent.length > 6) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
83 return 'max depth reached\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
84 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
85 var newindent = indent + '\t';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
86 var childindent = newindent + '\t'
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
87 var ret = indent + 'objectype {\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
88 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
89 ret += newindent + msgname + ':\n' + this.messages[msgname].str(childindent)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
90 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
91 return ret + indent + '}\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
92 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
93
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
94 objecttype.prototype.replaceParams = function(paramtypes, visited) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
95 if (visited === undefined) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
96 visited = {};
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 if (this.id in visited) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
99 return visited[this.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
100 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
101 var me = visited[this.id] = this.clone();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
102 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
103 me.messages[msgname] = me.messages[msgname].replaceParams(paramtypes, visited);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
104 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
105 return me;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
106 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
107
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
108 objecttype.prototype.clone = function() {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
109 var clone = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
110 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
111 clone.messages[msgname] = this.messages[msgname];
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 clone.typeparams = this.typeparams;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
114 return clone;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
115 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
116
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
117 function lambdatype()
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
118 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
119 this.id = nexttypeid++;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
120 this.messages = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
121 this.params = [];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
122 this.paramlu = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
123 this.typeparams = [];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
124 this.returntype = any;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
125 this.satisfies_cache = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
126 this.satisfies_cache[this.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
127 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
128
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
129 lambdatype.prototype.callable = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
130
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
131 lambdatype.prototype.addParam = function(name) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
132 this.paramlu[name] = this.params.length;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
133 this.params.push(any);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
134 };
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.paramType = function(name, type) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
137 this.params[this.paramlu[name]] = type;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
138 };
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 lambdatype.prototype.addMessage = function(name, type)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
141 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
142 this.messages[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.satisfiedBy = function(type) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
146 if (type.id in this.satisfies_cache) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
147 return this.satisfies_cache[type.id];
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 //temporarily set cache entry to true to prevent infinite recursion
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
150 this.satisfies_cache[type.id] = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
151 var ret = true;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
152 if (!(type.callable) || this.params.length != type.params.length) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
153 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
154 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
155 if (ret) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
156 for (var i in this.params) {
103
182c311a9fed Fix variance of lambda parameters
Mike Pavone <pavone@retrodev.com>
parents: 102
diff changeset
157 if (i >= type.params.length || !type.params[i].satisfiedBy(this.params[i])) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
158 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
159 break;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
160 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
161 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
162 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
163 if (ret) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
164 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
165 if (!(msgname in type.messages) || !this.messages[msgname].satisfiedBy(type.messages[msgname])) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
166 ret = false;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
167 break;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
168 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
169 }
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 ret = ret && this.returntype.satisfiedBy(type.returntype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
172 this.satisfies_cache[type.id] = ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
173 return ret;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
174 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
175
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
176 lambdatype.prototype.str = function(indent) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
177 if (indent === undefined) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
178 indent = '';
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 if (indent.length > 6) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
181 return 'max depth reached\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
182 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
183 var newindent = indent + '\t';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
184 var childindent = newindent + '\t'
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
185 var ret = indent + 'lambdatype {\n' + newindent + 'params: {\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
186 for (var i = 0; i < this.params.length; i++) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
187 ret += childindent + i + ':\n' + this.params[i].str(childindent + '\t');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
188 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
189 ret += newindent + '}\n' + newindent + 'returntype:\n' + this.returntype.str(childindent);
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 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
192 ret += newindent + msgname + ':\n' + this.messages[msgname].str(childindent)
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 return ret + indent + '}\n';
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
195 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
196
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
197 lambdatype.prototype.replaceParams = function(paramtypes, visited) {
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
198 if (visited === undefined) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
199 visited = {};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
200 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
201 if (this.id in visited) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
202 return visited[this.id];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
203 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
204 var me = visited[this.id] = this.clone();
101
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
205 for (var msgname in me.messages) {
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
206 me.messages[msgname] = me.messages[msgname].replaceParams(paramtypes, visited);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
207 }
101
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
208 for (var i in me.params) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
209 me.params[i] = me.params[i].replaceParams(paramtypes, visited);
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
210 }
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
211 me.returntype = me.returntype.replaceParams(paramtypes, visited);
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
212 return me;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
213 };
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 lambdatype.prototype.clone = function() {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
216 var clone = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
217 for (var msgname in this.messages) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
218 clone.messages[msgname] = this.messages[msgname];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
219 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
220 clone.paramlu = this.paramlu;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
221 clone.params = this.params.slice(0, this.params.length);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
222 clone.returntype = this.returntype;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
223 clone.typeparams = this.typeparams;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
224 return clone;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
225 };
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 function uniontype(a, b)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
228 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
229 this.a = a;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
230 this.b = b;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
231 this.id = nexttypeid++;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
232 this.satisfies_cache = null;
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
101
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
235 uniontype.prototype = {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
236 lazyinit: function() {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
237 if (this.satisfies_cache == null) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
238 this.satisfies_cache = {};
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
239 this.satisfies_cache[this.id] = true;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
240 this._messages = {};
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
241 if (this.a.messages !== undefined && this.b.messages !== undefined) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
242 for (var msgname in this.a.messages) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
243 if (msgname in this.b.messages) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
244 this._messages[msgname] = mkunion(this.a.messages[msgname], this.b.messages[msgname]);
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
245 }
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
246 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
247 }
101
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
248 this._callable = false;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
249 if (this.a.callable && this.b.callable && this.a.params.length == this.b.params.length) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
250 this._callable = true;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
251 this._params = [];
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
252 for (var i = 0; i < this.a.params.length; i++) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
253 this._params.push(mkunion(this.a.params[i], this.b.params[i]));
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
254 }
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
255 this._returntype = mkunion(this.a.returntype, this.b.returntype);
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
256 }
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
257 }
101
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
258 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
259 satisfiedBy: function(type)
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
260 {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
261 this.lazyinit();
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
262 if (type.id in this.satisfies_cache) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
263 return this.satisfies_cache[type.id];
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
264 }
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
265 this.satisfies_cache[type.id] = true;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
266 var ret = this.a.satisfiedBy(type) || this.b.satisfiedBy(type);
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
267 this.satisfies_cache[type.id] = ret;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
268 return ret;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
269 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
270 str: function(indent)
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
271 {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
272 if (indent === undefined) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
273 indent = '';
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
274 }
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
275 if (indent.length > 6) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
276 return 'max depth reached\n';
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
277 }
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
278 return indent + 'Union {\n\t' + indent + this.a.str(indent+'\t') + '\t' + indent + this.b.str(indent+'\t') + indent + '}\n';
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
279 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
280 replaceParams: function(paramtypes, visited) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
281 if (visited === undefined) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
282 visited = {};
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
283 }
101
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
284 if (this.id in visited) {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
285 return visited[this.id];
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
286 }
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
287 var me = visited[this.id] = this.clone();
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
288 me.a = me.a.replaceParams(paramtypes, visited);
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
289 me.b = me.b.replaceParams(paramtypes, visited);
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
290 return me;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
291 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
292 clone: function() {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
293 return new uniontype(this.a, this.b);
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
294 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
295 get messages() {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
296 this.lazyinit();
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
297 return this._messages;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
298 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
299 get params() {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
300 this.lazyinit();
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
301 return this._params;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
302 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
303 get returntype() {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
304 this.lazyinit();
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
305 return this._returntype;
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
306 },
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
307 get callable() {
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
308 this.lazyinit();
5d15b91e738a Fix paramerized types. Remove debug print calls.
Mike Pavone <pavone@retrodev.com>
parents: 100
diff changeset
309 return this._callable;
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
310 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
311 };
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
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
314 function mkunion(a, b)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
315 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
316 //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
317 if (a.satisfiedBy(b)) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
318 return a;
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 //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
321 if (b.satisfiedBy(a)) {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
322 return b;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
323 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
324 return new uniontype(a, b);
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
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
327 function withtparams(type, params)
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
328 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
329 this.type = type;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
330 this.params = params;
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
331 this.replaced = false;
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
332 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
333
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
334 withtparams.prototype = {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
335 satisfiedBy: function(type) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
336 this.lazyinit();
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
337 return this.type.satisfiedBy(type);
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
338 },
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
339 str: function(indent) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
340 if (indent === undefined) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
341 indent = '';
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
342 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
343 if (indent.length > 6) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
344 return 'max depth reached\n';
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
345 }
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
346 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
347 },
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
348 replaceParams: function(paramtypes) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
349 var replaced = false;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
350 for (var i in this.params) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
351 var newp = this.params[i].replaceParams(paramtypes);
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
352 if (newp != this.params[i]) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
353 replaced = true;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
354 this.params[i] = newp;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
355 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
356 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
357 return this;
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 lazyinit: function() {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
360 if (!this.replaced) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
361 var childptypes = {};
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
362 for (var i in this.type.typeparams) {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
363 childptypes[this.type.typeparams[i]] = this.params[i]
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
364 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
365 this.type = this.type.replaceParams(childptypes, {});
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
366 this.replaced = true;
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
367 }
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
368 },
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
369 get messages() {
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
370 this.lazyinit();
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
371 return this.type.messages;
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
372 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
373 };
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
374
129
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
375 object.prototype.toType = function(parent) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
376 var me = new objecttype();
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
377 for (var i in this.messages) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
378 this.messages[i].toObjectType(me);
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
379 }
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
380 return me;
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
381 };
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
382
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
383 lambda.prototype.toType = function(parent) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
384 var me = new lambdatype();
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
385 for (var i in this.args) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
386 me.addParam(this.args[i].cleanName());
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
387 }
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
388 for (var i in this.expressions) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
389 this.expressions[i].toType(me);
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
390 }
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
391 return me;
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
392 };
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
393
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
394 funcall.prototype.toType = function(parent) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
395 var name = this.name[this.name.length-1] == ':' ? this.name.substr(0, this.name.length-1) : this.name;
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
396 switch(name)
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
397 {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
398 case 'typeParam':
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
399 break;
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
400 case 'isa':
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
401 break;
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
402 };
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
403
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
404 assignment.prototype.toObjectType = function(parent) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
405 if (this.expression.instanceof lambda) {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
406 parent.addMessage(this.symbol.name, this.expression.toType(parent));
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
407 } else {
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
408 var valtype = this.expression.toType(parent);
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
409 var getter = new lambdatype();
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
410 getter.returntype = valtype;
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
411 var setter = new lambdatype();
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
412 setter.addParam('val');
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
413 setter.paramType('val', valtype);
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
414 setter.returntype = parent;
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
415 parent.addMessage(this.symbol.name, setter);
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
416 }
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
417 };
09b65b364927 Some old changes to the WIP type checker
Mike Pavone <pavone@retrodev.com>
parents: 103
diff changeset
418
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
419 function typetest()
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
420 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
421 var foo = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
422 var msgtype = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
423 msgtype.addParam('fo');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
424 msgtype.returntype = foo;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
425 foo.addMessage('bar', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
426 var baz = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
427 var msgtype2 = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
428 msgtype2.addParam('fo');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
429 msgtype2.paramType('fo', foo);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
430 msgtype2.returntype = baz;
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
431 baz.addMessage('bar', msgtype2);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
432 baz.addMessage('qux', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
433 var shizzle = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
434 shizzle.addMessage('bar', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
435 shizzle.addMessage('boo', msgtype);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
436 return {foo: foo, baz: baz, shizzle: shizzle};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
437 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
438
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
439 function paramtypetest()
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
440 {
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
441 var empty = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
442 var tlnode = new objecttype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
443 tlnode.typeparams = ['T'];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
444 var t = new typeparam('T', any);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
445 var q = new typeparam('Q', any);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
446 var head = new lambdatype();
100
9db0e3533b23 Some work on parameterized types
Mike Pavone <pavone@retrodev.com>
parents: 99
diff changeset
447 head.returntype = t;
99
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
448 tlnode.addMessage('head', head);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
449 var tail = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
450 var econs = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
451 econs.addParam('val');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
452 econs.typeparams = ['Q'];
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
453 econs.paramType('val', q);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
454 econs.returntype = new withtparams(tlnode, [q]);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
455 empty.addMessage('cons', econs);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
456 tail.returntype = new uniontype(new withtparams(tlnode, [t]), empty);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
457 tlnode.addMessage('tail', tail);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
458 var cons = new lambdatype();
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
459 cons.addParam('val');
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
460 cons.paramType('val', t);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
461 cons.returntype = new withtparams(tlnode, [t]);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
462 tlnode.addMessage('cons', cons);
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
463 return {empty: empty, tlnode: tlnode};
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
464 }
b58b19c455ec Initial work on type system
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
465