Skip to content

Commit

Permalink
Add support for UnaryOp.
Browse files Browse the repository at this point in the history
whitequark committed Jun 12, 2015
1 parent df68613 commit c89bf6f
Showing 4 changed files with 57 additions and 1 deletion.
12 changes: 12 additions & 0 deletions artiq/py2llvm/types.py
Original file line number Diff line number Diff line change
@@ -180,6 +180,18 @@ def TList(elt=None):
return TMono("list", {"elt": elt})


def is_var(typ):
return isinstance(typ, TVar)

def is_mono(typ, name, **params):
return isinstance(typ, TMono) and \
typ.name == name and typ.params == params

def is_numeric(typ):
return isinstance(typ, TMono) and \
typ.name in ('int', 'float')


class TypePrinter(object):
"""
A class that prints types using Python-like syntax and gives
37 changes: 36 additions & 1 deletion artiq/py2llvm/typing.py
Original file line number Diff line number Diff line change
@@ -284,6 +284,27 @@ def visit_BoolOp(self, node):
op_locs=node.op_locs, loc=node.loc)
return self.visit(node)

def visit_UnaryOp(self, node):
node = self.generic_visit(node)
node = asttyped.UnaryOpT(type=types.TVar(),
op=node.op, operand=node.operand,
loc=node.loc)
return self.visit(node)

def visit_BinOp(self, node):
node = self.generic_visit(node)
node = asttyped.BinOpT(type=types.TVar(),
left=node.left, op=node.op, right=node.right,
loc=node.loc)
return self.visit(node)

def visit_Compare(self, node):
node = self.generic_visit(node)
node = asttyped.CompareT(type=types.TVar(),
left=node.left, ops=node.ops, comparators=node.comparators,
loc=node.loc)
return self.visit(node)

# Visitors that just unify types
#
def visit_ListT(self, node):
@@ -310,6 +331,21 @@ def visit_BoolOpT(self, node):
node.loc, value.loc, self._makenotes_elts(node.values, "an operand"))
return node

def visit_UnaryOpT(self, node):
if isinstance(node.op, ast.Not):
node.type = types.TBool()
else:
operand_type = node.operand.type.find()
if types.is_numeric(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}",
{"type": types.TypePrinter().name(operand_type)},
node.operand.loc)
self.engine.process(diag)
return node

def visit_Assign(self, node):
node = self.generic_visit(node)
if len(node.targets) > 1:
@@ -375,7 +411,6 @@ def visit_unsupported(self, node):
visit_SetComp = visit_unsupported
visit_Str = visit_unsupported
visit_Starred = visit_unsupported
visit_UnaryOp = visit_unsupported
visit_Yield = visit_unsupported
visit_YieldFrom = visit_unsupported

3 changes: 3 additions & 0 deletions lit-test/py2llvm/typing/error_unify.py
Original file line number Diff line number Diff line change
@@ -16,3 +16,6 @@
1 and False
# 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)
~[]
6 changes: 6 additions & 0 deletions lit-test/py2llvm/typing/unify.py
Original file line number Diff line number Diff line change
@@ -41,3 +41,9 @@

1 and 0
# CHECK-L: 1:int(width='g) and 0:int(width='g):int(width='g)

~1
# CHECK-L: 1:int(width='h):int(width='h)

not 1
# CHECK-L: 1:int(width='i):bool

0 comments on commit c89bf6f

Please sign in to comment.