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:
parent
1389ff6789
commit
f3e620f48c
62 changed files with 2031 additions and 702 deletions
109
tolk-tester/tests/nullable-types.tolk
Normal file
109
tolk-tester/tests/nullable-types.tolk
Normal file
|
@ -0,0 +1,109 @@
|
|||
|
||||
fun getNullable4(): int? { return 4; }
|
||||
fun getNullableIntNull(): int? asm "PUSHNULL";
|
||||
|
||||
fun eqInt(x: int) { return x; }
|
||||
fun eq<T>(x: T) { return x; }
|
||||
|
||||
fun unwrap<T>(x: T?): T { return x!; }
|
||||
fun intOr0(x: int?): int { return null == x ? 0 : x!; }
|
||||
|
||||
@method_id(101)
|
||||
fun test101(x: int) {
|
||||
var re = x == 0 ? null : 100;
|
||||
return re == null ? re : 200 + getNullable4()!;
|
||||
}
|
||||
|
||||
@method_id(102)
|
||||
fun test102(a: int) {
|
||||
try {
|
||||
throw (123, a > 10 ? null : a);
|
||||
return 0;
|
||||
} catch (excno, arg) {
|
||||
var i = arg as int?;
|
||||
return excno + (i != null ? i!!!!! : -100);
|
||||
}
|
||||
}
|
||||
|
||||
@method_id(103)
|
||||
fun test103(x: int?): (bool, bool, int) {
|
||||
var x_gt_0 = x != null && eqInt(x!) > 0;
|
||||
var x_lt_0 = x != null && eq(x)! < 0;
|
||||
if (x == null) {
|
||||
return (x_gt_0, x_lt_0, 0);
|
||||
}
|
||||
return (x_gt_0, x_lt_0, x!);
|
||||
}
|
||||
|
||||
@method_id(104)
|
||||
fun test104(x: int?) {
|
||||
var x2 = eq(x = 10);
|
||||
var ab = (x2, getNullableIntNull());
|
||||
return (unwrap(ab.0) + (ab.1 == null ? -100 : ab.1!), ab.1);
|
||||
}
|
||||
|
||||
@method_id(105)
|
||||
fun test105() {
|
||||
var xy: (int?, int?) = (5, null);
|
||||
var ab = [1 ? [xy.0, xy.1] : null];
|
||||
ab.0!.0 = intOr0(ab.0!.0);
|
||||
ab.0!.1 = intOr0(ab.0!.1);
|
||||
return ab.0!.0! + ab.0!.1!;
|
||||
}
|
||||
|
||||
global gTup106: tuple?;
|
||||
global gInt106: int?;
|
||||
|
||||
@method_id(106)
|
||||
fun test106() {
|
||||
gInt106 = 0;
|
||||
gInt106! += 5;
|
||||
var int106: int? = 0;
|
||||
var gTup106 = createEmptyTuple();
|
||||
gTup106!.tuplePush(createEmptyTuple());
|
||||
(gTup106!.0 as tuple?)!.tuplePush(0 as int?);
|
||||
tuplePush(mutate gTup106!, gInt106);
|
||||
tuplePush(mutate gTup106!.0, int106! += 1);
|
||||
return (gTup106 == null, null != gTup106, gTup106, gTup106!.0 as tuple?);
|
||||
}
|
||||
|
||||
@method_id(107)
|
||||
fun test107() {
|
||||
var b: builder? = beginCell();
|
||||
b!.storeInt(1, 32).storeInt(2, 32);
|
||||
b = b!.storeInt(3, 32);
|
||||
storeInt(mutate b!, 4, 32);
|
||||
(b! as builder).storeInt(5, 32);
|
||||
return b!.getBuilderBitsCount();
|
||||
}
|
||||
|
||||
@method_id(108)
|
||||
fun test108() {
|
||||
var (a, b: cell?, c) = (1, beginCell().endCell(), 3);
|
||||
b = null;
|
||||
return a + (b == null ? 0 : b!.beginParse().loadInt(32)) + c;
|
||||
}
|
||||
|
||||
@method_id(109)
|
||||
fun test109() {
|
||||
var a = getNullable4();
|
||||
var b = getNullable4();
|
||||
return ([a, b] = [3, 4], a, b);
|
||||
}
|
||||
|
||||
fun main(x: int?, y: int?) {
|
||||
}
|
||||
|
||||
/**
|
||||
@testcase | 101 | 0 | (null)
|
||||
@testcase | 101 | -1 | 204
|
||||
@testcase | 102 | 5 | 128
|
||||
@testcase | 102 | 15 | 23
|
||||
@testcase | 103 | 10 | -1 0 10
|
||||
@testcase | 104 | 8 | -90 (null)
|
||||
@testcase | 105 | | 5
|
||||
@testcase | 106 | | 0 -1 [ [ 0 1 ] 5 ] [ 0 1 ]
|
||||
@testcase | 107 | | 160
|
||||
@testcase | 108 | | 4
|
||||
@testcase | 109 | | [ 3 4 ] 3 4
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue