diff --git a/.github/workflows/external-links.yml b/.github/workflows/external-links.yml index f8c779b74..452f1d375 100644 --- a/.github/workflows/external-links.yml +++ b/.github/workflows/external-links.yml @@ -12,25 +12,26 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: (docs) Check broken HTTPS links + - name: (docs) Check broken HTTP(S) links uses: lycheeverse/lychee-action@v2 id: lychee with: args: > - -n -s https --exclude-path docs/node_modules - --base 'https://docs.tact-lang.org' + -n -s https -s http --base 'https://docs.tact-lang.org' + --exclude-path docs/node_modules --exclude '.*?\\.(?:jpg|png)' docs/README.md './docs/**/*.mdx' output: "/dev/stdout" fail: false failIfEmpty: false - - name: (dev-docs) Check broken HTTPS links + - name: (dev-docs) Check broken HTTP(S) links uses: lycheeverse/lychee-action@v2 id: lychee_dev with: args: > - -n -s https --exclude-path node_modules --exclude-path docs + -n -s https -s http + --exclude-path node_modules --exclude-path docs './**/*.md' output: "/dev/stdout" fail: false diff --git a/dev-docs/CHANGELOG.md b/dev-docs/CHANGELOG.md index 4666d73d4..39684527d 100644 --- a/dev-docs/CHANGELOG.md +++ b/dev-docs/CHANGELOG.md @@ -17,7 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `replace` and `replaceGet` methods for the `Map` type: PR [#941](https://github.com/tact-lang/tact/pull/941) - Utility for logging errors in code that was supposed to be unreachable: PR [#991](https://github.com/tact-lang/tact/pull/991) - Ability to specify a compile-time message opcode expression: PR [#1188](https://github.com/tact-lang/tact/pull/1188) -- The `VarInt16`, `VarInt32`, `VarUint16`, `VarUint32` integer serialization types: PR [#1186](https://github.com/tact-lang/tact/pull/1186) +- The `VarInt16`, `VarInt32`, `VarUint16`, `VarUint32` integer serialization types: PR [#1186](https://github.com/tact-lang/tact/pull/1186), PR [#1274](https://github.com/tact-lang/tact/pull/1274) - `unboc`: a standalone CLI utility to expose Tact's TVM disassembler: PR [#1259](https://github.com/tact-lang/tact/pull/1259) - Added alternative parser: PR [#1258](https://github.com/tact-lang/tact/pull/1258) - Support for block statements: PR [#1334](https://github.com/tact-lang/tact/pull/1334) diff --git a/docs/grammars/grammar-tact.json b/docs/grammars/grammar-tact.json index 3e3aefdd2..f04339ce1 100644 --- a/docs/grammars/grammar-tact.json +++ b/docs/grammars/grammar-tact.json @@ -402,7 +402,7 @@ "comment": "Serialization", "patterns": [ { - "match": "(?

@@ -129,9 +129,13 @@ Name | [TL-B][tlb] | Inclusive range | Sp `uintX{:tact}` | [`uintX`][tlb-builtin] | $0$ to $2^{X} - 1$ | $X$ bits, where $X$ is between $1$ and $256$ `intX{:tact}` | [`intX`][tlb-builtin] | $-2^{X - 1}$ to $2^{X - 1} - 1$ | $X$ bits, where $X$ is between $1$ and $257$ -### Variable `coins` type {#serialization-coins} +### Types of variable bit-width {#serialization-varint} -In Tact, `coins{:tact}` is an alias to [`VarUInteger 16`][varuint] in [TL-B][tlb] representation, i.e. it takes a variable bit length depending on the optimal number of bytes needed to store the given integer and is commonly used for storing [nanoToncoin](/book/integers#nanotoncoin) amounts. +Name | [TL-B][tlb] | Inclusive range | Space taken +:------------: | :-------------------------: | :------------------: | :------------------------- +`coins{:tact}` | [`VarUInteger 16`][varuint] | $0$ to $2^{120} - 1$ | between $4$ and $124$ bits + +In Tact, variable `coins{:tact}` format is an alias to [`VarUInteger 16`][varuint] in [TL-B][tlb] representation, i.e. it takes a variable bit length depending on the optimal number of bytes needed to store the given integer and is commonly used for storing [nanoToncoin](/book/integers#nanotoncoin) amounts. This serialization format consists of two [TL-B fields](https://docs.ton.org/develop/data-formats/tl-b-language#field-definitions): @@ -166,6 +170,45 @@ struct Scrooge { } ``` +Name | [TL-B][tlb] | Inclusive range | Space taken +:----------------: | :-------------------------: | :-------------------------: | :------------------------- +`varuint16{:tact}` | [`VarUInteger 16`][varuint] | same as `coins{:tact}` | same as `coins{:tact}` +`varint16{:tact}` | `VarInteger 16` | $-2^{119}$ to $2^{119} - 1$ | between $4$ and $124$ bits +`varuint32{:tact}` | [`VarUInteger 32`][varuint] | $0$ to $2^{248} - 1$ | between $5$ and $253$ bits +`varint32{:tact}` | `VarInteger 32` | $-2^{247}$ to $2^{247} - 1$ | between $5$ and $253$ bits + +

+ +The `varuint16{:tact}` format is equivalent to [`coins{:tact}`](#serialization-varint). Its signed variant, `varint16{:tact}`, has the same memory layout except for the signed `value` field, which allows a different range of values: from $-2^{119}$ to $2^{119} - 1$, including both ends. + +To store greater values, use `varuint32{:tact}` and `varint32{:tact}` formats. These are serialized almost identical to `coins{:tact}` and lesser variable integer formats, but use a $5$-bit `len` field for storing the byte length. This allows the `value` to use up to $248$ bits for storing the actual number, meaning that both `varuint32{:tact}` and `varint32{:tact}` can occupy up to $253$ bits in total. + +Examples: + +```tact +struct BradBit { + // len: 00000, 5 bits + // value: none! + // in total: 5 bits + a: Int as varuint32 = 0; // 00000 + + // len: 00001, 5 bits + // value: 00000001, 8 bits + // in total: 13 bits + b: Int as varuint32 = 1; // 00001 00000001 + + // len: 00010, 5 bits + // value: 00000001 00000010, 16 bits + // in total: 21 bits + c: Int as varuint32 = 258; // 00010 00000001 00000010 + + // len: 11111, 5 bits + // value: two hundred and forty-eight 1's in binary + // in total: 253 bits + d: Int as varuint32 = pow(2, 248) - 1; // two hundred and forty-eight 1's in binary +} +``` + :::note Read more on serialization here: [Compatibility with FunC](/book/func#convert-serialization) diff --git a/docs/src/content/docs/book/maps.mdx b/docs/src/content/docs/book/maps.mdx index dfd051b0e..6d9a07007 100644 --- a/docs/src/content/docs/book/maps.mdx +++ b/docs/src/content/docs/book/maps.mdx @@ -43,6 +43,12 @@ struct SerializedMapInside { } ``` +Since map keys can only be of fixed-width, [variable integer types](/book/integers#serialization-varint) are not allowed for them. Instead, use [fixed-width serialization formats](/book/integers#serialization-fixed). + +However, map values of type [`Int{:tact}`][int] can have either [fixed](/book/integers#serialization-fixed) or [variable](/book/integers#serialization-varint) bit-length serialization formats specified. + +No other [allowed key or value types](#allowed-types) besides [`Int{:tact}`][int] have serialization formats available. + :::note Read more about serialization in Tact: [Compatibility with FunC](/book/func#convert-serialization). diff --git a/docs/src/content/docs/ref/core-cells.mdx b/docs/src/content/docs/ref/core-cells.mdx index 5815c171a..7a211a1a4 100644 --- a/docs/src/content/docs/ref/core-cells.mdx +++ b/docs/src/content/docs/ref/core-cells.mdx @@ -268,7 +268,7 @@ let fizz: Builder = b.storeCoins(42); :::note[Useful links:] - [Special `coins` serialization type](/book/integers#serialization-coins) + [Special `coins{:tact}` serialization type](/book/integers#serialization-varint) ::: @@ -610,7 +610,7 @@ let fizz: Int = s.loadCoins(); :::note[Useful links:] - [Special `coins` serialization type](/book/integers#serialization-coins) + [Special `coins{:tact}` serialization type](/book/integers#serialization-varint) :::