diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ece4f7753..3a8b0955b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Typos in ABI generation: : PR [#372](https://github.com/tact-lang/tact/pull/372) - `__tact_load_address_opt` code generation: PR [#373](https://github.com/tact-lang/tact/pull/373) - Empty messages are now correctly converted into cells: PR [#380](https://github.com/tact-lang/tact/pull/380) +- All integer and boolean expressions are now being attempted to be evaluated as constants. Additionally, compile-time errors are thrown for errors encountered during the evaluation of actual constants: PR [#352](https://github.com/tact-lang/tact/pull/352) ## [1.3.0] - 2024-05-03 diff --git a/cspell.json b/cspell.json index e80a984cff..c1680300a6 100644 --- a/cspell.json +++ b/cspell.json @@ -84,6 +84,7 @@ "src/test/feature-strings.spec.ts", "src/test/features/intrinsics.tact", "src/test/features/strings.tact", + "src/test/compilation-fail/fail-const-eval.spec.ts", "stdlib/stdlib.fc" ] } diff --git a/src/generator/intrinsics/tryExpressionIntrinsics.ts b/src/generator/intrinsics/tryExpressionIntrinsics.ts index d3ea26ef5d..cc889365df 100644 --- a/src/generator/intrinsics/tryExpressionIntrinsics.ts +++ b/src/generator/intrinsics/tryExpressionIntrinsics.ts @@ -1,3 +1,4 @@ +import { TactSyntaxError } from "../../errors"; import { ASTExpression } from "../../grammar/ast"; import { resolveConstantValue } from "../../types/resolveConstantValue"; import { getExpType } from "../../types/resolveExpression"; @@ -48,5 +49,42 @@ export function tryExpressionIntrinsics( } } + try { + const t = getExpType(ctx.ctx, exp); + + if (t.kind === "null") { + const r = resolveConstantValue(t, exp, ctx.ctx); + if (r !== null) { + throw new Error("Expected null"); + } + return "null()"; + } + if (t.kind === "ref") { + if (t.name === "Int") { + const r = resolveConstantValue(t, exp, ctx.ctx); + if (typeof r !== "bigint") { + throw new Error("Expected bigint"); + } + return r.toString(10); + } + if (t.name === "Bool") { + const r = resolveConstantValue(t, exp, ctx.ctx); + if (typeof r !== "boolean") { + throw new Error("Expected boolean"); + } + return r ? "true" : "false"; + } + } + } catch (e) { + if (e instanceof TactSyntaxError) { + if ( + !e.message.includes("Cannot reduce expression to a constant") && + !e.message.includes("Expected constant value") + ) { + throw e; + } + } + } + return null; } diff --git a/src/generator/writers/writeExpression.spec.ts b/src/generator/writers/writeExpression.spec.ts index 5a2d407696..cd3cf304fa 100644 --- a/src/generator/writers/writeExpression.spec.ts +++ b/src/generator/writers/writeExpression.spec.ts @@ -55,7 +55,7 @@ const golden: string[] = [ "($a + ($b / $c))", "true", "false", - "( (( (($a > 1)) ? (true) : (( (($b < 2)) ? (($c == 3)) : (false) )) )) ? (true) : ((~ ( (( (($d != 4)) ? (true) : (false) )) ? ((~ false)) : (false) ))) )", + "( (( (($a > 1)) ? (true) : (( (($b < 2)) ? (($c == 3)) : (false) )) )) ? (true) : ((~ ( (( (($d != 4)) ? (true) : (false) )) ? (true) : (false) ))) )", "$global_f1($a)", "$A$_constructor_a_b(1, 2)", `$j'a`, diff --git a/src/test/__snapshots__/feature-constants.spec.ts.snap b/src/test/__snapshots__/feature-constants.spec.ts.snap index 0f8e6144f9..cdadac1e51 100644 --- a/src/test/__snapshots__/feature-constants.spec.ts.snap +++ b/src/test/__snapshots__/feature-constants.spec.ts.snap @@ -225,6 +225,76 @@ ConstantTester { "type": "int", }, }, + { + "arguments": [], + "name": "something16", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "something17", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "something18", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "something19", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "minInt1", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "minInt2", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "minInt3", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, { "arguments": [], "name": "globalConst", @@ -372,7 +442,7 @@ ConstantTester { }, ], }, - "address": kQDv7yerqTCJwMlp3JugEltyVuclWRTw9BhZNDWZbYViC4MM, + "address": kQBLPCFB6hZTJVoIVoSLp-zwDPnb5aQG3LnI_S3IHwDre99T, "init": { "code": x{FF00F4A413F4BCF2C80B} x{62_} @@ -381,26 +451,61 @@ ConstantTester { x{6D} x{0192307FE07021D749C21F953020D70B1FDEC00001D749C121B0917FE070} x{2_} - x{6A_} - x{B22EF6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{74} - x{B226B6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} - x{2_} + x{5} x{2_} x{2_} - x{B24DF6CF36CF0C6_} + x{AFD96D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{AC5DED9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{74} + x{2_} + x{AFC9ED9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{82186A2BB7D000} - x{B245B6CF36CF0C6_} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{AC4D6D9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{8BC48656C6C6F20776F726C64218} + x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} + x{2_} + x{2_} + x{AFF86D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{AF976D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{B3C3F6CF36CF0C6_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{2_} + x{2_} + x{2_} + x{5} + x{A937DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82186A2BB7D000} + x{AAE0DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{84FF} + x{5} + x{A916DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{8BC48656C6C6F20776F726C64218} + x{AAC1DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} x{2_} x{5} x{A975DB3CDB3C31} @@ -441,7 +546,7 @@ ConstantTester { x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} x{800B} - x{AEE3435697066733A2F2F516D6655625A6767516B31555175766B51474D566231474E31597639424B4A46783247787A586F6231397453615382_} + x{AEE3435697066733A2F2F516D5952584D7874336E78397331376A3874474D64315751526D574D6A556764756E75365536685A4C764758627182_} x{AA45DB3CDB3C31} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} @@ -475,26 +580,61 @@ ConstantTester { x{6D} x{0192307FE07021D749C21F953020D70B1FDEC00001D749C121B0917FE070} x{2_} - x{6A_} - x{B22EF6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{74} - x{B226B6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} - x{2_} + x{5} + x{2_} + x{2_} + x{AFD96D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{AC5DED9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{74} + x{2_} + x{AFC9ED9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{AC4D6D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} x{2_} x{2_} - x{B24DF6CF36CF0C6_} + x{AFF86D9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{82186A2BB7D000} - x{B245B6CF36CF0C6_} + x{85FF} + x{AF976D9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{8BC48656C6C6F20776F726C64218} + x{85FF} + x{B3C3F6CF36CF0C6_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{2_} + x{2_} + x{2_} + x{5} + x{A937DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82186A2BB7D000} + x{AAE0DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{84FF} + x{5} + x{A916DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{8BC48656C6C6F20776F726C64218} + x{AAC1DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} x{2_} x{5} x{A975DB3CDB3C31} @@ -535,7 +675,7 @@ ConstantTester { x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} x{800B} - x{AEE3435697066733A2F2F516D6655625A6767516B31555175766B51474D566231474E31597639424B4A46783247787A586F6231397453615382_} + x{AEE3435697066733A2F2F516D5952584D7874336E78397331376A3874474D64315751526D574D6A556764756E75365536685A4C764758627182_} x{AA45DB3CDB3C31} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} diff --git a/src/test/__snapshots__/feature-implicit-init.spec.ts.snap b/src/test/__snapshots__/feature-implicit-init.spec.ts.snap index e1154c1f0c..0e9701228c 100644 --- a/src/test/__snapshots__/feature-implicit-init.spec.ts.snap +++ b/src/test/__snapshots__/feature-implicit-init.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`feature-send should deploy 1`] = ` +exports[`feature-implicit-init should deploy 1`] = ` [ { "$seq": 0, @@ -53,7 +53,7 @@ exports[`feature-send should deploy 1`] = ` ] `; -exports[`feature-send should increment counter 1`] = ` +exports[`feature-implicit-init should increment counter 1`] = ` [ { "$seq": 1, diff --git a/src/test/__snapshots__/feature-intrinsics.spec.ts.snap b/src/test/__snapshots__/feature-intrinsics.spec.ts.snap index 0c328fce34..a7e7be9385 100644 --- a/src/test/__snapshots__/feature-intrinsics.spec.ts.snap +++ b/src/test/__snapshots__/feature-intrinsics.spec.ts.snap @@ -7,52 +7,7 @@ exports[`feature-intrinsics should return correct intrinsic results 1`] = ` "events": [ { "$type": "storage-charged", - "amount": "0.000000011", - }, - { - "$type": "received", - "message": { - "body": { - "text": "emit_1", - "type": "text", - }, - "bounce": true, - "from": "@treasure(treasure)", - "to": "@contract", - "type": "internal", - "value": "1", - }, - }, - { - "$type": "processed", - "gasUsed": 7881n, - }, - { - "$type": "sent", - "messages": [ - { - "body": { - "text": "Hello world", - "type": "text", - }, - "to": null, - "type": "external-out", - }, - ], - }, - ], - }, -] -`; - -exports[`feature-intrinsics should return correct intrinsic results 1`] = ` -[ - { - "$seq": 1, - "events": [ - { - "$type": "storage-charged", - "amount": "0.000000011", + "amount": "0.00000001", }, { "$type": "received", diff --git a/src/test/compilation-fail/contracts/const-eval.tact b/src/test/compilation-fail/contracts/const-eval.tact new file mode 100644 index 0000000000..8bf2233c65 --- /dev/null +++ b/src/test/compilation-fail/contracts/const-eval.tact @@ -0,0 +1,14 @@ +contract ConstantTester { + init() { + + } + + receive() { + + } + + get fun something(): Int { + let x: Int = 2 / 0; + return x; + } +} \ No newline at end of file diff --git a/src/test/features/implicit-init-2.tact b/src/test/compilation-fail/contracts/implicit-init.tact similarity index 100% rename from src/test/features/implicit-init-2.tact rename to src/test/compilation-fail/contracts/implicit-init.tact diff --git a/src/test/features/invalid-address.tact b/src/test/compilation-fail/contracts/invalid-address.tact similarity index 100% rename from src/test/features/invalid-address.tact rename to src/test/compilation-fail/contracts/invalid-address.tact diff --git a/src/test/compilation-fail/fail-const-eval.spec.ts b/src/test/compilation-fail/fail-const-eval.spec.ts new file mode 100644 index 0000000000..f8fb640c04 --- /dev/null +++ b/src/test/compilation-fail/fail-const-eval.spec.ts @@ -0,0 +1,43 @@ +import { __DANGER_resetNodeId } from "../../grammar/ast"; +import { run } from "../../node"; +import { consoleLogger } from "../../logger"; + +describe("fail-const-eval", () => { + beforeAll(() => { + jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); + }); + + beforeEach(() => { + __DANGER_resetNodeId(); + }); + + afterAll(() => { + (consoleLogger.error as jest.Mock).mockRestore(); + }); + + afterEach(() => { + (consoleLogger.error as jest.Mock).mockClear(); + }); + + it("should not compile with division by zero", async () => { + const result = await run({ + configPath: __dirname + "/tact.config.json", + projectNames: ["const-eval"], + }); + expect(result).toBe(false); + expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( + "Cannot divide by zero", + ); + }); + + it("should not compile with invalid address", async () => { + const result = await run({ + configPath: __dirname + "/tact.config.json", + projectNames: ["invalid-address"], + }); + expect(result).toBe(false); + expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( + "FQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N is not a valid address", + ); + }); +}); diff --git a/src/test/compilation-fail/fail-implicit-init.spec.ts b/src/test/compilation-fail/fail-implicit-init.spec.ts new file mode 100644 index 0000000000..89b65b0bcc --- /dev/null +++ b/src/test/compilation-fail/fail-implicit-init.spec.ts @@ -0,0 +1,32 @@ +import { __DANGER_resetNodeId } from "../../grammar/ast"; +import { run } from "../../node"; +import { consoleLogger } from "../../logger"; + +describe("fail-implicit-init", () => { + beforeAll(() => { + jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); + }); + + beforeEach(() => { + __DANGER_resetNodeId(); + }); + + afterAll(() => { + (consoleLogger.error as jest.Mock).mockRestore(); + }); + + afterEach(() => { + (consoleLogger.error as jest.Mock).mockClear(); + }); + + it("should not compile with uninitialized storage fields", async () => { + const result = await run({ + configPath: __dirname + "/tact.config.json", + projectNames: ["implicit-init"], + }); + expect(result).toBe(false); + expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( + 'Field "test_field" is not set', + ); + }); +}); diff --git a/src/test/compilation-fail/tact.config.json b/src/test/compilation-fail/tact.config.json new file mode 100644 index 0000000000..9a77777704 --- /dev/null +++ b/src/test/compilation-fail/tact.config.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://raw.githubusercontent.com/tact-lang/tact/main/grammar/configSchema.json", + "projects": [ + { + "name": "implicit-init", + "path": "./contracts/implicit-init.tact", + "output": "./contracts/output" + }, + { + "name": "invalid-address", + "path": "./contracts/invalid-address.tact", + "output": "./contracts/output" + }, + { + "name": "const-eval", + "path": "./contracts/const-eval.tact", + "output": "./contracts/output" + } + ] +} diff --git a/src/test/feature-address.spec.ts b/src/test/feature-address.spec.ts index 731ef03f73..bbd61f77ad 100644 --- a/src/test/feature-address.spec.ts +++ b/src/test/feature-address.spec.ts @@ -3,7 +3,6 @@ import { ContractSystem } from "@tact-lang/emulator"; import { __DANGER_resetNodeId } from "../grammar/ast"; import { AddressTester } from "./features/output/address_AddressTester"; import { consoleLogger } from "../logger"; -import { run } from "../node"; describe("feature-address", () => { beforeAll(() => { @@ -40,15 +39,4 @@ describe("feature-address", () => { "0:4a81708d2cf7b15a1b362fbf64880451d698461f52f05f145b36c08517d76873", ); }); - - it("should not compile with uninitialized storage fields", async () => { - const result = await run({ - configPath: __dirname + "/test-tact.config.json", - projectNames: ["invalid-address"], - }); - expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( - "FQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N is not a valid address", - ); - expect(result).toBe(false); - }); }); diff --git a/src/test/feature-constants.spec.ts b/src/test/feature-constants.spec.ts index 18aba6d17a..77ff7fbe7d 100644 --- a/src/test/feature-constants.spec.ts +++ b/src/test/feature-constants.spec.ts @@ -36,6 +36,21 @@ describe("feature-constants", () => { expect(await contract.getSomething13()).toEqual(88n); expect(await contract.getSomething14()).toEqual(243n); expect(await contract.getSomething15()).toEqual(32n); + expect(await contract.getSomething16()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639936n, + ); + expect(await contract.getSomething17()).toEqual( + 115792089237316195423570985008687907853269984665640564039457584007913129639935n, + ); + expect(await contract.getSomething18()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639935n, + ); + expect(await contract.getSomething19()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639936n, + ); + expect(await contract.getMinInt1()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639936n, + ); expect(await contract.getGlobalConst()).toEqual(100n); }); }); diff --git a/src/test/feature-implicit-init.spec.ts b/src/test/feature-implicit-init.spec.ts index 1574746793..7379c588ef 100644 --- a/src/test/feature-implicit-init.spec.ts +++ b/src/test/feature-implicit-init.spec.ts @@ -2,26 +2,12 @@ import { toNano } from "@ton/core"; import { ContractSystem } from "@tact-lang/emulator"; import { __DANGER_resetNodeId } from "../grammar/ast"; import { MyContract } from "./features/output/implicit-init_MyContract"; -import { run } from "../node"; -import { consoleLogger } from "../logger"; - -describe("feature-send", () => { - beforeAll(() => { - jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); - }); +describe("feature-implicit-init", () => { beforeEach(() => { __DANGER_resetNodeId(); }); - afterAll(() => { - (consoleLogger.error as jest.Mock).mockRestore(); - }); - - afterEach(() => { - (consoleLogger.error as jest.Mock).mockClear(); - }); - it("should deploy", async () => { // Init const system = await ContractSystem.create(); @@ -61,15 +47,4 @@ describe("feature-send", () => { expect(await contract.getGetCounter()).toBe(2n); expect(tracker.collect()).toMatchSnapshot(); }); - - it("should not compile with uninitialized storage fields", async () => { - const result = await run({ - configPath: __dirname + "/test-tact.config.json", - projectNames: ["implicit-init-2"], - }); - expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( - 'Field "test_field" is not set', - ); - expect(result).toBe(false); - }); }); diff --git a/src/test/features/constants.tact b/src/test/features/constants.tact index 9a9de38e43..87682154e4 100644 --- a/src/test/features/constants.tact +++ b/src/test/features/constants.tact @@ -16,6 +16,10 @@ contract ConstantTester { const something13: Int = -123 ^ -35; const something14: Int = pow(3, 5); const something15: Int = pow2(5); + const something16: Int = -115792089237316195423570985008687907853269984665640564039457584007913129639936; + const something17: Int = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + const something18: Int = -(pow2(255) - 1 + pow2(255)); + const something19: Int = -(pow2(255) - 1 + pow2(255)) - 1; init() { @@ -85,6 +89,34 @@ contract ConstantTester { return self.something15; } + get fun something16(): Int { + return self.something16; + } + + get fun something17(): Int { + return self.something17; + } + + get fun something18(): Int { + return self.something18; + } + + get fun something19(): Int { + return self.something19; + } + + get fun minInt1(): Int { + return -115792089237316195423570985008687907853269984665640564039457584007913129639936; + } + + get fun minInt2(): Int { + return -(pow2(255) - 1 + pow2(255)); + } + + get fun minInt3(): Int { + return -(pow2(255) - 1 + pow2(255)) - 1; + } + get fun globalConst(): Int { return someGlobalConst; } diff --git a/src/test/test-tact.config.json b/src/test/test-tact.config.json deleted file mode 100644 index 9220c4be6c..0000000000 --- a/src/test/test-tact.config.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://raw.githubusercontent.com/tact-lang/tact/main/grammar/configSchema.json", - "projects": [ - { - "name": "implicit-init-2", - "path": "./features/implicit-init-2.tact", - "output": "./features/output", - "options": { - "debug": true - } - }, - { - "name": "invalid-address", - "path": "./features/invalid-address.tact", - "output": "./features/output" - } - ] -} diff --git a/src/types/resolveConstantValue.ts b/src/types/resolveConstantValue.ts index 2985293525..e3ea6f862a 100644 --- a/src/types/resolveConstantValue.ts +++ b/src/types/resolveConstantValue.ts @@ -71,13 +71,16 @@ function reduceInt(ast: ASTExpression): bigint { return reduceIntImpl(ast); } catch (error) { if (error instanceof RangeError) { - throwError( - "Cannot evaluate constant expression due to integer overflow", - ast.ref, - ); - } else { - throw error; + if (error.message === "Division by zero") { + throwError("Cannot divide by zero", ast.ref); + } else if (error.message === "Maximum BigInt size exceeded") { + throwError( + "Cannot evaluate constant expression due to integer overflow", + ast.ref, + ); + } } + throw error; } }