Documentation Index
Fetch the complete documentation index at: https://companyname-a7d5b98e-pr-1003-gas-tolk.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Tolk supports structures.
struct Point {
x: int
y: int
}
fun calcMaxCoord(p: Point) {
return p.x > p.y ? p.x : p.y
}
fun demo() {
// declared using object-literal syntax
var p: Point = { x: 10, y: 20 };
calcMaxCoord(p);
// constructed using object-literal syntax
calcMaxCoord({ x: 10, y: 20 });
}
Distinct structure types
Structures with identical fields are not assignable to each other:
struct SomeA { v: int }
struct SomeB { v: int }
fun acceptA(a: SomeA) {}
fun demo(a: SomeA, b: SomeB) {
b = a; // error, can not assign `SomeA` to `SomeB`
acceptA(b); // error, can not pass `SomeB` to `SomeA`
}
Even though SomeA and SomeB have identical layouts, they represent distinct types.
Contextual type inference
The compiler infers types from context. In the example below, the compiler determines that { ... } has type StoredInfo based on the parameter type:
fun store(info: StoredInfo) {
// ...
}
fun demo() {
store({
counterValue: ...,
ownerAddress: ...,
});
}
The same applies to return values and assignments:
fun loadData(): StoredInfo {
return {
counterValue: ...,
ownerAddress: ...,
}
}
fun demo() {
var s: StoredInfo = { counterValue, ... };
var s: (int, StoredInfo) = (0, { counterValue, ... });
}
Explicit type hints
Explicit type hints are available. In addition to the plain { ... } syntax, the form StructName { ... } can be used. The snippet below is equivalent to the previous example:
fun loadData() {
return StoredInfo {
counterValue: ...,
ownerAddress: ...,
}
}
fun demo() {
var s = StoredInfo { counterValue, ... };
var s = (0, StoredInfo { counterValue, ... });
}
When neither contextual information nor an explicit type hint is available, the type cannot be inferred and an error is produced.
val o = { x: 10, y: 20 }; // error, what type is it?
Methods
Methods are declared as extension functions:
fun Point.calcSquare(self) {
return self.x * self.y
}
Without self parameter, a method will be static. By default, self is immutable. The form mutate self enables mutation.
Serialization prefixes
Serialization prefixes do not affect typing or layout. The syntax struct (PREFIX) Name { ... } specifies a serialization prefix. The prefix affects only the binary representation; all other aspects remain unchanged.
struct (0x12345678) CounterIncrement {
byValue: uint32
}
fun demo(inc: CounterIncrement) {
// `inc` has one field; the prefix is not a property
inc.byValue
// `inc` is still one TVM `INT` on the stack
}
Structure syntax
Structure syntax includes:
- shorthand field syntax
{ x, y };
- default field values (
a: int32 = 10);
private and readonly fields;
- serialization prefixes (opcodes).
Stack layout and serialization
Fields are placed on the stack sequentially and are serialized in the same order. If a struct has a prefix, it is written first.
Serialization behavior can be overridden by defining custom serializers.
fun MyStruct.packToBuilder(self, mutate b: builder) {
// custom cell-composition logic
}
fun MyStruct.unpackFromSlice(mutate s: slice) {
// custom cell-parsing logic
}