1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-15 04:32:21 +00:00
ton/tolk-tester/tests/a10.tolk
tolk-vm 799e2d1265
[Tolk] Rewrite the type system from Hindley-Milner to static typing
FunC's (and Tolk's before this PR) type system is based on Hindley-Milner.
This is a common approach for functional languages, where
types are inferred from usage through unification.
As a result, type declarations are not necessary:
() f(a,b) { return a+b; } // a and b now int, since `+` (int, int)

While this approach works for now, problems arise with the introduction
of new types like bool, where `!x` must handle both int and bool.
It will also become incompatible with int32 and other strict integers.
This will clash with structure methods, struggle with proper generics,
and become entirely impractical for union types.

This PR completely rewrites the type system targeting the future.
1) type of any expression is inferred and never changed
2) this is available because dependent expressions already inferred
3) forall completely removed, generic functions introduced
   (they work like template functions actually, instantiated while inferring)
4) instantiation `<...>` syntax, example: `t.tupleAt<int>(0)`
5) `as` keyword, for example `t.tupleAt(0) as int`
6) methods binding is done along with type inferring, not before
   ("before", as worked previously, was always a wrong approach)
2025-01-15 15:38:43 +03:00

130 lines
2.2 KiB
Text

import "@stdlib/tvm-lowlevel"
fun pair_first<X, Y>(p: [X, Y]): X asm "FIRST";
fun one(dummy: tuple) {
return 1;
}
fun main(a: int, x: int) {
var y: int = 0;
var z: int = 0;
while ((y = x * x) > a) {
x -= 1;
z = one(null);
}
return (y, z);
}
fun throwIfLt10(x: int): void {
if (x > 10) {
return;
}
throw 234;
return;
}
@method_id(88)
fun test88(x: int) {
try {
var x: void = throwIfLt10(x);
return 0;
} catch(code) {
return code;
}
}
@method_id(89)
fun test89(last: int): (int, int, int, int) {
var t: tuple = createEmptyTuple();
t.tuplePush(1);
t.tuplePush(2);
t.tuplePush(3);
t.tuplePush(last);
return (t.tupleAt(0), t.tupleAt(t.tupleSize() - 1), t.tupleFirst(), t.tupleLast());
}
@pure fun get10() { return 10; }
@method_id(91)
fun touchCodegen2() {
var f = get10();
f.stackMoveToTop();
return f;
}
@method_id(92)
fun testDumpDontPolluteStack() {
var f = get10();
f.debugPrint();
debugPrint(10);
var s = "asdf";
s.debugPrintString();
debugDumpStack();
debugPrintString("my");
return (f, getRemainingBitsCount(s));
}
@method_id(93)
fun testStartBalanceCodegen1() {
var t = getMyOriginalBalanceWithExtraCurrencies();
var first = t.pair_first();
return first;
}
@method_id(94)
fun testStartBalanceCodegen2() {
var first = getMyOriginalBalance();
return first;
}
/**
method_id | in | out
@testcase | 0 | 101 15 | 100 1
@testcase | 0 | 101 14 | 100 1
@testcase | 0 | 101 10 | 100 0
@testcase | 0 | 100 10 | 100 0
@testcase | 0 | 100 10 | 100 0
@testcase | 88 | 5 | 234
@testcase | 88 | 50 | 0
@testcase | 89 | 4 | 1 4 1 4
@testcase | 91 | | 10
@testcase | 92 | | 10 32
@fif_codegen
"""
touchCodegen2 PROC:<{
//
get10 CALLDICT // f
}>
"""
@fif_codegen
"""
testDumpDontPolluteStack PROC:<{
...
DUMPSTK
x{6d79} PUSHSLICE // f s _9
STRDUMP DROP
SBITS // f _11
}>
"""
@fif_codegen
"""
testStartBalanceCodegen1 PROC:<{
//
BALANCE // t
FIRST // first
}>
"""
@fif_codegen
"""
testStartBalanceCodegen2 PROC:<{
//
BALANCE
FIRST // first
}>
"""
*/