Skip to content

Commit df68613

Browse files
author
whitequark
committedJun 11, 2015
Separate inference and asttyped transformation.
This allows to run inference several times on the same tree, as would be necessary when coercion nodes are added.
1 parent e18ea0d commit df68613

File tree

1 file changed

+64
-56
lines changed

1 file changed

+64
-56
lines changed
 

Diff for: ‎artiq/py2llvm/typing.py

+64-56
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,22 @@ def _unify(self, typea, typeb, loca, locb, makenotes=None):
166166
loca, highlights, notes)
167167
self.engine.process(diag)
168168

169+
# makenotes for the case where types of multiple elements are unified
170+
# with the type of parent expression
171+
def _makenotes_elts(self, elts, kind):
172+
def makenotes(printer, typea, typeb, loca, locb):
173+
return [
174+
diagnostic.Diagnostic("note",
175+
"{kind} of type {typea}",
176+
{"kind": kind, "typea": printer.name(elts[0].type)},
177+
elts[0].loc),
178+
diagnostic.Diagnostic("note",
179+
"{kind} of type {typeb}",
180+
{"kind": kind, "typeb": printer.name(typeb)},
181+
locb)
182+
]
183+
return makenotes
184+
169185
def _find_name(self, name, loc):
170186
for typing_env in reversed(self.env_stack):
171187
if name in typing_env:
@@ -212,26 +228,6 @@ def visit_FunctionDef(self, node):
212228

213229
return node
214230

215-
def visit_Return(self, node):
216-
node = self.generic_visit(node)
217-
def makenotes(printer, typea, typeb, loca, locb):
218-
return [
219-
diagnostic.Diagnostic("note",
220-
"function with return type {typea}",
221-
{"typea": printer.name(typea)},
222-
self.function.name_loc),
223-
diagnostic.Diagnostic("note",
224-
"a statement returning {typeb}",
225-
{"typeb": printer.name(typeb)},
226-
node.loc)
227-
]
228-
if node.value is None:
229-
self._unify(self.function.return_type, types.TNone(),
230-
self.function.name_loc, node.loc, makenotes)
231-
else:
232-
self._unify(self.function.return_type, node.value.type,
233-
self.function.name_loc, node.value.loc, makenotes)
234-
235231
def visit_Num(self, node):
236232
if isinstance(node.n, int):
237233
typ = types.TInt()
@@ -265,63 +261,55 @@ def visit_List(self, node):
265261
node = self.generic_visit(node)
266262
node = asttyped.ListT(type=types.TList(),
267263
elts=node.elts, ctx=node.ctx, loc=node.loc)
268-
def makenotes(printer, typea, typeb, loca, locb):
269-
return [
270-
diagnostic.Diagnostic("note",
271-
"a list element of type {typea}",
272-
{"typea": printer.name(node.elts[0].type)},
273-
node.elts[0].loc),
274-
diagnostic.Diagnostic("note",
275-
"a list element of type {typeb}",
276-
{"typeb": printer.name(typeb)},
277-
locb)
278-
]
279-
for elt in node.elts:
280-
self._unify(node.type["elt"], elt.type,
281-
node.loc, elt.loc, makenotes)
282-
return node
264+
return self.visit(node)
283265

284266
def visit_Subscript(self, node):
285267
node = self.generic_visit(node)
286268
node = asttyped.SubscriptT(type=types.TVar(),
287269
value=node.value, slice=node.slice, ctx=node.ctx,
288270
loc=node.loc)
289-
# TODO: support more than just lists
290-
self._unify(types.TList(node.type), node.value.type,
291-
node.loc, node.value.loc)
292-
return node
271+
return self.visit(node)
293272

294273
def visit_IfExp(self, node):
295274
node = self.generic_visit(node)
296-
self._unify(node.body.type, node.orelse.type,
297-
node.body.loc, node.orelse.loc)
298-
return asttyped.IfExpT(type=node.body.type,
275+
node = asttyped.IfExpT(type=types.TVar(),
299276
test=node.test, body=node.body, orelse=node.orelse,
300277
if_loc=node.if_loc, else_loc=node.else_loc, loc=node.loc)
278+
return self.visit(node)
301279

302280
def visit_BoolOp(self, node):
303281
node = self.generic_visit(node)
304282
node = asttyped.BoolOpT(type=types.TVar(),
305283
op=node.op, values=node.values,
306284
op_locs=node.op_locs, loc=node.loc)
307-
def makenotes(printer, typea, typeb, loca, locb):
308-
return [
309-
diagnostic.Diagnostic("note",
310-
"an operand of type {typea}",
311-
{"typea": printer.name(node.values[0].type)},
312-
node.values[0].loc),
313-
diagnostic.Diagnostic("note",
314-
"an operand of type {typeb}",
315-
{"typeb": printer.name(typeb)},
316-
locb)
317-
]
285+
return self.visit(node)
286+
287+
# Visitors that just unify types
288+
#
289+
def visit_ListT(self, node):
290+
for elt in node.elts:
291+
self._unify(node.type["elt"], elt.type,
292+
node.loc, elt.loc, self._makenotes_elts(node.elts, "a list element"))
293+
return node
294+
295+
def visit_SubscriptT(self, node):
296+
# TODO: support more than just lists
297+
self._unify(types.TList(node.type), node.value.type,
298+
node.loc, node.value.loc)
299+
return node
300+
301+
def visit_IfExpT(self, node):
302+
self._unify(node.body.type, node.orelse.type,
303+
node.body.loc, node.orelse.loc)
304+
node.type = node.body.type
305+
return node
306+
307+
def visit_BoolOpT(self, node):
318308
for value in node.values:
319309
self._unify(node.type, value.type,
320-
node.loc, value.loc, makenotes)
310+
node.loc, value.loc, self._makenotes_elts(node.values, "an operand"))
321311
return node
322312

323-
# Visitors that just unify types
324-
#
325313
def visit_Assign(self, node):
326314
node = self.generic_visit(node)
327315
if len(node.targets) > 1:
@@ -345,6 +333,26 @@ def visit_For(self, node):
345333
node.target.loc, node.iter.loc)
346334
return node
347335

336+
def visit_Return(self, node):
337+
node = self.generic_visit(node)
338+
def makenotes(printer, typea, typeb, loca, locb):
339+
return [
340+
diagnostic.Diagnostic("note",
341+
"function with return type {typea}",
342+
{"typea": printer.name(typea)},
343+
self.function.name_loc),
344+
diagnostic.Diagnostic("note",
345+
"a statement returning {typeb}",
346+
{"typeb": printer.name(typeb)},
347+
node.loc)
348+
]
349+
if node.value is None:
350+
self._unify(self.function.return_type, types.TNone(),
351+
self.function.name_loc, node.loc, makenotes)
352+
else:
353+
self._unify(self.function.return_type, node.value.type,
354+
self.function.name_loc, node.value.loc, makenotes)
355+
348356
# Unsupported visitors
349357
#
350358
def visit_unsupported(self, node):

0 commit comments

Comments
 (0)
Please sign in to comment.