From 23f33d7239d318674e5fa050f8c51592f82a053f Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 13 Jun 2015 13:45:09 +0300 Subject: [PATCH] Invert operand should be integer. --- artiq/py2llvm/builtins.py | 6 ++++++ artiq/py2llvm/typing.py | 18 ++++++++++++++---- lit-test/py2llvm/typing/error_unify.py | 7 +++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/artiq/py2llvm/builtins.py b/artiq/py2llvm/builtins.py index e898eed28..c547ef374 100644 --- a/artiq/py2llvm/builtins.py +++ b/artiq/py2llvm/builtins.py @@ -58,6 +58,12 @@ class TList(types.TMono): 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') diff --git a/artiq/py2llvm/typing.py b/artiq/py2llvm/typing.py index db00cdcb8..33e8c4dc2 100644 --- a/artiq/py2llvm/typing.py +++ b/artiq/py2llvm/typing.py @@ -389,16 +389,26 @@ class Inferencer(algorithm.Visitor): 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() + 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 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 operand to be of numeric type, not {type}", - {"type": types.TypePrinter().name(operand_type)}, + "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) diff --git a/lit-test/py2llvm/typing/error_unify.py b/lit-test/py2llvm/typing/error_unify.py index 8f0faf23a..73641b8c6 100644 --- a/lit-test/py2llvm/typing/error_unify.py +++ b/lit-test/py2llvm/typing/error_unify.py @@ -17,5 +17,8 @@ a = b # 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