def test_cond_two_pred(): expr = pt.Cond([pt.Int(1), pt.Bytes("one")], [pt.Int(0), pt.Bytes("zero")]) assert expr.type_of() == pt.TealType.bytes cond1, _ = pt.Int(1).__teal__(options) pred1, _ = pt.Bytes("one").__teal__(options) cond1Branch = pt.TealConditionalBlock([]) cond2, _ = pt.Int(0).__teal__(options) pred2, _ = pt.Bytes("zero").__teal__(options) cond2Branch = pt.TealConditionalBlock([]) end = pt.TealSimpleBlock([]) cond1.setNextBlock(cond1Branch) cond1Branch.setTrueBlock(pred1) cond1Branch.setFalseBlock(cond2) pred1.setNextBlock(end) cond2.setNextBlock(cond2Branch) cond2Branch.setTrueBlock(pred2) cond2Branch.setFalseBlock(pt.Err().__teal__(options)[0]) pred2.setNextBlock(end) expected = cond1 actual, _ = expr.__teal__(options) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_sort_multiple_branch(): blockTrueTrue = pt.TealSimpleBlock( [pt.TealOp(None, pt.Op.byte, '"true true"')]) blockTrueFalse = pt.TealSimpleBlock( [pt.TealOp(None, pt.Op.byte, '"true false"')]) blockTrueBranch = pt.TealConditionalBlock([]) blockTrueBranch.setTrueBlock(blockTrueTrue) blockTrueBranch.setFalseBlock(blockTrueFalse) blockTrue = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]) blockTrue.setNextBlock(blockTrueBranch) blockFalse = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) block = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) block.setTrueBlock(blockTrue) block.setFalseBlock(blockFalse) block.addIncoming() block.validateTree() expected = [ block, blockTrue, blockTrueBranch, blockTrueFalse, blockTrueTrue, blockFalse, ] actual = sortBlocks(block, blockFalse) assert actual == expected
def test_outgoing(): emptyBlock = pt.TealConditionalBlock([]) assert emptyBlock.getOutgoing() == [] trueBlock = pt.TealConditionalBlock([]) trueBlock.setTrueBlock(pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')])) assert trueBlock.getOutgoing() == [ pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]) ] falseBlock = pt.TealConditionalBlock([]) falseBlock.setFalseBlock( pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) ) assert falseBlock.getOutgoing() == [ pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) ] bothBlock = pt.TealConditionalBlock([]) bothBlock.setTrueBlock(pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')])) bothBlock.setFalseBlock( pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) ) assert bothBlock.getOutgoing() == [ pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]), pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]), ]
def test_normalize_branch_converge(): blockEnd = pt.TealSimpleBlock([]) blockTrueNext = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.int, 4)]) blockTrueNext.setNextBlock(blockEnd) blockTrue = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]) blockTrue.setNextBlock(blockTrueNext) blockFalse = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) blockFalse.setNextBlock(blockEnd) blockBranch = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) blockBranch.setTrueBlock(blockTrue) blockBranch.setFalseBlock(blockFalse) original = pt.TealSimpleBlock([]) original.setNextBlock(blockBranch) expectedEnd = pt.TealSimpleBlock([]) expectedTrue = pt.TealSimpleBlock( [pt.TealOp(None, pt.Op.byte, '"true"'), pt.TealOp(None, pt.Op.int, 4)]) expectedTrue.setNextBlock(expectedEnd) expectedFalse = pt.TealSimpleBlock( [pt.TealOp(None, pt.Op.byte, '"false"')]) expectedFalse.setNextBlock(expectedEnd) expected = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) expected.setTrueBlock(expectedTrue) expected.setFalseBlock(expectedFalse) original.addIncoming() actual = pt.TealBlock.NormalizeBlocks(original) actual.validateTree() assert actual == expected
def test_iterate_multiple_branch(): blockTrueTrue = pt.TealSimpleBlock( [pt.TealOp(None, pt.Op.byte, '"true true"')]) blockTrueFalse = pt.TealSimpleBlock( [pt.TealOp(None, pt.Op.byte, '"true false"')]) blockTrueBranch = pt.TealConditionalBlock([]) blockTrueBranch.setTrueBlock(blockTrueTrue) blockTrueBranch.setFalseBlock(blockTrueFalse) blockTrue = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]) blockTrue.setNextBlock(blockTrueBranch) blockFalse = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) block = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) block.setTrueBlock(blockTrue) block.setFalseBlock(blockFalse) blocks = list(pt.TealBlock.Iterate(block)) assert blocks == [ block, blockTrue, blockFalse, blockTrueBranch, blockTrueTrue, blockTrueFalse, ]
def test_constructor(): block1 = pt.TealConditionalBlock([]) assert block1.ops == [] assert block1.trueBlock is None assert block1.falseBlock is None block2 = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) assert block2.ops == [pt.TealOp(None, pt.Op.int, 1)] assert block2.trueBlock is None assert block2.falseBlock is None
def test_flattenBlocks_multiple_branch_converge(): blockEnd = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.return_)]) blockTrueTrue = pt.TealSimpleBlock( [pt.TealOp(None, pt.Op.byte, '"true true"')]) blockTrueTrue.setNextBlock(blockEnd) blockTrueFalse = pt.TealSimpleBlock([ pt.TealOp(None, pt.Op.byte, '"true false"'), pt.TealOp(None, pt.Op.err) ]) blockTrueBranch = pt.TealConditionalBlock([]) blockTrueBranch.setTrueBlock(blockTrueTrue) blockTrueBranch.setFalseBlock(blockTrueFalse) blockTrue = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]) blockTrue.setNextBlock(blockTrueBranch) blockFalse = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) blockFalse.setNextBlock(blockEnd) block = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) block.setTrueBlock(blockTrue) block.setFalseBlock(blockFalse) block.addIncoming() block.validateTree() blocks = [ block, blockFalse, blockTrue, blockTrueBranch, blockTrueFalse, blockTrueTrue, blockEnd, ] expected = [ pt.TealOp(None, pt.Op.int, 1), pt.TealOp(None, pt.Op.bnz, pt.LabelReference("l2")), pt.TealOp(None, pt.Op.byte, '"false"'), pt.TealOp(None, pt.Op.b, pt.LabelReference("l6")), pt.TealLabel(None, pt.LabelReference("l2")), pt.TealOp(None, pt.Op.byte, '"true"'), pt.TealOp(None, pt.Op.bnz, pt.LabelReference("l5")), pt.TealOp(None, pt.Op.byte, '"true false"'), pt.TealOp(None, pt.Op.err), pt.TealLabel(None, pt.LabelReference("l5")), pt.TealOp(None, pt.Op.byte, '"true true"'), pt.TealLabel(None, pt.LabelReference("l6")), pt.TealOp(None, pt.Op.return_), ] actual = flattenBlocks(blocks) assert actual == expected
def test_while_break(): i = pt.ScratchVar() i.store(pt.Int(0)) items = [ i.load() < pt.Int(2), i.store(i.load() + pt.Int(1)), pt.If(i.load() == pt.Int(1), pt.Break()), ] expr = pt.While(items[0]).Do(pt.Seq(items[1], items[2])) assert expr.type_of() == pt.TealType.none assert not expr.has_return() options.enterLoop() expected, condEnd = items[0].__teal__(options) do, doEnd = pt.Seq([items[1], items[2]]).__teal__(options) expectedBranch = pt.TealConditionalBlock([]) end = pt.TealSimpleBlock([]) expectedBranch.setTrueBlock(do) expectedBranch.setFalseBlock(end) condEnd.setNextBlock(expectedBranch) doEnd.setNextBlock(expected) breakBlocks, _ = options.exitLoop() for block in breakBlocks: block.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_for(): i = pt.ScratchVar() items = [ (i.store(pt.Int(0))), i.load() < pt.Int(10), i.store(i.load() + pt.Int(1)), pt.App.globalPut(pt.Itob(i.load()), i.load() * pt.Int(2)), ] expr = pt.For(items[0], items[1], items[2]).Do(pt.Seq([items[3]])) assert expr.type_of() == pt.TealType.none assert not expr.has_return() expected, varEnd = items[0].__teal__(options) condStart, condEnd = items[1].__teal__(options) stepStart, stepEnd = items[2].__teal__(options) do, doEnd = pt.Seq([items[3]]).__teal__(options) expectedBranch = pt.TealConditionalBlock([]) end = pt.TealSimpleBlock([]) varEnd.setNextBlock(condStart) doEnd.setNextBlock(stepStart) expectedBranch.setTrueBlock(do) expectedBranch.setFalseBlock(end) condEnd.setNextBlock(expectedBranch) stepEnd.setNextBlock(condStart) actual, _ = expr.__teal__(options) assert actual == expected
def test_true_block(): block = pt.TealConditionalBlock([]) block.setTrueBlock(pt.TealSimpleBlock([pt.TealOp(None, pt.Op.substring3)])) assert block.trueBlock == pt.TealSimpleBlock([pt.TealOp(None, pt.Op.substring3)]) assert block.getOutgoing() == [ pt.TealSimpleBlock([pt.TealOp(None, pt.Op.substring3)]) ]
def test_elseif_multiple(): args = [pt.Int(0), pt.Int(1), pt.Int(2), pt.Int(3), pt.Int(4), pt.Int(5), pt.Int(6)] expr = ( pt.If(args[0]) .Then(args[1]) .ElseIf(args[2]) .Then(args[3]) .ElseIf(args[4]) .Then(args[5]) .Else(args[6]) ) assert expr.type_of() == pt.TealType.uint64 elseIfExpr = pt.If(args[2], args[3], pt.If(args[4], args[5], args[6])) expected, _ = args[0].__teal__(options) thenBlock, _ = args[1].__teal__(options) elseStart, elseEnd = elseIfExpr.__teal__(options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(thenBlock) expectedBranch.setFalseBlock(elseStart) expected.setNextBlock(expectedBranch) end = pt.TealSimpleBlock([]) thenBlock.setNextBlock(end) elseEnd.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_flattenBlocks_branch(): blockTrue = pt.TealSimpleBlock([ pt.TealOp(None, pt.Op.byte, '"true"'), pt.TealOp(None, pt.Op.return_) ]) blockFalse = pt.TealSimpleBlock([ pt.TealOp(None, pt.Op.byte, '"false"'), pt.TealOp(None, pt.Op.return_) ]) block = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) block.setTrueBlock(blockTrue) block.setFalseBlock(blockFalse) block.addIncoming() block.validateTree() blocks = [block, blockFalse, blockTrue] expected = [ pt.TealOp(None, pt.Op.int, 1), pt.TealOp(None, pt.Op.bnz, pt.LabelReference("l2")), pt.TealOp(None, pt.Op.byte, '"false"'), pt.TealOp(None, pt.Op.return_), pt.TealLabel(None, pt.LabelReference("l2")), pt.TealOp(None, pt.Op.byte, '"true"'), pt.TealOp(None, pt.Op.return_), ] actual = flattenBlocks(blocks) assert actual == expected
def test_iterate_branch_converge(): blockEnd = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.return_)]) blockTrue = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]) blockTrue.setNextBlock(blockEnd) blockFalse = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) blockFalse.setNextBlock(blockEnd) block = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) block.setTrueBlock(blockTrue) block.setFalseBlock(blockFalse) blocks = list(pt.TealBlock.Iterate(block)) assert blocks == [block, blockTrue, blockFalse, blockEnd]
def test_cond_three_pred(): expr = pt.Cond([pt.Int(1), pt.Int(2)], [pt.Int(3), pt.Int(4)], [pt.Int(5), pt.Int(6)]) assert expr.type_of() == pt.TealType.uint64 cond1, _ = pt.Int(1).__teal__(options) pred1, _ = pt.Int(2).__teal__(options) cond1Branch = pt.TealConditionalBlock([]) cond2, _ = pt.Int(3).__teal__(options) pred2, _ = pt.Int(4).__teal__(options) cond2Branch = pt.TealConditionalBlock([]) cond3, _ = pt.Int(5).__teal__(options) pred3, _ = pt.Int(6).__teal__(options) cond3Branch = pt.TealConditionalBlock([]) end = pt.TealSimpleBlock([]) cond1.setNextBlock(cond1Branch) cond1Branch.setTrueBlock(pred1) cond1Branch.setFalseBlock(cond2) pred1.setNextBlock(end) cond2.setNextBlock(cond2Branch) cond2Branch.setTrueBlock(pred2) cond2Branch.setFalseBlock(cond3) pred2.setNextBlock(end) cond3.setNextBlock(cond3Branch) cond3Branch.setTrueBlock(pred3) cond3Branch.setFalseBlock(pt.Err().__teal__(options)[0]) pred3.setNextBlock(end) expected = cond1 actual, _ = expr.__teal__(options) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_cond_two_pred_multi(): args = [ pt.Int(1), [pt.Pop(pt.Int(1)), pt.Bytes("one")], pt.Int(0), [pt.Pop(pt.Int(2)), pt.Bytes("zero")], ] expr = pt.Cond( [args[0]] + args[1], [args[2]] + args[3], ) assert expr.type_of() == pt.TealType.bytes cond1, _ = args[0].__teal__(options) pred1, pred1End = pt.Seq(args[1]).__teal__(options) cond1Branch = pt.TealConditionalBlock([]) cond2, _ = args[2].__teal__(options) pred2, pred2End = pt.Seq(args[3]).__teal__(options) cond2Branch = pt.TealConditionalBlock([]) end = pt.TealSimpleBlock([]) cond1.setNextBlock(cond1Branch) cond1Branch.setTrueBlock(pred1) cond1Branch.setFalseBlock(cond2) pred1End.setNextBlock(end) cond2.setNextBlock(cond2Branch) cond2Branch.setTrueBlock(pred2) cond2Branch.setFalseBlock(pt.Err().__teal__(options)[0]) pred2End.setNextBlock(end) expected = cond1 actual, _ = expr.__teal__(options) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_teal_2_assert(): arg = pt.Int(1) expr = pt.Assert(arg) assert expr.type_of() == pt.TealType.none expected, _ = arg.__teal__(avm2Options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(pt.TealSimpleBlock([])) expectedBranch.setFalseBlock(pt.Err().__teal__(avm2Options)[0]) expected.setNextBlock(expectedBranch) actual, _ = expr.__teal__(avm2Options) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_sort_branch_converge(): blockEnd = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.return_)]) blockTrue = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"true"')]) blockTrue.setNextBlock(blockEnd) blockFalse = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.byte, '"false"')]) blockFalse.setNextBlock(blockEnd) block = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.int, 1)]) block.setTrueBlock(blockTrue) block.setFalseBlock(blockFalse) block.addIncoming() block.validateTree() expected = [block, blockFalse, blockTrue, blockEnd] actual = sortBlocks(block, blockEnd) assert actual == expected
def test_if_single(): args = [pt.Int(1), pt.Pop(pt.Int(1))] expr = pt.If(args[0], args[1]) assert expr.type_of() == pt.TealType.none expected, _ = args[0].__teal__(options) thenBlockStart, thenBlockEnd = args[1].__teal__(options) end = pt.TealSimpleBlock([]) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(thenBlockStart) expectedBranch.setFalseBlock(end) expected.setNextBlock(expectedBranch) thenBlockEnd.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_GetReferencedScratchSlots(): a = pt.ScratchSlot() b = pt.ScratchSlot() c = pt.ScratchSlot() d = pt.ScratchSlot() end = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.load, d)]) trueBranch = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.load, b)]) trueBranch.setNextBlock(end) falseBranch = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.load, c)]) falseBranch.setNextBlock(end) splitBranch = pt.TealConditionalBlock([pt.TealOp(None, pt.Op.load, a)]) splitBranch.setTrueBlock(trueBranch) splitBranch.setFalseBlock(falseBranch) slotReferences = pt.TealBlock.GetReferencedScratchSlots(splitBranch) assert slotReferences == [a, b, c, d]
def test_else_alt_multi(): args = [pt.Int(0), pt.Int(1), [pt.Pop(pt.Int(2)), pt.Int(3)]] expr = pt.If(args[0]).Then(args[1]).Else(*args[2]) expected, _ = args[0].__teal__(options) thenBlockStart, thenBlockEnd = args[1].__teal__(options) elseBlockStart, elseBlockEnd = pt.Seq(*args[2]).__teal__(options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(thenBlockStart) expectedBranch.setFalseBlock(elseBlockStart) expected.setNextBlock(expectedBranch) end = pt.TealSimpleBlock([]) thenBlockEnd.setNextBlock(end) elseBlockEnd.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_if_alt_none(): args = [pt.Int(0), pt.Pop(pt.Txn.sender()), pt.Pop(pt.Txn.receiver())] expr = pt.If(args[0]).Then(args[1]).Else(args[2]) assert expr.type_of() == pt.TealType.none expected, _ = args[0].__teal__(options) thenBlockStart, thenBlockEnd = args[1].__teal__(options) elseBlockStart, elseBlockEnd = args[2].__teal__(options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(thenBlockStart) expectedBranch.setFalseBlock(elseBlockStart) expected.setNextBlock(expectedBranch) end = pt.TealSimpleBlock([]) thenBlockEnd.setNextBlock(end) elseBlockEnd.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_if_alt_int(): args = [pt.Int(0), pt.Int(1), pt.Int(2)] expr = pt.If(args[0]).Then(args[1]).Else(args[2]) assert expr.type_of() == pt.TealType.uint64 expected, _ = args[0].__teal__(options) thenBlock, _ = args[1].__teal__(options) elseBlock, _ = args[2].__teal__(options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(thenBlock) expectedBranch.setFalseBlock(elseBlock) expected.setNextBlock(expectedBranch) end = pt.TealSimpleBlock([]) thenBlock.setNextBlock(end) elseBlock.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_if_bytes(): args = [pt.Int(1), pt.Txn.sender(), pt.Txn.receiver()] expr = pt.If(args[0], args[1], args[2]) assert expr.type_of() == pt.TealType.bytes expected, _ = args[0].__teal__(options) thenBlock, _ = args[1].__teal__(options) elseBlock, _ = args[2].__teal__(options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(thenBlock) expectedBranch.setFalseBlock(elseBlock) expected.setNextBlock(expectedBranch) end = pt.TealSimpleBlock([]) thenBlock.setNextBlock(end) elseBlock.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_while(): i = pt.ScratchVar() i.store(pt.Int(0)) items = [i.load() < pt.Int(2), [i.store(i.load() + pt.Int(1))]] expr = pt.While(items[0]).Do(pt.Seq(items[1])) assert expr.type_of() == pt.TealType.none assert not expr.has_return() expected, condEnd = items[0].__teal__(options) do, doEnd = pt.Seq(items[1]).__teal__(options) expectedBranch = pt.TealConditionalBlock([]) end = pt.TealSimpleBlock([]) expectedBranch.setTrueBlock(do) expectedBranch.setFalseBlock(end) condEnd.setNextBlock(expectedBranch) doEnd.setNextBlock(expected) actual, _ = expr.__teal__(options) assert actual == expected
def test_elseif_multiple_with_multi(): args = [ pt.Int(0), [pt.Pop(pt.Int(1)), pt.Int(2)], pt.Int(3), [pt.Pop(pt.Int(4)), pt.Int(5)], pt.Int(6), [pt.Pop(pt.Int(7)), pt.Int(8)], [pt.Pop(pt.Int(9)), pt.Int(10)], ] expr = ( pt.If(args[0]) .Then(*args[1]) .ElseIf(args[2]) .Then(*args[3]) .ElseIf(args[4]) .Then(*args[5]) .Else(*args[6]) ) elseIfExpr = pt.If( args[2], pt.Seq(args[3]), pt.If(args[4], pt.Seq(args[5]), pt.Seq(args[6])) ) expected, _ = args[0].__teal__(options) thenBlock, thenBlockEnd = pt.Seq(args[1]).__teal__(options) elseStart, elseBlockEnd = elseIfExpr.__teal__(options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(thenBlock) expectedBranch.setFalseBlock(elseStart) expected.setNextBlock(expectedBranch) end = pt.TealSimpleBlock([]) thenBlockEnd.setNextBlock(end) elseBlockEnd.setNextBlock(end) actual, _ = expr.__teal__(options) assert actual == expected
def test_false_block(): block = pt.TealConditionalBlock([]) block.setFalseBlock(pt.TealSimpleBlock([pt.TealOp(None, pt.Op.substring3)])) assert block.falseBlock == pt.TealSimpleBlock([pt.TealOp(None, pt.Op.substring3)])