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
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
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