Skip to content

Commit 0d3ad73

Browse files
authored
Merge pull request #2 from algorand/add-cond
add Cond operator
2 parents f2ee277 + ae168d7 commit 0d3ad73

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

pyteal/ops.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,3 +855,72 @@ def __str__(self):
855855

856856
def type_of(self):
857857
return self.child.type_of()
858+
859+
860+
class Err(LeafExpr):
861+
"""
862+
only used internally, not a user facing operator
863+
"""
864+
865+
#default constructor
866+
def __init__(self):
867+
pass
868+
869+
def __teal__(self):
870+
return [["err"]]
871+
872+
def __str__(self):
873+
return "(err)"
874+
875+
def type_of(self):
876+
return TealType.anytype
877+
878+
879+
class Cond(NaryExpr):
880+
881+
# default constructor
882+
def __init__(self, *argv):
883+
884+
if len(argv) < 1:
885+
raise TealInputError("Cond requires at least one [condition, value]")
886+
887+
value_type = 0
888+
889+
for arg in argv:
890+
msg = "Cond should be in the form of Cond([cond1, value1], [cond2, value2], ...), error in {}"
891+
if not isinstance(arg, list):
892+
raise TealInputError(msg.format(arg))
893+
if len(arg) != 2:
894+
raise TealInputError(msg.format(arg))
895+
896+
require_type(arg[0].type_of(), TealType.uint64) # cond_n should be int
897+
898+
if value_type == 0: # the types of all branches should be the same
899+
value_type = arg[1].type_of()
900+
else:
901+
require_type(arg[1].type_of(), value_type)
902+
903+
self.value_type = value_type
904+
self.args = argv
905+
906+
def __teal__(self):
907+
# converting cond to ite first
908+
def make_ite(conds):
909+
if len(conds) == 0:
910+
return Err()
911+
else:
912+
e = conds[0]
913+
return Ite(e[0], e[1], make_ite(conds[1:]))
914+
915+
desugared = make_ite(self.args)
916+
return desugared.__teal__()
917+
918+
def __str__(self):
919+
ret_str = "(Cond"
920+
for a in self.args:
921+
ret_str += " [" + a[0].__str__() + ", " + a[1].__str__() + "]"
922+
ret_str += ")"
923+
return ret_str
924+
925+
def type_of(self):
926+
return self.value_type

pyteal/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def __str__(self):
4141

4242

4343
def require_type(actual, expected):
44-
if actual != expected:
44+
if actual != expected and (actual != TealType.anytype) and (expected != TealType.anytype):
4545
raise TealTypeError(actual, expected)
4646

4747

tests/test_ops.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,17 @@ def test_nonce():
268268

269269
with pytest.raises(TealInputError):
270270
Nonce("base16", "7Z5PWO2C6LFNQFGHWKSK5H47IQP5OJW2M3HA2QPXTY3WTNP5NU2MHBW27M", Int(1))
271+
272+
273+
def test_cond():
274+
Cond([Int(1), Int(2)], [Int(0), Int(2)])
275+
Cond([Int(1), Int(2)])
276+
Cond([Int(1), Int(2)], [Int(2), Int(3)], [Int(3), Int(4)])
277+
278+
with pytest.raises(TealTypeError):
279+
Cond([Int(1), Int(2)],
280+
[Int(2), Txn.receiver()])
281+
282+
with pytest.raises(TealTypeError):
283+
Cond([Arg(0), Int(2)])
284+

0 commit comments

Comments
 (0)