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