From 19a5f30d7788aa9e425c6a1399dd00a2140c971e Mon Sep 17 00:00:00 2001 From: Gusarich Date: Fri, 25 Oct 2024 09:15:11 +0400 Subject: [PATCH 01/27] feat: add missing functions from `stdlib.fc` --- src/imports/stdlib.ts | 107 +++++++++++------- .../local-type-inference.spec.ts.snap | 33 ++++++ stdlib/std/cells.tact | 25 ++++ stdlib/std/contract.tact | 12 ++ stdlib/stdlib.fc | 23 +++- 5 files changed, 155 insertions(+), 45 deletions(-) diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index f38b5ce7c..b5e57d8d9 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -152,45 +152,52 @@ files['std/cells.tact'] = 'Ly8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9yZW1heWJlcmVmCi8vLwphc20oY2VsbCBzZWxmKSBl' + 'eHRlbmRzIGZ1biBzdG9yZU1heWJlUmVmKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IENlbGw/KTogQnVpbGRlciB7IFNUT1BUUkVGIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRD' + 'ZWxsKHNlbGY6IEJ1aWxkZXIpOiBDZWxsIHsgRU5EQyB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmcyhzZWxmOiBCdWlsZGVyKTogSW50IHsgQlJFRlMgfQoKYXNtIGV4dGVu' + - 'ZHMgZnVuIGJpdHMoc2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCi8vCi8vIFNsaWNlCi8vCgphc20gZXh0ZW5kcyBmdW4gYmVnaW5QYXJzZShzZWxmOiBDZWxs' + - 'KTogU2xpY2UgeyBDVE9TIH0KCmFzbSgtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZFJlZihzZWxmOiBTbGljZSk6IENlbGwgeyBMRFJFRiB9CgovLy8gRXh0' + - 'ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gUHJlbG9hZHMgdGhlIG5leHQgcmVmZXJlbmNl' + - 'IGZyb20gdGhlIGBTbGljZWAgYXMgYSBgQ2VsbGAuIERvZXNuJ3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBgU2xpY2VgLgovLy8KLy8vIEF0dGVtcHRzIHRvIHByZWxvYWQg' + - 'c3VjaCByZWZlcmVuY2UgYENlbGxgIHdoZW4gYFNsaWNlYCBkb2Vzbid0IGNvbnRhaW4gaXQgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDg6IGBDZWxs' + - 'IG92ZXJmbG93YC4KLy8vCi8vLyBBdHRlbXB0cyB0byBwcmVsb2FkIG1vcmUgZGF0YSB0aGFuIGBTbGljZWAgY29udGFpbnMgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGgg' + - 'ZXhpdCBjb2RlIDk6IGBDZWxsIHVuZGVyZmxvd2AuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIGxldCBzMTogU2xpY2UgPSBiZWdp' + - 'bkNlbGwoKS5zdG9yZVJlZihlbXB0eUNlbGwoKSkuYXNTbGljZSgpOwovLy8gICAgIGxldCBmaXp6OiBDZWxsID0gczEucHJlbG9hZFJlZigpOyAvLyBkaWRuJ3QgbW9k' + - 'aWZ5IHMxCi8vLwovLy8gICAgIGxldCBzMjogU2xpY2UgPSBiZWdpbkNlbGwoKQovLy8gICAgICAgICAuc3RvcmVSZWYoZW1wdHlDZWxsKCkpCi8vLyAgICAgICAgIC5z' + - 'dG9yZVJlZihzMS5hc0NlbGwoKSkKLy8vICAgICAgICAgLmFzU2xpY2UoKTsKLy8vICAgICBsZXQgcmVmMTogQ2VsbCA9IHMyLnByZWxvYWRSZWYoKTsKLy8vICAgICBs' + - 'ZXQgcmVmMjogQ2VsbCA9IHMyLnByZWxvYWRSZWYoKTsKLy8vICAgICByZWYxID09IHJlZjI7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICog' + - 'aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2VwcmVsb2FkcmVmCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2sv' + - 'ZXhpdC1jb2RlcwovLy8KYXNtIGV4dGVuZHMgZnVuIHByZWxvYWRSZWYoc2VsZjogU2xpY2UpOiBDZWxsIHsgUExEUkVGIH0KCi8vIHNwZWNpYWwgdHJlYXRtZW50IGlu' + - 'IEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERTTElDRVgiCkBuYW1lKGxvYWRfYml0cykKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2Fk' + - 'Qml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBh' + - 'c20gIlBMRFNMSUNFWCIKQG5hbWUocHJlbG9hZF9iaXRzKQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkQml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7CgovLyBz' + - 'cGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIkxESVgiCkBuYW1lKGxvYWRfaW50KQpleHRlbmRzIG11dGF0' + - 'ZXMgbmF0aXZlIGxvYWRJbnQoc2VsZjogU2xpY2UsIGw6IEludCk6IEludDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBs' + - 'YWNlZCB3aXRoIGFzbSAiUExESVgiCkBuYW1lKHByZWxvYWRfaW50KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkSW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7Cgov' + - 'LyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIkxEVVgiCkBuYW1lKGxvYWRfdWludCkKZXh0ZW5kcyBt' + - 'dXRhdGVzIG5hdGl2ZSBsb2FkVWludChzZWxmOiBTbGljZSwgbDogSW50KTogSW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90' + - 'IHJlcGxhY2VkIHdpdGggYXNtICJQTERVWCIKQG5hbWUocHJlbG9hZF91aW50KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkVWludChzZWxmOiBTbGljZSwgbDogSW50KTog' + - 'SW50OwoKYXNtKC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2FkQm9vbChzZWxmOiBTbGljZSk6IEJvb2wgeyAxIExESSB9CgovLy8gRXh0ZW5zaW9uIG11dGF0' + - 'aW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQWxpYXMgdG8gYFNsaWNlLmxvYWRCb29sKClgLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBg' + - 'YGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgczogU2xpY2UgPSBiZWdpbkNlbGwoKS5zdG9yZUJvb2wodHJ1ZSkuYXNTbGljZSgpOwovLy8gICAg' + - 'IGxldCBmaXp6OiBCb29sID0gcy5sb2FkQml0KCk7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVm' + - 'L2NvcmUtY2VsbHMjc2xpY2Vsb2FkYml0Ci8vLwphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxvYWRCaXQoc2VsZjogU2xpY2UpOiBCb29sIHsgMSBMREkg' + - 'fQoKYXNtKCAtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZENvaW5zKHNlbGY6IFNsaWNlKTogSW50IHsgTERWQVJVSU5UMTYgfQoKQG5hbWUoX190YWN0X2xv' + - 'YWRfYWRkcmVzcykKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2FkQWRkcmVzcyhzZWxmOiBTbGljZSk6IEFkZHJlc3M7Cgphc20gZXh0ZW5kcyBtdXRhdGVzIGZ1biBz' + - 'a2lwQml0cyhzZWxmOiBTbGljZSwgbDogSW50KSB7IFNEU0tJUEZJUlNUIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRQYXJzZShzZWxmOiBTbGljZSkgeyBFTkRTIH0KCi8v' + - 'Ci8vIFNsaWNlIHNpemUKLy8KCmFzbSBleHRlbmRzIGZ1biByZWZzKHNlbGY6IFNsaWNlKTogSW50IHsgU1JFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMoc2VsZjog' + - 'U2xpY2UpOiBJbnQgeyBTQklUUyB9Cgphc20gZXh0ZW5kcyBmdW4gZW1wdHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU0VNUFRZIH0KCmFzbSBleHRlbmRzIGZ1biBkYXRh' + - 'RW1wdHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU0RFTVBUWSB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmc0VtcHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNSRU1QVFkgfQoK' + - 'Ly8KLy8gQ29udmVyc2lvbnMKLy8KCmlubGluZSBleHRlbmRzIGZ1biBhc1NsaWNlKHNlbGY6IEJ1aWxkZXIpOiBTbGljZSB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxs' + - 'KCkuYmVnaW5QYXJzZSgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBDZWxsKTogU2xpY2UgewogICAgcmV0dXJuIHNlbGYuYmVnaW5QYXJzZSgp' + - 'Owp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNDZWxsKHNlbGY6IFNsaWNlKTogQ2VsbCB7CiAgICByZXR1cm4gYmVnaW5DZWxsKCkKICAgICAgICAuc3RvcmVTbGljZShz' + - 'ZWxmKQogICAgICAgIC5lbmRDZWxsKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjogQnVpbGRlcik6IENlbGwgewogICAgcmV0dXJuIHNlbGYuZW5k' + - 'Q2VsbCgpOwp9CgppbmxpbmUgZnVuIGVtcHR5Q2VsbCgpOiBDZWxsIHsKICAgIHJldHVybiBiZWdpbkNlbGwoKS5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlT' + - 'bGljZSgpOiBTbGljZSB7CiAgICByZXR1cm4gZW1wdHlDZWxsKCkuYXNTbGljZSgpOwp9Cg=='; + 'ZHMgZnVuIGJpdHMoc2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCmFzbSBmdW4gYnVpbGRlckRlcHRoKGJ1aWxkZXI6IEJ1aWxkZXIpOiBJbnQgeyBCREVQVEgg' + + 'fQoKLy8KLy8gU2xpY2UKLy8KCmFzbSBleHRlbmRzIGZ1biBiZWdpblBhcnNlKHNlbGY6IENlbGwpOiBTbGljZSB7IENUT1MgfQoKYXNtKC0+IDEgMCkgZXh0ZW5kcyBt' + + 'dXRhdGVzIGZ1biBsb2FkUmVmKHNlbGY6IFNsaWNlKTogQ2VsbCB7IExEUkVGIH0KCi8vLyBFeHRlbnNpb24gZnVuY3Rpb24gZm9yIHRoZSBgU2xpY2VgLiBBdmFpbGFi' + + 'bGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBQcmVsb2FkcyB0aGUgbmV4dCByZWZlcmVuY2UgZnJvbSB0aGUgYFNsaWNlYCBhcyBhIGBDZWxsYC4gRG9lc24ndCBt' + + 'b2RpZnkgdGhlIG9yaWdpbmFsIGBTbGljZWAuCi8vLwovLy8gQXR0ZW1wdHMgdG8gcHJlbG9hZCBzdWNoIHJlZmVyZW5jZSBgQ2VsbGAgd2hlbiBgU2xpY2VgIGRvZXNu' + + 'J3QgY29udGFpbiBpdCB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgODogYENlbGwgb3ZlcmZsb3dgLgovLy8KLy8vIEF0dGVtcHRzIHRvIHByZWxvYWQg' + + 'bW9yZSBkYXRhIHRoYW4gYFNsaWNlYCBjb250YWlucyB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgOTogYENlbGwgdW5kZXJmbG93YC4KLy8vCi8vLyBg' + + 'YGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbGV0IHMxOiBTbGljZSA9IGJlZ2luQ2VsbCgpLnN0b3JlUmVmKGVtcHR5Q2VsbCgpKS5hc1NsaWNlKCk7' + + 'Ci8vLyAgICAgbGV0IGZpeno6IENlbGwgPSBzMS5wcmVsb2FkUmVmKCk7IC8vIGRpZG4ndCBtb2RpZnkgczEKLy8vCi8vLyAgICAgbGV0IHMyOiBTbGljZSA9IGJlZ2lu' + + 'Q2VsbCgpCi8vLyAgICAgICAgIC5zdG9yZVJlZihlbXB0eUNlbGwoKSkKLy8vICAgICAgICAgLnN0b3JlUmVmKHMxLmFzQ2VsbCgpKQovLy8gICAgICAgICAuYXNTbGlj' + + 'ZSgpOwovLy8gICAgIGxldCByZWYxOiBDZWxsID0gczIucHJlbG9hZFJlZigpOwovLy8gICAgIGxldCByZWYyOiBDZWxsID0gczIucHJlbG9hZFJlZigpOwovLy8gICAg' + + 'IHJlZjEgPT0gcmVmMjsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxs' + + 'cyNzbGljZXByZWxvYWRyZWYKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzCi8vLwphc20gZXh0ZW5kcyBmdW4gcHJlbG9hZFJl' + + 'ZihzZWxmOiBTbGljZSk6IENlbGwgeyBQTERSRUYgfQoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNt' + + 'ICJMRFNMSUNFWCIKQG5hbWUobG9hZF9iaXRzKQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGljZTsKCi8vIHNw' + + 'ZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiUExEU0xJQ0VYIgpAbmFtZShwcmVsb2FkX2JpdHMpCmV4dGVu' + + 'ZHMgbmF0aXZlIHByZWxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGljZTsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5v' + + 'dCByZXBsYWNlZCB3aXRoIGFzbSAiTERJWCIKQG5hbWUobG9hZF9pbnQpCmV4dGVuZHMgbXV0YXRlcyBuYXRpdmUgbG9hZEludChzZWxmOiBTbGljZSwgbDogSW50KTog' + + 'SW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNtICJQTERJWCIKQG5hbWUocHJlbG9hZF9pbnQp' + + 'CmV4dGVuZHMgbmF0aXZlIHByZWxvYWRJbnQoc2VsZjogU2xpY2UsIGw6IEludCk6IEludDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNv' + + 'IG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERVWCIKQG5hbWUobG9hZF91aW50KQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRVaW50KHNlbGY6IFNsaWNlLCBsOiBJ' + + 'bnQpOiBJbnQ7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIlBMRFVYIgpAbmFtZShwcmVsb2Fk' + + 'X3VpbnQpCmV4dGVuZHMgbmF0aXZlIHByZWxvYWRVaW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7Cgphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxv' + + 'YWRCb29sKHNlbGY6IFNsaWNlKTogQm9vbCB7IDEgTERJIH0KCi8vLyBFeHRlbnNpb24gbXV0YXRpb24gZnVuY3Rpb24gZm9yIHRoZSBgU2xpY2VgLiBBbGlhcyB0byBg' + + 'U2xpY2UubG9hZEJvb2woKWAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBz' + + 'OiBTbGljZSA9IGJlZ2luQ2VsbCgpLnN0b3JlQm9vbCh0cnVlKS5hc1NsaWNlKCk7Ci8vLyAgICAgbGV0IGZpeno6IEJvb2wgPSBzLmxvYWRCaXQoKTsgLy8gdHJ1ZQov' + + 'Ly8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNzbGljZWxvYWRiaXQKLy8vCmFzbSgtPiAxIDAp' + + 'IGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZEJpdChzZWxmOiBTbGljZSk6IEJvb2wgeyAxIExESSB9Cgphc20oIC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2Fk' + + 'Q29pbnMoc2VsZjogU2xpY2UpOiBJbnQgeyBMRFZBUlVJTlQxNiB9CgpAbmFtZShfX3RhY3RfbG9hZF9hZGRyZXNzKQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRB' + + 'ZGRyZXNzKHNlbGY6IFNsaWNlKTogQWRkcmVzczsKCmFzbSBleHRlbmRzIG11dGF0ZXMgZnVuIHNraXBCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpIHsgU0RTS0lQRklS' + + 'U1QgfQoKYXNtIGV4dGVuZHMgZnVuIGVuZFBhcnNlKHNlbGY6IFNsaWNlKSB7IEVORFMgfQoKYXNtIGV4dGVuZHMgZnVuIHNraXBMYXN0Qml0cyhzZWxmOiBTbGljZSwg' + + 'bGVuOiBJbnQpOiBTbGljZSB7IFNEU0tJUExBU1QgfQoKYXNtIGV4dGVuZHMgZnVuIGZpcnN0Qml0cyhzZWxmOiBTbGljZSwgbGVuOiBJbnQpOiBTbGljZSB7IFNEQ1VU' + + 'RklSU1QgfQoKYXNtIGV4dGVuZHMgZnVuIHNsaWNlTGFzdChzZWxmOiBTbGljZSwgbGVuOiBJbnQpOiBTbGljZSB7IFNEQ1VUTEFTVCB9Cgphc20gZnVuIHNsaWNlRGVw' + + 'dGgoc2xpY2U6IFNsaWNlKTogSW50IHsgU0RFUFRIIH0KCi8vCi8vIFNsaWNlIHNpemUKLy8KCmFzbSBleHRlbmRzIGZ1biByZWZzKHNlbGY6IFNsaWNlKTogSW50IHsg' + + 'U1JFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMoc2VsZjogU2xpY2UpOiBJbnQgeyBTQklUUyB9Cgphc20gZXh0ZW5kcyBmdW4gZW1wdHkoc2VsZjogU2xpY2UpOiBC' + + 'b29sIHsgU0VNUFRZIH0KCmFzbSBleHRlbmRzIGZ1biBkYXRhRW1wdHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU0RFTVBUWSB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmc0Vt' + + 'cHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNSRU1QVFkgfQoKLy8KLy8gQ29udmVyc2lvbnMKLy8KCmlubGluZSBleHRlbmRzIGZ1biBhc1NsaWNlKHNlbGY6IEJ1aWxk' + + 'ZXIpOiBTbGljZSB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxsKCkuYmVnaW5QYXJzZSgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBDZWxsKTog' + + 'U2xpY2UgewogICAgcmV0dXJuIHNlbGYuYmVnaW5QYXJzZSgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNDZWxsKHNlbGY6IFNsaWNlKTogQ2VsbCB7CiAgICByZXR1' + + 'cm4gYmVnaW5DZWxsKCkKICAgICAgICAuc3RvcmVTbGljZShzZWxmKQogICAgICAgIC5lbmRDZWxsKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjog' + + 'QnVpbGRlcik6IENlbGwgewogICAgcmV0dXJuIHNlbGYuZW5kQ2VsbCgpOwp9CgppbmxpbmUgZnVuIGVtcHR5Q2VsbCgpOiBDZWxsIHsKICAgIHJldHVybiBiZWdpbkNl' + + 'bGwoKS5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlTbGljZSgpOiBTbGljZSB7CiAgICByZXR1cm4gZW1wdHlDZWxsKCkuYXNTbGljZSgpOwp9Cgphc20gZnVu' + + 'IHN0cmluZ0hhc2goZGF0YTogU2xpY2UpOiBJbnQgeyBTSEEyNTZVIH0KCnN0cnVjdCBEYXRhU2l6ZSB7CiAgICBjZWxsczogSW50OwogICAgYml0czogSW50OwogICAg' + + 'cmVmczogSW50Owp9Cgphc20gZnVuIGNvbXB1dGVEYXRhU2l6ZShjZWxsOiBDZWxsLCBtYXhDZWxsczogSW50KTogRGF0YVNpemUgeyBDREFUQVNJWkUgVFJJUExFIH0K' + + 'CmFzbSBmdW4gY29tcHV0ZVNsaWNlRGF0YVNpemUoc2xpY2U6IFNsaWNlLCBtYXhDZWxsczogSW50KTogRGF0YVNpemUgeyBTREFUQVNJWkUgVFJJUExFIH0KCmFzbSBm' + + 'dW4gY2VsbERlcHRoKGNlbGw6IENlbGwpOiBJbnQgeyBDREVQVEggfQoK'; files['std/config.tact'] = 'YXNtIGZ1biBnZXRDb25maWdQYXJhbShpZDogSW50KTogQ2VsbD8geyBDT05GSUdPUFRQQVJBTSB9Cg=='; files['std/context.tact'] = @@ -320,7 +327,9 @@ files['std/contract.tact'] = 'OyAgICAgICAgICAgICAvLyAyMzQKLy8vICAgICBwYXJzZWRWYXJBZGRyLmFkZHJlc3M7ICAgICAgICAgICAgICAgLy8gQ1N7Q2VsbHswMDIuLi4yYjN9IGJpdHM6IDQ0' + 'Li4xNjc7IHJlZnM6IDAuLjB9Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2Vl' + 'OiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNwYXJzZXZhcmFkZHJlc3MKLy8vCmFzbSBmdW4gcGFyc2VWYXJBZGRyZXNzKHNsaWNl' + - 'OiBTbGljZSk6IFZhckFkZHJlc3MgeyBSRVdSSVRFVkFSQUREUiB9Cg=='; + 'OiBTbGljZSk6IFZhckFkZHJlc3MgeyBSRVdSSVRFVkFSQUREUiB9Cgphc20gZnVuIGN1ckx0KCk6IEludCB7IExUSU1FIH0KCmFzbSBmdW4gYmxvY2tMdCgpOiBJbnQg' + + 'eyBCTE9DS0xUIH0KCmFzbSBmdW4gc2V0R2FzTGltaXQobGltaXQ6IEludCkgeyBTRVRHQVNMSU1JVCB9Cgphc20gZnVuIGdldFNlZWQoKTogSW50IHsgUkFORFNFRUQg' + + 'fQoKYXNtIGZ1biBzZXRTZWVkKHNlZWQ6IEludCkgeyBTRVRSQU5EIH0KCmFzbSBmdW4gbXlDb2RlKCk6IENlbGwgeyBNWUNPREUgfQo='; files['std/crypto.tact'] = 'YXNtIGV4dGVuZHMgZnVuIGhhc2goc2VsZjogQ2VsbCk6IEludCB7IEhBU0hDVSB9Cgphc20gZXh0ZW5kcyBmdW4gaGFzaChzZWxmOiBTbGljZSk6IEludCB7IEhBU0hT' + 'VSB9Cgphc20gZnVuIGNoZWNrU2lnbmF0dXJlKGhhc2g6IEludCwgc2lnbmF0dXJlOiBTbGljZSwgcHVibGljX2tleTogSW50KTogQm9vbCB7IENIS1NJR05VIH0KCmFz' + @@ -572,7 +581,7 @@ files['stdlib.fc'] = 'ZSBbc10gaW50byBhIHNlcGFyYXRlIGBzbGljZSBzJydgLgo7OyAoc2xpY2UsIHNsaWNlKSBsb2FkX2JpdHMoc2xpY2UgcywgaW50IGxlbikgYXNtKHMgbGVuIC0+IDEg' + 'MCkgIkxEU0xJQ0VYIjsKCjs7OyBQcmVsb2FkcyB0aGUgZmlyc3QgYDAg4omkIGxlbiDiiaQgMTAyM2AgYml0cyBmcm9tIHNsaWNlIFtzXSBpbnRvIGEgc2VwYXJhdGUg' + 'YHNsaWNlIHMnJ2AuCjs7IHNsaWNlIHByZWxvYWRfYml0cyhzbGljZSBzLCBpbnQgbGVuKSBhc20gIlBMRFNMSUNFWCI7Cgo7OzsgTG9hZHMgc2VyaWFsaXplZCBhbW91' + - 'bnQgb2YgVG9uQ29pbnMgKGFueSB1bnNpZ25lZCBpbnRlZ2VyIHVwIHRvIGAyXjEyMCAtIDFgKS4KKHNsaWNlLCBpbnQpIGxvYWRfZ3JhbXMoc2xpY2UgcykgYXNtKC0+' + + 'bnQgb2YgVG9uQ29pbnMgKGFueSB1bnNpZ25lZCBpbnRlZ2VyIHVwIHRvIGAyXjEyOCAtIDFgKS4KKHNsaWNlLCBpbnQpIGxvYWRfZ3JhbXMoc2xpY2UgcykgYXNtKC0+' + 'IDEgMCkgIkxER1JBTVMiOwooc2xpY2UsIGludCkgbG9hZF9jb2lucyhzbGljZSBzKSBhc20oLT4gMSAwKSAiTERWQVJVSU5UMTYiOwoKOzs7IFJldHVybnMgYWxsIGJ1' + 'dCB0aGUgZmlyc3QgYDAg4omkIGxlbiDiiaQgMTAyM2AgYml0cyBvZiBgc2xpY2VgIFtzXS4Kc2xpY2Ugc2tpcF9iaXRzKHNsaWNlIHMsIGludCBsZW4pIGFzbSAiU0RT' + 'S0lQRklSU1QiOwooc2xpY2UsICgpKSB+c2tpcF9iaXRzKHNsaWNlIHMsIGludCBsZW4pIGFzbSAiU0RTS0lQRklSU1QiOwoKOzs7IFJldHVybnMgdGhlIGZpcnN0IGAw' + @@ -618,7 +627,7 @@ files['stdlib.fc'] = 'KHggYiBsZW4pICJTVFVYIjsKCjs7OyBTdG9yZXMgYSBzaWduZWQgW2xlbl0tYml0IGludGVnZXIgYHhgIGludG8gYGJgIGZvcmAgMCDiiaQgbGVuIOKJpCAyNTdgLgo7' + 'OyBidWlsZGVyIHN0b3JlX2ludChidWlsZGVyIGIsIGludCB4LCBpbnQgbGVuKSBhc20oeCBiIGxlbikgIlNUSVgiOwoKCjs7OyBTdG9yZXMgYHNsaWNlYCBbc10gaW50' + 'byBgYnVpbGRlcmAgW2JdCmJ1aWxkZXIgc3RvcmVfc2xpY2UoYnVpbGRlciBiLCBzbGljZSBzKSBhc20gIlNUU0xJQ0VSIjsKCjs7OyBTdG9yZXMgKHNlcmlhbGl6ZXMp' + - 'IGFuIGludGVnZXIgW3hdIGluIHRoZSByYW5nZSBgMC4uMl4xMjAg4oiSIDFgIGludG8gYGJ1aWxkZXJgIFtiXS4KOzs7IFRoZSBzZXJpYWxpemF0aW9uIG9mIFt4XSBj' + + 'IGFuIGludGVnZXIgW3hdIGluIHRoZSByYW5nZSBgMC4uMl4xMjgg4oiSIDFgIGludG8gYGJ1aWxkZXJgIFtiXS4KOzs7IFRoZSBzZXJpYWxpemF0aW9uIG9mIFt4XSBj' + 'b25zaXN0cyBvZiBhIDQtYml0IHVuc2lnbmVkIGJpZy1lbmRpYW4gaW50ZWdlciBgbGAsCjs7OyB3aGljaCBpcyB0aGUgc21hbGxlc3QgaW50ZWdlciBgbCDiiaUgMGAs' + 'IHN1Y2ggdGhhdCBgeCA8IDJeOGxgLAo7OzsgZm9sbG93ZWQgYnkgYW4gYDhsYC1iaXQgdW5zaWduZWQgYmlnLWVuZGlhbiByZXByZXNlbnRhdGlvbiBvZiBbeF0uCjs7' + 'OyBJZiBbeF0gZG9lcyBub3QgYmVsb25nIHRvIHRoZSBzdXBwb3J0ZWQgcmFuZ2UsIGEgcmFuZ2UgY2hlY2sgZXhjZXB0aW9uIGlzIHRocm93bi4KOzs7Cjs7OyBTdG9y' + @@ -837,7 +846,19 @@ files['stdlib.fc'] = 'ZXJfbnVsbD8oYnVpbGRlciBiKSBhc20gIklTTlVMTCI7Cjs7OyBDb25jYXRlbmF0ZXMgdHdvIGJ1aWxkZXJzCmJ1aWxkZXIgc3RvcmVfYnVpbGRlcihidWlsZGVyIHRv' + 'LCBidWlsZGVyIGZyb20pIGFzbSAiU1RCUiI7Cgo7OyBDVVNUT006Cgo7OyBUVk0gVVBHUkFERSAyMDIzLTA3IGh0dHBzOi8vZG9jcy50b24ub3JnL2xlYXJuL3R2bS1p' + 'bnN0cnVjdGlvbnMvdHZtLXVwZ3JhZGUtMjAyMy0wNwo7OyBJbiBtYWlubmV0IHNpbmNlIDIwIERlYyAyMDIzIGh0dHBzOi8vdC5tZS90b25ibG9ja2NoYWluLzIyNgoK' + - 'Ozs7IFJldHJpZXZlcyBjb2RlIG9mIHNtYXJ0LWNvbnRyYWN0IGZyb20gYzcKY2VsbCBteV9jb2RlKCkgYXNtICJNWUNPREUiOwo='; + 'Ozs7IFJldHJpZXZlcyBjb2RlIG9mIHNtYXJ0LWNvbnRyYWN0IGZyb20gYzcKY2VsbCBteV9jb2RlKCkgYXNtICJNWUNPREUiOwoKOzs7IENyZWF0ZXMgYW4gb3V0cHV0' + + 'IGFjdGlvbiBhbmQgcmV0dXJucyBhIGZlZSBmb3IgY3JlYXRpbmcgYSBtZXNzYWdlLiBNb2RlIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaW4gdGhlIGNhc2Ugb2YgU0VO' + + 'RFJBV01TRwppbnQgc2VuZF9tZXNzYWdlKGNlbGwgbXNnLCBpbnQgbW9kZSkgaW1wdXJlIGFzbSAiU0VORE1TRyI7CgppbnQgZ2FzX2NvbnN1bWVkKCkgYXNtICJHQVND' + + 'T05TVU1FRCI7Cgo7OyBUVk0gVjYgaHR0cHM6Ly9naXRodWIuY29tL3Rvbi1ibG9ja2NoYWluL3Rvbi9ibG9iL3Rlc3RuZXQvZG9jL0dsb2JhbFZlcnNpb25zLm1kI3Zl' + + 'cnNpb24tNgoKaW50IGdldF9jb21wdXRlX2ZlZShpbnQgd29ya2NoYWluLCBpbnQgZ2FzX3VzZWQpIGFzbShnYXNfdXNlZCB3b3JrY2hhaW4pICJHRVRHQVNGRUUiOwpp' + + 'bnQgZ2V0X3N0b3JhZ2VfZmVlKGludCB3b3JrY2hhaW4sIGludCBzZWNvbmRzLCBpbnQgYml0cywgaW50IGNlbGxzKSBhc20oY2VsbHMgYml0cyBzZWNvbmRzIHdvcmtj' + + 'aGFpbikgIkdFVFNUT1JBR0VGRUUiOwppbnQgZ2V0X2ZvcndhcmRfZmVlKGludCB3b3JrY2hhaW4sIGludCBiaXRzLCBpbnQgY2VsbHMpIGFzbShjZWxscyBiaXRzIHdv' + + 'cmtjaGFpbikgIkdFVEZPUldBUkRGRUUiOwppbnQgZ2V0X3ByZWNvbXBpbGVkX2dhc19jb25zdW1wdGlvbigpIGFzbSAiR0VUUFJFQ09NUElMRURHQVMiOwoKaW50IGdl' + + 'dF9zaW1wbGVfY29tcHV0ZV9mZWUoaW50IHdvcmtjaGFpbiwgaW50IGdhc191c2VkKSBhc20oZ2FzX3VzZWQgd29ya2NoYWluKSAiR0VUR0FTRkVFU0lNUExFIjsKaW50' + + 'IGdldF9zaW1wbGVfZm9yd2FyZF9mZWUoaW50IHdvcmtjaGFpbiwgaW50IGJpdHMsIGludCBjZWxscykgYXNtKGNlbGxzIGJpdHMgd29ya2NoYWluKSAiR0VURk9SV0FS' + + 'REZFRVNJTVBMRSI7CmludCBnZXRfb3JpZ2luYWxfZndkX2ZlZShpbnQgd29ya2NoYWluLCBpbnQgZndkX2ZlZSkgYXNtKGZ3ZF9mZWUgd29ya2NoYWluKSAiR0VUT1JJ' + + 'R0lOQUxGV0RGRUUiOwppbnQgbXlfc3RvcmFnZV9kdWUoKSBhc20gIkRVRVBBWU1FTlQiOwoKdHVwbGUgZ2V0X2ZlZV9jb2ZpZ3MoKSBhc20gIlVOUEFDS0VEQ09ORklH' + + 'VFVQTEUiOwo='; files['stdlib.tact'] = 'aW1wb3J0ICIuL3N0ZC9wcmltaXRpdmVzIjsKaW1wb3J0ICIuL3N0ZC9jZWxscyI7CmltcG9ydCAiLi9zdGQvY3J5cHRvIjsKaW1wb3J0ICIuL3N0ZC90ZXh0IjsKaW1w' + 'b3J0ICIuL3N0ZC9tYXRoIjsKaW1wb3J0ICIuL3N0ZC9jb250cmFjdCI7CmltcG9ydCAiLi9zdGQvZGVidWciOwppbXBvcnQgIi4vc3RkL2NvbnRleHQiOwppbXBvcnQg' + diff --git a/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap b/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap index 5573c4ad8..c03922a12 100644 --- a/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap +++ b/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap @@ -321,6 +321,39 @@ exports[`local-type-inference should automatically set types for let statements }, ], "types": [ + { + "fields": [ + { + "name": "cells", + "type": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "name": "bits", + "type": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "name": "refs", + "type": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + ], + "header": null, + "name": "DataSize", + }, { "fields": [ { diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index 99c5b7443..51e03e52c 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -82,6 +82,8 @@ asm extends fun refs(self: Builder): Int { BREFS } asm extends fun bits(self: Builder): Int { BBITS } +asm fun builderDepth(builder: Builder): Int { BDEPTH } + // // Slice // @@ -167,6 +169,14 @@ asm extends mutates fun skipBits(self: Slice, l: Int) { SDSKIPFIRST } asm extends fun endParse(self: Slice) { ENDS } +asm extends fun skipLastBits(self: Slice, len: Int): Slice { SDSKIPLAST } + +asm extends fun firstBits(self: Slice, len: Int): Slice { SDCUTFIRST } + +asm extends fun sliceLast(self: Slice, len: Int): Slice { SDCUTLAST } + +asm fun sliceDepth(slice: Slice): Int { SDEPTH } + // // Slice size // @@ -210,3 +220,18 @@ inline fun emptyCell(): Cell { inline fun emptySlice(): Slice { return emptyCell().asSlice(); } + +asm fun stringHash(data: Slice): Int { SHA256U } + +struct DataSize { + cells: Int; + bits: Int; + refs: Int; +} + +asm fun computeDataSize(cell: Cell, maxCells: Int): DataSize { CDATASIZE TRIPLE } + +asm fun computeSliceDataSize(slice: Slice, maxCells: Int): DataSize { SDATASIZE TRIPLE } + +asm fun cellDepth(cell: Cell): Int { CDEPTH } + diff --git a/stdlib/std/contract.tact b/stdlib/std/contract.tact index 1420e3be2..79e1fda5b 100644 --- a/stdlib/std/contract.tact +++ b/stdlib/std/contract.tact @@ -240,3 +240,15 @@ asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR } /// See: https://docs.tact-lang.org/ref/core-advanced#parsevaraddress /// asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR } + +asm fun curLt(): Int { LTIME } + +asm fun blockLt(): Int { BLOCKLT } + +asm fun setGasLimit(limit: Int) { SETGASLIMIT } + +asm fun getSeed(): Int { RANDSEED } + +asm fun setSeed(seed: Int) { SETRAND } + +asm fun myCode(): Cell { MYCODE } diff --git a/stdlib/stdlib.fc b/stdlib/stdlib.fc index 91d461649..0eda659de 100644 --- a/stdlib/stdlib.fc +++ b/stdlib/stdlib.fc @@ -323,7 +323,7 @@ cell preload_ref(slice s) asm "PLDREF"; ;;; Preloads the first `0 ≤ len ≤ 1023` bits from slice [s] into a separate `slice s''`. ;; slice preload_bits(slice s, int len) asm "PLDSLICEX"; -;;; Loads serialized amount of TonCoins (any unsigned integer up to `2^120 - 1`). +;;; Loads serialized amount of TonCoins (any unsigned integer up to `2^128 - 1`). (slice, int) load_grams(slice s) asm(-> 1 0) "LDGRAMS"; (slice, int) load_coins(slice s) asm(-> 1 0) "LDVARUINT16"; @@ -440,7 +440,7 @@ builder store_ref(builder b, cell c) asm(c b) "STREF"; ;;; Stores `slice` [s] into `builder` [b] builder store_slice(builder b, slice s) asm "STSLICER"; -;;; Stores (serializes) an integer [x] in the range `0..2^120 − 1` into `builder` [b]. +;;; Stores (serializes) an integer [x] in the range `0..2^128 − 1` into `builder` [b]. ;;; The serialization of [x] consists of a 4-bit unsigned big-endian integer `l`, ;;; which is the smallest integer `l ≥ 0`, such that `x < 2^8l`, ;;; followed by an `8l`-bit unsigned big-endian representation of [x]. @@ -668,3 +668,22 @@ builder store_builder(builder to, builder from) asm "STBR"; ;;; Retrieves code of smart-contract from c7 cell my_code() asm "MYCODE"; + +;;; Creates an output action and returns a fee for creating a message. Mode has the same effect as in the case of SENDRAWMSG +int send_message(cell msg, int mode) impure asm "SENDMSG"; + +int gas_consumed() asm "GASCONSUMED"; + +;; TVM V6 https://github.com/ton-blockchain/ton/blob/testnet/doc/GlobalVersions.md#version-6 + +int get_compute_fee(int workchain, int gas_used) asm(gas_used workchain) "GETGASFEE"; +int get_storage_fee(int workchain, int seconds, int bits, int cells) asm(cells bits seconds workchain) "GETSTORAGEFEE"; +int get_forward_fee(int workchain, int bits, int cells) asm(cells bits workchain) "GETFORWARDFEE"; +int get_precompiled_gas_consumption() asm "GETPRECOMPILEDGAS"; + +int get_simple_compute_fee(int workchain, int gas_used) asm(gas_used workchain) "GETGASFEESIMPLE"; +int get_simple_forward_fee(int workchain, int bits, int cells) asm(cells bits workchain) "GETFORWARDFEESIMPLE"; +int get_original_fwd_fee(int workchain, int fwd_fee) asm(fwd_fee workchain) "GETORIGINALFWDFEE"; +int my_storage_due() asm "DUEPAYMENT"; + +tuple get_fee_cofigs() asm "UNPACKEDCONFIGTUPLE"; From a198af0ec128c909211fcda8a56059d8746bb2d2 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Fri, 25 Oct 2024 09:30:27 +0400 Subject: [PATCH 02/27] feat: add `sgn` math function --- src/imports/stdlib.ts | 3 ++- stdlib/std/math.tact | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index b5e57d8d9..176b5eda3 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -359,7 +359,8 @@ files['std/math.tact'] = 'aW4pOwp9CgovLyBNYXRoCgphc20gZnVuIG1pbih4OiBJbnQsIHk6IEludCk6IEludCB7IE1JTiB9Cgphc20gZnVuIG1heCh4OiBJbnQsIHk6IEludCk6IEludCB7IE1B' + 'WCB9Cgphc20gZnVuIGFicyh4OiBJbnQpOiBJbnQgeyBBQlMgfQoKYXNtIGZ1biBub3coKTogSW50IHsgTk9XIH0KCmFzbSBmdW4gbG9nMihudW06IEludCk6IEludCB7' + 'CiAgICBEVVAgNSBUSFJPV0lGTk9UIFVCSVRTSVpFIERFQwp9CgpAbmFtZShfX3RhY3RfbG9nKQpuYXRpdmUgbG9nKG51bTogSW50LCBiYXNlOiBJbnQpOiBJbnQ7CgpA' + - 'bmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0='; + 'bmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0KCmFz' + + 'bSBmdW4gc2duKHg6IEludCk6IEludCB7IFNHTiB9Cg=='; files['std/primitives.tact'] = 'cHJpbWl0aXZlIEludDsKcHJpbWl0aXZlIEJvb2w7CnByaW1pdGl2ZSBCdWlsZGVyOwpwcmltaXRpdmUgU2xpY2U7CnByaW1pdGl2ZSBDZWxsOwpwcmltaXRpdmUgQWRk' + 'cmVzczsKcHJpbWl0aXZlIFN0cmluZzsKcHJpbWl0aXZlIFN0cmluZ0J1aWxkZXI7'; diff --git a/stdlib/std/math.tact b/stdlib/std/math.tact index 2186bd633..ed0fb36b5 100644 --- a/stdlib/std/math.tact +++ b/stdlib/std/math.tact @@ -59,4 +59,6 @@ native log(num: Int, base: Int): Int; @name(__tact_pow) native pow(base: Int, exp: Int): Int; -asm fun pow2(exp: Int): Int { POW2 } \ No newline at end of file +asm fun pow2(exp: Int): Int { POW2 } + +asm fun sgn(x: Int): Int { SGN } From 165a1255377dd8e110fea478abe34e934aa61c42 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Fri, 25 Oct 2024 09:31:51 +0400 Subject: [PATCH 03/27] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d00388b5..f3841f0d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Docs: `preloadRef` method for the `Slice` type: PR [#1044](https://github.com/tact-lang/tact/pull/1044) - Docs: added DeDust cookbook: PR [#954](https://github.com/tact-lang/tact/pull/954) - Docs: described the limit for deeply nested expressions: PR [#1101](https://github.com/tact-lang/tact/pull/1101) +- New functions in stdlib from `stdlib.fc` and `math.fc`: PR [#985](https://github.com/tact-lang/tact/pull/985) ### Changed From 7941532c6f3fa7832d4adc4531177ecc64d70f0d Mon Sep 17 00:00:00 2001 From: Daniil Sedov Date: Sun, 17 Nov 2024 10:31:18 +0300 Subject: [PATCH 04/27] feat: apply suggestions from code review Co-authored-by: Novus Nota <68142933+novusnota@users.noreply.github.com> --- stdlib/std/cells.tact | 6 +++--- stdlib/std/math.tact | 2 +- stdlib/stdlib.fc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index 51e03e52c..22aa29794 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -82,7 +82,7 @@ asm extends fun refs(self: Builder): Int { BREFS } asm extends fun bits(self: Builder): Int { BBITS } -asm fun builderDepth(builder: Builder): Int { BDEPTH } +asm extends fun depth(self: Builder): Int { BDEPTH } // // Slice @@ -175,7 +175,7 @@ asm extends fun firstBits(self: Slice, len: Int): Slice { SDCUTFIRST } asm extends fun sliceLast(self: Slice, len: Int): Slice { SDCUTLAST } -asm fun sliceDepth(slice: Slice): Int { SDEPTH } +asm extends fun depth(self: Slice): Int { SDEPTH } // // Slice size @@ -233,5 +233,5 @@ asm fun computeDataSize(cell: Cell, maxCells: Int): DataSize { CDATASIZE TRIPLE asm fun computeSliceDataSize(slice: Slice, maxCells: Int): DataSize { SDATASIZE TRIPLE } -asm fun cellDepth(cell: Cell): Int { CDEPTH } +asm extends fun depth(self: Cell): Int { CDEPTH } diff --git a/stdlib/std/math.tact b/stdlib/std/math.tact index ed0fb36b5..0141d78d1 100644 --- a/stdlib/std/math.tact +++ b/stdlib/std/math.tact @@ -61,4 +61,4 @@ native pow(base: Int, exp: Int): Int; asm fun pow2(exp: Int): Int { POW2 } -asm fun sgn(x: Int): Int { SGN } +asm fun sign(x: Int): Int { SGN } diff --git a/stdlib/stdlib.fc b/stdlib/stdlib.fc index 0eda659de..3135b95d8 100644 --- a/stdlib/stdlib.fc +++ b/stdlib/stdlib.fc @@ -686,4 +686,4 @@ int get_simple_forward_fee(int workchain, int bits, int cells) asm(cells bits wo int get_original_fwd_fee(int workchain, int fwd_fee) asm(fwd_fee workchain) "GETORIGINALFWDFEE"; int my_storage_due() asm "DUEPAYMENT"; -tuple get_fee_cofigs() asm "UNPACKEDCONFIGTUPLE"; +tuple get_fee_configs() asm "UNPACKEDCONFIGTUPLE"; From 00790e4faa33418c13a5df8f9c7987463cac5390 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Sun, 17 Nov 2024 10:36:20 +0300 Subject: [PATCH 05/27] chore: fix varuint comment in stdlib --- stdlib/stdlib.fc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/stdlib.fc b/stdlib/stdlib.fc index 3135b95d8..7761b68f6 100644 --- a/stdlib/stdlib.fc +++ b/stdlib/stdlib.fc @@ -323,7 +323,7 @@ cell preload_ref(slice s) asm "PLDREF"; ;;; Preloads the first `0 ≤ len ≤ 1023` bits from slice [s] into a separate `slice s''`. ;; slice preload_bits(slice s, int len) asm "PLDSLICEX"; -;;; Loads serialized amount of TonCoins (any unsigned integer up to `2^128 - 1`). +;;; Loads serialized amount of TonCoins (any unsigned integer up to `2^120 - 1`). (slice, int) load_grams(slice s) asm(-> 1 0) "LDGRAMS"; (slice, int) load_coins(slice s) asm(-> 1 0) "LDVARUINT16"; @@ -440,7 +440,7 @@ builder store_ref(builder b, cell c) asm(c b) "STREF"; ;;; Stores `slice` [s] into `builder` [b] builder store_slice(builder b, slice s) asm "STSLICER"; -;;; Stores (serializes) an integer [x] in the range `0..2^128 − 1` into `builder` [b]. +;;; Stores (serializes) an integer [x] in the range `0..2^120 − 1` into `builder` [b]. ;;; The serialization of [x] consists of a 4-bit unsigned big-endian integer `l`, ;;; which is the smallest integer `l ≥ 0`, such that `x < 2^8l`, ;;; followed by an `8l`-bit unsigned big-endian representation of [x]. From 293c7cc0c744f365b376d96bb2e05b5fd31753b5 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Sun, 17 Nov 2024 10:38:10 +0300 Subject: [PATCH 06/27] feat: remove `stringHash` due to existence of `.hash` method --- stdlib/std/cells.tact | 2 -- 1 file changed, 2 deletions(-) diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index 22aa29794..ccf524458 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -221,8 +221,6 @@ inline fun emptySlice(): Slice { return emptyCell().asSlice(); } -asm fun stringHash(data: Slice): Int { SHA256U } - struct DataSize { cells: Int; bits: Int; From fba75c78867dcc6f96835ad6d1dd888606930a6d Mon Sep 17 00:00:00 2001 From: Gusarich Date: Sun, 17 Nov 2024 10:45:57 +0300 Subject: [PATCH 07/27] feat: update `stdlib.ts` --- src/imports/stdlib.ts | 87 +++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index 176b5eda3..15b18619c 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -152,40 +152,40 @@ files['std/cells.tact'] = 'Ly8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9yZW1heWJlcmVmCi8vLwphc20oY2VsbCBzZWxmKSBl' + 'eHRlbmRzIGZ1biBzdG9yZU1heWJlUmVmKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IENlbGw/KTogQnVpbGRlciB7IFNUT1BUUkVGIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRD' + 'ZWxsKHNlbGY6IEJ1aWxkZXIpOiBDZWxsIHsgRU5EQyB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmcyhzZWxmOiBCdWlsZGVyKTogSW50IHsgQlJFRlMgfQoKYXNtIGV4dGVu' + - 'ZHMgZnVuIGJpdHMoc2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCmFzbSBmdW4gYnVpbGRlckRlcHRoKGJ1aWxkZXI6IEJ1aWxkZXIpOiBJbnQgeyBCREVQVEgg' + - 'fQoKLy8KLy8gU2xpY2UKLy8KCmFzbSBleHRlbmRzIGZ1biBiZWdpblBhcnNlKHNlbGY6IENlbGwpOiBTbGljZSB7IENUT1MgfQoKYXNtKC0+IDEgMCkgZXh0ZW5kcyBt' + - 'dXRhdGVzIGZ1biBsb2FkUmVmKHNlbGY6IFNsaWNlKTogQ2VsbCB7IExEUkVGIH0KCi8vLyBFeHRlbnNpb24gZnVuY3Rpb24gZm9yIHRoZSBgU2xpY2VgLiBBdmFpbGFi' + - 'bGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBQcmVsb2FkcyB0aGUgbmV4dCByZWZlcmVuY2UgZnJvbSB0aGUgYFNsaWNlYCBhcyBhIGBDZWxsYC4gRG9lc24ndCBt' + - 'b2RpZnkgdGhlIG9yaWdpbmFsIGBTbGljZWAuCi8vLwovLy8gQXR0ZW1wdHMgdG8gcHJlbG9hZCBzdWNoIHJlZmVyZW5jZSBgQ2VsbGAgd2hlbiBgU2xpY2VgIGRvZXNu' + - 'J3QgY29udGFpbiBpdCB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgODogYENlbGwgb3ZlcmZsb3dgLgovLy8KLy8vIEF0dGVtcHRzIHRvIHByZWxvYWQg' + - 'bW9yZSBkYXRhIHRoYW4gYFNsaWNlYCBjb250YWlucyB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgOTogYENlbGwgdW5kZXJmbG93YC4KLy8vCi8vLyBg' + - 'YGB0YWN0Ci8vLyBmdW4gZXhhbXBsZXMoKSB7Ci8vLyAgICAgbGV0IHMxOiBTbGljZSA9IGJlZ2luQ2VsbCgpLnN0b3JlUmVmKGVtcHR5Q2VsbCgpKS5hc1NsaWNlKCk7' + - 'Ci8vLyAgICAgbGV0IGZpeno6IENlbGwgPSBzMS5wcmVsb2FkUmVmKCk7IC8vIGRpZG4ndCBtb2RpZnkgczEKLy8vCi8vLyAgICAgbGV0IHMyOiBTbGljZSA9IGJlZ2lu' + - 'Q2VsbCgpCi8vLyAgICAgICAgIC5zdG9yZVJlZihlbXB0eUNlbGwoKSkKLy8vICAgICAgICAgLnN0b3JlUmVmKHMxLmFzQ2VsbCgpKQovLy8gICAgICAgICAuYXNTbGlj' + - 'ZSgpOwovLy8gICAgIGxldCByZWYxOiBDZWxsID0gczIucHJlbG9hZFJlZigpOwovLy8gICAgIGxldCByZWYyOiBDZWxsID0gczIucHJlbG9hZFJlZigpOwovLy8gICAg' + - 'IHJlZjEgPT0gcmVmMjsgLy8gdHJ1ZQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxs' + - 'cyNzbGljZXByZWxvYWRyZWYKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvYm9vay9leGl0LWNvZGVzCi8vLwphc20gZXh0ZW5kcyBmdW4gcHJlbG9hZFJl' + - 'ZihzZWxmOiBTbGljZSk6IENlbGwgeyBQTERSRUYgfQoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNt' + - 'ICJMRFNMSUNFWCIKQG5hbWUobG9hZF9iaXRzKQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGljZTsKCi8vIHNw' + - 'ZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiUExEU0xJQ0VYIgpAbmFtZShwcmVsb2FkX2JpdHMpCmV4dGVu' + - 'ZHMgbmF0aXZlIHByZWxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGljZTsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5v' + - 'dCByZXBsYWNlZCB3aXRoIGFzbSAiTERJWCIKQG5hbWUobG9hZF9pbnQpCmV4dGVuZHMgbXV0YXRlcyBuYXRpdmUgbG9hZEludChzZWxmOiBTbGljZSwgbDogSW50KTog' + - 'SW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNtICJQTERJWCIKQG5hbWUocHJlbG9hZF9pbnQp' + - 'CmV4dGVuZHMgbmF0aXZlIHByZWxvYWRJbnQoc2VsZjogU2xpY2UsIGw6IEludCk6IEludDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNv' + - 'IG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERVWCIKQG5hbWUobG9hZF91aW50KQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRVaW50KHNlbGY6IFNsaWNlLCBsOiBJ' + - 'bnQpOiBJbnQ7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIlBMRFVYIgpAbmFtZShwcmVsb2Fk' + - 'X3VpbnQpCmV4dGVuZHMgbmF0aXZlIHByZWxvYWRVaW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7Cgphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxv' + - 'YWRCb29sKHNlbGY6IFNsaWNlKTogQm9vbCB7IDEgTERJIH0KCi8vLyBFeHRlbnNpb24gbXV0YXRpb24gZnVuY3Rpb24gZm9yIHRoZSBgU2xpY2VgLiBBbGlhcyB0byBg' + - 'U2xpY2UubG9hZEJvb2woKWAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBz' + - 'OiBTbGljZSA9IGJlZ2luQ2VsbCgpLnN0b3JlQm9vbCh0cnVlKS5hc1NsaWNlKCk7Ci8vLyAgICAgbGV0IGZpeno6IEJvb2wgPSBzLmxvYWRCaXQoKTsgLy8gdHJ1ZQov' + - 'Ly8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNzbGljZWxvYWRiaXQKLy8vCmFzbSgtPiAxIDAp' + - 'IGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZEJpdChzZWxmOiBTbGljZSk6IEJvb2wgeyAxIExESSB9Cgphc20oIC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2Fk' + - 'Q29pbnMoc2VsZjogU2xpY2UpOiBJbnQgeyBMRFZBUlVJTlQxNiB9CgpAbmFtZShfX3RhY3RfbG9hZF9hZGRyZXNzKQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRB' + - 'ZGRyZXNzKHNlbGY6IFNsaWNlKTogQWRkcmVzczsKCmFzbSBleHRlbmRzIG11dGF0ZXMgZnVuIHNraXBCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpIHsgU0RTS0lQRklS' + - 'U1QgfQoKYXNtIGV4dGVuZHMgZnVuIGVuZFBhcnNlKHNlbGY6IFNsaWNlKSB7IEVORFMgfQoKYXNtIGV4dGVuZHMgZnVuIHNraXBMYXN0Qml0cyhzZWxmOiBTbGljZSwg' + - 'bGVuOiBJbnQpOiBTbGljZSB7IFNEU0tJUExBU1QgfQoKYXNtIGV4dGVuZHMgZnVuIGZpcnN0Qml0cyhzZWxmOiBTbGljZSwgbGVuOiBJbnQpOiBTbGljZSB7IFNEQ1VU' + - 'RklSU1QgfQoKYXNtIGV4dGVuZHMgZnVuIHNsaWNlTGFzdChzZWxmOiBTbGljZSwgbGVuOiBJbnQpOiBTbGljZSB7IFNEQ1VUTEFTVCB9Cgphc20gZnVuIHNsaWNlRGVw' + - 'dGgoc2xpY2U6IFNsaWNlKTogSW50IHsgU0RFUFRIIH0KCi8vCi8vIFNsaWNlIHNpemUKLy8KCmFzbSBleHRlbmRzIGZ1biByZWZzKHNlbGY6IFNsaWNlKTogSW50IHsg' + + 'ZHMgZnVuIGJpdHMoc2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCmFzbSBleHRlbmRzIGZ1biBkZXB0aChzZWxmOiBCdWlsZGVyKTogSW50IHsgQkRFUFRIIH0K' + + 'Ci8vCi8vIFNsaWNlCi8vCgphc20gZXh0ZW5kcyBmdW4gYmVnaW5QYXJzZShzZWxmOiBDZWxsKTogU2xpY2UgeyBDVE9TIH0KCmFzbSgtPiAxIDApIGV4dGVuZHMgbXV0' + + 'YXRlcyBmdW4gbG9hZFJlZihzZWxmOiBTbGljZSk6IENlbGwgeyBMRFJFRiB9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQXZhaWxhYmxl' + + 'IHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gUHJlbG9hZHMgdGhlIG5leHQgcmVmZXJlbmNlIGZyb20gdGhlIGBTbGljZWAgYXMgYSBgQ2VsbGAuIERvZXNuJ3QgbW9k' + + 'aWZ5IHRoZSBvcmlnaW5hbCBgU2xpY2VgLgovLy8KLy8vIEF0dGVtcHRzIHRvIHByZWxvYWQgc3VjaCByZWZlcmVuY2UgYENlbGxgIHdoZW4gYFNsaWNlYCBkb2Vzbid0' + + 'IGNvbnRhaW4gaXQgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDg6IGBDZWxsIG92ZXJmbG93YC4KLy8vCi8vLyBBdHRlbXB0cyB0byBwcmVsb2FkIG1v' + + 'cmUgZGF0YSB0aGFuIGBTbGljZWAgY29udGFpbnMgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDk6IGBDZWxsIHVuZGVyZmxvd2AuCi8vLwovLy8gYGBg' + + 'dGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIGxldCBzMTogU2xpY2UgPSBiZWdpbkNlbGwoKS5zdG9yZVJlZihlbXB0eUNlbGwoKSkuYXNTbGljZSgpOwov' + + 'Ly8gICAgIGxldCBmaXp6OiBDZWxsID0gczEucHJlbG9hZFJlZigpOyAvLyBkaWRuJ3QgbW9kaWZ5IHMxCi8vLwovLy8gICAgIGxldCBzMjogU2xpY2UgPSBiZWdpbkNl' + + 'bGwoKQovLy8gICAgICAgICAuc3RvcmVSZWYoZW1wdHlDZWxsKCkpCi8vLyAgICAgICAgIC5zdG9yZVJlZihzMS5hc0NlbGwoKSkKLy8vICAgICAgICAgLmFzU2xpY2Uo' + + 'KTsKLy8vICAgICBsZXQgcmVmMTogQ2VsbCA9IHMyLnByZWxvYWRSZWYoKTsKLy8vICAgICBsZXQgcmVmMjogQ2VsbCA9IHMyLnByZWxvYWRSZWYoKTsKLy8vICAgICBy' + + 'ZWYxID09IHJlZjI7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMj' + + 'c2xpY2VwcmVsb2FkcmVmCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcwovLy8KYXNtIGV4dGVuZHMgZnVuIHByZWxvYWRSZWYo' + + 'c2VsZjogU2xpY2UpOiBDZWxsIHsgUExEUkVGIH0KCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAi' + + 'TERTTElDRVgiCkBuYW1lKGxvYWRfYml0cykKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2FkQml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7CgovLyBzcGVj' + + 'aWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIlBMRFNMSUNFWCIKQG5hbWUocHJlbG9hZF9iaXRzKQpleHRlbmRz' + + 'IG5hdGl2ZSBwcmVsb2FkQml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3Qg' + + 'cmVwbGFjZWQgd2l0aCBhc20gIkxESVgiCkBuYW1lKGxvYWRfaW50KQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRJbnQoc2VsZjogU2xpY2UsIGw6IEludCk6IElu' + + 'dDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiUExESVgiCkBuYW1lKHByZWxvYWRfaW50KQpl' + + 'eHRlbmRzIG5hdGl2ZSBwcmVsb2FkSW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBu' + + 'b3QgcmVwbGFjZWQgd2l0aCBhc20gIkxEVVgiCkBuYW1lKGxvYWRfdWludCkKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2FkVWludChzZWxmOiBTbGljZSwgbDogSW50' + + 'KTogSW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNtICJQTERVWCIKQG5hbWUocHJlbG9hZF91' + + 'aW50KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkVWludChzZWxmOiBTbGljZSwgbDogSW50KTogSW50OwoKYXNtKC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2Fk' + + 'Qm9vbChzZWxmOiBTbGljZSk6IEJvb2wgeyAxIExESSB9CgovLy8gRXh0ZW5zaW9uIG11dGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQWxpYXMgdG8gYFNs' + + 'aWNlLmxvYWRCb29sKClgLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgczog' + + 'U2xpY2UgPSBiZWdpbkNlbGwoKS5zdG9yZUJvb2wodHJ1ZSkuYXNTbGljZSgpOwovLy8gICAgIGxldCBmaXp6OiBCb29sID0gcy5sb2FkQml0KCk7IC8vIHRydWUKLy8v' + + 'IH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2Vsb2FkYml0Ci8vLwphc20oLT4gMSAwKSBl' + + 'eHRlbmRzIG11dGF0ZXMgZnVuIGxvYWRCaXQoc2VsZjogU2xpY2UpOiBCb29sIHsgMSBMREkgfQoKYXNtKCAtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZENv' + + 'aW5zKHNlbGY6IFNsaWNlKTogSW50IHsgTERWQVJVSU5UMTYgfQoKQG5hbWUoX190YWN0X2xvYWRfYWRkcmVzcykKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2FkQWRk' + + 'cmVzcyhzZWxmOiBTbGljZSk6IEFkZHJlc3M7Cgphc20gZXh0ZW5kcyBtdXRhdGVzIGZ1biBza2lwQml0cyhzZWxmOiBTbGljZSwgbDogSW50KSB7IFNEU0tJUEZJUlNU' + + 'IH0KCmFzbSBleHRlbmRzIGZ1biBlbmRQYXJzZShzZWxmOiBTbGljZSkgeyBFTkRTIH0KCmFzbSBleHRlbmRzIGZ1biBza2lwTGFzdEJpdHMoc2VsZjogU2xpY2UsIGxl' + + 'bjogSW50KTogU2xpY2UgeyBTRFNLSVBMQVNUIH0KCmFzbSBleHRlbmRzIGZ1biBmaXJzdEJpdHMoc2VsZjogU2xpY2UsIGxlbjogSW50KTogU2xpY2UgeyBTRENVVEZJ' + + 'UlNUIH0KCmFzbSBleHRlbmRzIGZ1biBzbGljZUxhc3Qoc2VsZjogU2xpY2UsIGxlbjogSW50KTogU2xpY2UgeyBTRENVVExBU1QgfQoKYXNtIGV4dGVuZHMgZnVuIGRl' + + 'cHRoKHNlbGY6IFNsaWNlKTogSW50IHsgU0RFUFRIIH0KCi8vCi8vIFNsaWNlIHNpemUKLy8KCmFzbSBleHRlbmRzIGZ1biByZWZzKHNlbGY6IFNsaWNlKTogSW50IHsg' + 'U1JFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMoc2VsZjogU2xpY2UpOiBJbnQgeyBTQklUUyB9Cgphc20gZXh0ZW5kcyBmdW4gZW1wdHkoc2VsZjogU2xpY2UpOiBC' + 'b29sIHsgU0VNUFRZIH0KCmFzbSBleHRlbmRzIGZ1biBkYXRhRW1wdHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU0RFTVBUWSB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmc0Vt' + 'cHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNSRU1QVFkgfQoKLy8KLy8gQ29udmVyc2lvbnMKLy8KCmlubGluZSBleHRlbmRzIGZ1biBhc1NsaWNlKHNlbGY6IEJ1aWxk' + @@ -193,11 +193,10 @@ files['std/cells.tact'] = 'U2xpY2UgewogICAgcmV0dXJuIHNlbGYuYmVnaW5QYXJzZSgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNDZWxsKHNlbGY6IFNsaWNlKTogQ2VsbCB7CiAgICByZXR1' + 'cm4gYmVnaW5DZWxsKCkKICAgICAgICAuc3RvcmVTbGljZShzZWxmKQogICAgICAgIC5lbmRDZWxsKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjog' + 'QnVpbGRlcik6IENlbGwgewogICAgcmV0dXJuIHNlbGYuZW5kQ2VsbCgpOwp9CgppbmxpbmUgZnVuIGVtcHR5Q2VsbCgpOiBDZWxsIHsKICAgIHJldHVybiBiZWdpbkNl' + - 'bGwoKS5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlTbGljZSgpOiBTbGljZSB7CiAgICByZXR1cm4gZW1wdHlDZWxsKCkuYXNTbGljZSgpOwp9Cgphc20gZnVu' + - 'IHN0cmluZ0hhc2goZGF0YTogU2xpY2UpOiBJbnQgeyBTSEEyNTZVIH0KCnN0cnVjdCBEYXRhU2l6ZSB7CiAgICBjZWxsczogSW50OwogICAgYml0czogSW50OwogICAg' + - 'cmVmczogSW50Owp9Cgphc20gZnVuIGNvbXB1dGVEYXRhU2l6ZShjZWxsOiBDZWxsLCBtYXhDZWxsczogSW50KTogRGF0YVNpemUgeyBDREFUQVNJWkUgVFJJUExFIH0K' + - 'CmFzbSBmdW4gY29tcHV0ZVNsaWNlRGF0YVNpemUoc2xpY2U6IFNsaWNlLCBtYXhDZWxsczogSW50KTogRGF0YVNpemUgeyBTREFUQVNJWkUgVFJJUExFIH0KCmFzbSBm' + - 'dW4gY2VsbERlcHRoKGNlbGw6IENlbGwpOiBJbnQgeyBDREVQVEggfQoK'; + 'bGwoKS5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlTbGljZSgpOiBTbGljZSB7CiAgICByZXR1cm4gZW1wdHlDZWxsKCkuYXNTbGljZSgpOwp9CgpzdHJ1Y3Qg' + + 'RGF0YVNpemUgewogICAgY2VsbHM6IEludDsKICAgIGJpdHM6IEludDsKICAgIHJlZnM6IEludDsKfQoKYXNtIGZ1biBjb21wdXRlRGF0YVNpemUoY2VsbDogQ2VsbCwg' + + 'bWF4Q2VsbHM6IEludCk6IERhdGFTaXplIHsgQ0RBVEFTSVpFIFRSSVBMRSB9Cgphc20gZnVuIGNvbXB1dGVTbGljZURhdGFTaXplKHNsaWNlOiBTbGljZSwgbWF4Q2Vs' + + 'bHM6IEludCk6IERhdGFTaXplIHsgU0RBVEFTSVpFIFRSSVBMRSB9Cgphc20gZXh0ZW5kcyBmdW4gZGVwdGgoc2VsZjogQ2VsbCk6IEludCB7IENERVBUSCB9Cgo='; files['std/config.tact'] = 'YXNtIGZ1biBnZXRDb25maWdQYXJhbShpZDogSW50KTogQ2VsbD8geyBDT05GSUdPUFRQQVJBTSB9Cg=='; files['std/context.tact'] = @@ -360,7 +359,7 @@ files['std/math.tact'] = 'WCB9Cgphc20gZnVuIGFicyh4OiBJbnQpOiBJbnQgeyBBQlMgfQoKYXNtIGZ1biBub3coKTogSW50IHsgTk9XIH0KCmFzbSBmdW4gbG9nMihudW06IEludCk6IEludCB7' + 'CiAgICBEVVAgNSBUSFJPV0lGTk9UIFVCSVRTSVpFIERFQwp9CgpAbmFtZShfX3RhY3RfbG9nKQpuYXRpdmUgbG9nKG51bTogSW50LCBiYXNlOiBJbnQpOiBJbnQ7CgpA' + 'bmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0KCmFz' + - 'bSBmdW4gc2duKHg6IEludCk6IEludCB7IFNHTiB9Cg=='; + 'bSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQo='; files['std/primitives.tact'] = 'cHJpbWl0aXZlIEludDsKcHJpbWl0aXZlIEJvb2w7CnByaW1pdGl2ZSBCdWlsZGVyOwpwcmltaXRpdmUgU2xpY2U7CnByaW1pdGl2ZSBDZWxsOwpwcmltaXRpdmUgQWRk' + 'cmVzczsKcHJpbWl0aXZlIFN0cmluZzsKcHJpbWl0aXZlIFN0cmluZ0J1aWxkZXI7'; @@ -582,7 +581,7 @@ files['stdlib.fc'] = 'ZSBbc10gaW50byBhIHNlcGFyYXRlIGBzbGljZSBzJydgLgo7OyAoc2xpY2UsIHNsaWNlKSBsb2FkX2JpdHMoc2xpY2UgcywgaW50IGxlbikgYXNtKHMgbGVuIC0+IDEg' + 'MCkgIkxEU0xJQ0VYIjsKCjs7OyBQcmVsb2FkcyB0aGUgZmlyc3QgYDAg4omkIGxlbiDiiaQgMTAyM2AgYml0cyBmcm9tIHNsaWNlIFtzXSBpbnRvIGEgc2VwYXJhdGUg' + 'YHNsaWNlIHMnJ2AuCjs7IHNsaWNlIHByZWxvYWRfYml0cyhzbGljZSBzLCBpbnQgbGVuKSBhc20gIlBMRFNMSUNFWCI7Cgo7OzsgTG9hZHMgc2VyaWFsaXplZCBhbW91' + - 'bnQgb2YgVG9uQ29pbnMgKGFueSB1bnNpZ25lZCBpbnRlZ2VyIHVwIHRvIGAyXjEyOCAtIDFgKS4KKHNsaWNlLCBpbnQpIGxvYWRfZ3JhbXMoc2xpY2UgcykgYXNtKC0+' + + 'bnQgb2YgVG9uQ29pbnMgKGFueSB1bnNpZ25lZCBpbnRlZ2VyIHVwIHRvIGAyXjEyMCAtIDFgKS4KKHNsaWNlLCBpbnQpIGxvYWRfZ3JhbXMoc2xpY2UgcykgYXNtKC0+' + 'IDEgMCkgIkxER1JBTVMiOwooc2xpY2UsIGludCkgbG9hZF9jb2lucyhzbGljZSBzKSBhc20oLT4gMSAwKSAiTERWQVJVSU5UMTYiOwoKOzs7IFJldHVybnMgYWxsIGJ1' + 'dCB0aGUgZmlyc3QgYDAg4omkIGxlbiDiiaQgMTAyM2AgYml0cyBvZiBgc2xpY2VgIFtzXS4Kc2xpY2Ugc2tpcF9iaXRzKHNsaWNlIHMsIGludCBsZW4pIGFzbSAiU0RT' + 'S0lQRklSU1QiOwooc2xpY2UsICgpKSB+c2tpcF9iaXRzKHNsaWNlIHMsIGludCBsZW4pIGFzbSAiU0RTS0lQRklSU1QiOwoKOzs7IFJldHVybnMgdGhlIGZpcnN0IGAw' + @@ -628,7 +627,7 @@ files['stdlib.fc'] = 'KHggYiBsZW4pICJTVFVYIjsKCjs7OyBTdG9yZXMgYSBzaWduZWQgW2xlbl0tYml0IGludGVnZXIgYHhgIGludG8gYGJgIGZvcmAgMCDiiaQgbGVuIOKJpCAyNTdgLgo7' + 'OyBidWlsZGVyIHN0b3JlX2ludChidWlsZGVyIGIsIGludCB4LCBpbnQgbGVuKSBhc20oeCBiIGxlbikgIlNUSVgiOwoKCjs7OyBTdG9yZXMgYHNsaWNlYCBbc10gaW50' + 'byBgYnVpbGRlcmAgW2JdCmJ1aWxkZXIgc3RvcmVfc2xpY2UoYnVpbGRlciBiLCBzbGljZSBzKSBhc20gIlNUU0xJQ0VSIjsKCjs7OyBTdG9yZXMgKHNlcmlhbGl6ZXMp' + - 'IGFuIGludGVnZXIgW3hdIGluIHRoZSByYW5nZSBgMC4uMl4xMjgg4oiSIDFgIGludG8gYGJ1aWxkZXJgIFtiXS4KOzs7IFRoZSBzZXJpYWxpemF0aW9uIG9mIFt4XSBj' + + 'IGFuIGludGVnZXIgW3hdIGluIHRoZSByYW5nZSBgMC4uMl4xMjAg4oiSIDFgIGludG8gYGJ1aWxkZXJgIFtiXS4KOzs7IFRoZSBzZXJpYWxpemF0aW9uIG9mIFt4XSBj' + 'b25zaXN0cyBvZiBhIDQtYml0IHVuc2lnbmVkIGJpZy1lbmRpYW4gaW50ZWdlciBgbGAsCjs7OyB3aGljaCBpcyB0aGUgc21hbGxlc3QgaW50ZWdlciBgbCDiiaUgMGAs' + 'IHN1Y2ggdGhhdCBgeCA8IDJeOGxgLAo7OzsgZm9sbG93ZWQgYnkgYW4gYDhsYC1iaXQgdW5zaWduZWQgYmlnLWVuZGlhbiByZXByZXNlbnRhdGlvbiBvZiBbeF0uCjs7' + 'OyBJZiBbeF0gZG9lcyBub3QgYmVsb25nIHRvIHRoZSBzdXBwb3J0ZWQgcmFuZ2UsIGEgcmFuZ2UgY2hlY2sgZXhjZXB0aW9uIGlzIHRocm93bi4KOzs7Cjs7OyBTdG9y' + @@ -858,8 +857,8 @@ files['stdlib.fc'] = 'dF9zaW1wbGVfY29tcHV0ZV9mZWUoaW50IHdvcmtjaGFpbiwgaW50IGdhc191c2VkKSBhc20oZ2FzX3VzZWQgd29ya2NoYWluKSAiR0VUR0FTRkVFU0lNUExFIjsKaW50' + 'IGdldF9zaW1wbGVfZm9yd2FyZF9mZWUoaW50IHdvcmtjaGFpbiwgaW50IGJpdHMsIGludCBjZWxscykgYXNtKGNlbGxzIGJpdHMgd29ya2NoYWluKSAiR0VURk9SV0FS' + 'REZFRVNJTVBMRSI7CmludCBnZXRfb3JpZ2luYWxfZndkX2ZlZShpbnQgd29ya2NoYWluLCBpbnQgZndkX2ZlZSkgYXNtKGZ3ZF9mZWUgd29ya2NoYWluKSAiR0VUT1JJ' + - 'R0lOQUxGV0RGRUUiOwppbnQgbXlfc3RvcmFnZV9kdWUoKSBhc20gIkRVRVBBWU1FTlQiOwoKdHVwbGUgZ2V0X2ZlZV9jb2ZpZ3MoKSBhc20gIlVOUEFDS0VEQ09ORklH' + - 'VFVQTEUiOwo='; + 'R0lOQUxGV0RGRUUiOwppbnQgbXlfc3RvcmFnZV9kdWUoKSBhc20gIkRVRVBBWU1FTlQiOwoKdHVwbGUgZ2V0X2ZlZV9jb25maWdzKCkgYXNtICJVTlBBQ0tFRENPTkZJ' + + 'R1RVUExFIjsK'; files['stdlib.tact'] = 'aW1wb3J0ICIuL3N0ZC9wcmltaXRpdmVzIjsKaW1wb3J0ICIuL3N0ZC9jZWxscyI7CmltcG9ydCAiLi9zdGQvY3J5cHRvIjsKaW1wb3J0ICIuL3N0ZC90ZXh0IjsKaW1w' + 'b3J0ICIuL3N0ZC9tYXRoIjsKaW1wb3J0ICIuL3N0ZC9jb250cmFjdCI7CmltcG9ydCAiLi9zdGQvZGVidWciOwppbXBvcnQgIi4vc3RkL2NvbnRleHQiOwppbXBvcnQg' + From f384afc111cbfbc3498c570c0c1ef924b8bc721e Mon Sep 17 00:00:00 2001 From: Gusarich Date: Sun, 17 Nov 2024 11:23:22 +0300 Subject: [PATCH 08/27] feat: add `MULRSHIFT` functions --- stdlib/std/math.tact | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/stdlib/std/math.tact b/stdlib/std/math.tact index 0141d78d1..edb05bff3 100644 --- a/stdlib/std/math.tact +++ b/stdlib/std/math.tact @@ -62,3 +62,12 @@ native pow(base: Int, exp: Int): Int; asm fun pow2(exp: Int): Int { POW2 } asm fun sign(x: Int): Int { SGN } + +// floor(x*y/2^z) +asm fun mulrshift(x: Int, y: Int, z: Int): Int { MULRSHIFT } + +// round(x*y/2^z) +asm fun mulrshift_round(x: Int, y: Int, z: Int): Int { MULRSHIFTR } + +// ceil(x*y/2^z) +asm fun mulrshift_ceil(x: Int, y: Int, z: Int): Int { MULRSHIFTC } From 0e3d6b43a9ef572a446594d0a79a7ed2ebffc962 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Sun, 17 Nov 2024 11:27:40 +0300 Subject: [PATCH 09/27] feat: update `stdlib.ts` --- src/imports/stdlib.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index 15b18619c..d1b4210bb 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -359,7 +359,9 @@ files['std/math.tact'] = 'WCB9Cgphc20gZnVuIGFicyh4OiBJbnQpOiBJbnQgeyBBQlMgfQoKYXNtIGZ1biBub3coKTogSW50IHsgTk9XIH0KCmFzbSBmdW4gbG9nMihudW06IEludCk6IEludCB7' + 'CiAgICBEVVAgNSBUSFJPV0lGTk9UIFVCSVRTSVpFIERFQwp9CgpAbmFtZShfX3RhY3RfbG9nKQpuYXRpdmUgbG9nKG51bTogSW50LCBiYXNlOiBJbnQpOiBJbnQ7CgpA' + 'bmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0KCmFz' + - 'bSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQo='; + 'bSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQoKLy8gZmxvb3IoeCp5LzJeeikKYXNtIGZ1biBtdWxyc2hpZnQoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IElu' + + 'dCB7IE1VTFJTSElGVCB9CgovLyByb3VuZCh4KnkvMl56KQphc20gZnVuIG11bHJzaGlmdF9yb3VuZCh4OiBJbnQsIHk6IEludCwgejogSW50KTogSW50IHsgTVVMUlNI' + + 'SUZUUiB9CgovLyBjZWlsKHgqeS8yXnopCmFzbSBmdW4gbXVscnNoaWZ0X2NlaWwoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IEludCB7IE1VTFJTSElGVEMgfQo='; files['std/primitives.tact'] = 'cHJpbWl0aXZlIEludDsKcHJpbWl0aXZlIEJvb2w7CnByaW1pdGl2ZSBCdWlsZGVyOwpwcmltaXRpdmUgU2xpY2U7CnByaW1pdGl2ZSBDZWxsOwpwcmltaXRpdmUgQWRk' + 'cmVzczsKcHJpbWl0aXZlIFN0cmluZzsKcHJpbWl0aXZlIFN0cmluZ0J1aWxkZXI7'; From 1db9371156f0980eef3440a160454df0de35462a Mon Sep 17 00:00:00 2001 From: Gusarich Date: Mon, 18 Nov 2024 06:37:23 +0300 Subject: [PATCH 10/27] feat: add `sqrt` function --- .../writeSerialization.spec.ts.snap | 114 ++++++++++++++++++ src/generator/writers/writeStdlib.ts | 26 ++++ src/imports/stdlib.ts | 3 +- stdlib/std/math.tact | 3 + 4 files changed, 145 insertions(+), 1 deletion(-) diff --git a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap index 30db3674f..738551146 100644 --- a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap +++ b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap @@ -1741,6 +1741,44 @@ return result;", "name": "__tact_pow", "signature": "int __tact_pow(int base, int exp)", }, + { + "code": { + "code": "UBITSIZE", + "kind": "asm", + "shuffle": "", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_log2_floor_unsafe", + "signature": "int __tact_log2_floor_unsafe(int num)", + }, + { + "code": { + "code": "if (num == 0) { return 0; } +int s = __tact_log2_floor_unsafe(num); +int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); + +do { + int q = (muldivc(num, 1, x) - x) / 2; + x += q; +} until (q == 0); + +return x;", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_log2_floor_unsafe", + }, + "flags": Set { + "inline", + }, + "name": "__tact_sqrt", + "signature": "int __tact_sqrt(int num)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -6167,6 +6205,44 @@ return result;", "name": "__tact_pow", "signature": "int __tact_pow(int base, int exp)", }, + { + "code": { + "code": "UBITSIZE", + "kind": "asm", + "shuffle": "", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_log2_floor_unsafe", + "signature": "int __tact_log2_floor_unsafe(int num)", + }, + { + "code": { + "code": "if (num == 0) { return 0; } +int s = __tact_log2_floor_unsafe(num); +int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); + +do { + int q = (muldivc(num, 1, x) - x) / 2; + x += q; +} until (q == 0); + +return x;", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_log2_floor_unsafe", + }, + "flags": Set { + "inline", + }, + "name": "__tact_sqrt", + "signature": "int __tact_sqrt(int num)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -10593,6 +10669,44 @@ return result;", "name": "__tact_pow", "signature": "int __tact_pow(int base, int exp)", }, + { + "code": { + "code": "UBITSIZE", + "kind": "asm", + "shuffle": "", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_log2_floor_unsafe", + "signature": "int __tact_log2_floor_unsafe(int num)", + }, + { + "code": { + "code": "if (num == 0) { return 0; } +int s = __tact_log2_floor_unsafe(num); +int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); + +do { + int q = (muldivc(num, 1, x) - x) / 2; + x += q; +} until (q == 0); + +return x;", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_log2_floor_unsafe", + }, + "flags": Set { + "inline", + }, + "name": "__tact_sqrt", + "signature": "int __tact_sqrt(int num)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); diff --git a/src/generator/writers/writeStdlib.ts b/src/generator/writers/writeStdlib.ts index 4bd365603..8017451cd 100644 --- a/src/generator/writers/writeStdlib.ts +++ b/src/generator/writers/writeStdlib.ts @@ -1133,6 +1133,32 @@ export function writeStdlib(ctx: WriterContext): void { }); }); + ctx.fun(`__tact_log2_floor_unsafe`, () => { + ctx.signature(`int __tact_log2_floor_unsafe(int num)`); + ctx.context("stdlib"); + ctx.asm("", "UBITSIZE"); + }); + + ctx.fun(`__tact_sqrt`, () => { + ctx.signature(`int __tact_sqrt(int num)`); + ctx.flag("inline"); + ctx.context("stdlib"); + ctx.body(() => { + ctx.write(` + if (num == 0) { return 0; } + int s = ${ctx.used("__tact_log2_floor_unsafe")}(num); + int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); + + do { + int q = (muldivc(num, 1, x) - x) / 2; + x += q; + } until (q == 0); + + return x; + `); + }); + }); + // generate dict operations for all combinations of key/value types for (const key of keyTypes) { for (const val of valTypes) { diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index d1b4210bb..fa64d7cb0 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -361,7 +361,8 @@ files['std/math.tact'] = 'bmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0KCmFz' + 'bSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQoKLy8gZmxvb3IoeCp5LzJeeikKYXNtIGZ1biBtdWxyc2hpZnQoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IElu' + 'dCB7IE1VTFJTSElGVCB9CgovLyByb3VuZCh4KnkvMl56KQphc20gZnVuIG11bHJzaGlmdF9yb3VuZCh4OiBJbnQsIHk6IEludCwgejogSW50KTogSW50IHsgTVVMUlNI' + - 'SUZUUiB9CgovLyBjZWlsKHgqeS8yXnopCmFzbSBmdW4gbXVscnNoaWZ0X2NlaWwoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IEludCB7IE1VTFJTSElGVEMgfQo='; + 'SUZUUiB9CgovLyBjZWlsKHgqeS8yXnopCmFzbSBmdW4gbXVscnNoaWZ0X2NlaWwoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IEludCB7IE1VTFJTSElGVEMgfQoKQG5h' + + 'bWUoX190YWN0X3NxcnQpCm5hdGl2ZSBzcXJ0KG51bTogSW50KTogSW50Owo='; files['std/primitives.tact'] = 'cHJpbWl0aXZlIEludDsKcHJpbWl0aXZlIEJvb2w7CnByaW1pdGl2ZSBCdWlsZGVyOwpwcmltaXRpdmUgU2xpY2U7CnByaW1pdGl2ZSBDZWxsOwpwcmltaXRpdmUgQWRk' + 'cmVzczsKcHJpbWl0aXZlIFN0cmluZzsKcHJpbWl0aXZlIFN0cmluZ0J1aWxkZXI7'; diff --git a/stdlib/std/math.tact b/stdlib/std/math.tact index edb05bff3..987698b8d 100644 --- a/stdlib/std/math.tact +++ b/stdlib/std/math.tact @@ -71,3 +71,6 @@ asm fun mulrshift_round(x: Int, y: Int, z: Int): Int { MULRSHIFTR } // ceil(x*y/2^z) asm fun mulrshift_ceil(x: Int, y: Int, z: Int): Int { MULRSHIFTC } + +@name(__tact_sqrt) +native sqrt(num: Int): Int; From a403986659e0733828156d796feef6cc11e08379 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Mon, 18 Nov 2024 11:30:59 +0300 Subject: [PATCH 11/27] feat: `sliceLast` -> `lastBits`, and make `computeDataSize` an extend function for both cell and slice --- src/imports/stdlib.ts | 27 ++++++++++++++------------- stdlib/std/cells.tact | 6 +++--- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index fa64d7cb0..ac38fd61f 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -184,19 +184,20 @@ files['std/cells.tact'] = 'cmVzcyhzZWxmOiBTbGljZSk6IEFkZHJlc3M7Cgphc20gZXh0ZW5kcyBtdXRhdGVzIGZ1biBza2lwQml0cyhzZWxmOiBTbGljZSwgbDogSW50KSB7IFNEU0tJUEZJUlNU' + 'IH0KCmFzbSBleHRlbmRzIGZ1biBlbmRQYXJzZShzZWxmOiBTbGljZSkgeyBFTkRTIH0KCmFzbSBleHRlbmRzIGZ1biBza2lwTGFzdEJpdHMoc2VsZjogU2xpY2UsIGxl' + 'bjogSW50KTogU2xpY2UgeyBTRFNLSVBMQVNUIH0KCmFzbSBleHRlbmRzIGZ1biBmaXJzdEJpdHMoc2VsZjogU2xpY2UsIGxlbjogSW50KTogU2xpY2UgeyBTRENVVEZJ' + - 'UlNUIH0KCmFzbSBleHRlbmRzIGZ1biBzbGljZUxhc3Qoc2VsZjogU2xpY2UsIGxlbjogSW50KTogU2xpY2UgeyBTRENVVExBU1QgfQoKYXNtIGV4dGVuZHMgZnVuIGRl' + - 'cHRoKHNlbGY6IFNsaWNlKTogSW50IHsgU0RFUFRIIH0KCi8vCi8vIFNsaWNlIHNpemUKLy8KCmFzbSBleHRlbmRzIGZ1biByZWZzKHNlbGY6IFNsaWNlKTogSW50IHsg' + - 'U1JFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMoc2VsZjogU2xpY2UpOiBJbnQgeyBTQklUUyB9Cgphc20gZXh0ZW5kcyBmdW4gZW1wdHkoc2VsZjogU2xpY2UpOiBC' + - 'b29sIHsgU0VNUFRZIH0KCmFzbSBleHRlbmRzIGZ1biBkYXRhRW1wdHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU0RFTVBUWSB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmc0Vt' + - 'cHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNSRU1QVFkgfQoKLy8KLy8gQ29udmVyc2lvbnMKLy8KCmlubGluZSBleHRlbmRzIGZ1biBhc1NsaWNlKHNlbGY6IEJ1aWxk' + - 'ZXIpOiBTbGljZSB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxsKCkuYmVnaW5QYXJzZSgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBDZWxsKTog' + - 'U2xpY2UgewogICAgcmV0dXJuIHNlbGYuYmVnaW5QYXJzZSgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNDZWxsKHNlbGY6IFNsaWNlKTogQ2VsbCB7CiAgICByZXR1' + - 'cm4gYmVnaW5DZWxsKCkKICAgICAgICAuc3RvcmVTbGljZShzZWxmKQogICAgICAgIC5lbmRDZWxsKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjog' + - 'QnVpbGRlcik6IENlbGwgewogICAgcmV0dXJuIHNlbGYuZW5kQ2VsbCgpOwp9CgppbmxpbmUgZnVuIGVtcHR5Q2VsbCgpOiBDZWxsIHsKICAgIHJldHVybiBiZWdpbkNl' + - 'bGwoKS5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlTbGljZSgpOiBTbGljZSB7CiAgICByZXR1cm4gZW1wdHlDZWxsKCkuYXNTbGljZSgpOwp9CgpzdHJ1Y3Qg' + - 'RGF0YVNpemUgewogICAgY2VsbHM6IEludDsKICAgIGJpdHM6IEludDsKICAgIHJlZnM6IEludDsKfQoKYXNtIGZ1biBjb21wdXRlRGF0YVNpemUoY2VsbDogQ2VsbCwg' + - 'bWF4Q2VsbHM6IEludCk6IERhdGFTaXplIHsgQ0RBVEFTSVpFIFRSSVBMRSB9Cgphc20gZnVuIGNvbXB1dGVTbGljZURhdGFTaXplKHNsaWNlOiBTbGljZSwgbWF4Q2Vs' + - 'bHM6IEludCk6IERhdGFTaXplIHsgU0RBVEFTSVpFIFRSSVBMRSB9Cgphc20gZXh0ZW5kcyBmdW4gZGVwdGgoc2VsZjogQ2VsbCk6IEludCB7IENERVBUSCB9Cgo='; + 'UlNUIH0KCmFzbSBleHRlbmRzIGZ1biBsYXN0Qml0cyhzZWxmOiBTbGljZSwgbGVuOiBJbnQpOiBTbGljZSB7IFNEQ1VUTEFTVCB9Cgphc20gZXh0ZW5kcyBmdW4gZGVw' + + 'dGgoc2VsZjogU2xpY2UpOiBJbnQgeyBTREVQVEggfQoKLy8KLy8gU2xpY2Ugc2l6ZQovLwoKYXNtIGV4dGVuZHMgZnVuIHJlZnMoc2VsZjogU2xpY2UpOiBJbnQgeyBT' + + 'UkVGUyB9Cgphc20gZXh0ZW5kcyBmdW4gYml0cyhzZWxmOiBTbGljZSk6IEludCB7IFNCSVRTIH0KCmFzbSBleHRlbmRzIGZ1biBlbXB0eShzZWxmOiBTbGljZSk6IEJv' + + 'b2wgeyBTRU1QVFkgfQoKYXNtIGV4dGVuZHMgZnVuIGRhdGFFbXB0eShzZWxmOiBTbGljZSk6IEJvb2wgeyBTREVNUFRZIH0KCmFzbSBleHRlbmRzIGZ1biByZWZzRW1w' + + 'dHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU1JFTVBUWSB9CgovLwovLyBDb252ZXJzaW9ucwovLwoKaW5saW5lIGV4dGVuZHMgZnVuIGFzU2xpY2Uoc2VsZjogQnVpbGRl' + + 'cik6IFNsaWNlIHsKICAgIHJldHVybiBzZWxmLmVuZENlbGwoKS5iZWdpblBhcnNlKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc1NsaWNlKHNlbGY6IENlbGwpOiBT' + + 'bGljZSB7CiAgICByZXR1cm4gc2VsZi5iZWdpblBhcnNlKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjogU2xpY2UpOiBDZWxsIHsKICAgIHJldHVy' + + 'biBiZWdpbkNlbGwoKQogICAgICAgIC5zdG9yZVNsaWNlKHNlbGYpCiAgICAgICAgLmVuZENlbGwoKTsKfQoKaW5saW5lIGV4dGVuZHMgZnVuIGFzQ2VsbChzZWxmOiBC' + + 'dWlsZGVyKTogQ2VsbCB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlDZWxsKCk6IENlbGwgewogICAgcmV0dXJuIGJlZ2luQ2Vs' + + 'bCgpLmVuZENlbGwoKTsKfQoKaW5saW5lIGZ1biBlbXB0eVNsaWNlKCk6IFNsaWNlIHsKICAgIHJldHVybiBlbXB0eUNlbGwoKS5hc1NsaWNlKCk7Cn0KCnN0cnVjdCBE' + + 'YXRhU2l6ZSB7CiAgICBjZWxsczogSW50OwogICAgYml0czogSW50OwogICAgcmVmczogSW50Owp9Cgphc20gZXh0ZW5kcyBmdW4gY29tcHV0ZURhdGFTaXplKHNlbGY6' + + 'IENlbGwsIG1heENlbGxzOiBJbnQpOiBEYXRhU2l6ZSB7IENEQVRBU0laRSBUUklQTEUgfQoKYXNtIGV4dGVuZHMgZnVuIGNvbXB1dGVEYXRhU2l6ZShzZWxmOiBTbGlj' + + 'ZSwgbWF4Q2VsbHM6IEludCk6IERhdGFTaXplIHsgU0RBVEFTSVpFIFRSSVBMRSB9Cgphc20gZXh0ZW5kcyBmdW4gZGVwdGgoc2VsZjogQ2VsbCk6IEludCB7IENERVBU' + + 'SCB9Cgo='; files['std/config.tact'] = 'YXNtIGZ1biBnZXRDb25maWdQYXJhbShpZDogSW50KTogQ2VsbD8geyBDT05GSUdPUFRQQVJBTSB9Cg=='; files['std/context.tact'] = diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index ccf524458..ad6d2e65c 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -173,7 +173,7 @@ asm extends fun skipLastBits(self: Slice, len: Int): Slice { SDSKIPLAST } asm extends fun firstBits(self: Slice, len: Int): Slice { SDCUTFIRST } -asm extends fun sliceLast(self: Slice, len: Int): Slice { SDCUTLAST } +asm extends fun lastBits(self: Slice, len: Int): Slice { SDCUTLAST } asm extends fun depth(self: Slice): Int { SDEPTH } @@ -227,9 +227,9 @@ struct DataSize { refs: Int; } -asm fun computeDataSize(cell: Cell, maxCells: Int): DataSize { CDATASIZE TRIPLE } +asm extends fun computeDataSize(self: Cell, maxCells: Int): DataSize { CDATASIZE TRIPLE } -asm fun computeSliceDataSize(slice: Slice, maxCells: Int): DataSize { SDATASIZE TRIPLE } +asm extends fun computeDataSize(self: Slice, maxCells: Int): DataSize { SDATASIZE TRIPLE } asm extends fun depth(self: Cell): Int { CDEPTH } From 364dbf8a966e8c98002e85d4f517eff6d71a95c6 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Mon, 18 Nov 2024 11:31:07 +0300 Subject: [PATCH 12/27] chore: add all function names to changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3841f0d7..86f2d8f8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Docs: `preloadRef` method for the `Slice` type: PR [#1044](https://github.com/tact-lang/tact/pull/1044) - Docs: added DeDust cookbook: PR [#954](https://github.com/tact-lang/tact/pull/954) - Docs: described the limit for deeply nested expressions: PR [#1101](https://github.com/tact-lang/tact/pull/1101) -- New functions in stdlib from `stdlib.fc` and `math.fc`: PR [#985](https://github.com/tact-lang/tact/pull/985) +- New functions in stdlib from `stdlib.fc` and `math.fc`: `Builder.depth`, `Slice.skipLastBits`, `Slice.firstBits`, `Slice.lastBits`, `Slice.depth`, `Cell.computeDataSize`, `Slice.computeDataSize`, `Cell.depth`, `curLt`, `blockLt`, `setGasLimit`, `getSeed`, `setSeed`, `myCode`, `sign`, `mulrshift`, `mulrshift_round`, `mulrshift_ceil`, `sqrt`: PR [#986](https://github.com/tact-lang/tact/pull/986) ### Changed From 30038ca3501989cfcdd6a122b8de40abe0f0ed73 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Mon, 18 Nov 2024 11:43:03 +0300 Subject: [PATCH 13/27] feat: `addressNone` --- CHANGELOG.md | 2 +- src/imports/stdlib.ts | 10 +++++----- stdlib/std/cells.tact | 2 ++ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86f2d8f8c..335d6e8d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Docs: `preloadRef` method for the `Slice` type: PR [#1044](https://github.com/tact-lang/tact/pull/1044) - Docs: added DeDust cookbook: PR [#954](https://github.com/tact-lang/tact/pull/954) - Docs: described the limit for deeply nested expressions: PR [#1101](https://github.com/tact-lang/tact/pull/1101) -- New functions in stdlib from `stdlib.fc` and `math.fc`: `Builder.depth`, `Slice.skipLastBits`, `Slice.firstBits`, `Slice.lastBits`, `Slice.depth`, `Cell.computeDataSize`, `Slice.computeDataSize`, `Cell.depth`, `curLt`, `blockLt`, `setGasLimit`, `getSeed`, `setSeed`, `myCode`, `sign`, `mulrshift`, `mulrshift_round`, `mulrshift_ceil`, `sqrt`: PR [#986](https://github.com/tact-lang/tact/pull/986) +- New functions in stdlib from `stdlib.fc` and `math.fc`: `Builder.depth`, `Slice.skipLastBits`, `Slice.firstBits`, `Slice.lastBits`, `Slice.depth`, `Cell.computeDataSize`, `Slice.computeDataSize`, `Cell.depth`, `curLt`, `blockLt`, `setGasLimit`, `getSeed`, `setSeed`, `myCode`, `sign`, `mulrshift`, `mulrshift_round`, `mulrshift_ceil`, `sqrt`, `addressNone`: PR [#986](https://github.com/tact-lang/tact/pull/986) ### Changed diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index ac38fd61f..0e46a8bbc 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -193,11 +193,11 @@ files['std/cells.tact'] = 'bGljZSB7CiAgICByZXR1cm4gc2VsZi5iZWdpblBhcnNlKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjogU2xpY2UpOiBDZWxsIHsKICAgIHJldHVy' + 'biBiZWdpbkNlbGwoKQogICAgICAgIC5zdG9yZVNsaWNlKHNlbGYpCiAgICAgICAgLmVuZENlbGwoKTsKfQoKaW5saW5lIGV4dGVuZHMgZnVuIGFzQ2VsbChzZWxmOiBC' + 'dWlsZGVyKTogQ2VsbCB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlDZWxsKCk6IENlbGwgewogICAgcmV0dXJuIGJlZ2luQ2Vs' + - 'bCgpLmVuZENlbGwoKTsKfQoKaW5saW5lIGZ1biBlbXB0eVNsaWNlKCk6IFNsaWNlIHsKICAgIHJldHVybiBlbXB0eUNlbGwoKS5hc1NsaWNlKCk7Cn0KCnN0cnVjdCBE' + - 'YXRhU2l6ZSB7CiAgICBjZWxsczogSW50OwogICAgYml0czogSW50OwogICAgcmVmczogSW50Owp9Cgphc20gZXh0ZW5kcyBmdW4gY29tcHV0ZURhdGFTaXplKHNlbGY6' + - 'IENlbGwsIG1heENlbGxzOiBJbnQpOiBEYXRhU2l6ZSB7IENEQVRBU0laRSBUUklQTEUgfQoKYXNtIGV4dGVuZHMgZnVuIGNvbXB1dGVEYXRhU2l6ZShzZWxmOiBTbGlj' + - 'ZSwgbWF4Q2VsbHM6IEludCk6IERhdGFTaXplIHsgU0RBVEFTSVpFIFRSSVBMRSB9Cgphc20gZXh0ZW5kcyBmdW4gZGVwdGgoc2VsZjogQ2VsbCk6IEludCB7IENERVBU' + - 'SCB9Cgo='; + 'bCgpLmVuZENlbGwoKTsKfQoKaW5saW5lIGZ1biBlbXB0eVNsaWNlKCk6IFNsaWNlIHsKICAgIHJldHVybiBlbXB0eUNlbGwoKS5hc1NsaWNlKCk7Cn0KCmFzbSBmdW4g' + + 'YWRkcmVzc05vbmUoKTogQWRkcmVzcyB7IGJ7MDB9IFBVU0hTTElDRSB9CgpzdHJ1Y3QgRGF0YVNpemUgewogICAgY2VsbHM6IEludDsKICAgIGJpdHM6IEludDsKICAg' + + 'IHJlZnM6IEludDsKfQoKYXNtIGV4dGVuZHMgZnVuIGNvbXB1dGVEYXRhU2l6ZShzZWxmOiBDZWxsLCBtYXhDZWxsczogSW50KTogRGF0YVNpemUgeyBDREFUQVNJWkUg' + + 'VFJJUExFIH0KCmFzbSBleHRlbmRzIGZ1biBjb21wdXRlRGF0YVNpemUoc2VsZjogU2xpY2UsIG1heENlbGxzOiBJbnQpOiBEYXRhU2l6ZSB7IFNEQVRBU0laRSBUUklQ' + + 'TEUgfQoKYXNtIGV4dGVuZHMgZnVuIGRlcHRoKHNlbGY6IENlbGwpOiBJbnQgeyBDREVQVEggfQoK'; files['std/config.tact'] = 'YXNtIGZ1biBnZXRDb25maWdQYXJhbShpZDogSW50KTogQ2VsbD8geyBDT05GSUdPUFRQQVJBTSB9Cg=='; files['std/context.tact'] = diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index ad6d2e65c..f1eb31bbc 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -221,6 +221,8 @@ inline fun emptySlice(): Slice { return emptyCell().asSlice(); } +asm fun addressNone(): Address { b{00} PUSHSLICE } + struct DataSize { cells: Int; bits: Int; From 58c33b55130c044e80b2ea129df844b205794cee Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 21 Nov 2024 20:14:20 +0300 Subject: [PATCH 14/27] feat: rename mulrshift functions --- stdlib/std/math.tact | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stdlib/std/math.tact b/stdlib/std/math.tact index 987698b8d..1a2aecb2a 100644 --- a/stdlib/std/math.tact +++ b/stdlib/std/math.tact @@ -64,13 +64,13 @@ asm fun pow2(exp: Int): Int { POW2 } asm fun sign(x: Int): Int { SGN } // floor(x*y/2^z) -asm fun mulrshift(x: Int, y: Int, z: Int): Int { MULRSHIFT } +asm fun mulShiftRight(x: Int, y: Int, z: Int): Int { MULRSHIFT } // round(x*y/2^z) -asm fun mulrshift_round(x: Int, y: Int, z: Int): Int { MULRSHIFTR } +asm fun mulShiftRightRound(x: Int, y: Int, z: Int): Int { MULRSHIFTR } // ceil(x*y/2^z) -asm fun mulrshift_ceil(x: Int, y: Int, z: Int): Int { MULRSHIFTC } +asm fun mulShiftRightCeil(x: Int, y: Int, z: Int): Int { MULRSHIFTC } @name(__tact_sqrt) native sqrt(num: Int): Int; From cbd36dce8847ebfb444801e6d10ad9626f689ed4 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 21 Nov 2024 20:22:53 +0300 Subject: [PATCH 15/27] feat: rewrite sqrt on tact --- src/generator/writers/writeStdlib.ts | 26 -------------------------- src/imports/stdlib.ts | 12 ++++++++---- stdlib/std/math.tact | 23 +++++++++++++++++++++-- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/generator/writers/writeStdlib.ts b/src/generator/writers/writeStdlib.ts index 8017451cd..4bd365603 100644 --- a/src/generator/writers/writeStdlib.ts +++ b/src/generator/writers/writeStdlib.ts @@ -1133,32 +1133,6 @@ export function writeStdlib(ctx: WriterContext): void { }); }); - ctx.fun(`__tact_log2_floor_unsafe`, () => { - ctx.signature(`int __tact_log2_floor_unsafe(int num)`); - ctx.context("stdlib"); - ctx.asm("", "UBITSIZE"); - }); - - ctx.fun(`__tact_sqrt`, () => { - ctx.signature(`int __tact_sqrt(int num)`); - ctx.flag("inline"); - ctx.context("stdlib"); - ctx.body(() => { - ctx.write(` - if (num == 0) { return 0; } - int s = ${ctx.used("__tact_log2_floor_unsafe")}(num); - int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); - - do { - int q = (muldivc(num, 1, x) - x) / 2; - x += q; - } until (q == 0); - - return x; - `); - }); - }); - // generate dict operations for all combinations of key/value types for (const key of keyTypes) { for (const val of valTypes) { diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index 0e46a8bbc..f809297ec 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -360,10 +360,14 @@ files['std/math.tact'] = 'WCB9Cgphc20gZnVuIGFicyh4OiBJbnQpOiBJbnQgeyBBQlMgfQoKYXNtIGZ1biBub3coKTogSW50IHsgTk9XIH0KCmFzbSBmdW4gbG9nMihudW06IEludCk6IEludCB7' + 'CiAgICBEVVAgNSBUSFJPV0lGTk9UIFVCSVRTSVpFIERFQwp9CgpAbmFtZShfX3RhY3RfbG9nKQpuYXRpdmUgbG9nKG51bTogSW50LCBiYXNlOiBJbnQpOiBJbnQ7CgpA' + 'bmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0KCmFz' + - 'bSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQoKLy8gZmxvb3IoeCp5LzJeeikKYXNtIGZ1biBtdWxyc2hpZnQoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IElu' + - 'dCB7IE1VTFJTSElGVCB9CgovLyByb3VuZCh4KnkvMl56KQphc20gZnVuIG11bHJzaGlmdF9yb3VuZCh4OiBJbnQsIHk6IEludCwgejogSW50KTogSW50IHsgTVVMUlNI' + - 'SUZUUiB9CgovLyBjZWlsKHgqeS8yXnopCmFzbSBmdW4gbXVscnNoaWZ0X2NlaWwoeDogSW50LCB5OiBJbnQsIHo6IEludCk6IEludCB7IE1VTFJTSElGVEMgfQoKQG5h' + - 'bWUoX190YWN0X3NxcnQpCm5hdGl2ZSBzcXJ0KG51bTogSW50KTogSW50Owo='; + 'bSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQoKYXNtIGZ1biBkaXZjKHg6IEludCwgeTogSW50KTogSW50IHsgRElWQyB9Cgphc20gZnVuIG11bGRpdmMoeDog' + + 'SW50LCB5OiBJbnQsIHo6IEludCk6IEludCB7IE1VTERJVkMgfQoKLy8gZmxvb3IoeCp5LzJeeikKYXNtIGZ1biBtdWxTaGlmdFJpZ2h0KHg6IEludCwgeTogSW50LCB6' + + 'OiBJbnQpOiBJbnQgeyBNVUxSU0hJRlQgfQoKLy8gcm91bmQoeCp5LzJeeikKYXNtIGZ1biBtdWxTaGlmdFJpZ2h0Um91bmQoeDogSW50LCB5OiBJbnQsIHo6IEludCk6' + + 'IEludCB7IE1VTFJTSElGVFIgfQoKLy8gY2VpbCh4KnkvMl56KQphc20gZnVuIG11bFNoaWZ0UmlnaHRDZWlsKHg6IEludCwgeTogSW50LCB6OiBJbnQpOiBJbnQgeyBN' + + 'VUxSU0hJRlRDIH0KCmZ1biBzcXJ0KG51bTogSW50KTogSW50IHsKICAgIGlmIChudW0gPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGxldCBzOiBJ' + + 'bnQgPSBsb2cyKG51bSk7CiAgICBsZXQgeDogSW50ID0gKHMgPT0gMSA/IChudW0gLSAxKSAvIDIgKyAxIDogMSA8PCAoKHMgKyAxKSAvIDIpKTsKCiAgICBsZXQgcTog' + + 'SW50ID0gMDsKCiAgICBkbyB7CiAgICAgICAgcSA9IChkaXZjKG51bSwgeCkgLSB4KSAvIDI7CiAgICAgICAgeCArPSBxOwogICAgfSB1bnRpbCAocSA9PSAwKTsKCiAg' + + 'ICByZXR1cm4geDsKfQo='; files['std/primitives.tact'] = 'cHJpbWl0aXZlIEludDsKcHJpbWl0aXZlIEJvb2w7CnByaW1pdGl2ZSBCdWlsZGVyOwpwcmltaXRpdmUgU2xpY2U7CnByaW1pdGl2ZSBDZWxsOwpwcmltaXRpdmUgQWRk' + 'cmVzczsKcHJpbWl0aXZlIFN0cmluZzsKcHJpbWl0aXZlIFN0cmluZ0J1aWxkZXI7'; diff --git a/stdlib/std/math.tact b/stdlib/std/math.tact index 1a2aecb2a..d48b18c07 100644 --- a/stdlib/std/math.tact +++ b/stdlib/std/math.tact @@ -63,6 +63,10 @@ asm fun pow2(exp: Int): Int { POW2 } asm fun sign(x: Int): Int { SGN } +asm fun divc(x: Int, y: Int): Int { DIVC } + +asm fun muldivc(x: Int, y: Int, z: Int): Int { MULDIVC } + // floor(x*y/2^z) asm fun mulShiftRight(x: Int, y: Int, z: Int): Int { MULRSHIFT } @@ -72,5 +76,20 @@ asm fun mulShiftRightRound(x: Int, y: Int, z: Int): Int { MULRSHIFTR } // ceil(x*y/2^z) asm fun mulShiftRightCeil(x: Int, y: Int, z: Int): Int { MULRSHIFTC } -@name(__tact_sqrt) -native sqrt(num: Int): Int; +fun sqrt(num: Int): Int { + if (num == 0) { + return 0; + } + + let s: Int = log2(num); + let x: Int = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); + + let q: Int = 0; + + do { + q = (divc(num, x) - x) / 2; + x += q; + } until (q == 0); + + return x; +} From 2aca9802a9600396a7c714d5ce08255cbd06b678 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 21 Nov 2024 20:26:00 +0300 Subject: [PATCH 16/27] chore: update serialization snapshots --- .../writeSerialization.spec.ts.snap | 114 ------------------ 1 file changed, 114 deletions(-) diff --git a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap index 738551146..30db3674f 100644 --- a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap +++ b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap @@ -1741,44 +1741,6 @@ return result;", "name": "__tact_pow", "signature": "int __tact_pow(int base, int exp)", }, - { - "code": { - "code": "UBITSIZE", - "kind": "asm", - "shuffle": "", - }, - "comment": null, - "context": "stdlib", - "depends": Set {}, - "flags": Set {}, - "name": "__tact_log2_floor_unsafe", - "signature": "int __tact_log2_floor_unsafe(int num)", - }, - { - "code": { - "code": "if (num == 0) { return 0; } -int s = __tact_log2_floor_unsafe(num); -int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); - -do { - int q = (muldivc(num, 1, x) - x) / 2; - x += q; -} until (q == 0); - -return x;", - "kind": "generic", - }, - "comment": null, - "context": "stdlib", - "depends": Set { - "__tact_log2_floor_unsafe", - }, - "flags": Set { - "inline", - }, - "name": "__tact_sqrt", - "signature": "int __tact_sqrt(int num)", - }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -6205,44 +6167,6 @@ return result;", "name": "__tact_pow", "signature": "int __tact_pow(int base, int exp)", }, - { - "code": { - "code": "UBITSIZE", - "kind": "asm", - "shuffle": "", - }, - "comment": null, - "context": "stdlib", - "depends": Set {}, - "flags": Set {}, - "name": "__tact_log2_floor_unsafe", - "signature": "int __tact_log2_floor_unsafe(int num)", - }, - { - "code": { - "code": "if (num == 0) { return 0; } -int s = __tact_log2_floor_unsafe(num); -int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); - -do { - int q = (muldivc(num, 1, x) - x) / 2; - x += q; -} until (q == 0); - -return x;", - "kind": "generic", - }, - "comment": null, - "context": "stdlib", - "depends": Set { - "__tact_log2_floor_unsafe", - }, - "flags": Set { - "inline", - }, - "name": "__tact_sqrt", - "signature": "int __tact_sqrt(int num)", - }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -10669,44 +10593,6 @@ return result;", "name": "__tact_pow", "signature": "int __tact_pow(int base, int exp)", }, - { - "code": { - "code": "UBITSIZE", - "kind": "asm", - "shuffle": "", - }, - "comment": null, - "context": "stdlib", - "depends": Set {}, - "flags": Set {}, - "name": "__tact_log2_floor_unsafe", - "signature": "int __tact_log2_floor_unsafe(int num)", - }, - { - "code": { - "code": "if (num == 0) { return 0; } -int s = __tact_log2_floor_unsafe(num); -int x = (s == 1 ? (num - 1) / 2 + 1 : 1 << ((s + 1) / 2)); - -do { - int q = (muldivc(num, 1, x) - x) / 2; - x += q; -} until (q == 0); - -return x;", - "kind": "generic", - }, - "comment": null, - "context": "stdlib", - "depends": Set { - "__tact_log2_floor_unsafe", - }, - "flags": Set { - "inline", - }, - "name": "__tact_sqrt", - "signature": "int __tact_sqrt(int num)", - }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); From 3dcaf2a22ac61b1696d72aee416451f515d85d9b Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 21 Nov 2024 20:26:08 +0300 Subject: [PATCH 17/27] chore: update cspell ignorelist --- cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.json b/cspell.json index b48885a05..50852ff42 100644 --- a/cspell.json +++ b/cspell.json @@ -73,6 +73,7 @@ "minmax", "mintable", "mktemp", + "muldivc", "multiformats", "nanotons", "Neovim", From 83d69e7739fb80056e37a7740c0764ef4f882d72 Mon Sep 17 00:00:00 2001 From: Daniil Sedov Date: Fri, 22 Nov 2024 10:23:01 +0300 Subject: [PATCH 18/27] chore: update CHANGELOG.md Co-authored-by: Novus Nota <68142933+novusnota@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335d6e8d6..68fb5bc92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Docs: `preloadRef` method for the `Slice` type: PR [#1044](https://github.com/tact-lang/tact/pull/1044) - Docs: added DeDust cookbook: PR [#954](https://github.com/tact-lang/tact/pull/954) - Docs: described the limit for deeply nested expressions: PR [#1101](https://github.com/tact-lang/tact/pull/1101) -- New functions in stdlib from `stdlib.fc` and `math.fc`: `Builder.depth`, `Slice.skipLastBits`, `Slice.firstBits`, `Slice.lastBits`, `Slice.depth`, `Cell.computeDataSize`, `Slice.computeDataSize`, `Cell.depth`, `curLt`, `blockLt`, `setGasLimit`, `getSeed`, `setSeed`, `myCode`, `sign`, `mulrshift`, `mulrshift_round`, `mulrshift_ceil`, `sqrt`, `addressNone`: PR [#986](https://github.com/tact-lang/tact/pull/986) +- New functions in stdlib from `stdlib.fc` and `math.fc`: `Builder.depth`, `Slice.skipLastBits`, `Slice.firstBits`, `Slice.lastBits`, `Slice.depth`, `Cell.computeDataSize`, `Slice.computeDataSize`, `Cell.depth`, `curLt`, `blockLt`, `setGasLimit`, `getSeed`, `setSeed`, `myCode`, `sign`, `divc`, `muldivc`, `mulShiftRight`, `mulShiftRightRound`, `mulShiftRightCeil`, `sqrt`, `addressNone`: PR [#986](https://github.com/tact-lang/tact/pull/986) ### Changed From e8011035139cdd6814948e64ec0afddf878ea4b5 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 28 Nov 2024 08:20:29 +0300 Subject: [PATCH 19/27] fix: `addressNone` and `computeDataSize` types --- src/imports/stdlib.ts | 8 ++++---- stdlib/std/cells.tact | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index f809297ec..25f6f64b3 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -194,10 +194,10 @@ files['std/cells.tact'] = 'biBiZWdpbkNlbGwoKQogICAgICAgIC5zdG9yZVNsaWNlKHNlbGYpCiAgICAgICAgLmVuZENlbGwoKTsKfQoKaW5saW5lIGV4dGVuZHMgZnVuIGFzQ2VsbChzZWxmOiBC' + 'dWlsZGVyKTogQ2VsbCB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlDZWxsKCk6IENlbGwgewogICAgcmV0dXJuIGJlZ2luQ2Vs' + 'bCgpLmVuZENlbGwoKTsKfQoKaW5saW5lIGZ1biBlbXB0eVNsaWNlKCk6IFNsaWNlIHsKICAgIHJldHVybiBlbXB0eUNlbGwoKS5hc1NsaWNlKCk7Cn0KCmFzbSBmdW4g' + - 'YWRkcmVzc05vbmUoKTogQWRkcmVzcyB7IGJ7MDB9IFBVU0hTTElDRSB9CgpzdHJ1Y3QgRGF0YVNpemUgewogICAgY2VsbHM6IEludDsKICAgIGJpdHM6IEludDsKICAg' + - 'IHJlZnM6IEludDsKfQoKYXNtIGV4dGVuZHMgZnVuIGNvbXB1dGVEYXRhU2l6ZShzZWxmOiBDZWxsLCBtYXhDZWxsczogSW50KTogRGF0YVNpemUgeyBDREFUQVNJWkUg' + - 'VFJJUExFIH0KCmFzbSBleHRlbmRzIGZ1biBjb21wdXRlRGF0YVNpemUoc2VsZjogU2xpY2UsIG1heENlbGxzOiBJbnQpOiBEYXRhU2l6ZSB7IFNEQVRBU0laRSBUUklQ' + - 'TEUgfQoKYXNtIGV4dGVuZHMgZnVuIGRlcHRoKHNlbGY6IENlbGwpOiBJbnQgeyBDREVQVEggfQoK'; + 'YWRkcmVzc05vbmUoKTogQWRkcmVzcz8geyBiezAwfSBQVVNIU0xJQ0UgfQoKc3RydWN0IERhdGFTaXplIHsKICAgIGNlbGxzOiBJbnQ7CiAgICBiaXRzOiBJbnQ7CiAg' + + 'ICByZWZzOiBJbnQ7Cn0KCmFzbSBleHRlbmRzIGZ1biBjb21wdXRlRGF0YVNpemUoc2VsZjogQ2VsbCwgbWF4Q2VsbHM6IEludCk6IERhdGFTaXplIHsgQ0RBVEFTSVpF' + + 'IH0KCmFzbSBleHRlbmRzIGZ1biBjb21wdXRlRGF0YVNpemUoc2VsZjogU2xpY2UsIG1heENlbGxzOiBJbnQpOiBEYXRhU2l6ZSB7IFNEQVRBU0laRSB9Cgphc20gZXh0' + + 'ZW5kcyBmdW4gZGVwdGgoc2VsZjogQ2VsbCk6IEludCB7IENERVBUSCB9Cgo='; files['std/config.tact'] = 'YXNtIGZ1biBnZXRDb25maWdQYXJhbShpZDogSW50KTogQ2VsbD8geyBDT05GSUdPUFRQQVJBTSB9Cg=='; files['std/context.tact'] = diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index f1eb31bbc..5306f2d6e 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -221,7 +221,7 @@ inline fun emptySlice(): Slice { return emptyCell().asSlice(); } -asm fun addressNone(): Address { b{00} PUSHSLICE } +asm fun addressNone(): Address? { b{00} PUSHSLICE } struct DataSize { cells: Int; @@ -229,9 +229,9 @@ struct DataSize { refs: Int; } -asm extends fun computeDataSize(self: Cell, maxCells: Int): DataSize { CDATASIZE TRIPLE } +asm extends fun computeDataSize(self: Cell, maxCells: Int): DataSize { CDATASIZE } -asm extends fun computeDataSize(self: Slice, maxCells: Int): DataSize { SDATASIZE TRIPLE } +asm extends fun computeDataSize(self: Slice, maxCells: Int): DataSize { SDATASIZE } asm extends fun depth(self: Cell): Int { CDEPTH } From b0ec7745f53c92509ec3f8fa303cbed025d8e7db Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 28 Nov 2024 08:20:46 +0300 Subject: [PATCH 20/27] chore: add comments with specs for new math functions --- stdlib/std/math.tact | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stdlib/std/math.tact b/stdlib/std/math.tact index d48b18c07..6b46f72c6 100644 --- a/stdlib/std/math.tact +++ b/stdlib/std/math.tact @@ -49,10 +49,12 @@ asm fun abs(x: Int): Int { ABS } asm fun now(): Int { NOW } +// floor(log2(num)) asm fun log2(num: Int): Int { DUP 5 THROWIFNOT UBITSIZE DEC } +// floor(log(num, base)) @name(__tact_log) native log(num: Int, base: Int): Int; @@ -63,8 +65,10 @@ asm fun pow2(exp: Int): Int { POW2 } asm fun sign(x: Int): Int { SGN } +// ceil(x/y) asm fun divc(x: Int, y: Int): Int { DIVC } +// ceil(x*y/z) asm fun muldivc(x: Int, y: Int, z: Int): Int { MULDIVC } // floor(x*y/2^z) @@ -76,6 +80,7 @@ asm fun mulShiftRightRound(x: Int, y: Int, z: Int): Int { MULRSHIFTR } // ceil(x*y/2^z) asm fun mulShiftRightCeil(x: Int, y: Int, z: Int): Int { MULRSHIFTC } +// round(sqrt(num)) fun sqrt(num: Int): Int { if (num == 0) { return 0; From 4d05722e68f36fc40b7b331394f88136010d8cdb Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 28 Nov 2024 08:20:58 +0300 Subject: [PATCH 21/27] feat: cover new functions with tests --- src/test/e2e-emulated/contracts/math.tact | 28 +++++++++ src/test/e2e-emulated/contracts/stdlib.tact | 68 ++++++++++++++++++++- src/test/e2e-emulated/math.spec.ts | 58 ++++++++++++++++++ src/test/e2e-emulated/stdlib.spec.ts | 62 ++++++++++++++++++- 4 files changed, 213 insertions(+), 3 deletions(-) diff --git a/src/test/e2e-emulated/contracts/math.tact b/src/test/e2e-emulated/contracts/math.tact index 28215f20a..01d434afd 100644 --- a/src/test/e2e-emulated/contracts/math.tact +++ b/src/test/e2e-emulated/contracts/math.tact @@ -426,4 +426,32 @@ contract MathTester with Deployable { a >>= b; return a; } + + get fun sign(x: Int): Int { + return sign(x); + } + + get fun divc(x: Int, y: Int): Int { + return divc(x, y); + } + + get fun muldivc(x: Int, y: Int, z: Int): Int { + return muldivc(x, y, z); + } + + get fun mulShiftRight(x: Int, y: Int, z: Int): Int { + return mulShiftRight(x, y, z); + } + + get fun mulShiftRightRound(x: Int, y: Int, z: Int): Int { + return mulShiftRightRound(x, y, z); + } + + get fun mulShiftRightCeil(x: Int, y: Int, z: Int): Int { + return mulShiftRightCeil(x, y, z); + } + + get fun sqrt(x: Int): Int { + return sqrt(x); + } } diff --git a/src/test/e2e-emulated/contracts/stdlib.tact b/src/test/e2e-emulated/contracts/stdlib.tact index c93ac431f..765f57f7f 100644 --- a/src/test/e2e-emulated/contracts/stdlib.tact +++ b/src/test/e2e-emulated/contracts/stdlib.tact @@ -58,4 +58,70 @@ contract StdlibTest { get fun parseVarAddress(slice: Slice): VarAddress { return parseVarAddress(slice); } -} \ No newline at end of file + + get fun builderDepth(bl: Builder): Int { + return bl.depth(); + } + + get fun skipLastBits(sc: Slice, n: Int): Slice { + return sc.skipLastBits(n); + } + + get fun firstBits(sc: Slice, n: Int): Slice { + return sc.firstBits(n); + } + + get fun lastBits(sc: Slice, n: Int): Slice { + return sc.lastBits(n); + } + + get fun sliceDepth(sc: Slice): Int { + return sc.depth(); + } + + get fun addressNone(): Address? { + return addressNone(); + } + + get fun computeDataSizeCell(c: Cell, maxCells: Int): DataSize { + return c.computeDataSize(maxCells); + } + + get fun computeDataSizeSlice(sc: Slice, maxCells: Int): DataSize { + return sc.computeDataSize(maxCells); + } + + get fun cellDepth(c: Cell): Int { + return c.depth(); + } + + get fun curLt(): Int { + return curLt(); + } + + get fun blockLt(): Int { + return blockLt(); + } + + get fun setGasLimit(gl: Int): Int { + setGasLimit(gl); + let x = 0; + repeat (100) { + x += 1; + } + return gasConsumed(); + } + + get fun getSeed(): Int { + return getSeed(); + } + + get fun setSeed(seed: Int): Int { + setSeed(seed); + return getSeed(); + } + + get fun myCode(): Cell { + return myCode(); + } +} diff --git a/src/test/e2e-emulated/math.spec.ts b/src/test/e2e-emulated/math.spec.ts index 397cf7d2b..c6c5a19cd 100644 --- a/src/test/e2e-emulated/math.spec.ts +++ b/src/test/e2e-emulated/math.spec.ts @@ -507,5 +507,63 @@ describe("math", () => { expect(await contract.getAugmentedShiftRight(2n, 1n)).toBe(1n); expect(await contract.getAugmentedShiftRight(4n, 2n)).toBe(1n); expect(await contract.getAugmentedShiftRight(16n, 3n)).toBe(2n); + + // sign + expect(await contract.getSign(123n)).toBe(1n); + expect(await contract.getSign(-123n)).toBe(-1n); + expect(await contract.getSign(0n)).toBe(0n); + + // divc: ceil(x/y) + expect(await contract.getDivc(123n, 123n)).toBe(1n); + expect(await contract.getDivc(123n, 124n)).toBe(1n); + expect(await contract.getDivc(0n, 123n)).toBe(0n); + expect(await contract.getDivc(123n, 122n)).toBe(2n); + + // muldivc: ceil(x*y/z) + expect(await contract.getMuldivc(123n, 123n, 123n)).toBe(123n); + expect(await contract.getMuldivc(100n, 100n, 10001n)).toBe(1n); + expect(await contract.getMuldivc(100n, 100n, 10000n)).toBe(1n); + expect(await contract.getMuldivc(100n, 100n, 9999n)).toBe(2n); + expect(await contract.getMuldivc(100n, 0n, 1n)).toBe(0n); + + // mulShiftRight: floor(x*y/2^z) + expect(await contract.getMulShiftRight(2n, 4n, 3n)).toBe(1n); + expect(await contract.getMulShiftRight(2n, 4n, 2n)).toBe(2n); + expect(await contract.getMulShiftRight(2n, 4n, 1n)).toBe(4n); + expect(await contract.getMulShiftRight(2n, 4n, 0n)).toBe(8n); + expect(await contract.getMulShiftRight(1n, 6n, 0n)).toBe(6n); + expect(await contract.getMulShiftRight(1n, 6n, 3n)).toBe(0n); + + // mulShiftRightRound: round(x*y/2^z) + expect(await contract.getMulShiftRightRound(2n, 4n, 3n)).toBe(1n); + expect(await contract.getMulShiftRightRound(2n, 4n, 2n)).toBe(2n); + expect(await contract.getMulShiftRightRound(2n, 4n, 1n)).toBe(4n); + expect(await contract.getMulShiftRightRound(2n, 4n, 0n)).toBe(8n); + expect(await contract.getMulShiftRightRound(1n, 6n, 0n)).toBe(6n); + expect(await contract.getMulShiftRightRound(1n, 4n, 3n)).toBe(1n); + expect(await contract.getMulShiftRightRound(1n, 3n, 3n)).toBe(0n); + + // mulShiftRightCeil: ceil(x*y/2^z) + expect(await contract.getMulShiftRightCeil(2n, 4n, 3n)).toBe(1n); + expect(await contract.getMulShiftRightCeil(2n, 4n, 2n)).toBe(2n); + expect(await contract.getMulShiftRightCeil(2n, 4n, 1n)).toBe(4n); + expect(await contract.getMulShiftRightCeil(2n, 4n, 0n)).toBe(8n); + expect(await contract.getMulShiftRightCeil(1n, 6n, 0n)).toBe(6n); + expect(await contract.getMulShiftRightCeil(1n, 7n, 3n)).toBe(1n); + expect(await contract.getMulShiftRightCeil(1n, 4n, 3n)).toBe(1n); + expect(await contract.getMulShiftRightCeil(1n, 3n, 3n)).toBe(1n); + + // sqrt: round(sqrt(num)) + for (let num = 0n; num <= 100n; num++) { + // console.log(`sqrt(${num}) = ${await contract.getSqrt(num)}`); + expect(await contract.getSqrt(num)).toBe( + BigInt(Math.round(Math.sqrt(Number(num)))), + ); + } + for (let num = -3n; num < 0n; num++) { + await expect(contract.getSqrt(num)).rejects.toThrow( + "Unable to execute get method. Got exit_code: 5", + ); + } }); }); diff --git a/src/test/e2e-emulated/stdlib.spec.ts b/src/test/e2e-emulated/stdlib.spec.ts index 440d82c13..679bea9a6 100644 --- a/src/test/e2e-emulated/stdlib.spec.ts +++ b/src/test/e2e-emulated/stdlib.spec.ts @@ -1,4 +1,4 @@ -import { Address, beginCell, toNano } from "@ton/core"; +import { Address, beginCell, Cell, toNano } from "@ton/core"; import { Blockchain, SandboxContract, TreasuryContract } from "@ton/sandbox"; import { StdlibTest } from "./contracts/output/stdlib_StdlibTest"; import "@ton/test-utils"; @@ -56,7 +56,7 @@ describe("stdlib", () => { .toString(), ).toBe(beginCell().storeBit(true).endCell().toString()); - expect(await contract.getTvm_2023_07Upgrade()).toEqual(1355n); + expect(await contract.getTvm_2023_07Upgrade()).toEqual(1455n); expect(await contract.getTvm_2024_04Upgrade()).toEqual(82009144n); expect( @@ -106,5 +106,63 @@ describe("stdlib", () => { expect(addrVar.address.asCell()).toEqualCell( beginCell().storeUint(345, 123).endCell(), ); + + expect(await contract.getBuilderDepth(beginCell())).toBe(0n); + expect( + await contract.getBuilderDepth(beginCell().storeRef(Cell.EMPTY)), + ).toBe(1n); + + expect(await contract.getSkipLastBits(slice, 1n)).toEqualSlice( + beginCell() + .storeBit(1) + .storeRef(beginCell().storeBit(1).endCell()) + .endCell() + .asSlice(), + ); + + expect(await contract.getFirstBits(slice, 1n)).toEqualSlice( + beginCell().storeBit(1).endCell().asSlice(), + ); + + expect(await contract.getLastBits(slice, 1n)).toEqualSlice( + beginCell().storeBit(1).endCell().asSlice(), + ); + + expect(await contract.getSliceDepth(slice)).toBe(1n); + + expect(await contract.getAddressNone()).toEqual(null); + + expect( + await contract.getComputeDataSizeCell(slice.asCell(), 1000n), + ).toMatchObject({ + $$type: "DataSize", + cells: 2n, + bits: 3n, + refs: 1n, + }); + + expect( + await contract.getComputeDataSizeSlice(slice, 1000n), + ).toMatchObject({ + $$type: "DataSize", + cells: 1n, // -1 for slice + bits: 3n, + refs: 1n, + }); + + expect(await contract.getCellDepth(slice.asCell())).toBe(1n); + + expect(await contract.getCurLt()).toBe(0n); + + expect(await contract.getBlockLt()).toBe(0n); + + expect(await contract.getSetGasLimit(5000n)).toBe(3997n); // 5000 just to make sure it's enough, 3997 is how much it actually costs + await expect(contract.getSetGasLimit(3996n)).rejects.toThrow("-14"); // 3996 gas is not enough for sure + + expect(await contract.getGetSeed()).toBe(0n); + + expect(await contract.getSetSeed(123n)).toBe(123n); + + expect(await contract.getMyCode()).toEqualCell(contract.init!.code); }); }); From 734f3a06e0aa0be6d13449fcc04871c3485fe68e Mon Sep 17 00:00:00 2001 From: Gusarich Date: Fri, 29 Nov 2024 15:52:43 +0300 Subject: [PATCH 22/27] feat: update stdlib.ts --- src/imports/stdlib.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index 25f6f64b3..293aabc01 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -357,17 +357,18 @@ files['std/math.tact'] = 'YW5kb21JbnQoKTogSW50IHsKICAgIG5hdGl2ZVByZXBhcmVSYW5kb20oKTsKICAgIHJldHVybiBuYXRpdmVSYW5kb20oKTsKfQoKaW5saW5lIGZ1biByYW5kb20obWlu' + 'OiBJbnQsIG1heDogSW50KTogSW50IHsKICAgIG5hdGl2ZVByZXBhcmVSYW5kb20oKTsKICAgIHJldHVybiBtaW4gKyBuYXRpdmVSYW5kb21JbnRlcnZhbChtYXggLSBt' + 'aW4pOwp9CgovLyBNYXRoCgphc20gZnVuIG1pbih4OiBJbnQsIHk6IEludCk6IEludCB7IE1JTiB9Cgphc20gZnVuIG1heCh4OiBJbnQsIHk6IEludCk6IEludCB7IE1B' + - 'WCB9Cgphc20gZnVuIGFicyh4OiBJbnQpOiBJbnQgeyBBQlMgfQoKYXNtIGZ1biBub3coKTogSW50IHsgTk9XIH0KCmFzbSBmdW4gbG9nMihudW06IEludCk6IEludCB7' + - 'CiAgICBEVVAgNSBUSFJPV0lGTk9UIFVCSVRTSVpFIERFQwp9CgpAbmFtZShfX3RhY3RfbG9nKQpuYXRpdmUgbG9nKG51bTogSW50LCBiYXNlOiBJbnQpOiBJbnQ7CgpA' + - 'bmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0KCmFz' + - 'bSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQoKYXNtIGZ1biBkaXZjKHg6IEludCwgeTogSW50KTogSW50IHsgRElWQyB9Cgphc20gZnVuIG11bGRpdmMoeDog' + - 'SW50LCB5OiBJbnQsIHo6IEludCk6IEludCB7IE1VTERJVkMgfQoKLy8gZmxvb3IoeCp5LzJeeikKYXNtIGZ1biBtdWxTaGlmdFJpZ2h0KHg6IEludCwgeTogSW50LCB6' + - 'OiBJbnQpOiBJbnQgeyBNVUxSU0hJRlQgfQoKLy8gcm91bmQoeCp5LzJeeikKYXNtIGZ1biBtdWxTaGlmdFJpZ2h0Um91bmQoeDogSW50LCB5OiBJbnQsIHo6IEludCk6' + - 'IEludCB7IE1VTFJTSElGVFIgfQoKLy8gY2VpbCh4KnkvMl56KQphc20gZnVuIG11bFNoaWZ0UmlnaHRDZWlsKHg6IEludCwgeTogSW50LCB6OiBJbnQpOiBJbnQgeyBN' + - 'VUxSU0hJRlRDIH0KCmZ1biBzcXJ0KG51bTogSW50KTogSW50IHsKICAgIGlmIChudW0gPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGxldCBzOiBJ' + - 'bnQgPSBsb2cyKG51bSk7CiAgICBsZXQgeDogSW50ID0gKHMgPT0gMSA/IChudW0gLSAxKSAvIDIgKyAxIDogMSA8PCAoKHMgKyAxKSAvIDIpKTsKCiAgICBsZXQgcTog' + - 'SW50ID0gMDsKCiAgICBkbyB7CiAgICAgICAgcSA9IChkaXZjKG51bSwgeCkgLSB4KSAvIDI7CiAgICAgICAgeCArPSBxOwogICAgfSB1bnRpbCAocSA9PSAwKTsKCiAg' + - 'ICByZXR1cm4geDsKfQo='; + 'WCB9Cgphc20gZnVuIGFicyh4OiBJbnQpOiBJbnQgeyBBQlMgfQoKYXNtIGZ1biBub3coKTogSW50IHsgTk9XIH0KCi8vIGZsb29yKGxvZzIobnVtKSkKYXNtIGZ1biBs' + + 'b2cyKG51bTogSW50KTogSW50IHsKICAgIERVUCA1IFRIUk9XSUZOT1QgVUJJVFNJWkUgREVDCn0KCi8vIGZsb29yKGxvZyhudW0sIGJhc2UpKQpAbmFtZShfX3RhY3Rf' + + 'bG9nKQpuYXRpdmUgbG9nKG51bTogSW50LCBiYXNlOiBJbnQpOiBJbnQ7CgpAbmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJ' + + 'bnQ7Cgphc20gZnVuIHBvdzIoZXhwOiBJbnQpOiBJbnQgeyBQT1cyIH0KCmFzbSBmdW4gc2lnbih4OiBJbnQpOiBJbnQgeyBTR04gfQoKLy8gY2VpbCh4L3kpCmFzbSBm' + + 'dW4gZGl2Yyh4OiBJbnQsIHk6IEludCk6IEludCB7IERJVkMgfQoKLy8gY2VpbCh4KnkveikKYXNtIGZ1biBtdWxkaXZjKHg6IEludCwgeTogSW50LCB6OiBJbnQpOiBJ' + + 'bnQgeyBNVUxESVZDIH0KCi8vIGZsb29yKHgqeS8yXnopCmFzbSBmdW4gbXVsU2hpZnRSaWdodCh4OiBJbnQsIHk6IEludCwgejogSW50KTogSW50IHsgTVVMUlNISUZU' + + 'IH0KCi8vIHJvdW5kKHgqeS8yXnopCmFzbSBmdW4gbXVsU2hpZnRSaWdodFJvdW5kKHg6IEludCwgeTogSW50LCB6OiBJbnQpOiBJbnQgeyBNVUxSU0hJRlRSIH0KCi8v' + + 'IGNlaWwoeCp5LzJeeikKYXNtIGZ1biBtdWxTaGlmdFJpZ2h0Q2VpbCh4OiBJbnQsIHk6IEludCwgejogSW50KTogSW50IHsgTVVMUlNISUZUQyB9CgovLyByb3VuZChz' + + 'cXJ0KG51bSkpCmZ1biBzcXJ0KG51bTogSW50KTogSW50IHsKICAgIGlmIChudW0gPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGxldCBzOiBJbnQg' + + 'PSBsb2cyKG51bSk7CiAgICBsZXQgeDogSW50ID0gKHMgPT0gMSA/IChudW0gLSAxKSAvIDIgKyAxIDogMSA8PCAoKHMgKyAxKSAvIDIpKTsKCiAgICBsZXQgcTogSW50' + + 'ID0gMDsKCiAgICBkbyB7CiAgICAgICAgcSA9IChkaXZjKG51bSwgeCkgLSB4KSAvIDI7CiAgICAgICAgeCArPSBxOwogICAgfSB1bnRpbCAocSA9PSAwKTsKCiAgICBy' + + 'ZXR1cm4geDsKfQo='; files['std/primitives.tact'] = 'cHJpbWl0aXZlIEludDsKcHJpbWl0aXZlIEJvb2w7CnByaW1pdGl2ZSBCdWlsZGVyOwpwcmltaXRpdmUgU2xpY2U7CnByaW1pdGl2ZSBDZWxsOwpwcmltaXRpdmUgQWRk' + 'cmVzczsKcHJpbWl0aXZlIFN0cmluZzsKcHJpbWl0aXZlIFN0cmluZ0J1aWxkZXI7'; From a2da1a25b795a7e04a01a7e6ad136f1106e92e5b Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:29:13 +0100 Subject: [PATCH 23/27] chore: typos and extra linkage --- docs/src/content/docs/book/exit-codes.mdx | 6 +++--- docs/src/content/docs/ref/core-math.mdx | 7 +++++-- src/test/exit-codes/compute-phase-errors.spec.ts | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/src/content/docs/book/exit-codes.mdx b/docs/src/content/docs/book/exit-codes.mdx index bfb6486b7..d292eff29 100644 --- a/docs/src/content/docs/book/exit-codes.mdx +++ b/docs/src/content/docs/book/exit-codes.mdx @@ -183,7 +183,7 @@ contract ItsSoOver { ### 4: Integer overflow {#4} -If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, or there's an attempt to [divide](/book/operators#binary-divide) or [modulo](/book/operators#binary-modulo) by zero, an error with exit code $4$ is thrown: `Integer overflow`. +If the [value in calculation](/book/integers#operations) goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, or there's an attempt to [divide](/book/operators#binary-divide) or [modulo](/book/operators#binary-modulo) by zero, an error with exit code $4$ is thrown: `Integer overflow`. ```tact let x = -pow(2, 255) - pow(2, 255); // -2^{256} @@ -213,9 +213,9 @@ try { // division (/) by a negative number or modulo (%) by zero ``` -### 5: Integer out of range {#5} +### 5: Integer out of expected range {#5} -Range check error — some integer is out of its expected range. I.e. any attempt to store an unexpected amount of data or specify an out-of-bounds value throws an error with exit code $5$: `Integer out of range`. +Range check error — [some integer](/book/integers#operations) is out of its expected range. I.e. any attempt to store an unexpected amount of data or specify an out-of-bounds value throws an error with exit code $5$: `Integer out of expected range`. Examples of specifying an out-of-bounds value: diff --git a/docs/src/content/docs/ref/core-math.mdx b/docs/src/content/docs/ref/core-math.mdx index e4ccb1f81..039a3a12b 100644 --- a/docs/src/content/docs/ref/core-math.mdx +++ b/docs/src/content/docs/ref/core-math.mdx @@ -46,7 +46,7 @@ max(0x45, 3_0_0); // 300 ## abs ```tact -fun abs(x: Int): Int +fun abs(x: Int): Int; ``` Computes and returns the [absolute value](https://en.wikipedia.org/wiki/Absolute_value) of the [`Int{:tact}`][int] value `x`. @@ -65,7 +65,7 @@ abs(-(-(-42))); // 42 fun log(num: Int, base: Int): Int; ``` -Computes and returns the [logarithm](https://en.wikipedia.org/wiki/Logarithm) of a number `num` $> 0$ to the base `base` $≥ 1$. Results are [rounded down](https://en.wikipedia.org/wiki/Rounding#Rounding_down). Passing a non-positive `num` value or a `base` less than $1$ throws an error with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. +Computes and returns the [logarithm](https://en.wikipedia.org/wiki/Logarithm) of a number `num` $> 0$ to the base `base` $≥ 1$. Results are [rounded down][round-down]. Passing a non-positive `num` value or a `base` less than $1$ throws an error with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. Usage examples: @@ -286,3 +286,6 @@ sha256(someVariableElsewhere); // will try to resolve at compile-time, [tvm]: https://docs.ton.org/learn/tvm-instructions/tvm-overview [ed]: https://en.wikipedia.org/wiki/EdDSA#Ed25519 [sha-2]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard + +[round-up]: https://en.wikipedia.org/wiki/Rounding#Rounding_up +[round-down]: https://en.wikipedia.org/wiki/Rounding#Rounding_down diff --git a/src/test/exit-codes/compute-phase-errors.spec.ts b/src/test/exit-codes/compute-phase-errors.spec.ts index 15f0c0199..cfdca0644 100644 --- a/src/test/exit-codes/compute-phase-errors.spec.ts +++ b/src/test/exit-codes/compute-phase-errors.spec.ts @@ -59,7 +59,7 @@ describe("compute phase errors", () => { await testComputePhaseExitCode(4, contract, treasure); }); - // 5: Integer out of range + // 5: Integer out of expected range it("should test exit code 5", async () => { await testComputePhaseExitCode(5, contract, treasure); }); From 2b72e665c08ba746ba2238c9fb398c1cd765abd5 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:30:04 +0100 Subject: [PATCH 24/27] feat(docs): all math functions and all new non-cell related functions documented, except for `addressNone` --- docs/cspell.json | 1 + docs/src/content/docs/book/exit-codes.mdx | 2 +- docs/src/content/docs/ref/core-advanced.mdx | 205 ++++++++++++++++--- docs/src/content/docs/ref/core-math.mdx | 158 +++++++++++++++ src/imports/stdlib.ts | 207 ++++++++++---------- stdlib/std/contract.tact | 4 +- 6 files changed, 447 insertions(+), 130 deletions(-) diff --git a/docs/cspell.json b/docs/cspell.json index 623040802..c1000d52b 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -160,6 +160,7 @@ "minmax", "mintable", "mktemp", + "muldivc", "multiformats", "nanotons", "nanotons", diff --git a/docs/src/content/docs/book/exit-codes.mdx b/docs/src/content/docs/book/exit-codes.mdx index d292eff29..57664463a 100644 --- a/docs/src/content/docs/book/exit-codes.mdx +++ b/docs/src/content/docs/book/exit-codes.mdx @@ -521,7 +521,7 @@ If the configuration is absent, default values are: * `max_msg_bits` is equal to $2^{21}$ — maximum message size in bits. * `max_msg_cells` is equal to $2^{13}$ — maximum number of [cells][cell] a message can occupy. * `max_library_cells` is equal to $1000$ — maximum number of [cells][cell] that can be used as [library reference cells](/book/cells#cells-kinds). -* `max_vm_data_depth` is equal to $2^{9}$ — maximum [cells][cell] depth in messages and account state. +* `max_vm_data_depth` is equal to $2^{9}$ — maximum [cells][cell] [depth](/book/cells#cells-representation) in messages and account state. * `ext_msg_limits.max_size` is equal to $65535$ — maximum external message size in bits. * `ext_msg_limits.max_depth` is equal to $2^{9}$ — maximum external message [depth](/book/cells#cells-representation). * `max_acc_state_cells` is equal to $2^{16}$ — maximum number of [cells][cell] that an account state can occupy. diff --git a/docs/src/content/docs/ref/core-advanced.mdx b/docs/src/content/docs/ref/core-advanced.mdx index 25dba26cd..5b9b4912c 100644 --- a/docs/src/content/docs/ref/core-advanced.mdx +++ b/docs/src/content/docs/ref/core-advanced.mdx @@ -31,7 +31,7 @@ let gas: Int = gasConsumed(); :::note[Useful links:] - [Gas in TON Docs](https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/fees#gas) + [Gas in TON Docs][gas] ::: @@ -68,7 +68,7 @@ fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int Calculates and returns the [storage fee][storage-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 18 of TON Blockchain](https://docs.ton.org/develop/howto/blockchain-configs#param-18). -Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_acc_state_cells` and `max_acc_state_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. In addition, make sure you take into account the [deduplication of cells with the same hash][deduplication]. +Note, that specifying values of `cells` and `bits` higher than their maximum values listed in [account state limits (`max_acc_state_cells` and `max_acc_state_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. In addition, make sure you take into account the [deduplication of cells with the same hash][deduplication]. Attempts to specify negative number of `cells`, `bits` or `seconds` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. @@ -189,7 +189,7 @@ Calculates and returns the [forward fee][forward-fee] in [nanoToncoins][nanotonc If both the source and the destination addresses are in the [basechain][basechain], then specify `isMasterchain` as `false{:tact}`. Otherwise, specify `true{:tact}`. -Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_msg_cells` and `max_msg_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. +Note, that specifying values of `cells` and `bits` higher than their maximum values listed in [account state limits (`max_msg_cells` and `max_msg_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of [`lump_price`][param-24-25]. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. In addition, make sure you take into account the [deduplication of cells with the same hash][deduplication], since for example the root cell and its data bits don't count towards the forward fee and are covered by the [`lump_price`][param-24-25]. @@ -276,31 +276,27 @@ let origFee: Int = getOriginalFwdFee(fee, false); ::: -## getConfigParam +## setGasLimit + +

```tact -fun getConfigParam(id: Int): Cell?; +fun setGasLimit(limit: Int); ``` -Loads a [configuration parameter](https://docs.ton.org/develop/howto/blockchain-configs) of TON Blockchain by its `id` number. +Sets the [`gas_limit`][param-20-21] to the [`Int{:tact}`][int] `limit` and resets the [`gas_credit`][param-20-21] to $0$. Note, that specifying the `limit` higher than the maximum allowed value of $2^{63} - 1$ will have the same result as with specifying that exact maximum or calling [`acceptMessage(){:tact}`](#acceptmessage). -Usage examples: +Attempts to specify a negative or insufficient value of `limit` will cause an exception with [exit code -14](/book/exit-codes#-14): `Out of gas error`. -```tact -// Parameter 0, address of a special smart contract that stores the blockchain's configuration -let configAddrAsCell: Cell = getConfigParam(0)!!; +Usage example: -// Parameter 18, configuration for determining the prices for data storage -let dataStorageFeeConfig: Cell = getConfigParam(18)!!; +```tact +setGasLimit(42000); ``` :::note - Standard library [`@stdlib/config`](/ref/stdlib-config) provides two related helper functions:\ - [`getConfigAddress(){:tact}`](/ref/stdlib-config#getconfigaddress) for retrieving config [`Address{:tact}`][p]\ - [`getElectorAddress(){:tact}`](/ref/stdlib-config#getconfigaddress) for retrieving elector [`Address{:tact}`][p] - - Read more about other parameters: [Config Parameters in TON Docs](https://docs.ton.org/develop/howto/blockchain-configs). + For more details, see: [Accept Message Effects in TON Docs](https://docs.ton.org/develop/smart-contracts/guidelines/accept). ::: @@ -310,7 +306,7 @@ let dataStorageFeeConfig: Cell = getConfigParam(18)!!; fun acceptMessage(); ``` -Agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. +Agrees to buy some [gas][gas] to finish the current transaction by setting the [`gas_limit`][param-20-21] to its maximum allowed value of $2^{63} - 1$ and resetting the [`gas_credit`][param-20-21] to $0$. This action is required to process external messages, which bring no value (hence no gas) with themselves. Usage example: @@ -342,7 +338,7 @@ contract Timeout { fun commit(); ``` -Commits the current state of [registers](https://docs.ton.org/learn/tvm-instructions/tvm-overview#control-registers) `c4` ("persistent data") and `c5` ("actions"), so that the current execution is considered "successful" with the saved values even if an exception in compute phase is thrown later. +Commits the current state of [registers][registers] `c4` ("persistent data") and `c5` ("actions"), so that the current execution is considered "successful" with the saved values even if an exception in compute phase is thrown later. Usage example: @@ -351,6 +347,146 @@ commit(); // now, transaction is considered "successful" throw(42); // and this won't fail it ``` +## myCode + +

+ +```tact +fun myCode(): Cell; +``` + +Returns the smart contract code [`Cell{:tact}`][cell] obtained from the `c7` [register][registers]. + +Usage example: + +```tact +let code: Cell = myCode(); +``` + +## getConfigParam + +```tact +fun getConfigParam(id: Int): Cell?; +``` + +Loads a [configuration parameter](https://docs.ton.org/develop/howto/blockchain-configs) of TON Blockchain by its `id` number. + +Usage examples: + +```tact +// Parameter 0, address of a special smart contract that stores the blockchain's configuration +let configAddrAsCell: Cell = getConfigParam(0)!!; + +// Parameter 18, configuration for determining the prices for data storage +let dataStorageFeeConfig: Cell = getConfigParam(18)!!; +``` + +:::note + + Standard library [`@stdlib/config`](/ref/stdlib-config) provides two related helper functions:\ + [`getConfigAddress(){:tact}`](/ref/stdlib-config#getconfigaddress) for retrieving config [`Address{:tact}`][p]\ + [`getElectorAddress(){:tact}`](/ref/stdlib-config#getconfigaddress) for retrieving elector [`Address{:tact}`][p] + + Read more about other parameters: [Config Parameters in TON Docs](https://docs.ton.org/develop/howto/blockchain-configs). + +::: + +## getSeed + +

+ +```tact +fun getSeed(): Int; +``` + +Generates and returns an unsigned $256$-bit [`Int{:tact}`][int] [seed][seed] for the random number generator. The resulting seed is commonly used with the [`setSeed(){:tact}`](#setseed) and [`nativeRandomize(){:tact}`](#nativerandomize) functions. + +Usage example: + +```tact +let seed: Int = getSeed(); +setSeed(seed); // from now on the results of pseudorandom number generator + // are completely determined by the seed, which can be handy in tests, + // but must not be used in production code! +``` + +:::note[Useful links:] + + [Random seed in Wikipedia][seed]\ + [`setSeed(){:tact}`](#setseed)\ + [`nativeRandomize(){:tact}`](#nativerandomize) + +::: + +## setSeed + +

+ +```tact +fun setSeed(seed: Int); +``` + +Sets the [seed][seed] of the random number generator to the unsigned $256$-bit [`Int{:tact}`][int] `seed` which can be obtained with the [`getSeed(){:tact}`](#getseed) function. + +Attempts to specify a negative value of `seed` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Usage example: + +```tact +let seed: Int = getSeed(); +setSeed(seed); // from now on the results of pseudorandom number generator + // are completely determined by the seed, which can be handy in tests, + // but must not be used in production code! +``` + +:::note[Useful links:] + + [Random seed in Wikipedia][seed]\ + [`getSeed(){:tact}`](#getseed) + +::: + +## curLt + +

+ +```tact +fun curLt(): Int; +``` + +Returns the [`Int{:tact}`][int] value of the [logical time][lt] of the current transaction. + +Usage example: + +```tact +let lt: Int = curLt(); +nativeRandomize(lt); // equivalent to calling nativeRandomizeLt() +``` + +:::note[Useful links:] + + [Random seed in Wikipedia][seed]\ + [`nativeRandomize{:tact}`](#nativerandomize)\ + [`nativeRandomizeLt{:tact}`](#nativerandomizelt) + +::: + +## blockLt + +

+ +```tact +fun blockLt(): Int; +``` + +Returns the [`Int{:tact}`][int] value of the [logical time][lt] of the current block. + +Usage example: + +```tact +let time: Int = blockLt(); +``` + ## nativePrepareRandom ```tact @@ -372,22 +508,31 @@ nativePrepareRandom(); // prepare the RNG fun nativeRandomize(x: Int); ``` -Randomizes the pseudo-random number generator with the specified seed `x`. +Randomizes the pseudorandom number generator with the specified unsigned $256$-bit [`Int{:tact}`][int] `x` by mixing it with the current [seed][seed]. The new seed is the unsigned $256$-bit [`Int{:tact}`][int] value of the [SHA-256][sha-2] hash of concatenated old seed and `x` in their $32$-byte strings [big-endian](https://en.wikipedia.org/wiki/Endianness) representation. + +Attempts to specify a negative value of `x` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. Usage example: ```tact -nativeRandomize(); // now, random numbers are less predictable -let idk: Int = randomInt(); // ???, it's random! +nativeRandomize(42); // now, random numbers are less predictable +let idk: Int = randomInt(); // ???, it's random, + // but the seed was adjusted deterministically! ``` +:::note[Useful links:] + + [Random seed in Wikipedia][seed] + +::: + ## nativeRandomizeLt ```tact fun nativeRandomizeLt(); ``` -Randomizes the random number generator with the current [logical time](https://docs.ton.org/develop/smart-contracts/guidelines/message-delivery-guarantees#what-is-a-logical-time). +Randomizes the random number generator with the [logical time][lt] of the current transaction. Equivalent to calling `nativeRandomize(curLt()){:tact}`. Usage example: @@ -398,6 +543,14 @@ nativeRandomizeLt(); // now, random numbers are unpredictable for users, let idk: Int = randomInt(); // ???, it's random! ``` +:::note[Useful links:] + + [Random seed in Wikipedia][seed]\ + [`nativeRandomize{:tact}`](#nativerandomize)\ + [`curLt(){:tact}`](#curlt) + +::: + ## nativeRandom ```tact @@ -579,6 +732,7 @@ parsedVarAddr.address.loadUint(123); // 345 [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[cell]: /book/cells#cells [slice]: /book/cells#slices [s]: /book/structs-and-messages#structs [masterchain]: /book/masterchain @@ -588,6 +742,7 @@ parsedVarAddr.address.loadUint(123); // 345 [tvm]: https://docs.ton.org/learn/tvm-instructions/tvm-overview [basechain]: https://docs.ton.org/v3/concepts/ton-blockchain/smart-contract-addresses#address-components [deduplication]: https://docs.ton.org/v3/documentation/data-formats/tlb/library-cells +[registers]: https://docs.ton.org/learn/tvm-instructions/tvm-overview#control-registers [storage-fee]: https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/fees-low-level#storage-fee [storage-fee-calc]: https://docs.ton.org/v3/guidelines/smart-contracts/fee-calculation#storage-fee @@ -600,3 +755,7 @@ parsedVarAddr.address.loadUint(123); // 345 [forward-fee]: https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/forward-fees [forward-fee-calc]: https://docs.ton.org/v3/guidelines/smart-contracts/fee-calculation#forward-fee [param-24-25]: https://docs.ton.org/v3/documentation/network/configs/blockchain-configs#param-24-and-25 + +[lt]: https://docs.ton.org/v3/documentation/smart-contracts/message-management/messages-and-transactions#what-is-a-logical-time +[seed]: https://en.wikipedia.org/wiki/Random_seed +[sha-2]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard diff --git a/docs/src/content/docs/ref/core-math.mdx b/docs/src/content/docs/ref/core-math.mdx index 039a3a12b..6d8227d81 100644 --- a/docs/src/content/docs/ref/core-math.mdx +++ b/docs/src/content/docs/ref/core-math.mdx @@ -3,6 +3,8 @@ title: Math description: "Various math helper functions from the Core library of Tact" --- +import { Badge } from '@astrojs/starlight/components'; + Various math helper functions. ## min @@ -59,6 +61,162 @@ abs(-42); // 42 abs(-(-(-42))); // 42 ``` +## sign + +

+ +```tact +fun sign(x: Int): Int; +``` + +Computes and returns the sign of the [`Int{:tact}`][int] value `x`. Produces $1$ is the `x` is negative, $-1$ if the `x` is positive, and $0$ if the `x` is $0$. + +Usage examples: + +```tact +sign(42); // 1 +sign(-42); // -1 +sign(-(-42)); // 1 +sign(-(-(-42))); // -1 +sign(0); // 0 +``` + +## sqrt + +

+ +```tact +fun sqrt(num: Int): Int; +``` + +Computes the [square root](https://en.wikipedia.org/wiki/Square_root) of the [`Int{:tact}`][int] value `num`. Returns the result rounded to the nearest integer. If there are two equally close integers, rounding is done toward the even one. + +Attempts to specify negative value of `num` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Usage examples: + +```tact +sqrt(4); // 2 +sqrt(3); // 2 +sqrt(2); // 1 +sqrt(1); // 1 +sqrt(0); // 0 +sqrt(-1); // ERROR! Exit code 5: Integer out of expected range +``` + +## divc + +

+ +```tact +fun divc(x: Int, y: Int): Int; +``` + +Computes and returns the [rounded up][round-up] result of division of the [`Int{:tact}`][int] `x` by the [`Int{:tact}`][int] `y`. + +Attempts to divide by `y` equal to $0$ throw an exception with [exit code 4](/book/exit-codes#4): `Integer overflow`. + +Usage examples: + +```tact +divc(4, 2); // 2 +divc(3, 2); // 2 +divc(-4, 2); // -2 +divc(-3, 2); // -1 +``` + +## muldivc + +

+ +```tact +fun muldivc(x: Int, y: Int, z: Int): Int; +``` + +Computes and returns the [rounded up][round-up] result of `(x * y) / z{:tact}`. + +If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, or if there's an attempt to divide by `z` equal to $0$, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`. + +Usage examples: + +```tact +muldivc(4, 1, 2); // 2 +muldivc(3, 1, 2); // 2 +muldivc(-4, 1, 2); // -2 +muldivc(-3, 1, 2); // -1 +muldivc(-3, 0, 2); // 0 +muldivc(-3, 0, ); // ERROR! Exit code 4: Integer overflow +``` + +## mulShiftRight + +

+ +```tact +fun mulShiftRight(x: Int, y: Int, z: Int): Int; +``` + +Computes and returns the [rounded down][round-down] result of `(x * y) / z{:tact}`. It is a more gas-efficient equivalent of doing the [bitwise shift right](/book/operators#binary-bitwise-shift-right) on the result of multiplication of [`Int{:tact}`][int] `x` times [`Int{:tact}`][int] `y`, where [`Int{:tact}`][int] `z` is the right operand of the shift. + +If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`. + +Attempts to specify negative value of `z` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Usage examples: + +```tact +mulShiftRight(5, 5, 2); // 6 +mulShiftRight(5, 5, 1); // 12 +mulShiftRight(5, 5, 0); // 25 +mulShiftRight(5, 5, -1); // ERROR! Exit code 5: Integer out of expected range +``` + +## mulShiftRightRound + +

+ +```tact +fun mulShiftRightRound(x: Int, y: Int, z: Int): Int; +``` + +Similar to [`mulShiftRight(){:tact}`](#mulshiftright), but instead of [rounding down][round-down], the result value is rounded to the nearest integer. If there are two equally close integers, rounding is done toward the even one. + +If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`. + +Attempts to specify negative value of `z` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Usage examples: + +```tact +mulShiftRightRound(5, 5, 2); // 6 +mulShiftRightRound(5, 5, 1); // 13 +mulShiftRightRound(5, 5, 0); // 25 +mulShiftRightRound(5, 5, -1); // ERROR! Exit code 5: Integer out of expected range +``` + +## mulShiftRightCeil + +

+ +```tact +fun mulShiftRightCeil(x: Int, y: Int, z: Int): Int; +``` + +Similar to [`mulShiftRight(){:tact}`](#mulshiftright), but instead of [rounding down][round-down], the result value is [rounded up][round-up]. + +If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`. + +Attempts to specify negative value of `z` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Usage examples: + +```tact +mulShiftRightCeil(5, 5, 2); // 7 +mulShiftRightCeil(5, 5, 1); // 13 +mulShiftRightCeil(5, 5, 0); // 25 +mulShiftRightCeil(5, 5, -1); // ERROR! Exit code 5: Integer out of expected range +``` + ## log ```tact diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index 293aabc01..1a83e4fb1 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -226,110 +226,109 @@ files['std/contract.tact'] = 'YWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBzdG9yYWdlIGZlZSBpbiBuYW5vVG9uY29pbnMgYEludGAgZm9yIHN0b3JpbmcgYSBjb250cmFjdCB3aXRoIGEgZ2l2ZW4g' + 'bnVtYmVyIG9mIGBjZWxsc2AgYW5kIGBiaXRzYCBmb3IgYSBudW1iZXIgb2YgYHNlY29uZHNgLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBp' + 'c01hc3RlcmNoYWluYCBpcyBgdHJ1ZWAsIG90aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJyZW50IHByaWNlcyBhcmUgb2J0YWluZWQg' + - 'ZnJvbSB0aGUgY29uZmlnIHBhcmFtIDE4IG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIE5vdGUsIHRoYXQgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFuZCBgYml0c2Ag' + - 'YXJlIHRha2VuIG1vZHVsbyB0aGVpciBtYXhpbXVtIHZhbHVlcyBwbHVzIDEuIFRoYXQgaXMsIHNwZWNpZnlpbmcgdmFsdWVzIGhpZ2hlciB0aGFuIHRob3NlIGxpc3Rl' + - 'ZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAoYG1heF9hY2Nfc3RhdGVfY2VsbHNgIGFuZCBgbWF4X2FjY19zdGF0ZV9iaXRzYCkgd2lsbCBoYXZlIHRoZSBzYW1lIHJl' + - 'c3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4gSW4gYWRkaXRpb24sIG1ha2Ugc3VyZSB5b3UgdGFrZSBpbnRvIGFjY291bnQgdGhlIGRlZHVw' + - 'bGljYXRpb24gb2YgY2VsbHMgd2l0aCB0aGUgc2FtZSBoYXNoLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2AsIGBi' + - 'aXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8g' + - 'YGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0gZ2V0U3RvcmFnZUZlZSgxXzAwMCwgMV8wMDAsIDFfMDAwLCBmYWxzZSk7Ci8v' + - 'LyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8vICog' + - 'aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0c2ltcGxlc3RvcmFnZWZlZQovLy8KYXNtIGZ1biBnZXRTdG9yYWdlRmVlKGNlbGxz' + - 'OiBJbnQsIGJpdHM6IEludCwgc2Vjb25kczogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VUU1RPUkFHRUZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9u' + - 'LiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBjb21wdXRlIGZlZSBpbiBuYW5vVG9uY29pbnMgYElu' + - 'dGAgZm9yIGEgdHJhbnNhY3Rpb24gdGhhdCBjb25zdW1lZCBgZ2FzVXNlZGAgYW1vdW50IG9mIGdhcy4gVXNlcyB0aGUgcHJpY2VzIG9mIHRoZSBtYXN0ZXJjaGFpbiBp' + - 'ZiBgaXNNYXN0ZXJjaGFpbmAgaXMgYHRydWVgLCBvdGhlcndpc2UgdGhlIHByaWNlcyBvZiB0aGUgYmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFp' + - 'bmVkIGZyb20gdGhlIGNvbmZpZyBwYXJhbSAyMCBmb3IgdGhlIG1hc3RlcmNoYWluIGFuZCBjb25maWcgcGFyYW0gMjEgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJs' + - 'b2NrY2hhaW4uCi8vLwovLy8gV2hlbiB0aGUgYGdhc1VzZWRgIGlzIGxlc3MgdGhhbiBhIGNlcnRhaW4gdGhyZXNob2xkIGNhbGxlZCBgZmxhdF9nYXNfbGltaXRgLCB0' + - 'aGVyZSdzIGEgbWluaW11bSBwcmljZSB0byBwYXkgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBmbGF0X2dhc19wcmljZWAuIFRoZSBsZXNzIGdhcyBpcyB1c2VkIGJlbG93' + - 'IHRoaXMgdGhyZXNob2xkLCB0aGUgaGlnaGVyIHRoZSBtaW5pbXVtIHByaWNlIHdpbGwgYmUuIFNlZSB0aGUgZXhhbXBsZSBmb3IgYGdldFNpbXBsZUNvbXB1dGVGZWUo' + - 'KWAgdG8gZGVyaXZlIHRoYXQgdGhyZXNob2xkLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgdmFsdWUgb2YgYGdhc1VzZWRgIHRocm93IGFuIGV4' + - 'Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewov' + - 'Ly8gICAgIGxldCBmZWU6IEludCA9IGdldENvbXB1dGVGZWUoMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3Qt' + - 'bGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Y29tcHV0ZWZlZQovLy8KYXNtIGZ1biBnZXRDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjog' + - 'Qm9vbCk6IEludCB7IEdFVEdBU0ZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBn' + - 'ZXRDb21wdXRlRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGZsYXRfZ2FzX3ByaWNlYCwgaS5lLiB3aXRob3V0IGEgbWluaW11bSBwcmljZSB0byBwYXkgaWYgdGhlIGBn' + - 'YXNVc2VkYCBpcyBsZXNzIHRoYW4gYSBjZXJ0YWluIHRocmVzaG9sZCBjYWxsZWQgYGZsYXRfZ2FzX2xpbWl0YC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRo' + - 'ZSBgZ2FzVXNlZGAgdGltZXMgdGhlIGN1cnJlbnQgZ2FzIHByaWNlLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2As' + - 'IGBiaXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwov' + - 'Ly8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZSA9IGdldENvbXB1dGVGZWUoMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0ZsYXQg' + - 'PSBnZXRTaW1wbGVDb21wdXRlRmVlKDAsIGZhbHNlKTsKLy8vICAgICBsZXQgbWF4RmxhdFByaWNlID0gZmVlIC0gZmVlTm9GbGF0OwovLy8gfQovLy8gYGBgCi8vLwov' + - 'Ly8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNnZXRzaW1wbGVzdG9yYWdlZmVlCi8vLyAqIGh0dHBzOi8vZG9j' + - 'cy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8vCmFzbSBmdW4gZ2V0U2ltcGxlQ29tcHV0ZUZlZShnYXNVc2VkOiBJbnQsIGlz' + - 'TWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRHQVNGRUVTSU1QTEUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8v' + - 'LwovLy8gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2luZyBtZXNzYWdlIGNvbnNp' + - 'c3Rpbmcgb2YgYSBnaXZlbiBudW1iZXIgb2YgYGNlbGxzYCBhbmQgYGJpdHNgLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBpc01hc3RlcmNo' + - 'YWluYCBpcyBgdHJ1ZXs6dGFjdH1gLCBvdGhlcndpc2UgdGhlIHByaWNlcyBvZiB0aGUgYmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFpbmVkIGZy' + - 'b20gdGhlIGNvbmZpZyBwYXJhbSAyNCBmb3IgdGhlIG1hc3RlcmNoYWluIGFuZCBjb25maWcgcGFyYW0gMjUgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJsb2NrY2hh' + - 'aW4uCi8vLwovLy8gSWYgYm90aCB0aGUgc291cmNlIGFuZCB0aGUgZGVzdGluYXRpb24gYWRkcmVzc2VzIGFyZSBpbiB0aGUgYmFzZWNoYWluLCB0aGVuIHNwZWNpZnkg' + - 'YGlzTWFzdGVyY2hhaW5gIGFzIGBmYWxzZWAuIE90aGVyd2lzZSwgc3BlY2lmeSBgdHJ1ZWAuCi8vLwovLy8gTm90ZSwgdGhhdCB0aGUgdmFsdWVzIG9mIGBjZWxsc2Ag' + - 'YW5kIGBiaXRzYCBhcmUgdGFrZW4gbW9kdWxvIHRoZWlyIG1heGltdW0gdmFsdWVzIHBsdXMgMS4gVGhhdCBpcywgc3BlY2lmeWluZyB2YWx1ZXMgaGlnaGVyIHRoYW4g' + - 'dGhvc2UgbGlzdGVkIGluIGFjY291bnQgc3RhdGUgbGltaXRzIChgbWF4X21zZ19jZWxsc2AgYW5kIGBtYXhfbXNnX2JpdHNgKSB3aWxsIGhhdmUgdGhlIHNhbWUgcmVz' + - 'dWx0IGFzIHdpdGggc3BlY2lmeWluZyB0aGUgZXhhY3QgbGltaXRzLgovLy8KLy8vIEhvd2V2ZXIsIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFu' + - 'ZCBgYml0c2AsIHRoaXMgZnVuY3Rpb24gYWx3YXlzIGFkZHMgdGhlIG1pbmltdW0gcHJpY2UgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBsdW1wX3ByaWNlYC4gU2VlIHRo' + - 'ZSBleGFtcGxlIGZvciBbYGdldFNpbXBsZUZvcndhcmRGZWUoKXs6dGFjdH1gXSgjZ2V0c2ltcGxlZm9yd2FyZGZlZSkgdG8gZGVyaXZlIGl0LiBJbiBhZGRpdGlvbiwg' + - 'bWFrZSBzdXJlIHlvdSB0YWtlIGludG8gYWNjb3VudCB0aGUgZGVkdXBsaWNhdGlvbiBvZiBjZWxscyB3aXRoIHRoZSBzYW1lIGhhc2gsIHNpbmNlIGZvciBleGFtcGxl' + - 'IHRoZSByb290IGNlbGwgYW5kIGl0cyBkYXRhIGJpdHMgZG9uJ3QgY291bnQgdG93YXJkcyB0aGUgZm9yd2FyZCBmZWUgYW5kIGFyZSBjb3ZlcmVkIGJ5IHRoZSBgbHVt' + - 'cF9wcmljZWAuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBuZWdhdGl2ZSBudW1iZXIgb2YgYGNlbGxzYCBvciBgYml0c2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdp' + - 'dGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0' + - 'IGZlZTogSW50ID0gZ2V0Rm9yd2FyZEZlZSgxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRh' + - 'Y3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNn' + - 'ZXRzaW1wbGVmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldG9yaWdpbmFsZndkZmVlCi8vLwphc20g' + - 'ZnVuIGdldEZvcndhcmRGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRSB9CgovLy8gR2xvYmFs' + - 'IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRGb3J3YXJkRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGx1' + - 'bXBfcHJpY2VgLCBpLmUuIHdpdGhvdXQgdGhlIG1pbmltdW0gcHJpY2UgdG8gcGF5IHJlZ2FyZGxlc3Mgb2YgdGhlIGFtb3VudCBvZiBgY2VsbHNgIG9yIGBiaXRzYC4g' + - 'Q2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgY2VsbHNgIHRpbWVzIHRoZSBjdXJyZW50IGNlbGwgcHJpY2UgcGx1cyBgYml0c2AgdGltZXMgdGhlIGN1cnJl' + - 'bnQgYml0IHByaWNlLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2Agb3IgYGJpdHNgIHRocm93IGFuIGV4Y2VwdGlv' + - 'biB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAg' + - 'IGxldCBmZWUgPSBnZXRGb3J3YXJkRmVlKDFfMDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0x1bXAgPSBnZXRTaW1wbGVGb3J3YXJkRmVlKDFfMDAw' + - 'LCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBsdW1wUHJpY2UgPSBmZWUgLSBmZWVOb0x1bXA7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBz' + - 'Oi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHNpbXBsZWZvcndhcmRmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVm' + - 'L2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8KYXNtIGZ1biBnZXRTaW1wbGVGb3J3YXJkRmVlKGNlbGxzOiBJbnQsIGJpdHM6IEludCwgaXNNYXN0ZXJjaGFp' + - 'bjogQm9vbCk6IEludCB7IEdFVEZPUldBUkRGRUVTSU1QTEUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8g' + - 'Q2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgc28tY2FsbGVkIF9vcmlnaW5hbF8gZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2lu' + - 'ZyBtZXNzYWdlIGJhc2VkIG9uIHRoZSBgZndkRmVlYCBvYnRhaW5lZCBmcm9tIHRoZSBpbmNvbWluZyBtZXNzYWdlLiBJZiBib3RoIHRoZSBzb3VyY2UgYW5kIHRoZSBk' + - 'ZXN0aW5hdGlvbiBhZGRyZXNzZXMgYXJlIGluIHRoZSBiYXNlY2hhaW4sIHRoZW4gc3BlY2lmeSBgaXNNYXN0ZXJjaGFpbmAgYXMgYGZhbHNlYC4gT3RoZXJ3aXNlLCBz' + - 'cGVjaWZ5IGB0cnVlYC4KLy8vCi8vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCB3aGVuIHRoZSBvdXRnb2luZyBtZXNzYWdlIGRlcGVuZHMgaGVhdmlseSBvbiB0aGUg' + - 'c3RydWN0dXJlIG9mIHRoZSBpbmNvbWluZyBtZXNzYWdlLCBzbyBtdWNoIHNvIHRoYXQgeW91IGNhbm5vdCBmdWxseSBwcmVkaWN0IHRoZSBmZWUgdXNpbmcgYGdldEZv' + - 'cndhcmRGZWUoKWAgYWxvbmUuIEV2ZW4gaWYgeW91IGNvdWxkLCBjYWxjdWxhdGluZyB0aGUgZXhhY3QgZmVlIHdpdGggbmFub1RvbmNvaW4tbGV2ZWwgcHJlY2lzaW9u' + - 'IGNhbiBiZSB2ZXJ5IGV4cGVuc2l2ZSwgc28gdGhlIGFwcHJveGltYXRlIHZhbHVlIGdpdmVuIGJ5IHRoaXMgZnVuY3Rpb24gaXMgb2Z0ZW4gZ29vZCBlbm91Z2guCi8v' + - 'LwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIHZhbHVlIG9mIGBmd2RGZWVgIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50' + - 'ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmd2RGZWU6IEludCA9IGNvbnRl' + - 'eHQoKS5yZWFkRm9yd2FyZEZlZSgpOwovLy8gICAgIGxldCBvcmlnRmVlOiBJbnQgPSBnZXRPcmlnaW5hbEZ3ZEZlZShmZWUsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAov' + - 'Ly8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0b3JpZ2luYWxmd2RmZWUKLy8vICogaHR0cHM6Ly9k' + - 'b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZh' + - 'bmNlZCNjb250ZXh0cmVhZGZvcndhcmRmZWUKLy8vCmFzbSBmdW4gZ2V0T3JpZ2luYWxGd2RGZWUoZndkRmVlOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQg' + - 'eyBHRVRPUklHSU5BTEZXREZFRSB9CgovLy8gU3RydWN0IHJlcHJlc2VudGluZyB0aGUgc3RhbmRhcmQgYWRkcmVzcyBvbiBUT04gQmxvY2tjaGFpbiB3aXRoIHNpZ25l' + - 'ZCA4LWJpdCBgd29ya2NoYWluYCBJRCBhbmQgYW4gdW5zaWduZWQgMjU2LWJpdCBgYWRkcmVzc2AgaW4gdGhlIHNwZWNpZmllZCBgd29ya2NoYWluYC4gQXZhaWxhYmxl' + - 'IHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQXQgdGhlIG1vbWVudCwgb25seSBgd29ya2NoYWluYCBJRHMgdXNlZCBvbiBUT04gYXJlIDAgb2YgdGhlIGJhc2VjaGFp' + - 'biBhbmQgLTEgb2YgdGhlIG1hc3RlcmNoYWluLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFy' + - 'c2VzdGRhZGRyZXNzCi8vLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA1' + - 'LUwxMDYKLy8vCnN0cnVjdCBTdGRBZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDg7CiAgICBhZGRyZXNzOiBJbnQgYXMgdWludDI1NjsKfQoKLy8vIFN0' + - 'cnVjdCByZXByZXNlbnRpbmcgdGhlIGFkZHJlc3Mgb2YgdmFyaWFibGUgbGVuZ3RoIHdpdGggc2lnbmVkIDMyLWJpdCBgd29ya2NoYWluYCBJRCBhbmQgYSBgU2xpY2Vg' + - 'IGNvbnRhaW5pbmcgdW5zaWduZWQgYGFkZHJlc3NgIGluIHRoZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8v' + - 'IFZhcmlhYmxlLWxlbmd0aCBhZGRyZXNzZXMgYXJlIGludGVuZGVkIGZvciBmdXR1cmUgZXh0ZW5zaW9ucywgYW5kIHdoaWxlIHZhbGlkYXRvcnMgbXVzdCBiZSByZWFk' + - 'eSB0byBhY2NlcHQgdGhlbSBpbiBpbmJvdW5kIG1lc3NhZ2VzLCB0aGUgc3RhbmRhcmQgKG5vbi12YXJpYWJsZSkgYWRkcmVzc2VzIGFyZSB1c2VkIHdoZW5ldmVyIHBv' + - 'c3NpYmxlLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2V2YXJhZGRyZXNzCi8vLyAqIGh0' + - 'dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA3LUwxMDgKLy8vCnN0cnVjdCBWYXJB' + - 'ZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDMyOwogICAgYWRkcmVzczogU2xpY2U7Cn0KCi8vLyBBc3NlbWJseSBmdW5jdGlvbi4gQXZhaWxhYmxlIHNp' + - 'bmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQ29udmVydHMgYSBgU2xpY2VgIGNvbnRhaW5pbmcgYW4gYWRkcmVzcyBpbnRvIHRoZSBgU3RkQWRkcmVzc2AgU3RydWN0IGFu' + - 'ZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhZGRyID0gYWRkcmVzcygiRVFEdEZwRXdjRkFFY1JlNW1M' + - 'VmgyTjZDMHgtX2hKRU03VzYxX0pMblNGNzRwNHEyIik7Ci8vLyAgICAgbGV0IHBhcnNlZEFkZHIgPSBwYXJzZVN0ZEFkZHJlc3MoYWRkci5hc1NsaWNlKCkpOwovLy8K' + - 'Ly8vICAgICBwYXJzZWRBZGRyLndvcmtjaGFpbjsgLy8gMAovLy8gICAgIHBhcnNlZEFkZHIuYWRkcmVzczsgICAvLyAxMDcuLi4yODcKLy8vIH0KLy8vIGBgYAovLy8K' + - 'Ly8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2VzdGRhZGRyZXNzCi8vLwphc20gZnVuIHBhcnNlU3RkQWRkcmVz' + - 'cyhzbGljZTogU2xpY2UpOiBTdGRBZGRyZXNzIHsgUkVXUklURVNUREFERFIgfQoKLy8vIEFzc2VtYmx5IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUu' + - 'MC4KLy8vCi8vLyBDb252ZXJ0cyBhIGBTbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRoZSBgVmFyQWRkcmVzc2AgU3Ry' + - 'dWN0IGFuZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCB2YXJBZGRyU2xpY2UgPSBiZWdpbkNlbGwoKQov' + - 'Ly8gICAgICAgICAuc3RvcmVVaW50KDYsIDMpICAgICAvLyB0byByZWNvZ25pemUgdGhlIGZvbGxvd2luZyBhcyBhIFZhckFkZHJlc3MKLy8vICAgICAgICAgLnN0b3Jl' + - 'VWludCgxMjMsIDkpICAgLy8gbWFrZSBhZGRyZXNzIG9jY3VweSAxMjMgYml0cwovLy8gICAgICAgICAuc3RvcmVVaW50KDIzNCwgMzIpICAvLyBzcGVjaWZ5IHdvcmtj' + - 'aGFpbiBJRCBvZiAyMzQKLy8vICAgICAgICAgLnN0b3JlVWludCgzNDUsIDEyMykgLy8gc3BlY2lmeSBhZGRyZXNzIG9mIDM0NQovLy8gICAgICAgICAuYXNTbGljZSgp' + - 'OwovLy8gICAgIGxldCBwYXJzZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwovLy8gICAgIHBhcnNlZFZhckFkZHIud29ya2NoYWlu' + - 'OyAgICAgICAgICAgICAvLyAyMzQKLy8vICAgICBwYXJzZWRWYXJBZGRyLmFkZHJlc3M7ICAgICAgICAgICAgICAgLy8gQ1N7Q2VsbHswMDIuLi4yYjN9IGJpdHM6IDQ0' + - 'Li4xNjc7IHJlZnM6IDAuLjB9Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2Vl' + - 'OiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNwYXJzZXZhcmFkZHJlc3MKLy8vCmFzbSBmdW4gcGFyc2VWYXJBZGRyZXNzKHNsaWNl' + - 'OiBTbGljZSk6IFZhckFkZHJlc3MgeyBSRVdSSVRFVkFSQUREUiB9Cgphc20gZnVuIGN1ckx0KCk6IEludCB7IExUSU1FIH0KCmFzbSBmdW4gYmxvY2tMdCgpOiBJbnQg' + - 'eyBCTE9DS0xUIH0KCmFzbSBmdW4gc2V0R2FzTGltaXQobGltaXQ6IEludCkgeyBTRVRHQVNMSU1JVCB9Cgphc20gZnVuIGdldFNlZWQoKTogSW50IHsgUkFORFNFRUQg' + - 'fQoKYXNtIGZ1biBzZXRTZWVkKHNlZWQ6IEludCkgeyBTRVRSQU5EIH0KCmFzbSBmdW4gbXlDb2RlKCk6IENlbGwgeyBNWUNPREUgfQo='; + 'ZnJvbSB0aGUgY29uZmlnIHBhcmFtIDE4IG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIE5vdGUsIHRoYXQgc3BlY2lmeWluZyB2YWx1ZXMgb2YgYGNlbGxzYCBhbmQg' + + 'YGJpdHNgIGhpZ2hlciB0aGFuIHRoZWlyIG1heGltdW0gdmFsdWVzIGxpc3RlZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAoYG1heF9hY2Nfc3RhdGVfY2VsbHNgIGFu' + + 'ZCBgbWF4X2FjY19zdGF0ZV9iaXRzYCkgd2lsbCBoYXZlIHRoZSBzYW1lIHJlc3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4gSW4gYWRkaXRp' + + 'b24sIG1ha2Ugc3VyZSB5b3UgdGFrZSBpbnRvIGFjY291bnQgdGhlIGRlZHVwbGljYXRpb24gb2YgY2VsbHMgd2l0aCB0aGUgc2FtZSBoYXNoLgovLy8KLy8vIEF0dGVt' + + 'cHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2AsIGBiaXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2Rl' + + 'IDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0g' + + 'Z2V0U3RvcmFnZUZlZSgxXzAwMCwgMV8wMDAsIDFfMDAwLCBmYWxzZSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxh' + + 'bmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0c2lt' + + 'cGxlc3RvcmFnZWZlZQovLy8KYXNtIGZ1biBnZXRTdG9yYWdlRmVlKGNlbGxzOiBJbnQsIGJpdHM6IEludCwgc2Vjb25kczogSW50LCBpc01hc3RlcmNoYWluOiBCb29s' + + 'KTogSW50IHsgR0VUU1RPUkFHRUZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFu' + + 'ZCByZXR1cm5zIHRoZSBjb21wdXRlIGZlZSBpbiBuYW5vVG9uY29pbnMgYEludGAgZm9yIGEgdHJhbnNhY3Rpb24gdGhhdCBjb25zdW1lZCBgZ2FzVXNlZGAgYW1vdW50' + + 'IG9mIGdhcy4gVXNlcyB0aGUgcHJpY2VzIG9mIHRoZSBtYXN0ZXJjaGFpbiBpZiBgaXNNYXN0ZXJjaGFpbmAgaXMgYHRydWVgLCBvdGhlcndpc2UgdGhlIHByaWNlcyBv' + + 'ZiB0aGUgYmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFpbmVkIGZyb20gdGhlIGNvbmZpZyBwYXJhbSAyMCBmb3IgdGhlIG1hc3RlcmNoYWluIGFu' + + 'ZCBjb25maWcgcGFyYW0gMjEgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJsb2NrY2hhaW4uCi8vLwovLy8gV2hlbiB0aGUgYGdhc1VzZWRgIGlzIGxlc3MgdGhhbiBh' + + 'IGNlcnRhaW4gdGhyZXNob2xkIGNhbGxlZCBgZmxhdF9nYXNfbGltaXRgLCB0aGVyZSdzIGEgbWluaW11bSBwcmljZSB0byBwYXkgYmFzZWQgb24gdGhlIHZhbHVlIG9m' + + 'IGBmbGF0X2dhc19wcmljZWAuIFRoZSBsZXNzIGdhcyBpcyB1c2VkIGJlbG93IHRoaXMgdGhyZXNob2xkLCB0aGUgaGlnaGVyIHRoZSBtaW5pbXVtIHByaWNlIHdpbGwg' + + 'YmUuIFNlZSB0aGUgZXhhbXBsZSBmb3IgYGdldFNpbXBsZUNvbXB1dGVGZWUoKWAgdG8gZGVyaXZlIHRoYXQgdGhyZXNob2xkLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNw' + + 'ZWNpZnkgbmVnYXRpdmUgdmFsdWUgb2YgYGdhc1VzZWRgIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQg' + + 'cmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmZWU6IEludCA9IGdldENvbXB1dGVGZWUoMV8wMDAsIGZhbHNlKTsK' + + 'Ly8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Y29tcHV0ZWZlZQovLy8KYXNtIGZ1' + + 'biBnZXRDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVEdBU0ZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFp' + + 'bGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRDb21wdXRlRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGZsYXRfZ2FzX3ByaWNlYCwg' + + 'aS5lLiB3aXRob3V0IGEgbWluaW11bSBwcmljZSB0byBwYXkgaWYgdGhlIGBnYXNVc2VkYCBpcyBsZXNzIHRoYW4gYSBjZXJ0YWluIHRocmVzaG9sZCBjYWxsZWQgYGZs' + + 'YXRfZ2FzX2xpbWl0YC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgZ2FzVXNlZGAgdGltZXMgdGhlIGN1cnJlbnQgZ2FzIHByaWNlLgovLy8KLy8vIEF0' + + 'dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2AsIGBiaXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBj' + + 'b2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZSA9IGdl' + + 'dENvbXB1dGVGZWUoMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0ZsYXQgPSBnZXRTaW1wbGVDb21wdXRlRmVlKDAsIGZhbHNlKTsKLy8vICAgICBsZXQgbWF4Rmxh' + + 'dFByaWNlID0gZmVlIC0gZmVlTm9GbGF0OwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1h' + + 'ZHZhbmNlZCNnZXRzaW1wbGVzdG9yYWdlZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8v' + + 'CmFzbSBmdW4gZ2V0U2ltcGxlQ29tcHV0ZUZlZShnYXNVc2VkOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRHQVNGRUVTSU1QTEUgfQoKLy8vIEds' + + 'b2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgZm9yd2FyZCBmZWUgaW4gbmFu' + + 'b1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2luZyBtZXNzYWdlIGNvbnNpc3Rpbmcgb2YgYSBnaXZlbiBudW1iZXIgb2YgYGNlbGxzYCBhbmQgYGJpdHNgLiBVc2Vz' + + 'IHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBpc01hc3RlcmNoYWluYCBpcyBgdHJ1ZXs6dGFjdH1gLCBvdGhlcndpc2UgdGhlIHByaWNlcyBvZiB0aGUg' + + 'YmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFpbmVkIGZyb20gdGhlIGNvbmZpZyBwYXJhbSAyNCBmb3IgdGhlIG1hc3RlcmNoYWluIGFuZCBjb25m' + + 'aWcgcGFyYW0gMjUgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJsb2NrY2hhaW4uCi8vLwovLy8gSWYgYm90aCB0aGUgc291cmNlIGFuZCB0aGUgZGVzdGluYXRpb24g' + + 'YWRkcmVzc2VzIGFyZSBpbiB0aGUgYmFzZWNoYWluLCB0aGVuIHNwZWNpZnkgYGlzTWFzdGVyY2hhaW5gIGFzIGBmYWxzZWAuIE90aGVyd2lzZSwgc3BlY2lmeSBgdHJ1' + + 'ZWAuCi8vLwovLy8gTm90ZSwgdGhhdCBzcGVjaWZ5aW5nIHZhbHVlcyBvZiBgY2VsbHNgIGFuZCBgYml0c2AgaGlnaGVyIHRoYW4gdGhlaXIgbWF4aW11bSB2YWx1ZXMg' + + 'bGlzdGVkIGluIGFjY291bnQgc3RhdGUgbGltaXRzIChgbWF4X21zZ19jZWxsc2AgYW5kIGBtYXhfbXNnX2JpdHNgKSB3aWxsIGhhdmUgdGhlIHNhbWUgcmVzdWx0IGFz' + + 'IHdpdGggc3BlY2lmeWluZyB0aGUgZXhhY3QgbGltaXRzLgovLy8KLy8vIEhvd2V2ZXIsIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFuZCBgYml0' + + 'c2AsIHRoaXMgZnVuY3Rpb24gYWx3YXlzIGFkZHMgdGhlIG1pbmltdW0gcHJpY2UgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBsdW1wX3ByaWNlYC4gU2VlIHRoZSBleGFt' + + 'cGxlIGZvciBbYGdldFNpbXBsZUZvcndhcmRGZWUoKXs6dGFjdH1gXSgjZ2V0c2ltcGxlZm9yd2FyZGZlZSkgdG8gZGVyaXZlIGl0LiBJbiBhZGRpdGlvbiwgbWFrZSBz' + + 'dXJlIHlvdSB0YWtlIGludG8gYWNjb3VudCB0aGUgZGVkdXBsaWNhdGlvbiBvZiBjZWxscyB3aXRoIHRoZSBzYW1lIGhhc2gsIHNpbmNlIGZvciBleGFtcGxlIHRoZSBy' + + 'b290IGNlbGwgYW5kIGl0cyBkYXRhIGJpdHMgZG9uJ3QgY291bnQgdG93YXJkcyB0aGUgZm9yd2FyZCBmZWUgYW5kIGFyZSBjb3ZlcmVkIGJ5IHRoZSBgbHVtcF9wcmlj' + + 'ZWAuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBuZWdhdGl2ZSBudW1iZXIgb2YgYGNlbGxzYCBvciBgYml0c2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhp' + + 'dCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTog' + + 'SW50ID0gZ2V0Rm9yd2FyZEZlZSgxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFu' + + 'Zy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNnZXRzaW1w' + + 'bGVmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldG9yaWdpbmFsZndkZmVlCi8vLwphc20gZnVuIGdl' + + 'dEZvcndhcmRGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0' + + 'aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRGb3J3YXJkRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGx1bXBfcHJp' + + 'Y2VgLCBpLmUuIHdpdGhvdXQgdGhlIG1pbmltdW0gcHJpY2UgdG8gcGF5IHJlZ2FyZGxlc3Mgb2YgdGhlIGFtb3VudCBvZiBgY2VsbHNgIG9yIGBiaXRzYC4gQ2FsY3Vs' + + 'YXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgY2VsbHNgIHRpbWVzIHRoZSBjdXJyZW50IGNlbGwgcHJpY2UgcGx1cyBgYml0c2AgdGltZXMgdGhlIGN1cnJlbnQgYml0' + + 'IHByaWNlLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2Agb3IgYGJpdHNgIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRo' + + 'IGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBm' + + 'ZWUgPSBnZXRGb3J3YXJkRmVlKDFfMDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0x1bXAgPSBnZXRTaW1wbGVGb3J3YXJkRmVlKDFfMDAwLCAxXzAw' + + 'MCwgZmFsc2UpOwovLy8gICAgIGxldCBsdW1wUHJpY2UgPSBmZWUgLSBmZWVOb0x1bXA7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9j' + + 'cy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHNpbXBsZWZvcndhcmRmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUt' + + 'YWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8KYXNtIGZ1biBnZXRTaW1wbGVGb3J3YXJkRmVlKGNlbGxzOiBJbnQsIGJpdHM6IEludCwgaXNNYXN0ZXJjaGFpbjogQm9v' + + 'bCk6IEludCB7IEdFVEZPUldBUkRGRUVTSU1QTEUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQ2FsY3Vs' + + 'YXRlcyBhbmQgcmV0dXJucyB0aGUgc28tY2FsbGVkIF9vcmlnaW5hbF8gZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2luZyBtZXNz' + + 'YWdlIGJhc2VkIG9uIHRoZSBgZndkRmVlYCBvYnRhaW5lZCBmcm9tIHRoZSBpbmNvbWluZyBtZXNzYWdlLiBJZiBib3RoIHRoZSBzb3VyY2UgYW5kIHRoZSBkZXN0aW5h' + + 'dGlvbiBhZGRyZXNzZXMgYXJlIGluIHRoZSBiYXNlY2hhaW4sIHRoZW4gc3BlY2lmeSBgaXNNYXN0ZXJjaGFpbmAgYXMgYGZhbHNlYC4gT3RoZXJ3aXNlLCBzcGVjaWZ5' + + 'IGB0cnVlYC4KLy8vCi8vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCB3aGVuIHRoZSBvdXRnb2luZyBtZXNzYWdlIGRlcGVuZHMgaGVhdmlseSBvbiB0aGUgc3RydWN0' + + 'dXJlIG9mIHRoZSBpbmNvbWluZyBtZXNzYWdlLCBzbyBtdWNoIHNvIHRoYXQgeW91IGNhbm5vdCBmdWxseSBwcmVkaWN0IHRoZSBmZWUgdXNpbmcgYGdldEZvcndhcmRG' + + 'ZWUoKWAgYWxvbmUuIEV2ZW4gaWYgeW91IGNvdWxkLCBjYWxjdWxhdGluZyB0aGUgZXhhY3QgZmVlIHdpdGggbmFub1RvbmNvaW4tbGV2ZWwgcHJlY2lzaW9uIGNhbiBi' + + 'ZSB2ZXJ5IGV4cGVuc2l2ZSwgc28gdGhlIGFwcHJveGltYXRlIHZhbHVlIGdpdmVuIGJ5IHRoaXMgZnVuY3Rpb24gaXMgb2Z0ZW4gZ29vZCBlbm91Z2guCi8vLwovLy8g' + + 'QXR0ZW1wdHMgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIHZhbHVlIG9mIGBmd2RGZWVgIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBv' + + 'dXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmd2RGZWU6IEludCA9IGNvbnRleHQoKS5y' + + 'ZWFkRm9yd2FyZEZlZSgpOwovLy8gICAgIGxldCBvcmlnRmVlOiBJbnQgPSBnZXRPcmlnaW5hbEZ3ZEZlZShmZWUsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8v' + + 'IFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0b3JpZ2luYWxmd2RmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRh' + + 'Y3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNj' + + 'b250ZXh0cmVhZGZvcndhcmRmZWUKLy8vCmFzbSBmdW4gZ2V0T3JpZ2luYWxGd2RGZWUoZndkRmVlOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRP' + + 'UklHSU5BTEZXREZFRSB9CgovLy8gU3RydWN0IHJlcHJlc2VudGluZyB0aGUgc3RhbmRhcmQgYWRkcmVzcyBvbiBUT04gQmxvY2tjaGFpbiB3aXRoIHNpZ25lZCA4LWJp' + + 'dCBgd29ya2NoYWluYCBJRCBhbmQgYW4gdW5zaWduZWQgMjU2LWJpdCBgYWRkcmVzc2AgaW4gdGhlIHNwZWNpZmllZCBgd29ya2NoYWluYC4gQXZhaWxhYmxlIHNpbmNl' + + 'IFRhY3QgMS41LjAuCi8vLwovLy8gQXQgdGhlIG1vbWVudCwgb25seSBgd29ya2NoYWluYCBJRHMgdXNlZCBvbiBUT04gYXJlIDAgb2YgdGhlIGJhc2VjaGFpbiBhbmQg' + + 'LTEgb2YgdGhlIG1hc3RlcmNoYWluLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2VzdGRh' + + 'ZGRyZXNzCi8vLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA1LUwxMDYK' + + 'Ly8vCnN0cnVjdCBTdGRBZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDg7CiAgICBhZGRyZXNzOiBJbnQgYXMgdWludDI1NjsKfQoKLy8vIFN0cnVjdCBy' + + 'ZXByZXNlbnRpbmcgdGhlIGFkZHJlc3Mgb2YgdmFyaWFibGUgbGVuZ3RoIHdpdGggc2lnbmVkIDMyLWJpdCBgd29ya2NoYWluYCBJRCBhbmQgYSBgU2xpY2VgIGNvbnRh' + + 'aW5pbmcgdW5zaWduZWQgYGFkZHJlc3NgIGluIHRoZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIFZhcmlh' + + 'YmxlLWxlbmd0aCBhZGRyZXNzZXMgYXJlIGludGVuZGVkIGZvciBmdXR1cmUgZXh0ZW5zaW9ucywgYW5kIHdoaWxlIHZhbGlkYXRvcnMgbXVzdCBiZSByZWFkeSB0byBh' + + 'Y2NlcHQgdGhlbSBpbiBpbmJvdW5kIG1lc3NhZ2VzLCB0aGUgc3RhbmRhcmQgKG5vbi12YXJpYWJsZSkgYWRkcmVzc2VzIGFyZSB1c2VkIHdoZW5ldmVyIHBvc3NpYmxl' + + 'LgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2V2YXJhZGRyZXNzCi8vLyAqIGh0dHBzOi8v' + + 'Z2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA3LUwxMDgKLy8vCnN0cnVjdCBWYXJBZGRyZXNz' + + 'IHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDMyOwogICAgYWRkcmVzczogU2xpY2U7Cn0KCi8vLyBBc3NlbWJseSBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRh' + + 'Y3QgMS41LjAuCi8vLwovLy8gQ29udmVydHMgYSBgU2xpY2VgIGNvbnRhaW5pbmcgYW4gYWRkcmVzcyBpbnRvIHRoZSBgU3RkQWRkcmVzc2AgU3RydWN0IGFuZCByZXR1' + + 'cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhZGRyID0gYWRkcmVzcygiRVFEdEZwRXdjRkFFY1JlNW1MVmgyTjZD' + + 'MHgtX2hKRU03VzYxX0pMblNGNzRwNHEyIik7Ci8vLyAgICAgbGV0IHBhcnNlZEFkZHIgPSBwYXJzZVN0ZEFkZHJlc3MoYWRkci5hc1NsaWNlKCkpOwovLy8KLy8vICAg' + + 'ICBwYXJzZWRBZGRyLndvcmtjaGFpbjsgLy8gMAovLy8gICAgIHBhcnNlZEFkZHIuYWRkcmVzczsgICAvLyAxMDcuLi4yODcKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNl' + + 'ZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2VzdGRhZGRyZXNzCi8vLwphc20gZnVuIHBhcnNlU3RkQWRkcmVzcyhzbGlj' + + 'ZTogU2xpY2UpOiBTdGRBZGRyZXNzIHsgUkVXUklURVNUREFERFIgfQoKLy8vIEFzc2VtYmx5IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8v' + + 'Ci8vLyBDb252ZXJ0cyBhIGBTbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRoZSBgVmFyQWRkcmVzc2AgU3RydWN0IGFu' + + 'ZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCB2YXJBZGRyU2xpY2UgPSBiZWdpbkNlbGwoKQovLy8gICAg' + + 'ICAgICAuc3RvcmVVaW50KDYsIDMpICAgICAvLyB0byByZWNvZ25pemUgdGhlIGZvbGxvd2luZyBhcyBhIFZhckFkZHJlc3MKLy8vICAgICAgICAgLnN0b3JlVWludCgx' + + 'MjMsIDkpICAgLy8gbWFrZSBhZGRyZXNzIG9jY3VweSAxMjMgYml0cwovLy8gICAgICAgICAuc3RvcmVVaW50KDIzNCwgMzIpICAvLyBzcGVjaWZ5IHdvcmtjaGFpbiBJ' + + 'RCBvZiAyMzQKLy8vICAgICAgICAgLnN0b3JlVWludCgzNDUsIDEyMykgLy8gc3BlY2lmeSBhZGRyZXNzIG9mIDM0NQovLy8gICAgICAgICAuYXNTbGljZSgpOwovLy8g' + + 'ICAgIGxldCBwYXJzZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwovLy8gICAgIHBhcnNlZFZhckFkZHIud29ya2NoYWluOyAgICAg' + + 'ICAgICAgICAvLyAyMzQKLy8vICAgICBwYXJzZWRWYXJBZGRyLmFkZHJlc3M7ICAgICAgICAgICAgICAgLy8gQ1N7Q2VsbHswMDIuLi4yYjN9IGJpdHM6IDQ0Li4xNjc7' + + 'IHJlZnM6IDAuLjB9Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRw' + + 'czovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNwYXJzZXZhcmFkZHJlc3MKLy8vCmFzbSBmdW4gcGFyc2VWYXJBZGRyZXNzKHNsaWNlOiBTbGlj' + + 'ZSk6IFZhckFkZHJlc3MgeyBSRVdSSVRFVkFSQUREUiB9Cgphc20gZnVuIGN1ckx0KCk6IEludCB7IExUSU1FIH0KCmFzbSBmdW4gYmxvY2tMdCgpOiBJbnQgeyBCTE9D' + + 'S0xUIH0KCmFzbSBmdW4gc2V0R2FzTGltaXQobGltaXQ6IEludCkgeyBTRVRHQVNMSU1JVCB9Cgphc20gZnVuIGdldFNlZWQoKTogSW50IHsgUkFORFNFRUQgfQoKYXNt' + + 'IGZ1biBzZXRTZWVkKHNlZWQ6IEludCkgeyBTRVRSQU5EIH0KCmFzbSBmdW4gbXlDb2RlKCk6IENlbGwgeyBNWUNPREUgfQo='; files['std/crypto.tact'] = 'YXNtIGV4dGVuZHMgZnVuIGhhc2goc2VsZjogQ2VsbCk6IEludCB7IEhBU0hDVSB9Cgphc20gZXh0ZW5kcyBmdW4gaGFzaChzZWxmOiBTbGljZSk6IEludCB7IEhBU0hT' + 'VSB9Cgphc20gZnVuIGNoZWNrU2lnbmF0dXJlKGhhc2g6IEludCwgc2lnbmF0dXJlOiBTbGljZSwgcHVibGljX2tleTogSW50KTogQm9vbCB7IENIS1NJR05VIH0KCmFz' + diff --git a/stdlib/std/contract.tact b/stdlib/std/contract.tact index 79e1fda5b..74fa06553 100644 --- a/stdlib/std/contract.tact +++ b/stdlib/std/contract.tact @@ -52,7 +52,7 @@ asm fun myStorageDue(): Int { DUEPAYMENT } /// /// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain. /// -/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash. +/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash. /// /// Attempts to specify negative number of `cells`, `bits` or `seconds` throw an exception with exit code 5: `Integer out of expected range`. /// @@ -112,7 +112,7 @@ asm fun getSimpleComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEES /// /// If both the source and the destination addresses are in the basechain, then specify `isMasterchain` as `false`. Otherwise, specify `true`. /// -/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_msg_cells` and `max_msg_bits`) will have the same result as with specifying the exact limits. +/// Note, that specifying values of `cells` and `bits` higher than their maximum values listed in account state limits (`max_msg_cells` and `max_msg_bits`) will have the same result as with specifying the exact limits. /// /// However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of `lump_price`. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. In addition, make sure you take into account the deduplication of cells with the same hash, since for example the root cell and its data bits don't count towards the forward fee and are covered by the `lump_price`. /// From 84535078cb8a00d538dcaaadfe6d7721cfaefd4a Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Thu, 5 Dec 2024 17:26:40 +0100 Subject: [PATCH 25/27] feat(docs): new cell-related functions plus minor corrections here and there --- docs/src/content/docs/ref/core-advanced.mdx | 2 +- docs/src/content/docs/ref/core-cells.mdx | 209 ++++++++++++++++++++ docs/src/content/docs/ref/core-common.mdx | 27 +-- docs/src/content/docs/ref/core-math.mdx | 6 +- 4 files changed, 229 insertions(+), 15 deletions(-) diff --git a/docs/src/content/docs/ref/core-advanced.mdx b/docs/src/content/docs/ref/core-advanced.mdx index 5b9b4912c..4787e5d0a 100644 --- a/docs/src/content/docs/ref/core-advanced.mdx +++ b/docs/src/content/docs/ref/core-advanced.mdx @@ -479,7 +479,7 @@ nativeRandomize(lt); // equivalent to calling nativeRandomizeLt() fun blockLt(): Int; ``` -Returns the [`Int{:tact}`][int] value of the [logical time][lt] of the current block. +Returns the [`Int{:tact}`][int] value of the [starting logical time][lt] of the current block. Usage example: diff --git a/docs/src/content/docs/ref/core-cells.mdx b/docs/src/content/docs/ref/core-cells.mdx index 770130032..78bb4b6e7 100644 --- a/docs/src/content/docs/ref/core-cells.mdx +++ b/docs/src/content/docs/ref/core-cells.mdx @@ -84,6 +84,64 @@ let c: Cell = emptyCell(); let fizz: Slice = c.beginParse(); ``` +## Cell.depth + +

+ +```tact +extends fun depth(self: Cell): Int; +``` + +Extension function for the [`Cell{:tact}`][cell]. + +Computes and returns the [`Int{:tact}`][int] [depth][std-repr] of the [`Cell{:tact}`][cell]. Produces $0$ if the [`Cell{:tact}`][cell] has no references, otherwise $1$ plus the maximum of the depths of the referenced cells. + +Usage example: + +```tact +let c: Cell = beginCell().storeInt(42, 7).endCell(); +let depth: Int = c.depth; +``` + +## Cell.computeDataSize + +

+ +```tact +extends fun computeDataSize(self: Cell, maxCells: Int): DataSize; +``` + +Extension function for the [`Cell{:tact}`][cell]. + +Computes and returns the number of distinct cells, bits and refs in the [`Cell{:tact}`][tact] by using a [depth-first search (DFS)][dfs] algorithm, recursively traversing each referenced cell. This function is computationally expensive and can consume a lot of [gas][gas]. + +The results are packed into a `DataSize{:tact}` [Struct][struct] consisting of: + +Field | Type | Description +:------ | :------------------ | :---------- +`cells` | [`Int{:tact}`][int] | The total number of nested cells, including the starting one +`bits` | [`Int{:tact}`][int] | The total number of bits in all nested cells, including the starting one +`refs` | [`Int{:tact}`][int] | The total number of refs in all nested cells, including the starting one + +If the specified `maxCells` value isn't enough to traverse all cells including the starting one, an exception with [exit code 8](/book/exit-codes#8) is thrown: `Cell overflow`. + +Attempts to specify a negative value of `maxCells` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Usage example: + +```tact +let c: Cell = beginCell().storeInt(42, 7).storeRef(emptyCell()).endCell(); +try { + let dataSize: DataSize = c.computeDataSize(2); + dataSize.cells; // 2 + dataSize.bits; // 7 + dataSize.refs; // 1 +} catch (exitCode) { + // if maxCells was insufficient to traverse the cell + // and all of its references, the exitCode here would be 8 +} +``` + ## Cell.hash ```tact @@ -367,6 +425,25 @@ let b: Builder = beginCell(); let fizz: Int = b.bits(); // 0 ``` +## Builder.depth + +

+ +```tact +extends fun depth(self: Builder): Int; +``` + +Extension function for the [`Builder{:tact}`][builder]. + +Computes and returns the [`Int{:tact}`][int] [depth][std-repr] of the [`Builder{:tact}`][builder]. Produces $0$ if the [`Builder{:tact}`][builder] has no references stored so far, otherwise $1$ plus the maximum of the depths of the referenced cells. + +Usage example: + +```tact +let b: Builder = beginCell().storeInt(42, 7); +let depth: Int = b.depth; +``` + ## Builder.asSlice ```tact @@ -527,6 +604,12 @@ let s: Slice = beginCell().storeInt(42, 7).asSlice(); let fizz: Slice = s.preloadBits(7); ``` +:::note + + In order to reduce gas usage, prefer using this function over calling [`Slice.firstBits(){:tact}`](#slicefirstbits) since the latter is less optimized. + +::: + ## Slice.skipBits ```tact @@ -549,6 +632,30 @@ s.skipBits(5); // all but first 5 bits let fizz: Slice = s.loadBits(1); // load only 1 bit ``` +## Slice.skipLastBits + +

+ +```tact +extends fun skipLastBits(self: Slice, len: Int); +``` + +Extension function for the [`Slice{:tact}`][slice]. + +Preloads all but the last $0 ≤$ `len` $≤ 1023$ bits from the [`Slice{:tact}`][slice]. + +Attempts to specify an out-of-bounds `len` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Attempts to preload more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. + +Usage example: + +```tact +let s: Slice = beginCell().storeInt(42, 7).asSlice(); +let allButLastFive: Slice = s.skipLastBits(5); // all but last 5 bits, + // i.e. only first 2 +``` + ## Slice.loadBool ```tact @@ -727,6 +834,106 @@ let s: Slice = beginCell().storeRef(emptyCell()).asSlice(); let fizz: Int = s.bits(); ``` +## Slice.firstBits + +

+ +```tact +extends fun firstBits(self: Slice, len: Int): Slice; +``` + +Extension function for the [`Slice{:tact}`][slice]. + +Preloads the first $0 ≤$ `len` $≤ 1023$ bits from the [`Slice{:tact}`][slice]. + +Attempts to specify an out-of-bounds `len` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Attempts to preload more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. + +Usage example: + +```tact +let s: Slice = beginCell().storeInt(42, 7).asSlice(); +let firstFive: Slice = s.firstBits(5); // first 5 bits +``` + +:::note + + In order to reduce gas usage, prefer calling [`Slice.preloadBits(){:tact}`](#slicepreloadbits) over using this function since the former is more optimized. + +::: + +## Slice.lastBits + +

+ +```tact +extends fun lastBits(self: Slice, len: Int): Slice; +``` + +Extension function for the [`Slice{:tact}`][slice]. + +Preloads the last $0 ≤$ `len` $≤ 1023$ bits from the [`Slice{:tact}`][slice]. + +Attempts to specify an out-of-bounds `len` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Attempts to preload more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. + +Usage example: + +```tact +let s: Slice = beginCell().storeInt(42, 7).asSlice(); +let lastFive: Slice = s.lastBits(5); // last 5 bits +``` + +## Slice.depth + +

+ +```tact +extends fun depth(self: Slice): Int; +``` + +Extension function for the [`Slice{:tact}`][slice]. + +Computes and returns the [`Int{:tact}`][int] [depth][std-repr] of the [`Slice{:tact}`][slice]. Produces $0$ if the [`Slice{:tact}`][slice] has no references, otherwise $1$ plus the maximum of the depths of the referenced cells. + +Usage example: + +```tact +let s: Slice = beginCell().storeInt(42, 7).asSlice(); +let depth: Int = s.depth; +``` + +## Slice.computeDataSize + +

+ +```tact +extends fun computeDataSize(self: Slice, maxCells: Int): DataSize; +``` + +Extension function for the [`Slice{:tact}`][slice]. Similar to [`Cell.computeDataSize(){:tact}`](#cellcomputedatasize), but doesn't take into account the cell that contains the [`Slice{:tact}`][slice] itself. However, accounts for its bits and refs. + +If the specified `maxCells` value isn't enough to traverse all cells **not** including the starting one, an exception with [exit code 8](/book/exit-codes#8) is thrown: `Cell overflow`. + +Attempts to specify a negative value of `maxCells` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. + +Usage example: + +```tact +let s: Slice = beginCell().storeInt(42, 7).storeRef(emptyCell()).asSlice(); +try { + let dataSize: DataSize = s.computeDataSize(1); + dataSize.cells; // 1 + dataSize.bits; // 7 + dataSize.refs; // 1 +} catch (exitCode) { + // if maxCells was insufficient to traverse the cell + // and all of its references, the exitCode here would be 8 +} +``` + ## Slice.empty ```tact @@ -1129,3 +1336,5 @@ fun cautiousParse(payload: Slice): TripleAxe? { [tlb]: https://docs.ton.org/develop/data-formats/tl-b-language [sha-2]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard +[dfs]: https://en.wikipedia.org/wiki/Depth-first_search +[gas]: https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/fees#gas diff --git a/docs/src/content/docs/ref/core-common.mdx b/docs/src/content/docs/ref/core-common.mdx index 64c28fdc3..ab858492c 100644 --- a/docs/src/content/docs/ref/core-common.mdx +++ b/docs/src/content/docs/ref/core-common.mdx @@ -3,6 +3,8 @@ title: Common description: "Commonly used global static functions from the Core library of Tact" --- +import { Badge } from '@astrojs/starlight/components'; + List of the most commonly used built-in [global static functions](/book/functions#global-static-functions). ## Contextual @@ -125,6 +127,10 @@ Creates a new [`Address{:tact}`][p] based on the [`chain` id](https://ton-blockc This function tries to resolve constant values in [compile-time](/ref/core-comptime) whenever possible. +Attempts to specify an invalid `chain` ID (not $-1$ or $0$) throw an exception with [exit code 136](/book/exit-codes#136): `Invalid address`. + +Attempts to specify an `chain` ID pointing to the masterchain ($-1$) without [masterchain support](/book/masterchain) enabled throw an exception with [exit code 137](/book/exit-codes#137): `Masterchain support is not enabled for this contract`. + Usage example: ```tact @@ -136,12 +142,6 @@ let oldTonFoundationAddr: Address = // chain id: 0 is a workchain, -1 is a masterchain ``` -:::caution - - This method throws an error with [exit code 136](/book/exit-codes#136) if `chain` is invalid or with [exit code 137](/book/exit-codes#137) if `chain` points to the masterchain ($-1$) without [masterchain support](/book/masterchain) enabled. - -::: - :::note[Useful links:] [`chain` (Workchain ID) in TON Docs](https://docs.ton.org/learn/overviews/addresses#workchain-id)\ @@ -172,6 +172,10 @@ fun contractAddressExt(chain: Int, code: Cell, data: Cell): Address; Computes smart contract's [`Address{:tact}`][p] based on the `chain` id, contract's `code` and contract's initial state `data`. Use [`initOf{:tact}`](/book/expressions#initof) expression to obtain initial `code` and initial `data` of a given contract. +Attempts to specify an invalid `chain` ID (not $-1$ or $0$) throw an exception with [exit code 136](/book/exit-codes#136): `Invalid address`. + +Attempts to specify an `chain` ID pointing to the masterchain ($-1$) without [masterchain support](/book/masterchain) enabled throw an exception with [exit code 137](/book/exit-codes#137): `Masterchain support is not enabled for this contract`. + Usage example: ```tact @@ -179,16 +183,17 @@ let initPkg: StateInit = initOf SomeContract(); let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data); ``` -:::caution +### addressNone - This method throws an error with [exit code 136](/book/exit-codes#136) if `chain` is invalid or with [exit code 137](/book/exit-codes#137) if `chain` points to the masterchain ($-1$) without [masterchain support](/book/masterchain) enabled. +

-::: +```tact +fun addressNone(): Address?; +``` :::note - For this function to work, the compiler option `debug` has to be set to `true{:tact}` for the current project in the [configuration file](/book/config).\ - Read more about debugging on the dedicated page: [Debugging](/book/debug). + TODO: awaits resolution of [those comments](https://github.com/tact-lang/tact/pull/986#discussion_r1865450023). ::: diff --git a/docs/src/content/docs/ref/core-math.mdx b/docs/src/content/docs/ref/core-math.mdx index 6d8227d81..0f4100c3b 100644 --- a/docs/src/content/docs/ref/core-math.mdx +++ b/docs/src/content/docs/ref/core-math.mdx @@ -91,7 +91,7 @@ fun sqrt(num: Int): Int; Computes the [square root](https://en.wikipedia.org/wiki/Square_root) of the [`Int{:tact}`][int] value `num`. Returns the result rounded to the nearest integer. If there are two equally close integers, rounding is done toward the even one. -Attempts to specify negative value of `num` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. +Attempts to specify a negative value of `num` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. Usage examples: @@ -160,7 +160,7 @@ Computes and returns the [rounded down][round-down] result of `(x * y) / z{:tact If the value in calculation goes beyond the range from $-2^{256}$ to $2^{256} - 1$ inclusive, an exception with [exit code 4](/book/exit-codes#4) is thrown: `Integer overflow`. -Attempts to specify negative value of `z` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. +Attempts to specify a negative value of `z` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. Usage examples: @@ -300,7 +300,7 @@ contract Example { :::note - Note, that if you only need to obtain powers of $2$, use the [`pow2(){:tact}`](#pow2) function, as it's more gas-efficient. + If you only need to obtain powers of $2$, use the [`pow2(){:tact}`](#pow2) function, as it's more gas-efficient. ::: From aa58a35ee3899a297520ec6300a25e3ac47de66e Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:44:41 +0100 Subject: [PATCH 26/27] chore: typo --- docs/src/content/docs/ref/core-math.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/ref/core-math.mdx b/docs/src/content/docs/ref/core-math.mdx index 0f4100c3b..9eb6fc375 100644 --- a/docs/src/content/docs/ref/core-math.mdx +++ b/docs/src/content/docs/ref/core-math.mdx @@ -145,7 +145,7 @@ muldivc(3, 1, 2); // 2 muldivc(-4, 1, 2); // -2 muldivc(-3, 1, 2); // -1 muldivc(-3, 0, 2); // 0 -muldivc(-3, 0, ); // ERROR! Exit code 4: Integer overflow +muldivc(-3, 0, 0); // ERROR! Exit code 4: Integer overflow ``` ## mulShiftRight From 4e73eb4d8cce38898636f6a76ccbb9d9dea83bb0 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Thu, 5 Dec 2024 20:18:21 +0100 Subject: [PATCH 27/27] chore: typo --- docs/src/content/docs/ref/core-math.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/ref/core-math.mdx b/docs/src/content/docs/ref/core-math.mdx index 9eb6fc375..3bfdb1c26 100644 --- a/docs/src/content/docs/ref/core-math.mdx +++ b/docs/src/content/docs/ref/core-math.mdx @@ -69,7 +69,7 @@ abs(-(-(-42))); // 42 fun sign(x: Int): Int; ``` -Computes and returns the sign of the [`Int{:tact}`][int] value `x`. Produces $1$ is the `x` is negative, $-1$ if the `x` is positive, and $0$ if the `x` is $0$. +Computes and returns the sign of the [`Int{:tact}`][int] value `x`. Produces $1$ if the `x` is positive, $-1$ if the `x` is negative, and $0$ if the `x` is $0$. Usage examples: