Skip to content

Commit

Permalink
feat(stdlib): add pow and pow2 functions (#267)
Browse files Browse the repository at this point in the history
and implement constant evaluation for both functions
  • Loading branch information
Gusarich authored Apr 21, 2024
1 parent dbc0165 commit 8410733
Show file tree
Hide file tree
Showing 13 changed files with 735 additions and 43 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `toString` extension function for `Address` type: PR [#224](https://github.com/tact-lang/tact/pull/224)
- Bitwise XOR operation (`^`): PR [#238](https://github.com/tact-lang/tact/pull/238)
- `isEmpty` method for `Map` type: PR [#266](https://github.com/tact-lang/tact/pull/266)
- `pow2` function: PR [#267](https://github.com/tact-lang/tact/pull/267)

### Changed

Expand All @@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `@stdlib/stoppable` now imports `@stdlib/ownable` so the programmer does not have to do it separately: PR [#193](https://github.com/tact-lang/tact/pull/193)
- Support escape sequences for strings (`\\`, `\"`, `\n`, `\r`, `\t`, `\v`, `\b`, `\f`, `\u{0}` through `\u{FFFFFF}`, `\u0000` through `\uFFFF`, `\x00` through `\xFF`): PR [#192](https://github.com/tact-lang/tact/pull/192)
- `newAddress` function now evaluates to a constant value if possible: PR [#237](https://github.com/tact-lang/tact/pull/237)
- `pow` function is now in the standard library, allowing its use at runtime. If constant arguments are used, the result is evaluated at compile-time: PR [#267](https://github.com/tact-lang/tact/pull/267)

### Fixed

Expand Down
40 changes: 0 additions & 40 deletions src/abi/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,6 @@ export const GlobalFunctions: Map<string, AbiFunction> = new Map([
},
},
],
[
"pow",
{
name: "pow",
resolve: (ctx, args, ref) => {
if (args.length !== 2) {
throwError("pow() expects two integer arguments", ref);
}
if (args[0].kind !== "ref") {
throwError("pow() expects two integer arguments", ref);
}
if (args[0].name !== "Int") {
throwError("pow() expects two integer arguments", ref);
}
if (args[1].kind !== "ref") {
throwError("pow() expects two integer arguments", ref);
}
if (args[1].name !== "Int") {
throwError("pow() expects two integer arguments", ref);
}
return { kind: "ref", name: "Int", optional: false };
},
generate: (ctx, args, resolved, ref) => {
if (resolved.length !== 2) {
throwError("pow() expects two integer arguments", ref);
}
const a = resolveConstantValue(
{ kind: "ref", name: "Int", optional: false },
resolved[0],
ctx.ctx,
) as bigint;
const b = resolveConstantValue(
{ kind: "ref", name: "Int", optional: false },
resolved[1],
ctx.ctx,
) as bigint;
return (a ** b).toString(10);
},
},
],
[
"require",
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3146,6 +3146,35 @@ return result;",
"name": "__tact_log",
"signature": "int __tact_log(int num, int base)",
},
{
"code": {
"code": "throw_unless(5, exp >= 0);
int result = 1;
repeat (exp) {
result *= base;
}
return result;",
"kind": "generic",
},
"comment": null,
"context": "stdlib",
"depends": Set {},
"flags": Set {},
"name": "__tact_pow",
"signature": "int __tact_pow(int base, int exp)",
},
{
"code": {
"code": "asm "POW2"",
"kind": "asm",
},
"comment": null,
"context": "stdlib",
"depends": Set {},
"flags": Set {},
"name": "__tact_pow2",
"signature": "int __tact_pow2(int exp)",
},
{
"code": {
"code": "var (v'a, v'b, v'c, v'd, v'e, v'f, v'g) = v;
Expand Down Expand Up @@ -7143,6 +7172,35 @@ return result;",
"name": "__tact_log",
"signature": "int __tact_log(int num, int base)",
},
{
"code": {
"code": "throw_unless(5, exp >= 0);
int result = 1;
repeat (exp) {
result *= base;
}
return result;",
"kind": "generic",
},
"comment": null,
"context": "stdlib",
"depends": Set {},
"flags": Set {},
"name": "__tact_pow",
"signature": "int __tact_pow(int base, int exp)",
},
{
"code": {
"code": "asm "POW2"",
"kind": "asm",
},
"comment": null,
"context": "stdlib",
"depends": Set {},
"flags": Set {},
"name": "__tact_pow2",
"signature": "int __tact_pow2(int exp)",
},
{
"code": {
"code": "var (v'a, v'b, v'c, v'd, v'e, v'f, v'g) = v;
Expand Down Expand Up @@ -11140,6 +11198,35 @@ return result;",
"name": "__tact_log",
"signature": "int __tact_log(int num, int base)",
},
{
"code": {
"code": "throw_unless(5, exp >= 0);
int result = 1;
repeat (exp) {
result *= base;
}
return result;",
"kind": "generic",
},
"comment": null,
"context": "stdlib",
"depends": Set {},
"flags": Set {},
"name": "__tact_pow",
"signature": "int __tact_pow(int base, int exp)",
},
{
"code": {
"code": "asm "POW2"",
"kind": "asm",
},
"comment": null,
"context": "stdlib",
"depends": Set {},
"flags": Set {},
"name": "__tact_pow2",
"signature": "int __tact_pow2(int exp)",
},
{
"code": {
"code": "var (v'a, v'b, v'c, v'd, v'e, v'f, v'g, v'h) = v;
Expand Down
21 changes: 21 additions & 0 deletions src/generator/writers/writeStdlib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1426,4 +1426,25 @@ export function writeStdlib(ctx: WriterContext) {
`);
});
});

ctx.fun(`__tact_pow`, () => {
ctx.signature(`int __tact_pow(int base, int exp)`);
ctx.context("stdlib");
ctx.body(() => {
ctx.write(`
throw_unless(5, exp >= 0);
int result = 1;
repeat (exp) {
result *= base;
}
return result;
`);
});
});

ctx.fun(`__tact_pow2`, () => {
ctx.signature(`int __tact_pow2(int exp)`);
ctx.context("stdlib");
ctx.asm(`asm "POW2"`);
});
}
3 changes: 2 additions & 1 deletion src/imports/stdlib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ files['std/math.tact'] =
'ZXJ2YWwobWF4IC0gbWluKTsKfQoKLy8gTWF0aAoKQG5hbWUobWluKQpuYXRpdmUgbWluKHg6IEludCwgeTogSW50KTogSW50OwoKQG5hbWUobWF4KQpuYXRpdmUgbWF4' +
'KHg6IEludCwgeTogSW50KTogSW50OwoKQG5hbWUoYWJzKQpuYXRpdmUgYWJzKHg6IEludCk6IEludDsKCkBuYW1lKG5vdykKbmF0aXZlIG5vdygpOiBJbnQ7CgpAbmFt' +
'ZShfX3RhY3RfbG9nMikKbmF0aXZlIGxvZzIobnVtOiBJbnQpOiBJbnQ7CgpAbmFtZShfX3RhY3RfbG9nKQpuYXRpdmUgbG9nKG51bTogSW50LCBiYXNlOiBJbnQpOiBJ' +
'bnQ7';
'bnQ7CgpAbmFtZShfX3RhY3RfcG93KQpuYXRpdmUgcG93KGJhc2U6IEludCwgZXhwOiBJbnQpOiBJbnQ7CgpAbmFtZShfX3RhY3RfcG93MikKbmF0aXZlIHBvdzIoZXhw' +
'OiBJbnQpOiBJbnQ7';
files['std/primitives.tact'] =
'cHJpbWl0aXZlIEludDsKcHJpbWl0aXZlIEJvb2w7CnByaW1pdGl2ZSBCdWlsZGVyOwpwcmltaXRpdmUgU2xpY2U7CnByaW1pdGl2ZSBDZWxsOwpwcmltaXRpdmUgQWRk' +
'cmVzczsKcHJpbWl0aXZlIFN0cmluZzsKcHJpbWl0aXZlIFN0cmluZ0J1aWxkZXI7';
Expand Down
Loading

0 comments on commit 8410733

Please sign in to comment.