Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1c48874a2a2e
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: faaf189961cf
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Jun 13, 2015

  1. Invert operand should be integer.

    whitequark committed Jun 13, 2015
    Copy the full SHA
    23f33d7 View commit details
  2. Add support for Attribute.

    whitequark committed Jun 13, 2015
    Copy the full SHA
    faaf189 View commit details
Showing with 59 additions and 16 deletions.
  1. +8 −0 artiq/py2llvm/builtins.py
  2. +2 −2 artiq/py2llvm/types.py
  3. +41 −12 artiq/py2llvm/typing.py
  4. +8 −2 lit-test/py2llvm/typing/error_unify.py
8 changes: 8 additions & 0 deletions artiq/py2llvm/builtins.py
Original file line number Diff line number Diff line change
@@ -26,6 +26,8 @@ def __init__(self):
class TTuple(types.Type):
"""A tuple type."""

attributes = {}

def __init__(self, elts=[]):
self.elts = elts

@@ -58,6 +60,12 @@ def __init__(self, elt=None):
super().__init__("list", {"elt": elt})


def is_int(typ, width=None):
if width:
return types.is_mono(typ, "int", {"width": width})
else:
return types.is_mono(typ, "int")

def is_numeric(typ):
return isinstance(typ, types.TMono) and \
typ.name in ('int', 'float')
4 changes: 2 additions & 2 deletions artiq/py2llvm/types.py
Original file line number Diff line number Diff line change
@@ -37,8 +37,6 @@ class TVar(Type):
folded into this class.
"""

attributes = ()

def __init__(self):
self.parent = self

@@ -71,6 +69,8 @@ def __repr__(self):
class TMono(Type):
"""A monomorphic type, possibly parametric."""

attributes = {}

def __init__(self, name, params={}):
self.name, self.params = name, params

53 changes: 41 additions & 12 deletions artiq/py2llvm/typing.py
Original file line number Diff line number Diff line change
@@ -224,20 +224,20 @@ def visit_List(self, node):
elts=node.elts, ctx=node.ctx, loc=node.loc)
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):
node = self.generic_visit(node)
node = asttyped.SubscriptT(type=types.TVar(),
value=node.value, slice=node.slice, ctx=node.ctx,
loc=node.loc)
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):
node = self.generic_visit(node)
node = asttyped.BoolOpT(type=types.TVar(),
@@ -266,6 +266,13 @@ def visit_Compare(self, node):
loc=node.loc)
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
#
def visit_unsupported(self, node):
@@ -275,7 +282,6 @@ def visit_unsupported(self, node):
self.engine.process(diag)

# expr
visit_Attribute = visit_unsupported
visit_BinOp = visit_unsupported
visit_Call = visit_unsupported
visit_Compare = visit_unsupported
@@ -373,6 +379,19 @@ def visit_ListT(self, node):
self._unify(node.type["elt"], elt.type,
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):
# TODO: support more than just lists
self._unify(builtins.TList(node.type), node.value.type,
@@ -389,18 +408,28 @@ def visit_BoolOpT(self, node):
node.loc, value.loc, self._makenotes_elts(node.values, "an operand"))

def visit_UnaryOpT(self, node):
operand_type = node.operand.type.find()
if isinstance(node.op, ast.Not):
node.type = builtins.TBool()
else:
operand_type = node.operand.type.find()
if builtins.is_numeric(operand_type):
elif isinstance(node.op, ast.Invert):
if builtins.is_int(operand_type):
node.type = operand_type
elif not types.is_var(operand_type):
diag = diagnostic.Diagnostic("error",
"expected operand to be of numeric type, not {type}",
"expected ~ operand to be of integer type, not {type}",
{"type": types.TypePrinter().name(operand_type)},
node.operand.loc)
self.engine.process(diag)
else: # UAdd, USub
if builtins.is_numeric(operand_type):
node.type = operand_type
elif not types.is_var(operand_type):
diag = diagnostic.Diagnostic("error",
"expected unary {op} operand to be of numeric type, not {type}",
{"op": node.op.loc.source(),
"type": types.TypePrinter().name(operand_type)},
node.operand.loc)
self.engine.process(diag)

def visit_Assign(self, node):
self.generic_visit(node)
10 changes: 8 additions & 2 deletions lit-test/py2llvm/typing/error_unify.py
Original file line number Diff line number Diff line change
@@ -17,5 +17,11 @@
# CHECK-L: note: an operand of type int(width='a)
# CHECK-L: note: an operand of type bool

# CHECK-L: ${LINE:+1}: error: expected operand to be of numeric type, not list(elt='a)
~[]
# CHECK-L: ${LINE:+1}: error: expected unary + operand to be of numeric type, not list(elt='a)
+[]

# CHECK-L: ${LINE:+1}: error: expected ~ operand to be of integer type, not float
~1.0

# CHECK-L: ${LINE:+1}: error: type int(width='a) does not have an attribute 'x'
(1).x