forked from M-Labs/artiq
Add support for Attribute.
This commit is contained in:
parent
23f33d7239
commit
faaf189961
|
@ -26,6 +26,8 @@ class TFloat(types.TMono):
|
||||||
class TTuple(types.Type):
|
class TTuple(types.Type):
|
||||||
"""A tuple type."""
|
"""A tuple type."""
|
||||||
|
|
||||||
|
attributes = {}
|
||||||
|
|
||||||
def __init__(self, elts=[]):
|
def __init__(self, elts=[]):
|
||||||
self.elts = elts
|
self.elts = elts
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,6 @@ class TVar(Type):
|
||||||
folded into this class.
|
folded into this class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
attributes = ()
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.parent = self
|
self.parent = self
|
||||||
|
|
||||||
|
@ -71,6 +69,8 @@ class TVar(Type):
|
||||||
class TMono(Type):
|
class TMono(Type):
|
||||||
"""A monomorphic type, possibly parametric."""
|
"""A monomorphic type, possibly parametric."""
|
||||||
|
|
||||||
|
attributes = {}
|
||||||
|
|
||||||
def __init__(self, name, params={}):
|
def __init__(self, name, params={}):
|
||||||
self.name, self.params = name, params
|
self.name, self.params = name, params
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,13 @@ class ASTTypedRewriter(algorithm.Transformer):
|
||||||
elts=node.elts, ctx=node.ctx, loc=node.loc)
|
elts=node.elts, ctx=node.ctx, loc=node.loc)
|
||||||
return self.visit(node)
|
return self.visit(node)
|
||||||
|
|
||||||
|
def visit_Attribute(self, node):
|
||||||
|
node = self.generic_visit(node)
|
||||||
|
node = asttyped.AttributeT(type=types.TVar(),
|
||||||
|
value=node.value, attr=node.attr, ctx=node.ctx,
|
||||||
|
dot_loc=node.dot_loc, attr_loc=node.attr_loc, loc=node.loc)
|
||||||
|
return self.visit(node)
|
||||||
|
|
||||||
def visit_Subscript(self, node):
|
def visit_Subscript(self, node):
|
||||||
node = self.generic_visit(node)
|
node = self.generic_visit(node)
|
||||||
node = asttyped.SubscriptT(type=types.TVar(),
|
node = asttyped.SubscriptT(type=types.TVar(),
|
||||||
|
@ -231,13 +238,6 @@ class ASTTypedRewriter(algorithm.Transformer):
|
||||||
loc=node.loc)
|
loc=node.loc)
|
||||||
return self.visit(node)
|
return self.visit(node)
|
||||||
|
|
||||||
def visit_IfExp(self, node):
|
|
||||||
node = self.generic_visit(node)
|
|
||||||
node = asttyped.IfExpT(type=types.TVar(),
|
|
||||||
test=node.test, body=node.body, orelse=node.orelse,
|
|
||||||
if_loc=node.if_loc, else_loc=node.else_loc, loc=node.loc)
|
|
||||||
return self.visit(node)
|
|
||||||
|
|
||||||
def visit_BoolOp(self, node):
|
def visit_BoolOp(self, node):
|
||||||
node = self.generic_visit(node)
|
node = self.generic_visit(node)
|
||||||
node = asttyped.BoolOpT(type=types.TVar(),
|
node = asttyped.BoolOpT(type=types.TVar(),
|
||||||
|
@ -266,6 +266,13 @@ class ASTTypedRewriter(algorithm.Transformer):
|
||||||
loc=node.loc)
|
loc=node.loc)
|
||||||
return self.visit(node)
|
return self.visit(node)
|
||||||
|
|
||||||
|
def visit_IfExp(self, node):
|
||||||
|
node = self.generic_visit(node)
|
||||||
|
node = asttyped.IfExpT(type=types.TVar(),
|
||||||
|
test=node.test, body=node.body, orelse=node.orelse,
|
||||||
|
if_loc=node.if_loc, else_loc=node.else_loc, loc=node.loc)
|
||||||
|
return self.visit(node)
|
||||||
|
|
||||||
# Unsupported visitors
|
# Unsupported visitors
|
||||||
#
|
#
|
||||||
def visit_unsupported(self, node):
|
def visit_unsupported(self, node):
|
||||||
|
@ -275,7 +282,6 @@ class ASTTypedRewriter(algorithm.Transformer):
|
||||||
self.engine.process(diag)
|
self.engine.process(diag)
|
||||||
|
|
||||||
# expr
|
# expr
|
||||||
visit_Attribute = visit_unsupported
|
|
||||||
visit_BinOp = visit_unsupported
|
visit_BinOp = visit_unsupported
|
||||||
visit_Call = visit_unsupported
|
visit_Call = visit_unsupported
|
||||||
visit_Compare = visit_unsupported
|
visit_Compare = visit_unsupported
|
||||||
|
@ -373,6 +379,19 @@ class Inferencer(algorithm.Visitor):
|
||||||
self._unify(node.type["elt"], elt.type,
|
self._unify(node.type["elt"], elt.type,
|
||||||
node.loc, elt.loc, self._makenotes_elts(node.elts, "a list element"))
|
node.loc, elt.loc, self._makenotes_elts(node.elts, "a list element"))
|
||||||
|
|
||||||
|
def visit_AttributeT(self, node):
|
||||||
|
object_type = node.value.type.find()
|
||||||
|
if not types.is_var(object_type):
|
||||||
|
if node.attr in object_type.attributes:
|
||||||
|
# assumes no free type variables in .attributes
|
||||||
|
node.type = object_type.attributes[node.attr]
|
||||||
|
else:
|
||||||
|
diag = diagnostic.Diagnostic("error",
|
||||||
|
"type {type} does not have an attribute '{attr}'",
|
||||||
|
{"type": types.TypePrinter().name(object_type), "attr": node.attr},
|
||||||
|
node.attr_loc, [node.value.loc])
|
||||||
|
self.engine.process(diag)
|
||||||
|
|
||||||
def visit_SubscriptT(self, node):
|
def visit_SubscriptT(self, node):
|
||||||
# TODO: support more than just lists
|
# TODO: support more than just lists
|
||||||
self._unify(builtins.TList(node.type), node.value.type,
|
self._unify(builtins.TList(node.type), node.value.type,
|
||||||
|
|
|
@ -22,3 +22,6 @@ a = b
|
||||||
|
|
||||||
# CHECK-L: ${LINE:+1}: error: expected ~ operand to be of integer type, not float
|
# CHECK-L: ${LINE:+1}: error: expected ~ operand to be of integer type, not float
|
||||||
~1.0
|
~1.0
|
||||||
|
|
||||||
|
# CHECK-L: ${LINE:+1}: error: type int(width='a) does not have an attribute 'x'
|
||||||
|
(1).x
|
||||||
|
|
Loading…
Reference in New Issue