annotate types.js @ 237:dae093baf36c

Optimized implementation of character classes
author Mike Pavone <pavone@retrodev.com>
date Sun, 05 Jan 2014 17:00:33 -0800
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