mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
In FunC (and in Tolk before), the assignment > lhs = rhs evaluation order (at IR level) was "rhs first, lhs second". In practice, this did not matter, because lhs could only be a primitive: > (v1, v2) = getValue() Left side of assignment actually has no "evaluation". Since Tolk implemented indexed access, there could be > getTensor().0 = getValue() or (in the future) > getObject().field = getValue() where evaluation order becomes significant. Now evaluation order will be to "lhs first, rhs second" (more expected from user's point of view), which will become significant when building control flow graph.
146 lines
2.8 KiB
Text
146 lines
2.8 KiB
Text
import "@stdlib/lisp-lists"
|
|
|
|
@method_id(101)
|
|
fun test1() {
|
|
var numbers: tuple = createEmptyList();
|
|
numbers = listPrepend(1, numbers);
|
|
numbers = listPrepend(2, numbers);
|
|
numbers = listPrepend(3, numbers);
|
|
numbers = listPrepend(4, numbers);
|
|
var (h: int, numbers redef) = listSplit(numbers);
|
|
h += listGetHead(numbers);
|
|
|
|
_ = null;
|
|
(_, _) = (null, null);
|
|
var t = createEmptyTuple();
|
|
do {
|
|
var num: int = numbers.listNext();
|
|
t.tuplePush(num);
|
|
} while (numbers != null);
|
|
|
|
return (h, numbers == null, t);
|
|
}
|
|
|
|
@method_id(102)
|
|
fun test2(x: int) {
|
|
if (null != x) {
|
|
var y: int = null;
|
|
if (y != null) { return 10; }
|
|
return y;
|
|
}
|
|
try {
|
|
return x + 10; // will throw, since not a number
|
|
} catch {
|
|
return -1;
|
|
}
|
|
return 100;
|
|
}
|
|
|
|
fun myIsNull(x: int): int {
|
|
return x == null ? -1 : x;
|
|
}
|
|
|
|
@method_id(103)
|
|
fun test3(x: int) {
|
|
return myIsNull(x > 10 ? null : x);
|
|
}
|
|
|
|
fun getUntypedNull() {
|
|
var untyped: null = null;
|
|
if (true) {
|
|
return untyped;
|
|
}
|
|
return untyped;
|
|
}
|
|
|
|
@method_id(104)
|
|
fun test4(): null {
|
|
var (_, (_, untyped: null)) = (3, (createEmptyTuple, null));
|
|
if (true) {
|
|
return untyped;
|
|
}
|
|
return untyped;
|
|
}
|
|
|
|
@method_id(105)
|
|
fun test5() {
|
|
var n: slice = getUntypedNull();
|
|
return !(null == n) ? n.loadInt(32) : 100;
|
|
}
|
|
|
|
@method_id(107)
|
|
fun test7() {
|
|
var b = beginCell().storeMaybeRef(null);
|
|
var s = b.endCell().beginParse();
|
|
var c = s.loadMaybeRef();
|
|
return (null == c) as int * 10 + (b != null) as int;
|
|
}
|
|
|
|
fun main() {
|
|
// now, the compiler doesn't optimize this at compile-time, fif codegen contains ifs
|
|
var i: int = null;
|
|
if (i == null) {
|
|
return 1;
|
|
}
|
|
return 10;
|
|
}
|
|
|
|
/**
|
|
@testcase | 101 | | 7 -1 [ 3 2 1 ]
|
|
@testcase | 102 | 5 | (null)
|
|
@testcase | 102 | null | -1
|
|
@testcase | 103 | 5 | 5
|
|
@testcase | 103 | 15 | -1
|
|
@testcase | 104 | | (null)
|
|
@testcase | 105 | | 100
|
|
@testcase | 107 | | -11
|
|
@fif_codegen
|
|
"""
|
|
test1 PROC:<{
|
|
//
|
|
PUSHNULL // numbers
|
|
1 PUSHINT // numbers '2=1
|
|
SWAP // '2=1 numbers
|
|
CONS // numbers
|
|
2 PUSHINT // numbers '4=2
|
|
SWAP // '4=2 numbers
|
|
CONS // numbers
|
|
3 PUSHINT // numbers '6=3
|
|
SWAP // '6=3 numbers
|
|
CONS // numbers
|
|
4 PUSHINT // numbers '8=4
|
|
SWAP // '8=4 numbers
|
|
CONS // numbers
|
|
UNCONS // h numbers
|
|
DUP // h numbers numbers
|
|
CAR // h numbers '13
|
|
"""
|
|
|
|
@fif_codegen
|
|
"""
|
|
main PROC:<{
|
|
//
|
|
PUSHNULL // i
|
|
ISNULL // '2
|
|
IFJMP:<{ //
|
|
1 PUSHINT // '3=1
|
|
}> //
|
|
10 PUSHINT // '4=10
|
|
}>
|
|
"""
|
|
|
|
@fif_codegen
|
|
"""
|
|
test7 PROC:<{
|
|
...
|
|
LDOPTREF // b '9 '8
|
|
DROP // b c
|
|
ISNULL // b '11
|
|
10 MULCONST // b '13
|
|
SWAP // '13 b
|
|
ISNULL // '13 '14
|
|
NOT // '13 '15
|
|
ADD // '16
|
|
}>
|
|
"""
|
|
*/
|