コード例 #1
0
ファイル: common.py プロジェクト: marcoeilers/nagini
 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
コード例 #2
0
ファイル: common.py プロジェクト: marcoeilers/nagini
 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
コード例 #3
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
コード例 #4
0
ファイル: common.py プロジェクト: marcoeilers/nagini
 def _combine_names(self, prefix: Expr, name: Expr, pos: Position, info: Info) -> Expr:
     """
     Returns an expression that combines the prefix-name and the name to a new name
     that represents 'prefix.name'.
     """
     name_type = self.viper.DomainType(NAME_DOMAIN, {}, [])
     if name.typ() == self.viper.Int:
         boxed_name = self.viper.DomainFuncApp(SINGLE_NAME, [name], name_type, pos,
                                               info, NAME_DOMAIN)
     else:
         boxed_name = name
     if prefix.typ() == self.viper.Int:
         boxed_prefix = self.viper.DomainFuncApp(SINGLE_NAME, [prefix], name_type, pos,
                                                 info, NAME_DOMAIN)
     else:
         boxed_prefix = prefix
     return self.viper.DomainFuncApp(COMBINE_NAME_FUNC, [boxed_prefix, boxed_name],
                                     name_type, pos, info, NAME_DOMAIN)
コード例 #5
0
ファイル: common.py プロジェクト: marcoeilers/nagini
 def _is_defined(self, name: Expr, module: Expr, pos: Position, info: Info) -> Expr:
     """
     Returns an expression that is true iff the name represented by the given
     expression is defined in the module represented by the other expression.
     """
     name_type = self.viper.DomainType(NAME_DOMAIN, {}, [])
     if name.typ() == self.viper.Int:
         boxed_name = self.viper.DomainFuncApp(SINGLE_NAME, [name], name_type, pos,
                                               info, NAME_DOMAIN)
     else:
         boxed_name = name
     return self.viper.AnySetContains(boxed_name, module, pos, info)
コード例 #6
0
ファイル: common.py プロジェクト: marcoeilers/nagini
 def _set_global_defined(self, decl_int: Expr, module_var: Expr, pos: Position,
                         info: Info) -> Stmt:
     """
     Returns a statement that sets the name of represented by the integer decl_int to
     be defined in the given set of names.
     """
     if decl_int.typ() == self.viper.Int:
         decl_int = self.viper.DomainFuncApp(SINGLE_NAME, [decl_int], self.name_type(),
                                             pos, info, NAME_DOMAIN)
     new_set = self.viper.ExplicitSet([decl_int], pos, info)
     union = self.viper.AnySetUnion(module_var, new_set, pos, info)
     return self.viper.LocalVarAssign(module_var, union, pos, info)