示例#1
0
 def visit_Name(self, node: ast.Name, program: VyperProgram,
                function: VyperFunction):
     if self.inside_loop:
         with switch(node.id) as case:
             if case(names.MSG)\
                     or case(names.BLOCK)\
                     or case(names.CHAIN)\
                     or case(names.TX):
                 pass
             else:
                 self.used_names.add(node.id)
     self.generic_visit(node, program, function)
示例#2
0
    def visit_FunctionCall(self, node: ast.FunctionCall):
        args = [self.visit(arg) for arg in node.args]
        if node.name == names.MIN:
            return min(args)
        elif node.name == names.MAX:
            return max(args)
        elif node.name == names.CONVERT:
            arg = args[0]
            second_arg = node.args[1]
            assert isinstance(second_arg, ast.Name)
            type_name = second_arg.id
            if isinstance(arg, int):
                with switch(type_name) as case:
                    if case(names.BOOL):
                        return bool(arg)
                    elif case(names.DECIMAL):
                        return Decimal[10](value=arg)
                    elif (case(names.INT128) or case(names.UINT256)
                          or case(names.BYTES32)):
                        return arg
            elif isinstance(arg, Decimal):
                with switch(type_name) as case:
                    if case(names.BOOL):
                        # noinspection PyUnresolvedReferences
                        return bool(arg.scaled_value)
                    elif case(names.DECIMAL):
                        return arg
                    elif (case(names.INT128) or case(names.UINT256)
                          or case(names.BYTES32)):
                        # noinspection PyUnresolvedReferences
                        return div(arg.scaled_value, arg.scaling_factor)
            elif isinstance(arg, bool):
                with switch(type_name) as case:
                    if case(names.BOOL):
                        return arg
                    elif (case(names.DECIMAL) or case(names.INT128)
                          or case(names.UINT256) or case(names.BYTES32)):
                        return int(arg)

        raise UnsupportedException(node)
示例#3
0
    def visit_Comparison(self, node: ast.Comparison):
        lhs = self.visit(node.left)
        rhs = self.visit(node.right)

        with switch(node.op) as case:
            if case(ast.ComparisonOperator.LT):
                return lhs < rhs
            elif case(ast.ComparisonOperator.LTE):
                return lhs <= rhs
            elif case(ast.ComparisonOperator.GT):
                return lhs > rhs
            elif case(ast.ComparisonOperator.GTE):
                return lhs >= rhs
            else:
                assert False
示例#4
0
    def arithmetic_op(self,
                      lhs,
                      op: ast.ArithmeticOperator,
                      rhs,
                      otype: PrimitiveType,
                      res: List[Stmt],
                      ctx: Context,
                      pos=None) -> Expr:
        ast_op = ast.ArithmeticOperator
        left_is_wrapped = self.is_wrapped(lhs)
        right_is_wrapped = self.is_wrapped(rhs)
        if ctx.inside_interpreted:
            if left_is_wrapped:
                left_is_wrapped = False
                lhs = helpers.w_unwrap(self.viper_ast, lhs, pos)
            if right_is_wrapped:
                right_is_wrapped = False
                rhs = helpers.w_unwrap(self.viper_ast, rhs, pos)
        elif ctx.inside_lemma:
            if not left_is_wrapped:
                left_is_wrapped = True
                lhs = helpers.w_wrap(self.viper_ast, lhs, pos)
            if not right_is_wrapped:
                right_is_wrapped = True
                rhs = helpers.w_wrap(self.viper_ast, rhs, pos)
        with switch(op, otype) as case:
            from twovyper.utils import _

            if (case(ast_op.DIV, _)
                    or case(ast_op.MOD, _)) and not self.no_reverts:
                expr = rhs
                if right_is_wrapped:
                    expr = helpers.w_unwrap(self.viper_ast, rhs, pos)
                cond = self.viper_ast.EqCmp(expr,
                                            self.viper_ast.IntLit(0, pos), pos)
                self.fail_if(cond, [], res, ctx, pos)

            if left_is_wrapped and right_is_wrapped:
                # Both are wrapped
                if case(ast_op.MUL, types.VYPER_DECIMAL):
                    expr = self._wrapped_decimal_mul(lhs, rhs, pos)
                elif case(ast_op.DIV, types.VYPER_DECIMAL):
                    expr = self._wrapped_decimal_div(lhs, rhs, pos)
                else:
                    expr = self._wrapped_arithmetic_ops[op](lhs, rhs, pos)
            else:
                if case(ast_op.MUL, types.VYPER_DECIMAL):
                    expr = self._decimal_mul(lhs, rhs, pos)
                elif case(ast_op.DIV, types.VYPER_DECIMAL):
                    expr = self._decimal_div(lhs, rhs, pos)
                else:
                    expr = self._arithmetic_ops[op](lhs, rhs, pos)

        if types.is_bounded(otype):
            assert isinstance(otype, BoundedType)
            if is_compatible_version('<=0.1.0-beta.17') and op == ast_op.POW:
                # In certain versions of Vyper there was no overflow check for POW.
                self.check_underflow(expr, otype, res, ctx, pos)
            else:
                self.check_under_overflow(expr, otype, res, ctx, pos)

        return expr