-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathbool.py
104 lines (91 loc) · 3.24 KB
/
bool.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import typing
from collections.abc import Sequence
import mypy.nodes
from puya import log
from puya.awst.nodes import (
BinaryBooleanOperator,
BoolConstant,
BooleanBinaryOperation,
Expression,
Not,
NumericComparison,
NumericComparisonExpression,
)
from puya.parse import SourceLocation
from puyapy.awst_build import intrinsic_factory, pytypes
from puyapy.awst_build.eb import _expect as expect
from puyapy.awst_build.eb._base import NotIterableInstanceExpressionBuilder
from puyapy.awst_build.eb.interface import (
BuilderComparisonOp,
InstanceBuilder,
LiteralBuilder,
NodeBuilder,
TypeBuilder,
)
logger = log.get_logger(__name__)
class BoolTypeBuilder(TypeBuilder):
def __init__(self, location: SourceLocation):
super().__init__(pytypes.BoolType, location)
@typing.override
def try_convert_literal(
self, literal: LiteralBuilder, location: SourceLocation
) -> InstanceBuilder | None:
match literal.value:
case bool(literal_value):
expr = BoolConstant(value=literal_value, source_location=location)
return BoolExpressionBuilder(expr)
return None
@typing.override
def call(
self,
args: Sequence[NodeBuilder],
arg_kinds: list[mypy.nodes.ArgKind],
arg_names: list[str | None],
location: SourceLocation,
) -> InstanceBuilder:
arg = expect.at_most_one_arg(args, location)
match arg:
case None:
false = BoolConstant(value=False, source_location=location)
return BoolExpressionBuilder(false)
case InstanceBuilder(pytype=pytypes.BoolType):
return arg
case _:
return arg.bool_eval(location)
class BoolExpressionBuilder(NotIterableInstanceExpressionBuilder):
def __init__(self, expr: Expression):
super().__init__(pytypes.BoolType, expr)
@typing.override
def to_bytes(self, location: SourceLocation) -> Expression:
return intrinsic_factory.itob(self.resolve(), location)
@typing.override
def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> InstanceBuilder:
if not negate:
return self
return BoolExpressionBuilder(Not(location, self.resolve()))
@typing.override
def compare(
self, other: InstanceBuilder, op: BuilderComparisonOp, location: SourceLocation
) -> InstanceBuilder:
if other.pytype != pytypes.BoolType:
return NotImplemented
cmp_expr = NumericComparisonExpression(
source_location=location,
lhs=self.resolve(),
operator=NumericComparison(op.value),
rhs=other.resolve(),
)
return BoolExpressionBuilder(cmp_expr)
@typing.override
def bool_binary_op(
self, other: InstanceBuilder, op: BinaryBooleanOperator, location: SourceLocation
) -> InstanceBuilder:
if other.pytype != pytypes.BoolType:
return super().bool_binary_op(other, op, location)
result = BooleanBinaryOperation(
left=self.resolve(),
op=op,
right=other.resolve(),
source_location=location,
)
return BoolExpressionBuilder(result)