1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

[Tolk] Nullable types T? and null safety

This commit introduces nullable types `T?` that are
distinct from non-nullable `T`.
Example: `int?` (int or null) and `int` are different now.
Previously, `null` could be assigned to any primitive type.
Now, it can be assigned only to `T?`.

A non-null assertion operator `!` was also introduced,
similar to `!` in TypeScript and `!!` in Kotlin.

If `int?` still occupies 1 stack slot, `(int,int)?` and
other nullable tensors occupy N+1 slots, the last for
"null precedence". `v == null` actually compares that slot.
Assigning `(int,int)` to `(int,int)?` implicitly creates
a null presence slot. Assigning `null` to `(int,int)?` widens
this null value to 3 slots. This is called "type transitioning".

All stdlib functions prototypes have been updated to reflect
whether they return/accept a nullable or a strict value.

This commit also contains refactoring from `const FunctionData*`
to `FunctionPtr` and similar.
This commit is contained in:
tolk-vm 2025-02-24 20:13:36 +03:00
parent 1389ff6789
commit f3e620f48c
No known key found for this signature in database
GPG key ID: 7905DD7FE0324B12
62 changed files with 2031 additions and 702 deletions

View file

@ -86,8 +86,8 @@ fun test104() {
}
@method_id(105)
fun test105(x: int, y: int): (tuple, int, (int, int), int, int) {
var ab = (createEmptyTuple(), (x, y), tupleSize);
fun test105(x: int, y: int): (tuple, int, (int?, int), int, int) {
var ab = (createEmptyTuple(), (x as int?, y), tupleSize);
ab.0.tuplePush(1);
tuplePush(mutate ab.0, 2);
ab.1.0 = null;
@ -98,7 +98,7 @@ fun test105(x: int, y: int): (tuple, int, (int, int), int, int) {
@method_id(106)
fun test106(x: int, y: int) {
var ab = [createEmptyTuple(), [x, y], tupleSize];
var ab = [createEmptyTuple(), [x as int?, y], tupleSize];
ab.0.tuplePush(1);
tuplePush(mutate ab.0, 2);
ab.1.0 = null;
@ -233,6 +233,25 @@ fun test121(zero: int) {
return t;
}
fun isFirstComponentGt0<T1,T2>(t: (T1, T2)): bool {
return t.0 > 0;
}
@method_id(122)
fun test122(x: (int, int)) {
return (
isFirstComponentGt0(x), isFirstComponentGt0((2, beginCell())), isFirstComponentGt0<int,slice?>((0, null)),
x.isFirstComponentGt0(), (2, beginCell()).isFirstComponentGt0(), (0, null).isFirstComponentGt0<int,slice?>()
);
}
@method_id(123)
fun test123() {
var t = [[10, 20]] as [[int,int]]?;
t!.0.0 = t!.0.1 = 100;
return t;
}
fun main(){}
@ -258,6 +277,8 @@ fun main(){}
@testcase | 119 | 1 2 3 4 | 4 1 3
@testcase | 120 | | 3 4 [ 5 6 ]
@testcase | 121 | 0 | [ 3 ]
@testcase | 122 | 1 2 | -1 -1 0 -1 -1 0
@testcase | 123 | | [ [ 100 100 ] ]
@fif_codegen
"""