2024-10-31 07:18:54 +00:00
|
|
|
fun store_u32(mutate self: builder, value: int): self {
|
|
|
|
return self.storeUint(value, 32);
|
2024-10-31 07:11:41 +00:00
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
fun load_u32(mutate self: slice): int {
|
|
|
|
return self.loadUint(32);
|
2024-10-31 07:11:41 +00:00
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
fun myLoadInt(mutate self: slice, len: int): int
|
|
|
|
asm(-> 1 0) "LDIX";
|
|
|
|
fun myStoreInt(mutate self: builder, x: int, len: int): self
|
|
|
|
asm(x self len) "STIX";
|
2024-10-31 07:11:41 +00:00
|
|
|
|
|
|
|
@method_id(101)
|
|
|
|
fun test1(): [int,int,int,int,int] {
|
2024-10-31 07:16:19 +00:00
|
|
|
var b: builder = beginCell().storeUint(1, 32);
|
|
|
|
b = b.storeUint(2, 32);
|
2024-10-31 07:18:54 +00:00
|
|
|
b.storeUint(3, 32);
|
2024-10-31 07:11:41 +00:00
|
|
|
b = b.store_u32(4);
|
2024-10-31 07:18:54 +00:00
|
|
|
b.store_u32(5);
|
2024-10-31 07:11:41 +00:00
|
|
|
|
2024-10-31 07:16:19 +00:00
|
|
|
var cs: slice = b.endCell().beginParse();
|
2024-10-31 07:18:54 +00:00
|
|
|
var one: int = cs.loadUint(32);
|
|
|
|
var (two: int, three: int) = (cs.loadUint(32), cs.load_u32());
|
|
|
|
var four: int = cs.load_u32();
|
|
|
|
var five: int = cs.load_u32();
|
2024-10-31 07:11:41 +00:00
|
|
|
|
|
|
|
return [one,two,three,four,five];
|
|
|
|
}
|
|
|
|
|
|
|
|
@method_id(102)
|
|
|
|
fun test2(): [int,int,int] {
|
2024-10-31 07:18:54 +00:00
|
|
|
var b: builder = beginCell().myStoreInt(1, 32);
|
|
|
|
b = b.myStoreInt(2, 32);
|
|
|
|
b.myStoreInt(3, 32);
|
2024-10-31 07:11:41 +00:00
|
|
|
|
2024-10-31 07:16:19 +00:00
|
|
|
var cs: slice = b.endCell().beginParse();
|
2024-10-31 07:18:54 +00:00
|
|
|
var one: int = cs.myLoadInt(32);
|
|
|
|
var (two: int, three: int) = (cs.myLoadInt(32), cs.myLoadInt(32));
|
2024-10-31 07:11:41 +00:00
|
|
|
|
|
|
|
return [one,two,three];
|
|
|
|
}
|
|
|
|
|
|
|
|
@method_id(103)
|
|
|
|
fun test3(ret: int): int {
|
2024-10-31 07:18:54 +00:00
|
|
|
val same: int = beginCell().storeUint(ret,32).endCell().beginParse().loadUint(32);
|
2024-10-31 07:11:41 +00:00
|
|
|
return same;
|
|
|
|
}
|
|
|
|
|
|
|
|
@method_id(104)
|
|
|
|
fun test4(): [int,int] {
|
2024-10-31 07:18:54 +00:00
|
|
|
var b: builder = beginCell().myStoreInt(1, 32);
|
|
|
|
b = b.storeInt(2, 32).storeInt(3, 32);
|
2024-10-31 07:11:41 +00:00
|
|
|
|
2024-10-31 07:16:19 +00:00
|
|
|
var cs: slice = b.endCell().beginParse();
|
2024-10-31 07:18:54 +00:00
|
|
|
var (one, _, three) = (cs.getFirstBits(32).loadUint(32), cs.skipBits(64), cs.load_u32());
|
2024-10-31 07:11:41 +00:00
|
|
|
|
|
|
|
return [one,three];
|
|
|
|
}
|
|
|
|
|
|
|
|
@method_id(105)
|
|
|
|
fun test5(): [int,int] {
|
2024-10-31 07:18:54 +00:00
|
|
|
var cref: cell = endCell(beginCell().store_u32(105));
|
2024-10-31 07:16:19 +00:00
|
|
|
var c: cell = beginCell().storeRef(cref).storeRef(cref).store_u32(1).endCell();
|
|
|
|
|
|
|
|
var cs: slice = beginParse(c);
|
2024-10-31 07:18:54 +00:00
|
|
|
var sto5x2: int = cs.loadRef().beginParse().load_u32() + cs.loadRef().beginParse().loadUint(32);
|
|
|
|
return [sto5x2, cs.load_u32()];
|
|
|
|
}
|
|
|
|
|
|
|
|
@method_id(106)
|
|
|
|
fun test6() {
|
|
|
|
return beginCell().storeUint(1, 32).storeUint(2, 32).storeUint(3, 32);
|
2024-10-31 07:11:41 +00:00
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
@method_id(107)
|
|
|
|
fun test7() {
|
|
|
|
// since .store() methods now mutate, this piece of code works not as earlier (mutates uri_builder)
|
|
|
|
var uri_builder = beginCell();
|
|
|
|
var uri_slice = uri_builder.storeSlice(".json").endCell().beginParse();
|
|
|
|
var image_slice = uri_builder.storeSlice(".png").endCell().beginParse();
|
|
|
|
return (uri_builder.getBuilderBitsCount(), uri_slice.getRemainingBitsCount(), image_slice.getRemainingBitsCount());
|
|
|
|
}
|
|
|
|
|
|
|
|
@method_id(108)
|
|
|
|
fun test8() {
|
|
|
|
var uri_builder = beginCell();
|
|
|
|
var fresh = uri_builder;
|
|
|
|
var uri_slice = fresh.storeSlice(".json").endCell().beginParse();
|
|
|
|
var fresh redef = uri_builder;
|
|
|
|
var image_slice = fresh.storeSlice(".png").endCell().beginParse();
|
|
|
|
return (uri_builder.getBuilderBitsCount(), uri_slice.getRemainingBitsCount(), image_slice.getRemainingBitsCount());
|
|
|
|
}
|
2024-10-31 07:11:41 +00:00
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
|
|
|
|
fun sumNumbersInSlice(mutate self: slice): int {
|
2024-10-31 07:11:41 +00:00
|
|
|
var result = 0;
|
2024-10-31 07:18:54 +00:00
|
|
|
while (!self.isEndOfSliceBits()) {
|
|
|
|
result += self.loadUint(32);
|
2024-10-31 07:11:41 +00:00
|
|
|
}
|
2024-10-31 07:18:54 +00:00
|
|
|
return result;
|
2024-10-31 07:11:41 +00:00
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
@method_id(110)
|
|
|
|
fun test10() {
|
2024-10-31 07:16:19 +00:00
|
|
|
var ref = beginCell().storeInt(100, 32).endCell();
|
|
|
|
var s: slice = beginCell().storeInt(1, 32).storeInt(2, 32).storeRef(ref).endCell().beginParse();
|
2024-10-31 07:18:54 +00:00
|
|
|
var result = (getRemainingBitsCount(s), s.sumNumbersInSlice(), getRemainingBitsCount(s), isEndOfSlice(s), isEndOfSliceBits(s), isEndOfSliceRefs(s));
|
|
|
|
var ref2: cell = s.loadRef();
|
2024-10-31 07:16:19 +00:00
|
|
|
var s2: slice = ref2.beginParse();
|
|
|
|
s.assertEndOfSlice();
|
2024-10-31 07:18:54 +00:00
|
|
|
return (result, s2.loadInt(32), s2.isEndOfSlice());
|
2024-10-31 07:11:41 +00:00
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
@method_id(111)
|
|
|
|
fun test11() {
|
2024-10-31 07:16:19 +00:00
|
|
|
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);
|
2024-10-31 07:18:54 +00:00
|
|
|
s.skipBits(32);
|
2024-10-31 07:16:19 +00:00
|
|
|
var s1: slice = s.getFirstBits(64);
|
2024-10-31 07:18:54 +00:00
|
|
|
var n1 = s1.loadInt(32);
|
2024-10-31 07:16:19 +00:00
|
|
|
var size2 = getRemainingBitsCount(s);
|
2024-10-31 07:18:54 +00:00
|
|
|
s.loadInt(32);
|
2024-10-31 07:16:19 +00:00
|
|
|
var size3 = getRemainingBitsCount(s);
|
2024-10-31 07:18:54 +00:00
|
|
|
s.removeLastBits(32);
|
2024-10-31 07:16:19 +00:00
|
|
|
var size4 = getRemainingBitsCount(s);
|
2024-10-31 07:18:54 +00:00
|
|
|
var n2 = s.loadInt(32);
|
2024-10-31 07:16:19 +00:00
|
|
|
var size5 = getRemainingBitsCount(s);
|
2024-10-31 07:11:41 +00:00
|
|
|
return (n1, n2, size1, size2, size3, size4, size5);
|
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
@method_id(112)
|
|
|
|
fun test12() {
|
2024-10-31 07:11:41 +00:00
|
|
|
var (result1, result2) = (0, 0);
|
|
|
|
try {
|
2024-10-31 07:16:19 +00:00
|
|
|
beginCell().storeRef(beginCell().endCell()).endCell().beginParse().assertEndOfSlice();
|
2024-10-31 07:11:41 +00:00
|
|
|
result1 = 100;
|
|
|
|
} catch (code) {
|
|
|
|
result1 = code;
|
|
|
|
}
|
|
|
|
try {
|
2024-10-31 07:16:19 +00:00
|
|
|
beginCell().endCell().beginParse().assertEndOfSlice();
|
2024-10-31 07:11:41 +00:00
|
|
|
result2 = 100;
|
|
|
|
} catch (code) {
|
|
|
|
result2 = code;
|
|
|
|
}
|
|
|
|
return (result1, result2);
|
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
@method_id(113)
|
|
|
|
fun test13() {
|
2024-10-31 07:16:19 +00:00
|
|
|
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();
|
2024-10-31 07:18:54 +00:00
|
|
|
s.loadRef();
|
|
|
|
s.loadRef();
|
|
|
|
var n = s.loadInt(32);
|
2024-10-31 07:16:19 +00:00
|
|
|
var (n_cells2, n_bits2, n_refs2) = s.calculateSliceSizeStrict(10);
|
2024-10-31 07:11:41 +00:00
|
|
|
return ([n_cells1, n_bits1, n_refs1], [n_cells2, n_bits2, n_refs2], n);
|
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
@method_id(114)
|
2025-01-13 08:21:24 +00:00
|
|
|
fun test110(x: bool) {
|
|
|
|
var s = beginCell().storeBool(x == true).storeBool(false).storeBool(x).endCell().beginParse();
|
2024-10-31 07:18:54 +00:00
|
|
|
return (s.loadBool(), s.loadBool(), s.loadBool());
|
2024-10-31 07:16:19 +00:00
|
|
|
}
|
|
|
|
|
2024-10-31 07:18:54 +00:00
|
|
|
@method_id(115)
|
2024-10-31 07:16:19 +00:00
|
|
|
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();
|
2024-10-31 07:18:54 +00:00
|
|
|
var op1 = s.loadUint(32);
|
|
|
|
var q1 = s.loadUint(64);
|
2024-10-31 07:16:19 +00:00
|
|
|
if (s.addressIsNone()) {
|
2024-10-31 07:18:54 +00:00
|
|
|
s.skipBits(2);
|
2024-10-31 07:16:19 +00:00
|
|
|
}
|
2025-01-13 08:21:24 +00:00
|
|
|
if (s.loadBool() == false) {
|
|
|
|
assert(!s.loadBool()) throw 444;
|
2024-10-31 07:18:54 +00:00
|
|
|
s.skipBouncedPrefix();
|
2024-10-31 07:16:19 +00:00
|
|
|
}
|
2024-10-31 07:18:54 +00:00
|
|
|
var op2 = s.loadMessageOp();
|
|
|
|
var q2 = s.loadMessageQueryId();
|
|
|
|
s.skipBits(64);
|
2024-10-31 07:16:19 +00:00
|
|
|
s.assertEndOfSlice();
|
2025-01-13 08:21:24 +00:00
|
|
|
assert(isMessageBounced(0x001) && !isMessageBounced(0x002)) throw 444;
|
2024-10-31 07:16:19 +00:00
|
|
|
return (op1, q1, op2, q2);
|
|
|
|
}
|
|
|
|
|
2024-10-31 07:11:41 +00:00
|
|
|
fun main(): int {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
@testcase | 101 | | [ 1 2 3 4 5 ]
|
|
|
|
@testcase | 102 | | [ 1 2 3 ]
|
|
|
|
@testcase | 103 | 103 | 103
|
|
|
|
@testcase | 104 | | [ 1 3 ]
|
|
|
|
@testcase | 105 | | [ 210 1 ]
|
2024-10-31 07:18:54 +00:00
|
|
|
@testcase | 107 | | 72 40 72
|
|
|
|
@testcase | 108 | | 0 40 32
|
|
|
|
@testcase | 110 | | 64 3 0 0 -1 0 100 -1
|
|
|
|
@testcase | 111 | | 2 3 224 192 160 128 96
|
|
|
|
@testcase | 112 | | 9 100
|
|
|
|
@testcase | 113 | | [ 3 128 5 ] [ 2 96 3 ] 444
|
|
|
|
@testcase | 114 | -1 | -1 0 -1
|
|
|
|
@testcase | 114 | 0 | 0 0 0
|
|
|
|
@testcase | 115 | | 123 456 123 456
|
|
|
|
|
|
|
|
Note, that since 'compute-asm-ltr' became on be default, chaining methods codegen is not quite optimal.
|
|
|
|
@fif_codegen
|
|
|
|
"""
|
|
|
|
test6 PROC:<{
|
|
|
|
//
|
[Tolk] AST-based semantic analysis, get rid of Expr
This is a huge refactoring focusing on untangling compiler internals
(previously forked from FunC).
The goal is to convert AST directly to Op (a kind of IR representation),
doing all code analysis at AST level.
Noteable changes:
- AST-based semantic kernel includes: registering global symbols,
scope handling and resolving local/global identifiers,
lvalue/rvalue calc and check, implicit return detection,
mutability analysis, pure/impure validity checks,
simple constant folding
- values of `const` variables are calculated NOT based on CodeBlob,
but via a newly-introduced AST-based constant evaluator
- AST vertices are now inherited from expression/statement/other;
expression vertices have common properties (TypeExpr, lvalue/rvalue)
- symbol table is rewritten completely, SymDef/SymVal no longer exist,
lexer now doesn't need to register identifiers
- AST vertices have references to symbols, filled at different
stages of pipeline
- the remaining "FunC legacy part" is almost unchanged besides Expr
which was fully dropped; AST is converted to Ops (IR) directly
2024-12-16 18:19:45 +00:00
|
|
|
NEWC // _0
|
|
|
|
1 PUSHINT // _0 _1=1
|
|
|
|
SWAP // _1=1 _0
|
2024-10-31 07:18:54 +00:00
|
|
|
32 STU // _0
|
[Tolk] AST-based semantic analysis, get rid of Expr
This is a huge refactoring focusing on untangling compiler internals
(previously forked from FunC).
The goal is to convert AST directly to Op (a kind of IR representation),
doing all code analysis at AST level.
Noteable changes:
- AST-based semantic kernel includes: registering global symbols,
scope handling and resolving local/global identifiers,
lvalue/rvalue calc and check, implicit return detection,
mutability analysis, pure/impure validity checks,
simple constant folding
- values of `const` variables are calculated NOT based on CodeBlob,
but via a newly-introduced AST-based constant evaluator
- AST vertices are now inherited from expression/statement/other;
expression vertices have common properties (TypeExpr, lvalue/rvalue)
- symbol table is rewritten completely, SymDef/SymVal no longer exist,
lexer now doesn't need to register identifiers
- AST vertices have references to symbols, filled at different
stages of pipeline
- the remaining "FunC legacy part" is almost unchanged besides Expr
which was fully dropped; AST is converted to Ops (IR) directly
2024-12-16 18:19:45 +00:00
|
|
|
2 PUSHINT // _0 _5=2
|
|
|
|
SWAP // _5=2 _0
|
2024-10-31 07:18:54 +00:00
|
|
|
32 STU // _0
|
[Tolk] AST-based semantic analysis, get rid of Expr
This is a huge refactoring focusing on untangling compiler internals
(previously forked from FunC).
The goal is to convert AST directly to Op (a kind of IR representation),
doing all code analysis at AST level.
Noteable changes:
- AST-based semantic kernel includes: registering global symbols,
scope handling and resolving local/global identifiers,
lvalue/rvalue calc and check, implicit return detection,
mutability analysis, pure/impure validity checks,
simple constant folding
- values of `const` variables are calculated NOT based on CodeBlob,
but via a newly-introduced AST-based constant evaluator
- AST vertices are now inherited from expression/statement/other;
expression vertices have common properties (TypeExpr, lvalue/rvalue)
- symbol table is rewritten completely, SymDef/SymVal no longer exist,
lexer now doesn't need to register identifiers
- AST vertices have references to symbols, filled at different
stages of pipeline
- the remaining "FunC legacy part" is almost unchanged besides Expr
which was fully dropped; AST is converted to Ops (IR) directly
2024-12-16 18:19:45 +00:00
|
|
|
3 PUSHINT // _0 _9=3
|
|
|
|
SWAP // _9=3 _0
|
2024-10-31 07:18:54 +00:00
|
|
|
32 STU // _0
|
|
|
|
}>
|
|
|
|
"""
|
2024-10-31 07:11:41 +00:00
|
|
|
*/
|