Skip to content

Commit

Permalink
feat(docs): comptime functions slice, rawSlice, ascii and `crc3…
Browse files Browse the repository at this point in the history
…2` (#951)

* chore(CI): try using `pnpm setup` as advised

that may or may not require sourcing proper files on the system, like
.profile/.bashrc for systems using Bash (Linux in GitHub Actions),
.zprofile/.zshrc for systems using Zsh (macOS in GitHub Actions), etc.

Because of some bug in macos-latest, which overrides the used version of
Node.js (from 22 specified to 20 installed), which then causes
compilation errors with Tact (`.isSubsetOf()` stuff)
  • Loading branch information
novusnota authored Oct 28, 2024
1 parent 9ed1c94 commit 757e62b
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 11 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/tact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,17 @@ jobs:
- name: (pnpm) Test creation of new Blueprint projects
if: ${{ matrix.package-manager == 'pnpm' }}
run: |
npm i -g pnpm
# Installing the specific pnpm version to work around https://github.com/pnpm/pnpm/issues/5000
# and not fail suddenly when a release comes that fixes this
# NOTE: revisit and simplify this step if/when those bugs with pnpm are resolved
npm i -g [email protected]
# To help pnpm recognize the shell (they cannot do it themselves sometimes...)
${{ matrix.os != 'windows-latest' && 'export SHELL=bash' || 'echo windows_noop' }}
pnpm setup -f
# To source .bashrc on Linux:
${{ matrix.os == 'ubuntu-latest' && 'source ~/.bashrc' || 'echo noop' }}
# To expose stuff for pnpm directly on macOS (because otherwise the pre-installed Node.js version gets used):
${{ matrix.os == 'macos-latest' && 'export PNPM_HOME=~/Library/pnpm; export PATH=$PNPM_HOME:$PATH' || 'echo noop' }}
pnpm link -g
cd ..
pnpm create ton@latest test-project --type tact-counter --contractName Counter
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The `deepEquals` method for the `Map` type: PR [#637](https://github.com/tact-lang/tact/pull/637), PR [#939](https://github.com/tact-lang/tact/pull/939)
- `asm` bodies for module-level functions: PR [#769](https://github.com/tact-lang/tact/pull/769), PR [#825](https://github.com/tact-lang/tact/pull/825)
- Corresponding stdlib functions for new TVM instructions from 2023.07 and 2024.04 upgrades: PR [#331](https://github.com/tact-lang/tact/pull/331). Added the `storeBuilder` extension function and `gasConsumed`, `getComputeFee`, `getStorageFee`, `getForwardFee`, `getSimpleComputeFee`, `getSimpleForwardFee`, `getOriginalFwdFee`, `myStorageDue` functions.
- `slice`, `rawSlice`, `ascii` and `crc32` built-in functions: PR [#787](https://github.com/tact-lang/tact/pull/787), PR [#799](https://github.com/tact-lang/tact/pull/799)
- `slice`, `rawSlice`, `ascii` and `crc32` built-in functions: PR [#787](https://github.com/tact-lang/tact/pull/787), PR [#799](https://github.com/tact-lang/tact/pull/799), PR [#951](https://github.com/tact-lang/tact/pull/951)
- `Builder.storeMaybeRef`, `parseStdAddress` and `parseVarAddress` stdlib functions: PR [#793](https://github.com/tact-lang/tact/pull/793), PR [#950](https://github.com/tact-lang/tact/pull/950)
- The compiler development guide: PR [#833](https://github.com/tact-lang/tact/pull/833)
- Constant evaluator now uses an interpreter: PR [#664](https://github.com/tact-lang/tact/pull/664). This allows calls to user-defined functions and references to declared global constants.
Expand Down
138 changes: 129 additions & 9 deletions docs/src/content/docs/ref/core-comptime.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: Compile-time
description: "Various compile-time global functions from the Core library of Tact"
---

import { Badge } from '@astrojs/starlight/components';

This page lists all the built-in [global static functions](/book/functions#global-static-functions), which are evaluated at the time of building the Tact project and cannot work with non-constant, run-time data. These functions are commonly referred to as "compile-time functions".

## address
Expand All @@ -11,7 +13,7 @@ This page lists all the built-in [global static functions](/book/functions#globa
fun address(s: String): Address;
```

A compile-time function that converts a [`String{:tact}`][p] with an address into the [`Address{:tact}`][p] type.
A compile-time function that converts a [`String{:tact}`][p] with an address into the [`Address{:tact}`][p] type and embeds it into the contract.

Usage example:

Expand All @@ -23,28 +25,141 @@ contract Example {
}
```

:::note

The `address("...Address..."){:tact}` in Tact is equivalent to `"...Address..."a{:func}` in FunC.

:::

## cell

```tact
fun cell(bocBase64: String): Cell;
```

A compile-time function that embeds a base64-encoded [BoC](https://docs.ton.org/develop/data-formats/cell-boc#bag-of-cells) `bocBase64` as a [`Cell{:tact}`][cell] into the contract.
A compile-time function that embeds a base64-encoded [BoC][boc] `bocBase64` as a [`Cell{:tact}`][cell] into the contract.

Usage example:
Usage examples:

```tact
contract Example {
// Persistent state variables
storedCell: Cell =
stored: Cell =
// Init package for Wallet V3R1 as a base64-encoded BoC
cell("te6cckEBAQEAYgAAwP8AIN0gggFMl7qXMO1E0NcLH+Ck8mCDCNcYINMf0x/TH/gjE7vyY+1E0NMf0x/T/9FRMrryoVFEuvKiBPkBVBBV+RDyo/gAkyDXSpbTB9QC+wDo0QGkyMsfyx/L/8ntVD++buA="); // works at compile-time!
}
```

:::note[Useful links:]
## slice

<Badge text="Available since Tact 1.5" variant="tip" size="medium"/><p/>

```tact
fun slice(bocBase64: String): Slice;
```

A compile-time function that embeds a base64-encoded [BoC][boc] `bocBase64` as a [`Slice{:tact}`][slice] into the contract.

Usage examples:

```tact
contract Example {
// Persistent state variables
stored: Slice =
// Works at compile-time!
slice("te6cckEBAQEADgAAGEhlbGxvIHdvcmxkIXgtxbw="); // Hello world!
}
```

## rawSlice

<Badge text="Available since Tact 1.5" variant="tip" size="medium"/><p/>

```tact
fun rawSlice(hex: String): Slice;
```

A compile-time function that converts `hex` [`String{:tact}`][p] with hex-encoded and optionally bit-padded contents as a [`Slice{:tact}`][slice] into the contract.

Contents are bit-padded if there's an underscore `_` at the very end of [`String{:tact}`][p]. The padding removes all the trailing zeros and the last $1$ bit before them:

```tact
// Not bit-padded
rawSlice("4a").loadUint(8); // 74, or 1001010 in binary
// Bit-padded
rawSlice("4a_").loadUint(6); // 18, or 10010 in binary
```

Note, that this function is limited and only allows to specify up to $1023$ bits.

Usage example:

```tact
contract Example {
// Persistent state variables
stored: Slice =
rawSlice("000DEADBEEF000"); // CS{Cell{03f...430} bits: 588..644; refs: 1..1}
bitPadded: Slice =
rawSlice("000DEADBEEF000_"); // CS{Cell{03f...e14} bits: 36..79; refs: 0..0}
}
```

:::note

[Bag of Cells in TON Docs](https://docs.ton.org/develop/data-formats/cell-boc#bag-of-cells)
The `rawSlice("...Hex contents..."){:tact}` in Tact is equivalent to `"...Hex contents..."s{:func}` in FunC.

:::

## ascii

<Badge text="Available since Tact 1.5" variant="tip" size="medium"/><p/>

```tact
fun ascii(str: String): Int;
```

A compile-time function that concatenates the hexadecimal values of the characters in `str` into one and embeds the resulting [`Int{:tact}`][int] into the contract. Only works for strings that occupy up to $32$ bytes, which allows to represent up to $32$ [ASCII codes](https://en.wikipedia.org/wiki/ASCII#Control_code_chart) or up to $8$ $4$-byte [Unicode code points](https://en.wikipedia.org/wiki/List_of_Unicode_characters).

Usage example:

```tact
contract Example {
// Persistent state variables
a: Int = ascii("a"); // 97 or 0x61, one byte in total
zap: Int = ascii("⚡"); // 14850721 or 0xE29AA1, 3 bytes in total
doubleZap: Int = ascii("⚡⚡"); // 249153768823457 or 0xE29AA1E29AA1, 6 bytes in total
}
```

:::note

The `ascii("...String contents..."){:tact}` in Tact is equivalent to `"...String contents..."u{:func}` in FunC.

:::

## crc32

<Badge text="Available since Tact 1.5" variant="tip" size="medium"/><p/>

```tact
fun crc32(str: String): Int;
```

A compile-time function that computes a checksum using [CRC-32](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) algorithm and embeds the resulting [`Int{:tact}`][int] value into the contract.

Usage example:

```tact
contract Example {
// Persistent state variables
checksum: Int = crc32("000DEADBEEF000"); // 1821923098
}
```

:::note

The `crc32("...String contents..."){:tact}` in Tact is equivalent to `"...String contents..."c{:func}` in FunC.

:::

Expand All @@ -61,9 +176,9 @@ Usage example:
```tact
contract Example {
// Persistent state variables
one: Int = ton("1"); // 10^9 nanoToncoins, which is equal to one Toncoin
pointOne: Int = ton("0.1"); // 10^8 nanoToncoins, which is equal to 0.1 Toncoin
nano: Int = ton("0.000000001"); // 1 nanoToncoin, which is equal to 10^-9 Toncoins
one: Int = ton("1"); // one Toncoin, which is equivalent to 10^9 nanoToncoins
pointOne: Int = ton("0.1"); // 0.1 Toncoin, which is equivalent to 10^8 nanoToncoins
nano: Int = ton("0.000000001"); // 10^-9 Toncoins, which is equivalent to 1 nanoToncoin
// works at compile-time!
}
```
Expand All @@ -72,3 +187,8 @@ contract Example {
[bool]: /book/types#booleans
[int]: /book/integers
[cell]: /book/cells#cells
[slice]: /book/cells#slices

[boc]: /book/cells#cells-boc

[crc]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check

0 comments on commit 757e62b

Please sign in to comment.