コード例 #1
0
 def types_from_Compare(self, node):
     # comparison: `x < y`
     if isinstance(node.op, vy_ast.In):
         # x in y
         left = self.get_possible_types_from_node(node.left)
         right = self.get_possible_types_from_node(node.right)
         if next((i for i in left if isinstance(i, ArrayDefinition)),
                 False):
             raise InvalidOperation(
                 "Left operand in membership comparison cannot be Array type",
                 node.left,
             )
         if next((i for i in right if not isinstance(i, ArrayDefinition)),
                 False):
             raise InvalidOperation(
                 "Right operand must be Array for membership comparison",
                 node.right)
         types_list = [
             i for i in left
             if _is_type_in_list(i, [i.value_type for i in right])
         ]
         if not types_list:
             raise TypeMismatch(
                 "Cannot perform membership comparison between dislike types",
                 node)
     else:
         types_list = get_common_types(node.left, node.right)
         _validate_op(node, types_list, "validate_comparator")
     return [BoolDefinition()]
コード例 #2
0
ファイル: numeric.py プロジェクト: MaxIsWell42/MakeCards
    def validate_numeric_op(
            self, node: Union[vy_ast.UnaryOp, vy_ast.BinOp,
                              vy_ast.AugAssign]) -> None:
        if self._invalid_op and isinstance(node.op, self._invalid_op):
            raise InvalidOperation(
                f"Cannot perform {node.op.description} on {self}", node)

        if isinstance(node.op, vy_ast.Pow):
            if isinstance(node, vy_ast.BinOp):
                left, right = node.left, node.right
            elif isinstance(node, vy_ast.AugAssign):
                left, right = node.target, node.value
            else:
                raise CompilerPanic(
                    f"Unexpected node type for numeric op: {type(node).__name__}"
                )

            value_bits = self._bits - (1 if self._is_signed else 0)

            # constant folding ensures one of `(left, right)` is never a literal
            if isinstance(left, vy_ast.Int):
                if left.value >= 2**value_bits:
                    raise OverflowException(
                        "Base is too large, calculation will always overflow",
                        left)
                elif left.value < -(2**value_bits):
                    raise OverflowException(
                        "Base is too small, calculation will always underflow",
                        left)
            elif isinstance(right, vy_ast.Int):
                if right.value < 0:
                    raise InvalidOperation("Cannot calculate a negative power",
                                           right)
                if right.value > value_bits:
                    raise OverflowException(
                        "Power is too large, calculation will always overflow",
                        right)
            else:
                msg = (
                    "Cannot apply an overflow check on exponentiation when both "
                    "the base and power are unknown at compile-time.")
                if not self._is_signed:
                    msg = (
                        f"{msg} To perform this operation without an overflow check, use "
                        f"`pow_mod256({left.node_source_code}, {right.node_source_code})`"
                    )
                raise InvalidOperation(msg, node)
コード例 #3
0
 def _op(self, left, right):
     if isinstance(left, decimal.Decimal):
         raise TypeMismatch(
             "Cannot perform exponentiation on decimal values.",
             self._parent)
     if right < 0:
         raise InvalidOperation("Cannot calculate a negative power",
                                self._parent)
     return int(left**right)
コード例 #4
0
ファイル: bases.py プロジェクト: sambacha/vyper-xcode
    def validate_boolean_op(self, node: vy_ast.BoolOp) -> None:
        """
        Validate a boolean operation for this type.

        Arguments
        ---------
        node : BoolOp
            Vyper ast node of the boolean operation to be validated.

        Returns
        -------
        None. A failed validation must raise an exception.
        """
        raise InvalidOperation(f"Invalid type for operand: {self}", node)
コード例 #5
0
ファイル: utils.py プロジェクト: vyperlang/vyper
    def types_from_Compare(self, node):
        # comparisons, e.g. `x < y`

        # TODO fixme circular import
        from vyper.semantics.types.user.enum import EnumDefinition

        if isinstance(node.op, (vy_ast.In, vy_ast.NotIn)):
            # x in y
            left = self.get_possible_types_from_node(node.left)
            right = self.get_possible_types_from_node(node.right)
            if any(isinstance(t, EnumDefinition) for t in left):
                types_list = get_common_types(node.left, node.right)
                _validate_op(node, types_list, "validate_comparator")
                return [BoolDefinition()]

            if any(isinstance(i, ArrayDefinition) for i in left):
                raise InvalidOperation(
                    "Left operand in membership comparison cannot be Array type",
                    node.left)
            if any(not isinstance(i, (DynamicArrayDefinition, ArrayDefinition))
                   for i in right):
                raise InvalidOperation(
                    "Right operand must be Array for membership comparison",
                    node.right)
            types_list = [
                i for i in left
                if _is_type_in_list(i, [i.value_type for i in right])
            ]
            if not types_list:
                raise TypeMismatch(
                    "Cannot perform membership comparison between dislike types",
                    node)
        else:
            types_list = get_common_types(node.left, node.right)
            _validate_op(node, types_list, "validate_comparator")
        return [BoolDefinition()]
コード例 #6
0
ファイル: bases.py プロジェクト: benjyz/vyper
    def validate_numeric_op(
        self, node: Union[vy_ast.UnaryOp, vy_ast.BinOp, vy_ast.AugAssign]
    ) -> None:
        """
        Validate a numeric operation for this type.

        Arguments
        ---------
        node : UnaryOp | BinOp | AugAssign
            Vyper ast node of the numeric operation to be validated.

        Returns
        -------
        None. A failed validation must raise an exception.
        """
        raise InvalidOperation(f"Cannot perform {node.op.description} on {self}", node)
コード例 #7
0
ファイル: bases.py プロジェクト: sambacha/vyper-xcode
    def validate_comparator(self, node: vy_ast.Compare) -> None:
        """
        Validate a comparator for this type.

        Arguments
        ---------
        node : Compare
            Vyper ast node of the comparator to be validated.

        Returns
        -------
        None. A failed validation must raise an exception.
        """
        if not isinstance(node.op, (vy_ast.Eq, vy_ast.NotEq)):
            raise InvalidOperation(
                f"Cannot perform {node.op.description} comparison on {self}",
                node)
コード例 #8
0
ファイル: utils.py プロジェクト: saliksyed/vyper
def _validate_op(node, types_list, validation_fn_name):
    if not types_list:
        raise TypeMismatch(f"Cannot perform {node.op.description} between dislike types", node)

    if len(types_list) == 1:
        getattr(types_list[0], validation_fn_name)(node)
        return types_list

    for type_ in types_list.copy():
        try:
            getattr(type_, validation_fn_name)(node)
        except InvalidOperation:
            types_list.remove(type_)

    if types_list:
        return types_list
    raise InvalidOperation(f"Cannot perform {node.op.description} on value", node)
コード例 #9
0
ファイル: bases.py プロジェクト: sambacha/vyper-xcode
 def validate_modification(
         cls, node: Union[vy_ast.Assign, vy_ast.AugAssign]) -> None:
     # always raises - do not implement in inherited classes
     raise InvalidOperation("Cannot assign to a type", node)