mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
[Tolk] Completely rework stdlib: multiple files and renaming
- split stdlib.tolk into multiple files (tolk-stdlib/ folder) (the "core" common.tolk is auto-imported, the rest are needed to be explicitly imported like "@stdlib/tvm-dicts.tolk") - all functions were renamed to long and clear names - new naming is camelCase
This commit is contained in:
parent
e2edadba92
commit
12ff28ac94
48 changed files with 2966 additions and 2458 deletions
|
@ -1,3 +1,5 @@
|
|||
fun pair_first<X, Y>(p: [X, Y]): X asm "FIRST";
|
||||
|
||||
fun one(dummy: tuple) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -30,6 +32,29 @@ fun test88(x: int) {
|
|||
}
|
||||
}
|
||||
|
||||
@method_id(89)
|
||||
fun test89(last: 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());
|
||||
}
|
||||
|
||||
@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
|
||||
|
@ -39,4 +64,24 @@ fun test88(x: int) {
|
|||
@testcase | 0 | 100 10 | 100 0
|
||||
@testcase | 88 | 5 | 234
|
||||
@testcase | 88 | 50 | 0
|
||||
@testcase | 89 | 4 | 1 4 1 4
|
||||
|
||||
|
||||
@fif_codegen
|
||||
"""
|
||||
testStartBalanceCodegen1 PROC:<{
|
||||
//
|
||||
BALANCE // t
|
||||
FIRST // first
|
||||
}>
|
||||
"""
|
||||
|
||||
@fif_codegen
|
||||
"""
|
||||
testStartBalanceCodegen2 PROC:<{
|
||||
//
|
||||
BALANCE
|
||||
FIRST // first
|
||||
}>
|
||||
"""
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,7 @@ fun f(a: int, b: int, c: int, d: int, e: int, f: int): (int, int) {
|
|||
return (Dx/D,Dy/D);
|
||||
};;;;
|
||||
|
||||
fun mulDivR(x: int, y: int, z: int): int { return muldivr(x, y, z); }
|
||||
fun mulDivR(x: int, y: int, z: int): int { return mulDivRound(x, y, z); }
|
||||
|
||||
fun calc_phi(): int {
|
||||
var n = 1;
|
||||
|
|
|
@ -4,8 +4,8 @@ asm "NIL";
|
|||
@pure
|
||||
fun tpush2<X>(t: tuple, x: X): (tuple, ())
|
||||
asm "TPUSH";
|
||||
fun emptyTuple(): tuple { return empty_tuple2(); }
|
||||
fun tuplePush<X>(t: tuple, value: X): (tuple, ()) { return tpush2(t, value); }
|
||||
fun myEmptyTuple(): tuple { return empty_tuple2(); }
|
||||
fun myTuplePush<X>(t: tuple, value: X): (tuple, ()) { return tpush2(t, value); }
|
||||
|
||||
@pure
|
||||
fun asm_func_1(x: int, y: int, z: int): tuple
|
||||
|
@ -31,7 +31,7 @@ fun asmFuncModify(a: tuple, b: int, c: int): (tuple, ()) { return asm_func_modif
|
|||
global t: tuple;
|
||||
|
||||
fun foo(x: int): int {
|
||||
t~tuplePush(x);
|
||||
t~myTuplePush(x);
|
||||
return x * 10;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ fun test_old_1(): (tuple, tuple) {
|
|||
|
||||
@method_id(12)
|
||||
fun test_old_2(): (tuple, tuple) {
|
||||
t = emptyTuple();
|
||||
t = myEmptyTuple();
|
||||
var t2: tuple = asm_func_2(foo(11), foo(22), foo(33));
|
||||
return (t, t2);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ fun test_old_3(): (tuple, tuple) {
|
|||
|
||||
@method_id(14)
|
||||
fun test_old_4(): (tuple, tuple) {
|
||||
t = emptyTuple();
|
||||
t = myEmptyTuple();
|
||||
var t2: tuple = empty_tuple2();
|
||||
// This actually computes left-to-right even without compute-asm-ltr
|
||||
t2 = asm_func_4(foo(11), (foo(22), (foo(33), foo(44))), foo(55));
|
||||
|
|
|
@ -7,40 +7,45 @@
|
|||
// without affecting performance and even bytecode hashes.
|
||||
// This works with ~functions also. And even works with wrappers of wrappers.
|
||||
// Moreover, such wrappers can reorder input parameters, see a separate test camel2.tolk.
|
||||
import "@stdlib/tvm-dicts"
|
||||
|
||||
fun myBeginCell(): builder { return begin_cell(); }
|
||||
fun myEndCell(b: builder): cell { return end_cell(b); }
|
||||
fun myStoreRef(b: builder, c: cell): builder { return store_ref(b, c); }
|
||||
fun myStoreUint(b: builder, i: int, bw: int): builder { return store_uint(b, i, bw); }
|
||||
fun myBeginCell(): builder { return beginCell(); }
|
||||
fun myEndCell(b: builder): cell { return endCell(b); }
|
||||
fun myStoreRef(b: builder, c: cell): builder { return storeRef(b, c); }
|
||||
fun myStoreUint(b: builder, i: int, bw: int): builder { return storeUint(b, i, bw); }
|
||||
|
||||
// 'inline' is not needed actually, but if it exists, it's just ignored
|
||||
@inline
|
||||
@pure
|
||||
fun myBeginParse(c: cell): slice { return begin_parse(c); }
|
||||
fun myBeginParse(c: cell): slice { return beginParse(c); }
|
||||
@inline
|
||||
@pure
|
||||
fun mySkipBits(s: slice, len: int): slice { return skip_bits(s, len); }
|
||||
fun mySkipBits(s: slice, len: int): slice { return skipBits(s, len); }
|
||||
@inline
|
||||
@pure
|
||||
fun ~mySkipBits(s: slice, len: int): (slice, ()) { return ~skip_bits(s, len); }
|
||||
fun ~mySkipBits(s: slice, len: int): (slice, ()) { return ~skipBits(s, len); }
|
||||
@inline
|
||||
@pure
|
||||
fun ~myLoadUint(s: slice, len: int): (slice, int) { return load_uint(s, len); }
|
||||
fun ~myLoadUint(s: slice, len: int): (slice, int) { return loadUint(s, len); }
|
||||
|
||||
fun myComputeDataSize(c: cell, maxCells: int): (int, int, int) { return compute_data_size(c, maxCells); }
|
||||
fun myComputeDataSize(c: cell, maxCells: int): (int, int, int) { return calculateCellSizeStrict(c, maxCells); }
|
||||
|
||||
fun dict__new(): cell { return new_dict(); }
|
||||
fun dict__iset(dict: cell, keyLen: int, index: int, value: slice): cell { return idict_set(dict, keyLen, index, value); }
|
||||
fun ~dict__iset(dict: cell, keyLen: int, index: int, value: slice): (cell, ()) { return ~idict_set(dict, keyLen, index, value); }
|
||||
fun dict__tryIGet(dict: cell, keyLen: int, index: int): (slice, int) { return idict_get?(dict, keyLen, index); }
|
||||
fun dict__tryIGetMin(dict: cell, keyLen: int): (int, slice, int) { return idict_get_min?(dict, keyLen); }
|
||||
fun dict__new(): cell { return createEmptyDict(); }
|
||||
fun dict__iset(dict: cell, keyLen: int, index: int, value: slice): cell { return iDictSet(dict, keyLen, index, value); }
|
||||
fun ~dict__iset(dict: cell, keyLen: int, index: int, value: slice): (cell, ()) { return ~iDictSet(dict, keyLen, index, value); }
|
||||
fun dict__tryIGet(dict: cell, keyLen: int, index: int): (slice, int) { return iDictGet(dict, keyLen, index); }
|
||||
fun dict__tryIGetMin(dict: cell, keyLen: int): (int, slice, int) { return iDictGetFirst(dict, keyLen); }
|
||||
|
||||
fun myEmptyTuple(): tuple { return empty_tuple(); }
|
||||
@pure
|
||||
fun triple_second<X, Y, Z>(p: [X, Y, Z]): Y
|
||||
asm "SECOND";
|
||||
|
||||
fun myEmptyTuple(): tuple { return createEmptyTuple(); }
|
||||
fun emptyTuple1(): tuple { return myEmptyTuple(); }
|
||||
fun emptyTuple11(): tuple { return emptyTuple1(); }
|
||||
fun myTuplePush<X>(t: tuple, value: X): tuple { return tpush(t, value); }
|
||||
fun ~myTuplePush<X>(t: tuple, value: X): (tuple, ()) { return ~tpush(t, value); }
|
||||
fun myTupleAt<X>(t: tuple, index: int): X { return at(t, index); }
|
||||
fun myTuplePush<X>(t: tuple, value: X): tuple { return tuplePush(t, value); }
|
||||
fun ~myTuplePush<X>(t: tuple, value: X): (tuple, ()) { return ~tuplePush(t, value); }
|
||||
fun myTupleAt<X>(t: tuple, index: int): X { return tupleAt(t, index); }
|
||||
fun tripleSecond<X1, Y2, Z3>(p: [X1, Y2, Z3]): Y2 { return triple_second(p); }
|
||||
@pure
|
||||
fun nullValue<X>(): X
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
// But swapping arguments may sometimes lead to bytecode changes (see test2),
|
||||
// both with compute-asm-ltr and without it.
|
||||
|
||||
fun myBeginCell(): builder { return begin_cell(); }
|
||||
fun myEndCell(b: builder): cell { return end_cell(b); }
|
||||
fun myStoreRef1(b: builder, c: cell): builder { return store_ref(b, c); }
|
||||
fun myStoreRef2(c: cell, b: builder): builder { return store_ref(b, c); }
|
||||
fun myStoreUint1(b: builder, x: int, bw: int): builder { return store_uint(b, x, bw); }
|
||||
fun myStoreUint2(b: builder, bw: int, x: int): builder { return store_uint(b, x, bw); }
|
||||
fun myBeginCell(): builder { return beginCell(); }
|
||||
fun myEndCell(b: builder): cell { return endCell(b); }
|
||||
fun myStoreRef1(b: builder, c: cell): builder { return storeRef(b, c); }
|
||||
fun myStoreRef2(c: cell, b: builder): builder { return storeRef(b, c); }
|
||||
fun myStoreUint1(b: builder, x: int, bw: int): builder { return storeUint(b, x, bw); }
|
||||
fun myStoreUint2(b: builder, bw: int, x: int): builder { return storeUint(b, x, bw); }
|
||||
|
||||
fun computeDataSize1(c: cell, maxCells: int): (int, int, int) { return compute_data_size(c, maxCells); }
|
||||
fun computeDataSize2(maxCells: int, c: cell): (int, int, int) { return compute_data_size(c, maxCells); }
|
||||
fun computeDataSize1(c: cell, maxCells: int): (int, int, int) { return calculateCellSizeStrict(c, maxCells); }
|
||||
fun computeDataSize2(maxCells: int, c: cell): (int, int, int) { return calculateCellSizeStrict(c, maxCells); }
|
||||
|
||||
fun fake(a: int, b: int, c: int): void
|
||||
asm "DROP DROP DROP";
|
||||
|
@ -48,24 +48,24 @@ fun test2(): (int, int, int) {
|
|||
fun test3(): (int, int, int) {
|
||||
var x: int = 1;
|
||||
var y: int = 1;
|
||||
var to_be_ref: cell = begin_cell().end_cell();
|
||||
var in_c: builder = begin_cell().store_uint(123, 8);
|
||||
in_c = store_ref(in_c, to_be_ref);
|
||||
var (a, b, c) = compute_data_size(in_c.end_cell(), 10);
|
||||
var to_be_ref: cell = beginCell().endCell();
|
||||
var in_c: builder = beginCell().storeUint(123, 8);
|
||||
in_c = storeRef(in_c, to_be_ref);
|
||||
var (a, b, c) = calculateCellSizeStrict(in_c.endCell(), 10);
|
||||
return (a, b + x, c + y);
|
||||
}
|
||||
|
||||
fun beginCell1(): builder { return begin_cell(); }
|
||||
fun beginCell1(): builder { return beginCell(); }
|
||||
fun beginCell11(): builder { return beginCell1(); }
|
||||
fun beginCell111(): builder { return beginCell11(); }
|
||||
|
||||
fun endCell1(b: builder): cell { return end_cell(b); }
|
||||
fun endCell1(b: builder): cell { return endCell(b); }
|
||||
fun endCell11(b: builder): cell { return endCell1(b); }
|
||||
|
||||
fun beginParse1(c: cell): slice { return begin_parse(c); }
|
||||
fun beginParse1(c: cell): slice { return beginParse(c); }
|
||||
fun beginParse11(c: cell): slice { return beginParse1(c); }
|
||||
|
||||
fun storeInt1(b: builder, bw: int, x: int): builder { return store_int(b, x, bw); }
|
||||
fun storeInt1(b: builder, bw: int, x: int): builder { return storeInt(b, x, bw); }
|
||||
fun storeInt11(bw: int, x: int, b: builder): builder { return storeInt1(b, bw, x); }
|
||||
fun storeInt111(b: builder, x: int, bw: int): builder { return storeInt11(bw, x, b); }
|
||||
|
||||
|
|
|
@ -4,17 +4,17 @@
|
|||
// (save to a variable, return from a function, etc.)
|
||||
// it also works, since a function becomes codegenerated (though direct calls are expectedly inlined).
|
||||
|
||||
fun myBeginCell(): builder { return begin_cell(); }
|
||||
fun myEndCell(b: builder): cell { return end_cell(b); }
|
||||
fun myStoreRef(b: builder, c: cell): builder { return store_ref(b, c); }
|
||||
fun myStoreUint3(i: int, bw: int, b: builder): builder { return store_uint(b, i, bw); }
|
||||
fun myBeginCell(): builder { return beginCell(); }
|
||||
fun myEndCell(b: builder): cell { return endCell(b); }
|
||||
fun myStoreRef(b: builder, c: cell): builder { return storeRef(b, c); }
|
||||
fun myStoreUint3(i: int, bw: int, b: builder): builder { return storeUint(b, i, bw); }
|
||||
|
||||
fun computeDataSize2(maxCells: int, c: cell): (int, int, int) { return compute_data_size(c, maxCells); }
|
||||
fun computeDataSize2(maxCells: int, c: cell): (int, int, int) { return calculateCellSizeStrict(c, maxCells); }
|
||||
|
||||
fun myEmptyTuple(): tuple { return empty_tuple(); }
|
||||
fun myTuplePush<X>(t: tuple, value: X): tuple { return tpush(t, value); }
|
||||
fun ~myTuplePush<X>(t: tuple, value: X): (tuple, ()) { return ~tpush(t, value); }
|
||||
fun tupleGetFirst<X>(t: tuple): X { return first(t); }
|
||||
fun myEmptyTuple(): tuple { return createEmptyTuple(); }
|
||||
fun myTuplePush<X>(t: tuple, value: X): tuple { return tuplePush(t, value); }
|
||||
fun ~myTuplePush<X>(t: tuple, value: X): (tuple, ()) { return ~tuplePush(t, value); }
|
||||
fun myTupleGetFirst<X>(t: tuple): X { return tupleFirst(t); }
|
||||
|
||||
|
||||
@inline
|
||||
|
@ -32,7 +32,7 @@ fun test1(): (int, int, int) {
|
|||
|
||||
var t: tuple = myEmptyTuple();
|
||||
t~myTuplePush(myStoreRef);
|
||||
var refStorer = tupleGetFirst(t);
|
||||
var refStorer = myTupleGetFirst(t);
|
||||
|
||||
var x: int = 1;
|
||||
var y: int = 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Here we test that a just-return function is not a valid wrapper, it will not be inlined.
|
||||
// (doesn't use all arguments, has different pureness, has method_id, etc.)
|
||||
|
||||
fun myStoreUint(b: builder, x: int, unused: int): builder { return store_uint(b, x, x); }
|
||||
fun myStoreUint(b: builder, x: int, unused: int): builder { return storeUint(b, x, x); }
|
||||
fun throwIf(excNo: int, cond: int) { assert(!cond) throw excNo; }
|
||||
|
||||
fun initial1(x: auto) { return x; }
|
||||
|
@ -17,11 +17,11 @@ fun postpone_elections(): int {
|
|||
}
|
||||
|
||||
fun setAndGetData(ret: int): int {
|
||||
var c: cell = begin_cell().store_uint(ret, 8).end_cell();
|
||||
set_data(c);
|
||||
var s: slice = get_data().begin_parse();
|
||||
var c: cell = beginCell().storeUint(ret, 8).endCell();
|
||||
setContractData(c);
|
||||
var s: slice = getContractData().beginParse();
|
||||
throwIf(101, 0);
|
||||
return s~load_uint(8);
|
||||
return s~loadUint(8);
|
||||
}
|
||||
|
||||
fun setAndGetDataWrapper(ret: int): int {
|
||||
|
@ -30,9 +30,9 @@ fun setAndGetDataWrapper(ret: int): int {
|
|||
|
||||
@method_id(101)
|
||||
fun test1(): int {
|
||||
var c: cell = begin_cell().myStoreUint(32, 10000000).end_cell();
|
||||
var s: slice = c.begin_parse();
|
||||
return s~load_uint(32);
|
||||
var c: cell = beginCell().myStoreUint(32, 10000000).endCell();
|
||||
var s: slice = c.beginParse();
|
||||
return s~loadUint(32);
|
||||
}
|
||||
|
||||
get fun test2(ret: int): int {
|
||||
|
@ -47,13 +47,13 @@ fun test3(): int {
|
|||
global t: tuple;
|
||||
|
||||
fun foo(x: int): int {
|
||||
t~tpush(x);
|
||||
t~tuplePush(x);
|
||||
return x * 10;
|
||||
}
|
||||
|
||||
@method_id(104)
|
||||
fun test4(): (tuple, tuple) {
|
||||
t = empty_tuple();
|
||||
t = createEmptyTuple();
|
||||
var t2: tuple = asmFunc4(foo(11), (foo(22), (foo(33), foo(44))), foo(55));
|
||||
return (t, t2);
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
fun store_u32(b: builder, value: int): builder {
|
||||
return b.store_uint(value, 32);
|
||||
return b.storeUint(value, 32);
|
||||
}
|
||||
fun ~store_u32(b: builder, value: int): (builder, ()) {
|
||||
return ~store_uint(b, value, 32);
|
||||
return ~storeUint(b, value, 32);
|
||||
}
|
||||
|
||||
fun load_u32(cs: slice): (slice, int) {
|
||||
return cs.load_uint(32);
|
||||
return cs.loadUint(32);
|
||||
}
|
||||
|
||||
fun my_load_int(s: slice, len: int): (slice, int)
|
||||
fun my_loadInt(s: slice, len: int): (slice, int)
|
||||
asm(s len -> 1 0) "LDIX"; // top is "value slice"
|
||||
fun my_store_int(b: builder, x: int, len: int): builder
|
||||
fun my_storeInt(b: builder, x: int, len: int): builder
|
||||
asm(x b len) "STIX";
|
||||
fun ~my_store_int(b: builder, x: int, len: int): (builder, ())
|
||||
fun ~my_storeInt(b: builder, x: int, len: int): (builder, ())
|
||||
asm(x b len) "STIX";
|
||||
|
||||
@method_id(101)
|
||||
fun test1(): [int,int,int,int,int] {
|
||||
var b: builder = begin_cell().store_uint(1, 32);
|
||||
b = b.store_uint(2, 32);
|
||||
b~store_uint(3, 32);
|
||||
var b: builder = beginCell().storeUint(1, 32);
|
||||
b = b.storeUint(2, 32);
|
||||
b~storeUint(3, 32);
|
||||
b = b.store_u32(4);
|
||||
b~store_u32(5);
|
||||
|
||||
var cs: slice = b.end_cell().begin_parse();
|
||||
var (cs redef, one: int) = cs.load_uint(32);
|
||||
var (two: int, three: int) = (cs~load_uint(32), cs~load_u32());
|
||||
var cs: slice = b.endCell().beginParse();
|
||||
var (cs redef, one: int) = cs.loadUint(32);
|
||||
var (two: int, three: int) = (cs~loadUint(32), cs~load_u32());
|
||||
var (cs redef, four: int) = cs.load_u32();
|
||||
var five: int = cs~load_u32();
|
||||
|
||||
|
@ -35,82 +35,82 @@ fun test1(): [int,int,int,int,int] {
|
|||
|
||||
@method_id(102)
|
||||
fun test2(): [int,int,int] {
|
||||
var b: builder = begin_cell().my_store_int(1, 32);
|
||||
b = b.my_store_int(2, 32);
|
||||
b~my_store_int(3, 32);
|
||||
var b: builder = beginCell().my_storeInt(1, 32);
|
||||
b = b.my_storeInt(2, 32);
|
||||
b~my_storeInt(3, 32);
|
||||
|
||||
var cs: slice = b.end_cell().begin_parse();
|
||||
var (cs redef, one: int) = cs.my_load_int(32);
|
||||
var (two: int, three: int) = (cs~my_load_int(32), cs~my_load_int(32));
|
||||
var cs: slice = b.endCell().beginParse();
|
||||
var (cs redef, one: int) = cs.my_loadInt(32);
|
||||
var (two: int, three: int) = (cs~my_loadInt(32), cs~my_loadInt(32));
|
||||
|
||||
return [one,two,three];
|
||||
}
|
||||
|
||||
@method_id(103)
|
||||
fun test3(ret: int): int {
|
||||
var (_, same: int) = begin_cell().store_uint(ret,32).end_cell().begin_parse().load_uint(32);
|
||||
var (_, same: int) = beginCell().storeUint(ret,32).endCell().beginParse().loadUint(32);
|
||||
return same;
|
||||
}
|
||||
|
||||
@method_id(104)
|
||||
fun test4(): [int,int] {
|
||||
var b: builder = my_store_int(begin_cell(), 1, 32);
|
||||
b = store_int(store_int(b, 2, 32), 3, 32);
|
||||
var b: builder = my_storeInt(beginCell(), 1, 32);
|
||||
b = storeInt(storeInt(b, 2, 32), 3, 32);
|
||||
|
||||
var cs: slice = b.end_cell().begin_parse();
|
||||
var cs32: slice = cs.first_bits(32); // todo s.first_bits()~load_uint() doesn't work, 'lvalue expected'
|
||||
var (one, _, three) = (cs32~load_int(32), cs~skip_bits(64), cs~load_u32());
|
||||
var cs: slice = b.endCell().beginParse();
|
||||
var cs32: slice = cs.getFirstBits(32); // todo s.first_bits()~loadUint() doesn't work, 'lvalue expected'
|
||||
var (one, _, three) = (cs32~loadInt(32), cs~skipBits(64), cs~load_u32());
|
||||
|
||||
return [one,three];
|
||||
}
|
||||
|
||||
@method_id(105)
|
||||
fun test5(): [int,int] {
|
||||
var cref: cell = end_cell(store_u32(begin_cell(), 105));
|
||||
var c: cell = begin_cell().store_ref(cref).store_ref(cref).store_u32(1).end_cell();
|
||||
var cref: cell = endCell(store_u32(beginCell(), 105));
|
||||
var c: cell = beginCell().storeRef(cref).storeRef(cref).store_u32(1).endCell();
|
||||
|
||||
var cs: slice = begin_parse(c);
|
||||
// todo I want cs~load_ref().begin_parse()~load_u32(), but 'lvalue expected'
|
||||
var ref1 = cs~load_ref().begin_parse();
|
||||
var ref2 = cs~load_ref().begin_parse();
|
||||
var sto5x2: int = ref1~load_u32() + ref2~load_uint(32);
|
||||
var cs: slice = beginParse(c);
|
||||
// todo I want cs~loadRef().beginParse()~load_u32(), but 'lvalue expected'
|
||||
var ref1 = cs~loadRef().beginParse();
|
||||
var ref2 = cs~loadRef().beginParse();
|
||||
var sto5x2: int = ref1~load_u32() + ref2~loadUint(32);
|
||||
return [sto5x2, cs~load_u32()];
|
||||
}
|
||||
|
||||
|
||||
fun ~sumNumbersInSlice(s: slice): (slice, int) {
|
||||
var result = 0;
|
||||
while (!slice_data_empty?(s)) {
|
||||
result += s~load_uint(32);
|
||||
while (!s.isEndOfSliceBits()) {
|
||||
result += s~loadUint(32);
|
||||
}
|
||||
return (s, result);
|
||||
}
|
||||
|
||||
@method_id(106)
|
||||
fun test6() {
|
||||
var ref = begin_cell().store_int(100, 32).end_cell();
|
||||
var s: slice = begin_cell().store_int(1, 32).store_int(2, 32).store_ref(ref).end_cell().begin_parse();
|
||||
var result = (slice_bits(s), s~sumNumbersInSlice(), slice_bits(s), slice_empty?(s), slice_data_empty?(s), slice_refs_empty?(s));
|
||||
var ref2: cell = s~load_ref();
|
||||
var s2: slice = ref2.begin_parse();
|
||||
s.end_parse();
|
||||
return (result, s2~load_int(32), s2.slice_empty?());
|
||||
var ref = beginCell().storeInt(100, 32).endCell();
|
||||
var s: slice = beginCell().storeInt(1, 32).storeInt(2, 32).storeRef(ref).endCell().beginParse();
|
||||
var result = (getRemainingBitsCount(s), s~sumNumbersInSlice(), getRemainingBitsCount(s), isEndOfSlice(s), isEndOfSliceBits(s), isEndOfSliceRefs(s));
|
||||
var ref2: cell = s~loadRef();
|
||||
var s2: slice = ref2.beginParse();
|
||||
s.assertEndOfSlice();
|
||||
return (result, s2~loadInt(32), s2.isEndOfSlice());
|
||||
}
|
||||
|
||||
@method_id(107)
|
||||
fun test7() {
|
||||
var s: slice = begin_cell().store_int(1, 32).store_int(2, 32).store_int(3, 32).store_int(4, 32).store_int(5, 32).store_int(6, 32).store_int(7, 32).end_cell().begin_parse();
|
||||
var size1 = slice_bits(s);
|
||||
s~skip_bits(32);
|
||||
var s1: slice = s.first_bits(64);
|
||||
var n1 = s1~load_int(32);
|
||||
var size2 = slice_bits(s);
|
||||
s~load_int(32);
|
||||
var size3 = slice_bits(s);
|
||||
s~skip_last_bits(32);
|
||||
var size4 = slice_bits(s);
|
||||
var n2 = s~load_int(32);
|
||||
var size5 = slice_bits(s);
|
||||
var s: slice = beginCell().storeInt(1, 32).storeInt(2, 32).storeInt(3, 32).storeInt(4, 32).storeInt(5, 32).storeInt(6, 32).storeInt(7, 32).endCell().beginParse();
|
||||
var size1 = getRemainingBitsCount(s);
|
||||
s~skipBits(32);
|
||||
var s1: slice = s.getFirstBits(64);
|
||||
var n1 = s1~loadInt(32);
|
||||
var size2 = getRemainingBitsCount(s);
|
||||
s~loadInt(32);
|
||||
var size3 = getRemainingBitsCount(s);
|
||||
s~removeLastBits(32);
|
||||
var size4 = getRemainingBitsCount(s);
|
||||
var n2 = s~loadInt(32);
|
||||
var size5 = getRemainingBitsCount(s);
|
||||
return (n1, n2, size1, size2, size3, size4, size5);
|
||||
}
|
||||
|
||||
|
@ -118,13 +118,13 @@ fun test7() {
|
|||
fun test108() {
|
||||
var (result1, result2) = (0, 0);
|
||||
try {
|
||||
begin_cell().store_ref(begin_cell().end_cell()).end_cell().begin_parse().end_parse();
|
||||
beginCell().storeRef(beginCell().endCell()).endCell().beginParse().assertEndOfSlice();
|
||||
result1 = 100;
|
||||
} catch (code) {
|
||||
result1 = code;
|
||||
}
|
||||
try {
|
||||
begin_cell().end_cell().begin_parse().end_parse();
|
||||
beginCell().endCell().beginParse().assertEndOfSlice();
|
||||
result2 = 100;
|
||||
} catch (code) {
|
||||
result2 = code;
|
||||
|
@ -134,18 +134,48 @@ fun test108() {
|
|||
|
||||
@method_id(109)
|
||||
fun test109() {
|
||||
var ref2 = begin_cell().store_int(1, 32).end_cell();
|
||||
var ref1 = begin_cell().store_int(1, 32).store_ref(ref2).end_cell();
|
||||
var c = begin_cell().store_int(444, 32).store_ref(ref1).store_ref(ref1).store_ref(ref1).store_ref(ref2).store_int(4, 32).end_cell();
|
||||
var (n_cells1, n_bits1, n_refs1) = c.compute_data_size(10);
|
||||
var s = c.begin_parse();
|
||||
s~load_ref();
|
||||
s~load_ref();
|
||||
var n = s~load_int(32);
|
||||
var (n_cells2, n_bits2, n_refs2) = s.slice_compute_data_size(10);
|
||||
var ref2 = beginCell().storeInt(1, 32).endCell();
|
||||
var ref1 = beginCell().storeInt(1, 32).storeRef(ref2).endCell();
|
||||
var c = beginCell().storeInt(444, 32).storeRef(ref1).storeRef(ref1).storeRef(ref1).storeRef(ref2).storeInt(4, 32).endCell();
|
||||
var (n_cells1, n_bits1, n_refs1) = c.calculateCellSizeStrict(10);
|
||||
var s = c.beginParse();
|
||||
s~loadRef();
|
||||
s~loadRef();
|
||||
var n = s~loadInt(32);
|
||||
var (n_cells2, n_bits2, n_refs2) = s.calculateSliceSizeStrict(10);
|
||||
return ([n_cells1, n_bits1, n_refs1], [n_cells2, n_bits2, n_refs2], n);
|
||||
}
|
||||
|
||||
@method_id(110)
|
||||
fun test110(x: int) {
|
||||
var s = beginCell().storeBool(x < 0).storeBool(0).storeBool(x).endCell().beginParse();
|
||||
return (s~loadBool(), s~loadBool(), s~loadBool());
|
||||
}
|
||||
|
||||
@method_id(111)
|
||||
fun test111() {
|
||||
var s = beginCell().storeMessageOp(123).storeMessageQueryId(456)
|
||||
.storeAddressNone().storeAddressNone()
|
||||
.storeUint(0, 32)
|
||||
.storeUint(123, 32).storeUint(456, 64).storeUint(789, 64)
|
||||
.endCell().beginParse();
|
||||
var op1 = s~loadUint(32);
|
||||
var q1 = s~loadUint(64);
|
||||
if (s.addressIsNone()) {
|
||||
s~skipBits(2);
|
||||
}
|
||||
if (s~loadBool() == 0) {
|
||||
assert(s~loadBool() == 0) throw 444;
|
||||
s~skipBits(32);
|
||||
}
|
||||
var op2 = s~loadMessageOp();
|
||||
var q2 = s~loadMessageQueryId();
|
||||
s~skipBits(64);
|
||||
s.assertEndOfSlice();
|
||||
assert(isMessageBounced(0x001)) throw 444;
|
||||
return (op1, q1, op2, q2);
|
||||
}
|
||||
|
||||
fun main(): int {
|
||||
return 0;
|
||||
}
|
||||
|
@ -160,4 +190,7 @@ fun main(): int {
|
|||
@testcase | 107 | | 2 3 224 192 160 128 96
|
||||
@testcase | 108 | | 9 100
|
||||
@testcase | 109 | | [ 3 128 5 ] [ 2 96 3 ] 444
|
||||
@testcase | 110 | -1 | -1 0 -1
|
||||
@testcase | 110 | 0 | 0 0 0
|
||||
@testcase | 111 | | 123 456 123 456
|
||||
*/
|
||||
|
|
|
@ -43,7 +43,7 @@ asm "SDEQ";
|
|||
fun stslicer(b: builder, s: slice): builder
|
||||
asm "STSLICER";
|
||||
|
||||
fun storeUint(b: builder, x: int, len: int): builder { return store_uint(b, x, len); }
|
||||
fun myStoreUint(b: builder, x: int, len: int): builder { return storeUint(b, x, len); }
|
||||
fun endSlice(b: builder): slice { return endcs(b); }
|
||||
|
||||
fun main() {
|
||||
|
@ -59,9 +59,9 @@ fun main() {
|
|||
var s2: slice = sget2();
|
||||
var s3: slice = newc().stslicer(str1).stslicer(str2r).endcs();
|
||||
|
||||
assert(sdeq(s1, newc().storeUint(str1int, 12 * nibbles).endcs())) throw int111;
|
||||
assert(sdeq(s2, newc().store_uint(str2int, 6 * nibbles).endSlice())) throw 112;
|
||||
assert(sdeq(s3, newc().store_uint(0x636f6e737431AABBCC, 18 * nibbles).endcs())) throw 113;
|
||||
assert(sdeq(s1, newc().myStoreUint(str1int, 12 * nibbles).endcs())) throw int111;
|
||||
assert(sdeq(s2, newc().storeUint(str2int, 6 * nibbles).endSlice())) throw 112;
|
||||
assert(sdeq(s3, newc().storeUint(0x636f6e737431AABBCC, 18 * nibbles).endcs())) throw 113;
|
||||
|
||||
var i4: int = iget240();
|
||||
assert(i4 == 240) throw ((104));
|
||||
|
|
106
tolk-tester/tests/dicts-demo.tolk
Normal file
106
tolk-tester/tests/dicts-demo.tolk
Normal file
|
@ -0,0 +1,106 @@
|
|||
import "@stdlib/tvm-dicts"
|
||||
|
||||
fun ~addIntToIDict(iDict: cell, key: int, number: int): (cell, ()) {
|
||||
iDict~iDictSetBuilder(32, key, beginCell().storeInt(number, 32));
|
||||
return (iDict, ());
|
||||
}
|
||||
|
||||
fun calculateDictLen(d: cell) {
|
||||
var len = 0;
|
||||
var (k, v, f) = d.uDictGetFirst(32);
|
||||
while (f) {
|
||||
len += 1;
|
||||
(k, v, f) = d.uDictGetNext(32, k);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
fun ~loadTwoDigitNumberFromSlice(s: slice): (slice, int) {
|
||||
var n1 = s~loadInt(8);
|
||||
var n2 = s~loadInt(8);
|
||||
return (s, (n1 - 48) * 10 + (n2 - 48));
|
||||
}
|
||||
|
||||
|
||||
@method_id(101)
|
||||
fun test101(getK1: int, getK2: int, getK3: int) {
|
||||
var dict = createEmptyDict();
|
||||
dict~uDictSetBuilder(32, 1, beginCell().storeUint(1, 32));
|
||||
var (old1: slice, found1) = dict~uDictSetAndGet(32, getK1, beginCell().storeUint(2, 32).endCell().beginParse());
|
||||
var (old2: slice, found2) = dict~uDictSetAndGet(32, getK2, beginCell().storeUint(3, 32).endCell().beginParse());
|
||||
var (cur3: slice, found3) = dict.uDictGet(32, getK3);
|
||||
return (
|
||||
found1 ? old1~loadUint(32) : -1,
|
||||
found2 ? old2~loadUint(32) : -1,
|
||||
found3 ? cur3~loadUint(32) : -1
|
||||
);
|
||||
}
|
||||
|
||||
@method_id(102)
|
||||
fun test102() {
|
||||
var dict = createEmptyDict();
|
||||
dict~addIntToIDict(2, 102);
|
||||
dict~addIntToIDict(1, 101);
|
||||
dict~addIntToIDict(4, 104);
|
||||
dict~addIntToIDict(3, 103);
|
||||
var deleted = createEmptyTuple();
|
||||
var shouldBreak = false;
|
||||
while (!shouldBreak) {
|
||||
var (kDel, kVal, wasDel) = dict~iDictDeleteLastAndGet(32);
|
||||
if (wasDel) {
|
||||
deleted~tuplePush([kDel, kVal~loadInt(32)]);
|
||||
} else {
|
||||
shouldBreak = true;
|
||||
}
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@method_id(103)
|
||||
fun test103() {
|
||||
var dict = createEmptyDict();
|
||||
dict~uDictSetBuilderIfNotExists(32, 1,beginCell().storeInt(1, 32));
|
||||
dict~uDictSetBuilderIfNotExists(32, 1,beginCell().storeInt(1, 32));
|
||||
var len1 = calculateDictLen(dict);
|
||||
dict~uDictSetBuilderIfExists(32, 2,beginCell().storeInt(1, 32));
|
||||
dict~uDictSetBuilderIfExists(32, 2,beginCell().storeInt(1, 32));
|
||||
var len2 = calculateDictLen(dict);
|
||||
dict~uDictSetBuilder(32, 3,beginCell().storeInt(1, 32));
|
||||
dict~uDictSetBuilderIfExists(32, 3,beginCell().storeInt(1, 32));
|
||||
var len3 = calculateDictLen(dict);
|
||||
var (delK1, _, _) = dict~uDictDeleteFirstAndGet(32);
|
||||
var (delK2, _, _) = dict~uDictDeleteFirstAndGet(32);
|
||||
var (delK3, _, _) = dict~uDictDeleteFirstAndGet(32);
|
||||
return (len1, len2, len3, delK1, delK2, delK3);
|
||||
}
|
||||
|
||||
@method_id(104)
|
||||
fun test104() {
|
||||
var dict = createEmptyDict();
|
||||
dict~sDictSetBuilder(32, "7800", beginCell().storeUint(5 + 48, 8).storeUint(6 + 48, 8));
|
||||
dict~sDictSet(32, "key1", "12");
|
||||
var (old1, _) = dict~sDictSetAndGet(32, "key1", "34");
|
||||
var (old2, _) = dict~sDictDeleteAndGet(32, "key1");
|
||||
var (restK, restV, _) = dict.sDictGetFirst(32);
|
||||
var (restK1, restV1, _) = dict~sDictDeleteLastAndGet(32);
|
||||
assert (restK.isSliceBitsEqual(restK1)) throw 123;
|
||||
assert (restV.isSliceBitsEqual(restV1)) throw 123;
|
||||
return (
|
||||
old1~loadTwoDigitNumberFromSlice(),
|
||||
old2~loadTwoDigitNumberFromSlice(),
|
||||
restV~loadTwoDigitNumberFromSlice(),
|
||||
restK~loadTwoDigitNumberFromSlice(),
|
||||
restK~loadTwoDigitNumberFromSlice()
|
||||
);
|
||||
}
|
||||
|
||||
fun main() {}
|
||||
|
||||
/**
|
||||
@testcase | 101 | 1 1 1 | 1 2 3
|
||||
@testcase | 101 | 1 2 1 | 1 -1 2
|
||||
@testcase | 101 | 1 2 3 | 1 -1 -1
|
||||
@testcase | 102 | | [ [ 4 104 ] [ 3 103 ] [ 2 102 ] [ 1 101 ] ]
|
||||
@testcase | 103 | | 1 1 2 1 3 (null)
|
||||
@testcase | 104 | | 12 34 56 78 0
|
||||
*/
|
21
tolk-tester/tests/imports/use-dicts-err.tolk
Normal file
21
tolk-tester/tests/imports/use-dicts-err.tolk
Normal file
|
@ -0,0 +1,21 @@
|
|||
fun prepareDict_3_30_4_40_5_x(valueAt5: int): cell {
|
||||
var dict: cell = createEmptyDict();
|
||||
dict~idict_set_builder(32, 3, begin_cell().store_int(30, 32));
|
||||
dict~idict_set_builder(32, 4, begin_cell().store_int(40, 32));
|
||||
dict~idict_set_builder(32, 5, begin_cell().store_int(valueAt5, 32));
|
||||
return dict;
|
||||
}
|
||||
|
||||
fun lookupIdxByValue(idict32: cell, value: int): int {
|
||||
var cur_key = -1;
|
||||
do {
|
||||
var (cur_key redef, cs: slice, found: int) = idict32.idict_get_next?(32, cur_key);
|
||||
// one-line condition (via &) doesn't work, since right side is calculated immediately
|
||||
if (found) {
|
||||
if (cs~load_int(32) == value) {
|
||||
return cur_key;
|
||||
}
|
||||
}
|
||||
} while (found);
|
||||
return -1;
|
||||
}
|
23
tolk-tester/tests/imports/use-dicts.tolk
Normal file
23
tolk-tester/tests/imports/use-dicts.tolk
Normal file
|
@ -0,0 +1,23 @@
|
|||
import "@stdlib/tvm-dicts"
|
||||
|
||||
fun prepareDict_3_30_4_40_5_x(valueAt5: int): cell {
|
||||
var dict: cell = createEmptyDict();
|
||||
dict~iDictSetBuilder(32, 3, beginCell().storeInt(30, 32));
|
||||
dict~iDictSetBuilder(32, 4, beginCell().storeInt(40, 32));
|
||||
dict~iDictSetBuilder(32, 5, beginCell().storeInt(valueAt5, 32));
|
||||
return dict;
|
||||
}
|
||||
|
||||
fun lookupIdxByValue(idict32: cell, value: int): int {
|
||||
var cur_key = -1;
|
||||
do {
|
||||
var (cur_key redef, cs: slice, found: int) = idict32.iDictGetNext(32, cur_key);
|
||||
// one-line condition (via &) doesn't work, since right side is calculated immediately
|
||||
if (found) {
|
||||
if (cs~loadInt(32) == value) {
|
||||
return cur_key;
|
||||
}
|
||||
}
|
||||
} while (found);
|
||||
return -1;
|
||||
}
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/**
|
||||
@compilation_should_fail
|
||||
@stderr invalid-import.tolk:2:7: error: Failed to import: cannot find file
|
||||
On Linux/Mac, `realpath()` returns an error, and the error message is `cannot find file`
|
||||
On Windows, it fails after, on reading, with a message "cannot open file"
|
||||
@stderr invalid-import.tolk:2:7: error: Failed to import: cannot
|
||||
@stderr import "unexisting.tolk";
|
||||
*/
|
||||
|
|
9
tolk-tester/tests/invalid-no-import-2.tolk
Normal file
9
tolk-tester/tests/invalid-no-import-2.tolk
Normal file
|
@ -0,0 +1,9 @@
|
|||
import "@stdlib/tvm-dicts"
|
||||
import "imports/use-dicts-err.tolk"
|
||||
|
||||
/**
|
||||
@compilation_should_fail
|
||||
@stderr imports/use-dicts-err.tolk:2:22
|
||||
@stderr Using a non-imported symbol `createEmptyDict`
|
||||
@stderr Forgot to import "@stdlib/tvm-dicts"?
|
||||
*/
|
|
@ -2,7 +2,7 @@ global g: int;
|
|||
|
||||
@pure
|
||||
fun f_pure(): builder {
|
||||
var b: builder = begin_cell();
|
||||
var b: builder = beginCell();
|
||||
g = g + 1;
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
@pure
|
||||
fun validate_input(input: cell): (int, int) {
|
||||
var (x, y, z, correct) = compute_data_size?(input, 10);
|
||||
var (x, y, z, correct) = calculateCellSize(input, 10);
|
||||
assert(correct) throw 102;
|
||||
}
|
||||
|
||||
@pure
|
||||
fun someF(): int {
|
||||
var c: cell = begin_cell().end_cell();
|
||||
var c: cell = beginCell().endCell();
|
||||
validate_input(c);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
global moddiv: int;
|
||||
global mulDivMod: int;
|
||||
|
||||
/**
|
||||
@compilation_should_fail
|
||||
@stderr global moddiv: int;
|
||||
@stderr global mulDivMod: int;
|
||||
@stderr redefinition of built-in symbol
|
||||
*/
|
||||
|
|
|
@ -4,11 +4,11 @@ fun main(x: int): int {
|
|||
} else {
|
||||
var y: slice = "20";
|
||||
}
|
||||
~dump(y);
|
||||
debugPrint(y);
|
||||
}
|
||||
|
||||
/**
|
||||
@compilation_should_fail
|
||||
@stderr ~dump(y);
|
||||
@stderr debugPrint(y);
|
||||
@stderr undefined symbol `y`
|
||||
*/
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import "imports/use-dicts.tolk"
|
||||
|
||||
fun simpleAllConst() {
|
||||
return (!0, !!0 & !false, !!!0, !1, !!1, !-1, !!-1, (!5 == 0) == !0, !0 == true);
|
||||
}
|
||||
|
@ -43,29 +45,10 @@ fun someSum(upto: int) {
|
|||
return x;
|
||||
}
|
||||
|
||||
|
||||
fun lookupIdxByValue(idict32: cell, value: int) {
|
||||
var cur_key = -1;
|
||||
do {
|
||||
var (cur_key redef, cs: slice, found: int) = idict32.idict_get_next?(32, cur_key);
|
||||
// todo one-line condition (via &) doesn't work, since right side is calculated immediately
|
||||
if (found) {
|
||||
if (cs~load_int(32) == value) {
|
||||
return cur_key;
|
||||
}
|
||||
}
|
||||
} while (found);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@method_id(104)
|
||||
fun testDict(last: int) {
|
||||
// prepare dict: [3 => 30, 4 => 40, 5 => 50]
|
||||
var dict: cell = new_dict();
|
||||
dict~idict_set_builder(32, 3, begin_cell().store_int(30, 32));
|
||||
dict~idict_set_builder(32, 4, begin_cell().store_int(40, 32));
|
||||
dict~idict_set_builder(32, 5, begin_cell().store_int(!last ? 100 : last, 32));
|
||||
|
||||
// prepare dict: [3 => 30, 4 => 40, 5 => x]
|
||||
var dict = prepareDict_3_30_4_40_5_x(!last ? 100 : last);
|
||||
return (lookupIdxByValue(dict, 30), lookupIdxByValue(dict, last), lookupIdxByValue(dict, 100));
|
||||
}
|
||||
|
||||
|
|
|
@ -50,14 +50,14 @@ fun add3(a: int, b: int, c: int) { return a+b+c; }
|
|||
}
|
||||
|
||||
fun `load:u32`(cs: slice): (slice, int) {
|
||||
return cs.load_uint(32);
|
||||
return cs.loadUint(32);
|
||||
}
|
||||
|
||||
@method_id(116) fun `call_~_via_backticks`():[int,int,int,int] {
|
||||
var b:builder = begin_cell().store_uint(1, 32).store_uint(2, 32).store_uint(3, 32).store_uint(4, 32);
|
||||
var `cs`:slice = b.end_cell().begin_parse();
|
||||
var (`cs` redef,one:int) = `cs`.`load_uint`(32);
|
||||
var (two:int,three:int) = (`cs`~`load_uint`(32), cs~`load:u32`());
|
||||
var b:builder = beginCell().storeUint(1, 32).storeUint(2, 32).storeUint(3, 32).storeUint(4, 32);
|
||||
var `cs`:slice = b.endCell().beginParse();
|
||||
var (`cs` redef,one:int) = `cs`.`loadUint`(32);
|
||||
var (two:int,three:int) = (`cs`~`loadUint`(32), cs~`load:u32`());
|
||||
var (cs redef,four:int) = cs.`load:u32`();
|
||||
return [one,two,three,four];
|
||||
}
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import "../../crypto/smartcont/stdlib.tolk"
|
||||
import "@stdlib/lisp-lists"
|
||||
|
||||
@method_id(101)
|
||||
fun test1() {
|
||||
var numbers: tuple = null;
|
||||
numbers = cons(1, numbers);
|
||||
numbers = cons(2, numbers);
|
||||
numbers = cons(3, numbers);
|
||||
numbers = cons(4, numbers);
|
||||
var (h, numbers redef) = uncons(numbers);
|
||||
h += car(numbers);
|
||||
var numbers: tuple = createEmptyList();
|
||||
numbers = listPrepend(1, numbers);
|
||||
numbers = listPrepend(2, numbers);
|
||||
numbers = listPrepend(3, numbers);
|
||||
numbers = listPrepend(4, numbers);
|
||||
var (h, numbers redef) = listSplit(numbers);
|
||||
h += listGetHead(numbers);
|
||||
|
||||
var t = empty_tuple();
|
||||
var t = createEmptyTuple();
|
||||
do {
|
||||
var num = numbers~list_next();
|
||||
t~tpush(num);
|
||||
var num = numbers~listNext();
|
||||
t~tuplePush(num);
|
||||
} while (numbers != null);
|
||||
|
||||
return (h, numbers == null, t);
|
||||
|
@ -52,7 +53,7 @@ fun getUntypedNull() {
|
|||
|
||||
@method_id(104)
|
||||
fun test4() {
|
||||
var (_, (_, untyped)) = (3, (empty_tuple, null));
|
||||
var (_, (_, untyped)) = (3, (createEmptyTuple, null));
|
||||
if (true) {
|
||||
return untyped;
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ fun test4() {
|
|||
@method_id(105)
|
||||
fun test5() {
|
||||
var n = getUntypedNull();
|
||||
return !(null == n) ? n~load_int(32) : 100;
|
||||
return !(null == n) ? n~loadInt(32) : 100;
|
||||
}
|
||||
|
||||
@method_id(106)
|
||||
|
@ -72,9 +73,9 @@ fun test6(x: int) {
|
|||
|
||||
@method_id(107)
|
||||
fun test7() {
|
||||
var b = begin_cell().store_maybe_ref(null);
|
||||
var s = b.end_cell().begin_parse();
|
||||
var c = s~load_maybe_ref();
|
||||
var b = beginCell().storeMaybeRef(null);
|
||||
var s = b.endCell().beginParse();
|
||||
var c = s~loadMaybeRef();
|
||||
return (null == c) * 10 + (b != null);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,16 +11,16 @@ fun f_pure2(): int {
|
|||
|
||||
@pure
|
||||
fun get_contract_data(): (int, int) {
|
||||
var c: cell = get_data();
|
||||
var cs: slice = c.begin_parse();
|
||||
cs~load_bits(32);
|
||||
var value: int = cs~load_uint(16);
|
||||
var c: cell = getContractData();
|
||||
var cs: slice = c.beginParse();
|
||||
cs~loadBits(32);
|
||||
var value: int = cs~loadUint(16);
|
||||
return (1, value);
|
||||
}
|
||||
|
||||
fun save_contract_data(value: int) {
|
||||
var b: builder = begin_cell().store_int(1, 32).store_uint(value, 16);
|
||||
set_data(b.end_cell());
|
||||
var b: builder = beginCell().storeInt(1, 32).storeUint(value, 16);
|
||||
setContractData(b.endCell());
|
||||
}
|
||||
|
||||
@pure
|
||||
|
|
|
@ -43,10 +43,10 @@ fun main() {
|
|||
var i_mini: int = string_minihash();
|
||||
var i_maxi: int = string_maxihash();
|
||||
var i_crc: int = string_crc32();
|
||||
assert(sdeq(s_ascii, newc().store_uint(0x737472696E67, 12 * 4).endcs())) throw 101;
|
||||
assert(sdeq(s_raw, newc().store_uint(0xABCDEF, 6 * 4).endcs())) throw 102;
|
||||
assert(sdeq(s_addr, newc().store_uint(4, 3).store_int(-1, 8)
|
||||
.store_uint(0x3333333333333333333333333333333333333333333333333333333333333333, 256).endcs()), 103);
|
||||
assert(sdeq(s_ascii, newc().storeUint(0x737472696E67, 12 * 4).endcs())) throw 101;
|
||||
assert(sdeq(s_raw, newc().storeUint(0xABCDEF, 6 * 4).endcs())) throw 102;
|
||||
assert(sdeq(s_addr, newc().storeUint(4, 3).storeInt(-1, 8)
|
||||
.storeUint(0x3333333333333333333333333333333333333333333333333333333333333333, 256).endcs()), 103);
|
||||
assert(i_hex == 0x4142434445464748494A4B4C4D4E4F505152535455565758595A303132333435) throw 104;
|
||||
assert(i_mini == 0x7a62e8a8) throw 105;
|
||||
assert(i_maxi == 0x7a62e8a8ebac41bd6de16c65e7be363bc2d2cbc6a0873778dead4795c13db979) throw 106;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
fun main(): int {
|
||||
var c: cell = my_begin_cell().store_int(demo_10, 32).my_end_cell();
|
||||
var c: cell = my_begin_cell().storeInt(demo_10, 32).my_end_cell();
|
||||
var cs: slice = my_begin_parse(c);
|
||||
var ten: int = cs~load_int(32);
|
||||
var ten: int = cs~loadInt(32);
|
||||
return 1 + demo1(ten) + demo_var;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@method_id(101)
|
||||
fun test1(cs: slice) {
|
||||
return cs~load_uint(8)+cs~load_uint(8)+cs~load_uint(8)+cs~load_uint(8);
|
||||
return cs~loadUint(8)+cs~loadUint(8)+cs~loadUint(8)+cs~loadUint(8);
|
||||
}
|
||||
|
||||
@method_id(102)
|
||||
|
@ -12,15 +12,15 @@ fun test2(cs: slice) {
|
|||
}
|
||||
|
||||
fun main(cs: slice) {
|
||||
return (cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(8));
|
||||
return (cs~loadUint(8), cs~loadUint(8), cs~loadUint(8), cs~loadUint(8));
|
||||
}
|
||||
|
||||
fun f(cs: slice) {
|
||||
return (cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(8),
|
||||
cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(8),
|
||||
cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(8),
|
||||
cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(8),
|
||||
cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(8));
|
||||
return (cs~loadUint(8), cs~loadUint(8), cs~loadUint(8), cs~loadUint(8),
|
||||
cs~loadUint(8), cs~loadUint(8), cs~loadUint(8), cs~loadUint(8),
|
||||
cs~loadUint(8), cs~loadUint(8), cs~loadUint(8), cs~loadUint(8),
|
||||
cs~loadUint(8), cs~loadUint(8), cs~loadUint(8), cs~loadUint(8),
|
||||
cs~loadUint(8), cs~loadUint(8), cs~loadUint(8), cs~loadUint(8));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ const TOLKFIFTLIB_MODULE = getenv('TOLKFIFTLIB_MODULE')
|
|||
const TOLKFIFTLIB_WASM = getenv('TOLKFIFTLIB_WASM')
|
||||
const FIFT_EXECUTABLE = getenv('FIFT_EXECUTABLE')
|
||||
const FIFT_LIBS_FOLDER = getenv('FIFTPATH') // this env is needed for fift to work properly
|
||||
const STDLIB_FOLDER = __dirname + '/../crypto/smartcont/tolk-stdlib'
|
||||
const TMP_DIR = os.tmpdir()
|
||||
|
||||
class CmdLineOptions {
|
||||
|
@ -475,25 +476,33 @@ function copyToCStringPtr(mod, str, ptr) {
|
|||
return allocated;
|
||||
}
|
||||
|
||||
/** @return {string} */
|
||||
function copyFromCString(mod, ptr) {
|
||||
return mod.UTF8ToString(ptr);
|
||||
}
|
||||
|
||||
/** @return {{status: string, message: string, fiftCode: string, codeBoc: string, codeHashHex: string}} */
|
||||
function compileFile(mod, filename, experimentalOptions) {
|
||||
// see tolk-wasm.cpp: typedef void (*CStyleReadFileCallback)(int, char const*, char**, char**)
|
||||
// see tolk-wasm.cpp: typedef void (*WasmFsReadCallback)(int, char const*, char**, char**)
|
||||
const callbackPtr = mod.addFunction((kind, dataPtr, destContents, destError) => {
|
||||
if (kind === 0) { // realpath
|
||||
try {
|
||||
const relativeFilename = copyFromCString(mod, dataPtr)
|
||||
copyToCStringPtr(mod, fs.realpathSync(relativeFilename), destContents);
|
||||
let relative = copyFromCString(mod, dataPtr)
|
||||
if (relative.startsWith('@stdlib/')) {
|
||||
// import "@stdlib/filename" or import "@stdlib/filename.tolk"
|
||||
relative = STDLIB_FOLDER + '/' + relative.substring(7)
|
||||
if (!relative.endsWith('.tolk')) {
|
||||
relative += '.tolk'
|
||||
}
|
||||
}
|
||||
copyToCStringPtr(mod, fs.realpathSync(relative), destContents);
|
||||
} catch (err) {
|
||||
copyToCStringPtr(mod, 'cannot find file', destError);
|
||||
}
|
||||
} else if (kind === 1) { // read file
|
||||
try {
|
||||
const filename = copyFromCString(mod, dataPtr) // already normalized (as returned above)
|
||||
copyToCStringPtr(mod, fs.readFileSync(filename).toString('utf-8'), destContents);
|
||||
const absolute = copyFromCString(mod, dataPtr) // already normalized (as returned above)
|
||||
copyToCStringPtr(mod, fs.readFileSync(absolute).toString('utf-8'), destContents);
|
||||
} catch (err) {
|
||||
copyToCStringPtr(mod, err.message || err.toString(), destError);
|
||||
}
|
||||
|
@ -506,7 +515,6 @@ function compileFile(mod, filename, experimentalOptions) {
|
|||
optimizationLevel: 2,
|
||||
withStackComments: true,
|
||||
experimentalOptions: experimentalOptions || undefined,
|
||||
stdlibLocation: __dirname + '/../crypto/smartcont/stdlib.tolk',
|
||||
entrypointFileName: filename
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue