Пример #1
0
    def translate_AnnAssign(self, node: ast.AnnAssign, res: List[Expr],
                            ctx: Context):
        pos = self.to_position(node, ctx)

        self._add_local_var(node.target, ctx)
        lhs = ctx.all_vars[node.target.id]

        if node.value is None:
            vyper_type = node.target.type
            rhs = self.type_translator.default_value(None, vyper_type, res,
                                                     ctx)
        elif types.is_numeric(node.value.type):
            rhs = self.expression_translator.translate_top_level_expression(
                node.value, res, ctx)
        else:
            # Ignore the $wrap information, if the node is not numeric
            rhs = self.expression_translator.translate(node.value, res, ctx)

        if self.arithmetic_translator.is_wrapped(rhs):
            if types.is_numeric(node.value.type):
                lhs.new_idx()
                lhs.is_local = False
            else:
                rhs = helpers.w_unwrap(self.viper_ast, rhs)
        assign = self.viper_ast.EqCmp(lhs.local_var(ctx, pos), rhs, pos)
        expr = self.viper_ast.Implies(ctx.pure_conds, assign,
                                      pos) if ctx.pure_conds else assign
        res.append(expr)
Пример #2
0
 def assign_to_Name(self, node: ast.Name, value: Expr, res: List[Expr],
                    ctx: Context):
     pos = self.to_position(node, ctx)
     var = ctx.locals.get(node.id)
     w_value = value
     if var:
         if isinstance(var, TranslatedPureIndexedVar):
             var.new_idx()
         if (types.is_numeric(node.type) and not var.is_local
                 and self.expression_translator.arithmetic_translator.
                 is_unwrapped(value)):
             w_value = helpers.w_wrap(self.viper_ast, value)
         elif (types.is_numeric(node.type) and var.is_local
               and self.expression_translator.arithmetic_translator.
               is_wrapped(value)):
             var.is_local = False
         elif (types.is_numeric(node.type) and self._always_wrap
               and var.is_local and self.expression_translator.
               arithmetic_translator.is_unwrapped(value)):
             var.is_local = False
             w_value = helpers.w_wrap(self.viper_ast, value)
         elif (not types.is_numeric(node.type)
               and self.expression_translator.arithmetic_translator.
               is_wrapped(value)):
             w_value = helpers.w_unwrap(self.viper_ast, value)
     lhs = self.expression_translator.translate(node, res, ctx)
     assign = self.viper_ast.EqCmp(lhs, w_value, pos)
     expr = self.viper_ast.Implies(ctx.pure_conds, assign,
                                   pos) if ctx.pure_conds else assign
     res.append(expr)
Пример #3
0
 def _wrapped_decimal_div(self, lhs, rhs, pos=None, info=None) -> Expr:
     scaling_factor = self.viper_ast.IntLit(
         types.VYPER_DECIMAL.scaling_factor, pos)
     uw_lhs = helpers.w_unwrap(self.viper_ast, lhs, pos)
     uw_mult = self.viper_ast.Mul(uw_lhs, scaling_factor, pos)
     mult = helpers.w_wrap(self.viper_ast, uw_mult, pos)
     return helpers.w_div(self.viper_ast, mult, rhs, pos, info)
Пример #4
0
 def add_model_var(name, var_type, rhs, components):
     new_var_name = ctx.new_local_var_name(
         mangled.model_var_name(*components))
     vtype = self.type_translator.translate(var_type, ctx)
     new_var = self.viper_ast.LocalVarDecl(new_var_name, vtype, pos)
     ctx.new_local_vars.append(new_var)
     transform[new_var_name] = name
     type_map[new_var_name] = var_type
     if hasattr(rhs, 'isSubtype') and rhs.isSubtype(
             helpers.wrapped_int_type(self.viper_ast)):
         rhs = helpers.w_unwrap(self.viper_ast, rhs)
     res.append(
         self.viper_ast.LocalVarAssign(new_var.localVar(), rhs, pos))
Пример #5
0
    def translate_Return(self, node: ast.Return, res: List[Expr],
                         ctx: Context):
        assert node.value
        assert isinstance(ctx.result_var, TranslatedPureIndexedVar)
        assert isinstance(ctx.success_var, TranslatedPureIndexedVar)
        pos = self.to_position(node, ctx)

        expr = self.expression_translator.translate_top_level_expression(
            node.value, res, ctx)
        if (self.arithmetic_translator.is_unwrapped(
                ctx.result_var.local_var(ctx))
                and self.arithmetic_translator.is_wrapped(expr)):
            expr = helpers.w_unwrap(self.viper_ast, expr)

        ctx.result_var.new_idx()
        assign = self.viper_ast.EqCmp(ctx.result_var.local_var(ctx), expr, pos)
        expr = self.viper_ast.Implies(ctx.pure_conds, assign,
                                      pos) if ctx.pure_conds else assign
        res.append(expr)
        cond = ctx.pure_conds or self.viper_ast.TrueLit(pos)
        ctx.pure_returns.append((cond, ctx.result_var.evaluate_idx(ctx)))
        ctx.pure_success.append((cond, ctx.success_var.evaluate_idx(ctx)))
Пример #6
0
 def unwrap(a: Expr) -> Expr:
     if hasattr(a, 'isSubtype') and a.isSubtype(wrapped_int_type):
         nonlocal had_wrapped_integers
         had_wrapped_integers = True
         return helpers.w_unwrap(_self.viper_ast, a, pos, info)
     return a
Пример #7
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