Ejemplo n.º 1
0
 def to_ref(self, e: Expr, ctx: Context) -> Expr:
     """
     Converts the given expression to an expression of the Silver type Ref
     if it isn't already, either by boxing a primitive or undoing a
     previous unboxing operation.
     """
     # Avoid wrapping non-pure expressions (leads to errors within Silver's
     # Consistency object)
     if not self._is_pure(e):
         return e
     result = e
     if e.typ() == self.viper.Int:
         if (isinstance(e, self.viper.ast.FuncApp) and
                 e.funcname() == 'int___unbox__'):
             result = e.args().head()
         else:
             prim_int = ctx.module.global_module.classes[PRIMITIVE_INT_TYPE]
             result = self.get_function_call(prim_int, '__box__',
                                             [result], [None], None, ctx,
                                             position=e.pos())
     elif e.typ() == self.viper.Bool:
         if (isinstance(e, self.viper.ast.FuncApp) and
                 e.funcname() == 'bool___unbox__'):
             result = e.args().head()
         else:
             prim_bool = ctx.module.global_module.classes[PRIMITIVE_BOOL_TYPE]
             result = self.get_function_call(prim_bool, '__box__',
                                             [result], [None], None, ctx,
                                             position=e.pos())
     return result
Ejemplo n.º 2
0
 def to_bool(self, e: Expr, ctx: Context, node: ast.AST = None) -> Expr:
     """
     Converts the given expression to an expression of the Silver type Bool
     if it isn't already, either by calling __bool__ on an object and
     possibly unboxing the result, or by undoing a previous boxing operation.
     """
     # Avoid wrapping non-pure expressions (leads to errors within Silver's
     # Consistency object)
     if not self._is_pure(e):
         return e
     if e.typ() == self.viper.Bool:
         return e
     if e.typ() != self.viper.Ref:
         e = self.to_ref(e, ctx)
     if (isinstance(e, self.viper.ast.FuncApp) and
             e.funcname() == '__prim__bool___box__'):
         return e.args().head()
     result = e
     call_bool = True
     if node:
         node_type = self.get_type(node, ctx)
         if node_type.name == 'bool':
             call_bool = False
         if call_bool:
             result = self.get_function_call(node_type, '__bool__',
                                             [result], [None], node, ctx,
                                             position=e.pos())
     if result.typ() != self.viper.Bool:
         bool_type = ctx.module.global_module.classes['bool']
         result = self.get_function_call(bool_type, '__unbox__',
                                         [result], [None], node, ctx,
                                         position=e.pos())
     return result
Ejemplo n.º 3
0
 def get_sequence(self,
                  receiver: PythonType,
                  arg: Expr,
                  arg_type: PythonType,
                  node: ast.AST,
                  ctx: Context,
                  position: Position = None) -> Expr:
     """
     Returns a sequence (Viper type Seq[Ref]) representing the contents of arg.
     Defaults to type___sil_seq__, but used simpler expressions for known types
     to improve performance/triggering.
     """
     position = position if position else self.to_position(node, ctx)
     info = self.no_info(ctx)
     if not isinstance(receiver, UnionType) or isinstance(
             receiver, OptionalType):
         if receiver.name == LIST_TYPE:
             seq_ref = self.viper.SeqType(self.viper.Ref)
             field = self.viper.Field('list_acc', seq_ref, position, info)
             res = self.viper.FieldAccess(arg, field, position, info)
             return res
         if receiver.name == PSEQ_TYPE:
             if (isinstance(arg, self.viper.ast.FuncApp)
                     and arg.funcname() == 'PSeq___create__'):
                 args = self.viper.to_list(arg.args())
                 return args[0]
     return self.get_function_call(receiver, '__sil_seq__', [arg],
                                   [arg_type], node, ctx, position)
Ejemplo n.º 4
0
 def to_int(self, e: Expr, ctx: Context) -> Expr:
     """
     Converts the given expression to an expression of the Silver type Int
     if it isn't already, either by unboxing a reference or undoing a
     previous boxing operation.
     """
     # Avoid wrapping non-pure expressions (leads to errors within Silver's
     # Consistency object)
     if not self._is_pure(e):
         return e
     if e.typ() == self.viper.Int:
         return e
     if e.typ() != self.viper.Ref:
         e = self.to_ref(e, ctx)
     if (isinstance(e, self.viper.ast.FuncApp)
             and e.funcname() == '__prim__int___box__'):
         return e.args().head()
     result = e
     int_type = ctx.module.global_module.classes[INT_TYPE]
     result = self.get_function_call(int_type,
                                     '__unbox__', [result], [None],
                                     None,
                                     ctx,
                                     position=e.pos())
     return result
Ejemplo n.º 5
0
 def unwrap(self, e: Expr) -> Expr:
     if isinstance(e, self.viper.ast.FuncApp):
         if (e.funcname().endswith('__box__') or
                 e.funcname().endswith('__unbox__')):
             return e.args().head()
     return e