git @ Cat's Eye Technologies Castile / 7179e74
Report line numbers on type errors. Chris Pressey 3 years ago
2 changed file(s) with 63 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
0 struct person { name: string };
1 fun foo(a, b: integer|string) {
2 r = a;
3 typecase b is integer {
4 r = r + b;
5 };
6 typecase b is person {
7 r = r + len(b);
8 };
9 r
10 }
11 main = fun() {
12 a = 0;
13 a = foo(a, 333 as integer|string);
14 a = foo(a, "hiya" as integer|string);
15 a /* should output 337 */
16 }
55
66
77 class CastileTypeError(ValueError):
8 pass
8 def __init__(self, ast, message, *args, **kwargs):
9 message = 'line {}: {}'.format(ast.line, message)
10 super(CastileTypeError, self).__init__(message, *args, **kwargs)
911
1012
1113 class StructDefinition(object):
4850 print('%s: %s' % (name, type))
4951 return type
5052
51 def assert_eq(self, t1, t2):
53 def assert_eq(self, ast, t1, t2):
5254 if t1 == t2:
5355 return
54 raise CastileTypeError("type mismatch: %s != %s" % (t1, t2))
56 raise CastileTypeError(ast, "type mismatch: %s != %s" % (t1, t2))
5557
5658 def collect_structs(self, ast):
5759 for child in ast.children:
6163 def collect_struct(self, ast):
6264 name = ast.value
6365 if name in self.structs:
64 raise CastileTypeError('duplicate struct %s' % name)
66 raise CastileTypeError(ast, 'duplicate struct %s' % name)
6567 struct_fields = {}
6668 type_exprs = []
6769 i = 0
7375 assert child.tag == 'FieldDefn', child.tag
7476 field_name = child.value
7577 if field_name in struct_fields:
76 raise CastileTypeError('already-defined field %s' % field_name)
78 raise CastileTypeError(child, 'already-defined field %s' % field_name)
7779 struct_fields[field_name] = i
7880 i += 1
7981 type_exprs.append(self.type_of(child.children[0]))
8284 def resolve_structs(self, ast):
8385 if isinstance(ast.type, Struct):
8486 if ast.type.name not in self.structs:
85 raise CastileTypeError('undefined struct %s' % ast.type.name)
87 raise CastileTypeError(ast, 'undefined struct %s' % ast.type.name)
8688 ast.type.defn = self.structs[ast.type.name]
8789 for child in ast.children:
8890 self.resolve_structs(child)
9193 def type_of(self, ast):
9294 if ast.tag == 'Op':
9395 if ast.value in ('and', 'or'):
94 self.assert_eq(self.type_of(ast.children[0]), Boolean())
95 self.assert_eq(self.type_of(ast.children[1]), Boolean())
96 self.assert_eq(ast, self.type_of(ast.children[0]), Boolean())
97 self.assert_eq(ast, self.type_of(ast.children[1]), Boolean())
9698 ast.type = Boolean()
9799 elif ast.value in ('+', '-', '*', '/'):
98100 type1 = self.type_of(ast.children[0])
99101 type2 = self.type_of(ast.children[1])
100 self.assert_eq(type1, type2)
101 self.assert_eq(type1, Integer())
102 self.assert_eq(ast, type1, type2)
103 self.assert_eq(ast, type1, Integer())
102104 ast.type = Integer()
103105 elif ast.value in ('==', '!=', '>', '>=', '<', '<='):
104106 type1 = self.type_of(ast.children[0])
105107 type2 = self.type_of(ast.children[1])
106 self.assert_eq(type1, type2)
108 self.assert_eq(ast, type1, type2)
107109 if isinstance(type1, Struct):
108 raise CastileTypeError("structs cannot be compared")
110 raise CastileTypeError(ast, "structs cannot be compared")
109111 if isinstance(type1, Union) and type1.contains_instance_of(Struct):
110 raise CastileTypeError("unions containing structs cannot be compared")
112 raise CastileTypeError(ast, "unions containing structs cannot be compared")
111113 ast.type = Boolean()
112114 elif ast.tag == 'Not':
113115 type1 = self.type_of(ast.children[0])
114 self.assert_eq(type1, Boolean())
116 self.assert_eq(ast, type1, Boolean())
115117 ast.type = Boolean()
116118 elif ast.tag == 'IntLit':
117119 ast.type = Integer()
121123 ast.type = Boolean()
122124 elif ast.tag == 'FunLit':
123125 save_context = self.context
124 self.context = ScopedContext({}, self.toplevel_context,
125 level='argument')
126 self.context = ScopedContext(
127 {}, self.toplevel_context, level='argument'
128 )
126129 self.return_type = None
127130 arg_types = self.type_of(ast.children[0]) # args
128131 t = self.type_of(ast.children[1]) # body
129 self.assert_eq(t, Void())
132 self.assert_eq(ast, t, Void())
130133 self.context = save_context
131134 return_type = self.return_type
132135 self.return_type = None
151154 elif ast.tag == 'Body':
152155 self.context = ScopedContext({}, self.context,
153156 level='local')
154 self.assert_eq(self.type_of(ast.children[1]), Void())
157 self.assert_eq(ast, self.type_of(ast.children[1]), Void())
155158 self.context = self.context.parent
156159 ast.type = Void()
157160 elif ast.tag == 'FunType':
164167 for c in ast.children:
165168 type_ = self.type_of(c)
166169 if type_ in types:
167 raise CastileTypeError("bad union type")
170 raise CastileTypeError(c, "bad union type")
168171 types.append(type_)
169172 ast.type = Union(types)
170173 elif ast.tag == 'StructType':
179182 assert isinstance(t1, Function), \
180183 '%r is not a function' % t1
181184 if len(t1.arg_types) != len(ast.children) - 1:
182 raise CastileTypeError("argument mismatch")
185 raise CastileTypeError(ast, "argument mismatch")
183186 i = 0
184187 for child in ast.children[1:]:
185 self.assert_eq(self.type_of(child), t1.arg_types[i])
188 self.assert_eq(ast, self.type_of(child), t1.arg_types[i])
186189 i += 1
187190 ast.type = t1.return_type
188191 elif ast.tag == 'Return':
190193 if self.return_type is None:
191194 self.return_type = t1
192195 else:
193 self.assert_eq(t1, self.return_type)
196 self.assert_eq(ast, t1, self.return_type)
194197 ast.type = Void()
195198 elif ast.tag == 'Break':
196199 ast.type = Void()
203206 if len(ast.children) == 3:
204207 # TODO useless! is void.
205208 t3 = self.type_of(ast.children[2])
206 self.assert_eq(t2, t3)
209 self.assert_eq(ast, t2, t3)
207210 ast.type = t2
208211 else:
209212 ast.type = Void()
212215 within_control = self.within_control
213216 self.within_control = True
214217 t1 = self.type_of(ast.children[0])
215 self.assert_eq(t1, Boolean())
218 self.assert_eq(ast, t1, Boolean())
216219 t2 = self.type_of(ast.children[1])
217220 ast.type = Void()
218221 self.within_control = within_control
219222 elif ast.tag == 'Block':
220223 for child in ast.children:
221 self.assert_eq(self.type_of(child), Void())
224 self.assert_eq(ast, self.type_of(child), Void())
222225 ast.type = Void()
223226 elif ast.tag == 'Assignment':
224227 t2 = self.type_of(ast.children[1])
226229 name = ast.children[0].value
227230 if ast.aux == 'defining instance':
228231 if self.within_control:
229 raise CastileTypeError('definition of %s within control block' % name)
232 raise CastileTypeError(ast, 'definition of %s within control block' % name)
230233 if name in self.context:
231 raise CastileTypeError('definition of %s shadows previous' % name)
234 raise CastileTypeError(ast, 'definition of %s shadows previous' % name)
232235 self.set(name, t2)
233236 t1 = t2
234237 else:
235238 if name not in self.context:
236 raise CastileTypeError('variable %s used before definition' % name)
239 raise CastileTypeError(ast, 'variable %s used before definition' % name)
237240 t1 = self.type_of(ast.children[0])
238 self.assert_eq(t1, t2)
241 self.assert_eq(ast, t1, t2)
239242 # not quite useless now (typecase still likes this)
240243 if self.context.level(ast.children[0].value) != 'local':
241 raise CastileTypeError('cannot assign to non-local')
244 raise CastileTypeError(ast, 'cannot assign to non-local')
242245 ast.type = Void()
243246 elif ast.tag == 'Make':
244247 t = self.type_of(ast.children[0])
245248 if t.name not in self.structs:
246 raise CastileTypeError("undefined struct %s" % t.name)
249 raise CastileTypeError(ast, "undefined struct %s" % t.name)
247250 struct_defn = self.structs[t.name]
248251 if struct_defn.scope_idents is not None:
249252 if self.current_defn not in struct_defn.scope_idents:
250 raise CastileTypeError("inaccessible struct %s for make: %s not in %s" %
253 raise CastileTypeError(ast, "inaccessible struct %s for make: %s not in %s" %
251254 (t.name, self.current_defn, struct_defn.scope_idents)
252255 )
253256 if len(struct_defn.content_types) != len(ast.children) - 1:
254 raise CastileTypeError("argument mismatch; expected {}, got {} in {}".format(
257 raise CastileTypeError(ast, "argument mismatch; expected {}, got {} in {}".format(
255258 len(struct_defn.content_types), len(ast.children) - 1, ast
256259 ))
257260 i = 0
260263 t1 = self.type_of(defn)
261264 pos = struct_defn.field_names[name]
262265 defn.aux = pos
263 self.assert_eq(t1, struct_defn.content_types[pos])
266 self.assert_eq(ast, t1, struct_defn.content_types[pos])
264267 i += 1
265268 ast.type = t
266269 elif ast.tag == 'FieldInit':
270273 struct_defn = self.structs[t.name]
271274 if struct_defn.scope_idents is not None:
272275 if self.current_defn not in struct_defn.scope_idents:
273 raise CastileTypeError("inaccessible struct %s for access: %s not in %s" %
276 raise CastileTypeError(ast, "inaccessible struct %s for access: %s not in %s" %
274277 (t.name, self.current_defn, struct_defn.scope_idents)
275278 )
276279 field_name = ast.value
277280 struct_fields = struct_defn.field_names
278281 if field_name not in struct_fields:
279 raise CastileTypeError("undefined field")
282 raise CastileTypeError(ast, "undefined field")
280283 index = struct_fields[field_name]
281284 # we make this value available to compiler backends
282285 ast.aux = index
286289 t1 = self.type_of(ast.children[0])
287290 t2 = self.type_of(ast.children[1])
288291 if not isinstance(t1, Union):
289 raise CastileTypeError('bad typecase, %s not a union' % t1)
292 raise CastileTypeError(ast, 'bad typecase, %s not a union' % t1)
290293 if not t1.contains(t2):
291 raise CastileTypeError('bad typecase, %s not in %s' % (t2, t1))
294 raise CastileTypeError(ast, 'bad typecase, %s not in %s' % (t2, t1))
292295 # typecheck t3 with variable in children[0] having type t2
293296 assert ast.children[0].tag == 'VarRef'
294297 within_control = self.within_control
300303 self.within_control = within_control
301304 elif ast.tag == 'Program':
302305 for defn in ast.children:
303 self.assert_eq(self.type_of(defn), Void())
306 self.assert_eq(ast, self.type_of(defn), Void())
304307 ast.type = Void()
305308 self.resolve_structs(ast)
306309 elif ast.tag == 'Defn':
308311 t = self.type_of(ast.children[0])
309312 self.current_defn = None
310313 if ast.value in self.forwards:
311 self.assert_eq(self.forwards[ast.value], t)
314 self.assert_eq(ast, self.forwards[ast.value], t)
312315 del self.forwards[ast.value]
313316 else:
314317 self.set(ast.value, t)
316319 # any return type is fine, for now, so,
317320 # we compare it against itself
318321 rt = t.return_type
319 self.assert_eq(t, Function([], rt))
322 self.assert_eq(ast, t, Function([], rt))
320323 ast.type = Void()
321324 elif ast.tag == 'Forward':
322325 t = self.type_of(ast.children[0])
329332 value_t = self.type_of(ast.children[0])
330333 union_t = self.type_of(ast.children[1])
331334 if not isinstance(union_t, Union):
332 raise CastileTypeError('bad cast, not a union: %s' % union_t)
335 raise CastileTypeError(ast, 'bad cast, not a union: %s' % union_t)
333336 if not union_t.contains(value_t):
334337 raise CastileTypeError(
335 'bad cast, %s does not include %s' % (union_t, value_t)
338 ast, 'bad cast, %s does not include %s' % (union_t, value_t)
336339 )
337340 ast.type = union_t
338341 else: