diff --git a/.cspell.json b/.cspell.json index 7bce4751..3d7c1ecf 100644 --- a/.cspell.json +++ b/.cspell.json @@ -103,6 +103,8 @@ "locktimes", "lokad", "lshift", + "LSHIFTNUM", + "LSHIFTBIN", "mecenas", "meep", "minimaldata", @@ -154,6 +156,8 @@ "ripemd", "rosco", "rshift", + "RSHIFTBIN", + "RSHIFTNUM", "sablier", "satoshis", "sats", @@ -221,6 +225,7 @@ "cherian", "CSCriptNum", "docu", + "fflate", "fundme", "getblockcount", "getrawtransaction", diff --git a/examples/announcement.cash b/examples/announcement.cash index d8dbce8a..ffcb5ada 100644 --- a/examples/announcement.cash +++ b/examples/announcement.cash @@ -1,4 +1,4 @@ -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; /* This is a contract showcasing covenants outside of regular transactional use. * It enforces the contract to make an "announcement" on Memo.cash, and send the diff --git a/examples/announcement.ts b/examples/announcement.ts index a7710c03..ba3f5c1e 100644 --- a/examples/announcement.ts +++ b/examples/announcement.ts @@ -1,19 +1,26 @@ -import { Contract, ElectrumNetworkProvider, Output, TransactionBuilder } from 'cashscript'; +import { Contract, Output, randomUtxo, TransactionBuilder } from 'cashscript'; import { compileFile } from 'cashc'; import { stringify } from '@bitauth/libauth'; import { URL } from 'url'; +import { MockNetworkProvider } from 'cashscript/dist'; // Compile the Announcement contract to an artifact object const artifact = compileFile(new URL('announcement.cash', import.meta.url)); // Initialise a network provider for network operations on MAINNET const addressType = 'p2sh20'; -const provider = new ElectrumNetworkProvider(); + +// Once you're ready to send transactions on a real network (like chipnet or mainnet), use the ElectrumNetworkProvider +// const provider = new ElectrumNetworkProvider(); +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters (none) const contract = new Contract(artifact, [], { provider, addressType }); +// Add a mock UTXO to the mock network provider +provider.addUtxo(contract.address, randomUtxo()); + // Get contract balance & output address + balance console.log('contract address:', contract.address); const contractUtxos = await contract.getUtxos(); diff --git a/examples/hodl_vault.cash b/examples/hodl_vault.cash index 95adbfa8..6bf77f1a 100644 --- a/examples/hodl_vault.cash +++ b/examples/hodl_vault.cash @@ -1,4 +1,4 @@ -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; // This contract forces HODLing until a certain price target has been reached // A minimum block is provided to ensure that oracle price entries from before this block are disregarded @@ -11,7 +11,7 @@ contract HodlVault( int minBlock, int priceTarget ) { - function spend(sig ownerSig, datasig oracleSig, bytes oracleMessage) { + function spend(sig ownerSig, datasig oracleSig, bytes8 oracleMessage) { // message: { blockHeight, price } bytes4 blockHeightBin, bytes4 priceBin = oracleMessage.split(4); int blockHeight = int(blockHeightBin); diff --git a/examples/hodl_vault.ts b/examples/hodl_vault.ts index a151451d..22cd0363 100644 --- a/examples/hodl_vault.ts +++ b/examples/hodl_vault.ts @@ -1,5 +1,5 @@ import { stringify } from '@bitauth/libauth'; -import { Contract, SignatureTemplate, ElectrumNetworkProvider, TransactionBuilder, Output } from 'cashscript'; +import { Contract, SignatureTemplate, TransactionBuilder, Output, MockNetworkProvider, randomUtxo } from 'cashscript'; import { compileFile } from 'cashc'; import { URL } from 'url'; @@ -14,14 +14,18 @@ import { // Compile the HodlVault contract to an artifact object const artifact = compileFile(new URL('hodl_vault.cash', import.meta.url)); -// Initialise a network provider for network operations on CHIPNET -const provider = new ElectrumNetworkProvider('chipnet'); +// Once you're ready to send transactions on a real network (like chipnet or mainnet), use the ElectrumNetworkProvider +// const provider = new ElectrumNetworkProvider(); +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters const parameters = [alicePub, oraclePub, 100000n, 30000n]; const contract = new Contract(artifact, parameters, { provider }); +// Add a mock UTXO to the mock network provider +provider.addUtxo(contract.address, randomUtxo()); + // Get contract balance & output address + balance console.log('contract address:', contract.address); const contractUtxos = await contract.getUtxos(); diff --git a/examples/mecenas.cash b/examples/mecenas.cash index aef868ab..b04d563d 100644 --- a/examples/mecenas.cash +++ b/examples/mecenas.cash @@ -1,4 +1,4 @@ -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; /* This is an unofficial CashScript port of Licho's Mecenas contract. It is * not compatible with Licho's EC plugin, but rather meant as a demonstration diff --git a/examples/mecenas.ts b/examples/mecenas.ts index cf28c126..e99d5b25 100644 --- a/examples/mecenas.ts +++ b/examples/mecenas.ts @@ -1,5 +1,5 @@ import { stringify } from '@bitauth/libauth'; -import { Contract, ElectrumNetworkProvider, Output, TransactionBuilder } from 'cashscript'; +import { Contract, MockNetworkProvider, Output, randomUtxo, TransactionBuilder } from 'cashscript'; import { compileFile } from 'cashc'; import { URL } from 'url'; @@ -9,8 +9,9 @@ import { aliceAddress, alicePkh, bobPkh } from './common.js'; // Compile the Mecenas contract to an artifact object const artifact = compileFile(new URL('mecenas.cash', import.meta.url)); -// Initialise a network provider for network operations on CHIPNET -const provider = new ElectrumNetworkProvider('chipnet'); +// Once you're ready to send transactions on a real network (like chipnet or mainnet), use the ElectrumNetworkProvider +// const provider = new ElectrumNetworkProvider(); +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters: @@ -18,6 +19,9 @@ const provider = new ElectrumNetworkProvider('chipnet'); const pledgeAmount = 10_000n; const contract = new Contract(artifact, [alicePkh, bobPkh, pledgeAmount], { provider }); +// Add a mock UTXO to the mock network provider +provider.addUtxo(contract.address, randomUtxo()); + // Get contract balance & output address + balance console.log('contract address:', contract.address); const contractUtxos = await contract.getUtxos(); diff --git a/examples/mecenas_locktime.cash b/examples/mecenas_locktime.cash index f4d1ccdc..3d73b1f5 100644 --- a/examples/mecenas_locktime.cash +++ b/examples/mecenas_locktime.cash @@ -1,4 +1,4 @@ -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; // This is an experimental contract for a more "streaming" Mecenas experience // Completely untested, just a concept @@ -40,7 +40,7 @@ contract Mecenas( // Insert new initialBlock (OP_PUSHBYTES_8 ) // Note that constructor parameters are added in reverse order, // so initialBlock is the first statement in the contract bytecode. - bytes newContract = 0x08 + bytes8(tx.locktime) + this.activeBytecode.split(9)[1]; + bytes newContract = 0x08 + toPaddedBytes(tx.locktime, 8) + this.activeBytecode.split(9)[1]; // Create the locking bytecode for the new contract and check that // the change output sends to that contract diff --git a/examples/p2pkh.cash b/examples/p2pkh.cash index 0cd49ca0..66b407f6 100644 --- a/examples/p2pkh.cash +++ b/examples/p2pkh.cash @@ -1,4 +1,4 @@ -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract P2PKH(bytes20 pkh) { // Require pk to match stored pkh and signature to match diff --git a/examples/p2pkh.js b/examples/p2pkh.js index b10dc6f8..77acb632 100644 --- a/examples/p2pkh.js +++ b/examples/p2pkh.js @@ -1,6 +1,6 @@ import { URL } from 'url'; import { compileFile } from 'cashc'; -import { ElectrumNetworkProvider, Contract, SignatureTemplate, TransactionBuilder } from 'cashscript'; +import { Contract, SignatureTemplate, TransactionBuilder, MockNetworkProvider, randomUtxo } from 'cashscript'; import { stringify } from '@bitauth/libauth'; // Import Alice's keys from common.ts @@ -9,13 +9,17 @@ import { alicePkh, alicePriv, aliceAddress, alicePub } from './common.js'; // Compile the P2PKH contract to an artifact object const artifact = compileFile(new URL('p2pkh.cash', import.meta.url)); -// Initialise a network provider for network operations on CHIPNET -const provider = new ElectrumNetworkProvider('chipnet'); +// Once you're ready to send transactions on a real network (like chipnet or mainnet), use the ElectrumNetworkProvider +// const provider = new ElectrumNetworkProvider(); +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters (pkh: alicePkh) const contract = new Contract(artifact, [alicePkh], { provider }); +// Add a mock UTXO to the mock network provider +provider.addUtxo(contract.address, randomUtxo()); + // Get contract balance & output address + balance console.log('contract address:', contract.address); const contractUtxos = await contract.getUtxos(); @@ -52,4 +56,4 @@ if (changeAmount > 1000n) transactionBuilder.addOutput(changeOutput); const tx = await transactionBuilder.send(); -console.log('transaction details:', stringify(tx)); \ No newline at end of file +console.log('transaction details:', stringify(tx)); diff --git a/examples/p2pkh.ts b/examples/p2pkh.ts index 867cb694..4ae8f07c 100644 --- a/examples/p2pkh.ts +++ b/examples/p2pkh.ts @@ -1,6 +1,6 @@ import { stringify } from '@bitauth/libauth'; import { compileFile } from 'cashc'; -import { ElectrumNetworkProvider, SignatureTemplate, Contract, TransactionBuilder, Output } from 'cashscript'; +import { SignatureTemplate, Contract, TransactionBuilder, Output, MockNetworkProvider, randomUtxo } from 'cashscript'; import { URL } from 'url'; // Import Alice's keys from common.ts @@ -9,13 +9,17 @@ import { alicePkh, alicePriv, aliceAddress, alicePub } from './common.js'; // Compile the P2PKH contract to an artifact object const artifact = compileFile(new URL('p2pkh.cash', import.meta.url)); -// Initialise a network provider for network operations on CHIPNET -const provider = new ElectrumNetworkProvider('chipnet'); +// Once you're ready to send transactions on a real network (like chipnet or mainnet), use the ElectrumNetworkProvider +// const provider = new ElectrumNetworkProvider(); +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters (pkh: alicePkh) const contract = new Contract(artifact, [alicePkh], { provider }); +// Add a mock UTXO to the mock network provider +provider.addUtxo(contract.address, randomUtxo()); + // Get contract balance & output address + balance console.log('contract address:', contract.address); const contractUtxos = await contract.getUtxos(); diff --git a/examples/package.json b/examples/package.json index 518528e8..e600e443 100644 --- a/examples/package.json +++ b/examples/package.json @@ -1,7 +1,7 @@ { "name": "cashscript-examples", "private": true, - "version": "0.12.1", + "version": "0.13.0-next.3", "description": "Usage examples of the CashScript SDK", "main": "p2pkh.js", "type": "module", @@ -13,8 +13,8 @@ "dependencies": { "@bitauth/libauth": "^3.1.0-next.8", "@types/node": "^22.17.0", - "cashc": "^0.12.1", - "cashscript": "^0.12.1", + "cashc": "^0.13.0-next.3", + "cashscript": "^0.13.0-next.3", "eslint": "^8.56.0", "typescript": "^5.9.2" } diff --git a/examples/testing-suite/.gitignore b/examples/testing-suite/.gitignore new file mode 100644 index 00000000..c1480624 --- /dev/null +++ b/examples/testing-suite/.gitignore @@ -0,0 +1,2 @@ +**/dist/ +**/node_modules/ diff --git a/examples/testing-suite/README.md b/examples/testing-suite/README.md new file mode 100644 index 00000000..37b83690 --- /dev/null +++ b/examples/testing-suite/README.md @@ -0,0 +1,25 @@ +# CashScript Testing Suite + +This is an example project to demonstrate how to write and compile CashScript contracts and test them using the CashScript SDK and Vitest. + +## Writing a CashScript contract + +We have included two simple example contracts in the `contracts/` directory that can be used as a starting point to write your own contracts. The contracts demonstrate logs, require statements and transaction signatures. + +## Compiling the contracts + +We have included a task to compile the contracts in the `tasks/` directory called `compile.ts`. This task will compile all the contracts in the `contracts/` directory and save the artifacts in the `artifacts/` directory. This includes both the JSON and TypeScript artifacts. It is recommended to use the TypeScript artifacts for proper type-safety. + +You can run the task with `yarn compile`. + +## Running the tests + +We have included test files in the `test/` directory, which test the expected functionality of the contracts. For key management, we have included a utility file in the `utils/` directory which exports testing keys for Alice and Bob. + +You can run the tests with `yarn test`. + +## Next steps + +Once you're getting comfortable writing, compiling and testing CashScript contracts, you can copy the `testing-suite` directory into your own project to use as a starting point. From there you can start writing more complex contracts and integrate them into full applications. + +We recommend checking out the [CashScript SDK documentation](https://cashscript.org/docs/sdk/) for more information on how to use the CashScript SDK, and the specific section on the [testing setup](https://cashscript.org/docs/sdk/testing-setup) for more information on how to test your contracts. diff --git a/examples/testing-suite/artifacts/example.artifact.ts b/examples/testing-suite/artifacts/example.artifact.ts index 6670b71d..c7e9ea74 100644 --- a/examples/testing-suite/artifacts/example.artifact.ts +++ b/examples/testing-suite/artifacts/example.artifact.ts @@ -13,10 +13,10 @@ export default { }, ], bytecode: 'OP_1 OP_NUMEQUAL', - source: 'contract Example() {\n function test(int value) {\n console.log(value, \'test\');\n require(value == 1, \'Wrong value passed\');\n }\n}\n', + source: 'contract Example() {\n function test(int value) {\n console.log(value, "test");\n require(value == 1, "Wrong value passed");\n }\n}\n', debug: { - bytecode: '007a519c', - sourceMap: '4:12:4:17;;:21::22;:12:::1', + bytecode: '519c', + sourceMap: '4:21:4:22;:4::46:1', logs: [ { ip: 0, @@ -33,7 +33,7 @@ export default { ], requires: [ { - ip: 4, + ip: 2, line: 4, message: 'Wrong value passed', }, @@ -41,7 +41,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-04-11T09:08:09.750Z', + updatedAt: '2026-01-13T10:40:29.996Z', } as const; diff --git a/examples/testing-suite/artifacts/example.json b/examples/testing-suite/artifacts/example.json index 6f306b3f..6b1b7e54 100644 --- a/examples/testing-suite/artifacts/example.json +++ b/examples/testing-suite/artifacts/example.json @@ -41,7 +41,7 @@ }, "compiler": { "name": "cashc", - "version": "0.12.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-12-09T10:19:09.338Z" + "updatedAt": "2026-01-13T10:40:29.996Z" } \ No newline at end of file diff --git a/examples/testing-suite/artifacts/transfer_with_timeout.artifact.ts b/examples/testing-suite/artifacts/transfer_with_timeout.artifact.ts new file mode 100644 index 00000000..6bb9e8b9 --- /dev/null +++ b/examples/testing-suite/artifacts/transfer_with_timeout.artifact.ts @@ -0,0 +1,63 @@ +export default { + contractName: 'TransferWithTimeout', + constructorInputs: [ + { + name: 'sender', + type: 'pubkey', + }, + { + name: 'recipient', + type: 'pubkey', + }, + { + name: 'timeout', + type: 'int', + }, + ], + abi: [ + { + name: 'transfer', + inputs: [ + { + name: 'recipientSig', + type: 'sig', + }, + ], + }, + { + name: 'timeout', + inputs: [ + { + name: 'senderSig', + type: 'sig', + }, + ], + }, + ], + bytecode: 'OP_3 OP_PICK OP_0 OP_NUMEQUAL OP_IF OP_4 OP_ROLL OP_ROT OP_CHECKSIG OP_NIP OP_NIP OP_NIP OP_ELSE OP_3 OP_ROLL OP_1 OP_NUMEQUALVERIFY OP_3 OP_ROLL OP_SWAP OP_CHECKSIGVERIFY OP_SWAP OP_CHECKLOCKTIMEVERIFY OP_2DROP OP_1 OP_ENDIF', + source: 'pragma cashscript ^0.13.0;\n\ncontract TransferWithTimeout(\n pubkey sender,\n pubkey recipient,\n int timeout\n) {\n // Require recipient\'s signature to match\n function transfer(sig recipientSig) {\n require(checkSig(recipientSig, recipient));\n }\n\n // Require timeout time to be reached and sender\'s signature to match\n function timeout(sig senderSig) {\n require(checkSig(senderSig, sender));\n require(tx.time >= timeout);\n }\n}\n', + debug: { + bytecode: '5379009c63547a7bac77777767537a519d537a7cad7cb16d5168', + sourceMap: '9:4:11:5;;;;;10:25:10:37;;:39::48;:8::51:1;9:4:11:5;;;;14::17::0;;;;15:25:15:34;;:36::42;:8::45:1;16:27:16:34:0;:8::36:1;14:4:17:5;;3:0:18:1', + logs: [], + requires: [ + { + ip: 12, + line: 10, + }, + { + ip: 23, + line: 15, + }, + { + ip: 25, + line: 16, + }, + ], + }, + compiler: { + name: 'cashc', + version: '0.13.0-next.2', + }, + updatedAt: '2026-01-13T10:40:30.007Z', +} as const; diff --git a/examples/testing-suite/artifacts/transfer_with_timeout.json b/examples/testing-suite/artifacts/transfer_with_timeout.json new file mode 100644 index 00000000..b57cfa91 --- /dev/null +++ b/examples/testing-suite/artifacts/transfer_with_timeout.json @@ -0,0 +1,63 @@ +{ + "contractName": "TransferWithTimeout", + "constructorInputs": [ + { + "name": "sender", + "type": "pubkey" + }, + { + "name": "recipient", + "type": "pubkey" + }, + { + "name": "timeout", + "type": "int" + } + ], + "abi": [ + { + "name": "transfer", + "inputs": [ + { + "name": "recipientSig", + "type": "sig" + } + ] + }, + { + "name": "timeout", + "inputs": [ + { + "name": "senderSig", + "type": "sig" + } + ] + } + ], + "bytecode": "OP_3 OP_PICK OP_0 OP_NUMEQUAL OP_IF OP_4 OP_ROLL OP_ROT OP_CHECKSIG OP_NIP OP_NIP OP_NIP OP_ELSE OP_3 OP_ROLL OP_1 OP_NUMEQUALVERIFY OP_3 OP_ROLL OP_SWAP OP_CHECKSIGVERIFY OP_SWAP OP_CHECKLOCKTIMEVERIFY OP_2DROP OP_1 OP_ENDIF", + "source": "pragma cashscript ^0.13.0;\n\ncontract TransferWithTimeout(\n pubkey sender,\n pubkey recipient,\n int timeout\n) {\n // Require recipient's signature to match\n function transfer(sig recipientSig) {\n require(checkSig(recipientSig, recipient));\n }\n\n // Require timeout time to be reached and sender's signature to match\n function timeout(sig senderSig) {\n require(checkSig(senderSig, sender));\n require(tx.time >= timeout);\n }\n}\n", + "debug": { + "bytecode": "5379009c63547a7bac77777767537a519d537a7cad7cb16d5168", + "sourceMap": "9:4:11:5;;;;;10:25:10:37;;:39::48;:8::51:1;9:4:11:5;;;;14::17::0;;;;15:25:15:34;;:36::42;:8::45:1;16:27:16:34:0;:8::36:1;14:4:17:5;;3:0:18:1", + "logs": [], + "requires": [ + { + "ip": 12, + "line": 10 + }, + { + "ip": 23, + "line": 15 + }, + { + "ip": 25, + "line": 16 + } + ] + }, + "compiler": { + "name": "cashc", + "version": "0.13.0-next.2" + }, + "updatedAt": "2026-01-13T10:40:30.007Z" +} \ No newline at end of file diff --git a/examples/testing-suite/contracts/transfer_with_timeout.cash b/examples/testing-suite/contracts/transfer_with_timeout.cash new file mode 100644 index 00000000..ab06c01a --- /dev/null +++ b/examples/testing-suite/contracts/transfer_with_timeout.cash @@ -0,0 +1,18 @@ +pragma cashscript ^0.13.0; + +contract TransferWithTimeout( + pubkey sender, + pubkey recipient, + int timeout +) { + // Require recipient's signature to match + function transfer(sig recipientSig) { + require(checkSig(recipientSig, recipient)); + } + + // Require timeout time to be reached and sender's signature to match + function timeout(sig senderSig) { + require(checkSig(senderSig, sender)); + require(tx.time >= timeout); + } +} diff --git a/examples/testing-suite/package.json b/examples/testing-suite/package.json index da596187..ad392252 100644 --- a/examples/testing-suite/package.json +++ b/examples/testing-suite/package.json @@ -1,6 +1,6 @@ { "name": "testing-suite", - "version": "0.12.1", + "version": "0.13.0-next.3", "description": "Example project to develop and test CashScript contracts", "main": "index.js", "type": "module", @@ -12,21 +12,14 @@ "test": "test" }, "scripts": { - "build": "yarn clean && yarn compile", - "clean": "rm -rf ./dist", - "compile": "tsc -p tsconfig.json && yarn run task:compile", + "compile": "tsx tasks/compile.ts", "lint": "eslint . --ext .ts --ignore-path ../../.eslintignore", - "prepare": "yarn build", - "prepublishOnly": "yarn test && yarn lint", - "task:compile": "tsx tasks/index.ts compile", - "pretest": "yarn run task:compile", "test": "vitest run" }, "dependencies": { "@bitauth/libauth": "^3.1.0-next.8", - "cashc": "^0.12.1", - "cashscript": "^0.12.1", - "url-join": "^5.0.0" + "cashc": "^0.13.0-next.3", + "cashscript": "^0.13.0-next.3" }, "devDependencies": { "tsx": "^4.20.3", diff --git a/examples/testing-suite/src/index.ts b/examples/testing-suite/src/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/testing-suite/tasks/compile.ts b/examples/testing-suite/tasks/compile.ts new file mode 100644 index 00000000..503f6004 --- /dev/null +++ b/examples/testing-suite/tasks/compile.ts @@ -0,0 +1,33 @@ +import { formatArtifact } from '@cashscript/utils'; +import { compileString } from 'cashc'; +import fs from 'fs'; +import { URL } from 'url'; + +export const compile = (): void => { + const directory = new URL('../contracts', import.meta.url); + const result = fs.readdirSync(directory) + .filter((fn) => fn.endsWith('.cash')); + + fs.mkdirSync(new URL('../artifacts', import.meta.url), { recursive: true }); + + result.forEach((fn) => { + const contractFile = new URL(fn, `${directory}/`); + const jsonOutputFile = new URL(`../artifacts/${fn.replace('.cash', '.json')}`, import.meta.url); + const tsOutputFile = new URL(`../artifacts/${fn.replace('.cash', '.artifact.ts')}`, import.meta.url); + + try { + const contents = fs.readFileSync(contractFile, { encoding: 'utf-8' }); + const artifact = compileString(contents); + + fs.writeFileSync(jsonOutputFile, formatArtifact(artifact, 'json')); + fs.writeFileSync(tsOutputFile, formatArtifact(artifact, 'ts')); + } catch (error: any) { + console.error(`Error compiling ${fn}: ${error.message}`); + return; + } + + console.log(`Successfully compiled ${fn}`); + }); +}; + +compile(); diff --git a/examples/testing-suite/tasks/index.ts b/examples/testing-suite/tasks/index.ts deleted file mode 100644 index e04ce9cf..00000000 --- a/examples/testing-suite/tasks/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { compileString } from 'cashc'; -import fs from 'fs'; -import { URL } from 'url'; -import urlJoin from 'url-join'; - -export const compile = (): void => { - const directory = new URL('../contracts', import.meta.url); - const result = fs.readdirSync(directory) - .filter((fn) => fn.endsWith('.cash')) - .map((fn) => ({ fn, contents: fs.readFileSync(new URL(urlJoin(directory.toString(), fn)), { encoding: 'utf-8' }) })); - - result.forEach(({ fn, contents }) => { - const artifact = compileString(contents); - - fs.writeFileSync(new URL(`../artifacts/${fn.replace('.cash', '.json')}`, import.meta.url), JSON.stringify(artifact, null, 2)); - }); -}; - -switch (process.argv[2]) { - case 'compile': - compile(); - break; - default: - console.log('Unknown task'); - break; -} diff --git a/examples/testing-suite/test/example.test.ts b/examples/testing-suite/test/example.test.ts index efff9b34..f2f2dfbd 100644 --- a/examples/testing-suite/test/example.test.ts +++ b/examples/testing-suite/test/example.test.ts @@ -3,26 +3,29 @@ import { Contract, MockNetworkProvider, TransactionBuilder, randomUtxo } from 'c import 'cashscript/vitest'; describe('test example contract functions', () => { - it('should check for output logs and error messages', async () => { - const provider = new MockNetworkProvider(); - const contract = new Contract(artifact, [], { provider }); + const provider = new MockNetworkProvider(); + const contract = new Contract(artifact, [], { provider }); - // Create a contract Utxo - const contractUtxo = randomUtxo(); - provider.addUtxo(contract.address, contractUtxo); + // Create a contract Utxo + const contractUtxo = randomUtxo(); + provider.addUtxo(contract.address, contractUtxo); - const transactionWrongValuePassed = new TransactionBuilder({ provider }) - .addInput(contractUtxo, contract.unlock.test(0n)) + it('should succeed when correct parameter is passed', () => { + const transaction = new TransactionBuilder({ provider }) + .addInput(contractUtxo, contract.unlock.test(1n)) .addOutput({ to: contract.address, amount: 10000n }); - expect(transactionWrongValuePassed).toLog(/0 test/); - expect(transactionWrongValuePassed).toFailRequireWith(/Wrong value passed/); + expect(transaction).toLog(/1 test/); + expect(transaction).not.toFailRequire(); + }); - const transactionRightValuePassed = new TransactionBuilder({ provider }) - .addInput(contractUtxo, contract.unlock.test(1n)) - .addOutput({ to: contract.address, amount: 10000n }) - .send(); + it('should fail require statement and log when incorrect parameter is passed', () => { + const transaction = new TransactionBuilder({ provider }) + .addInput(contractUtxo, contract.unlock.test(0n)) + .addOutput({ to: contract.address, amount: 10000n }); - await expect(transactionRightValuePassed).resolves.not.toThrow(); + expect(transaction).toLog(/0 test/); + expect(transaction).toFailRequireWith(/Wrong value passed/); }); + }); diff --git a/examples/testing-suite/test/transfer_with_timeout.test.ts b/examples/testing-suite/test/transfer_with_timeout.test.ts new file mode 100644 index 00000000..69edfc4a --- /dev/null +++ b/examples/testing-suite/test/transfer_with_timeout.test.ts @@ -0,0 +1,29 @@ +import artifact from '../artifacts/transfer_with_timeout.artifact.js'; +import { Contract, MockNetworkProvider, SignatureTemplate, TransactionBuilder, randomUtxo } from 'cashscript'; +import { alicePriv, alicePub, bobPub } from '../utils/keys.js'; +import 'cashscript/vitest'; + +describe('test example contract functions', () => { + const provider = new MockNetworkProvider(); + const contract = new Contract(artifact, [alicePub, bobPub, 100000n], { provider }); + + // Create a contract Utxo + const contractUtxo = randomUtxo(); + provider.addUtxo(contract.address, contractUtxo); + + it('should succeed when timeout is called after timeout block', async () => { + // given + const to = contract.address; + const amount = 10000n; + const blockHeight = await provider.getBlockHeight(); + + // when + const tx = new TransactionBuilder({ provider }) + .addInput(contractUtxo, contract.unlock.timeout(new SignatureTemplate(alicePriv))) + .addOutput({ to, amount }) + .setLocktime(blockHeight); + + // then + expect(tx).not.toFailRequire(); + }); +}); diff --git a/examples/testing-suite/tsconfig.build.json b/examples/testing-suite/tsconfig.build.json deleted file mode 100644 index e51f262b..00000000 --- a/examples/testing-suite/tsconfig.build.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "compilerOptions": { - "target": "es2021", - "module": "esnext", - "declaration": true, - "lib": [ - "es2022", - "dom" - ], - "types": [ - "node", - "vitest/globals" - ], - "sourceMap": true, - "strict": true, - "strictPropertyInitialization": false, - "experimentalDecorators": true, - "moduleResolution": "node", - "resolveJsonModule": true, - "esModuleInterop": true, - "skipLibCheck": true, - }, - "exclude": [ - "node_modules", - "dist", - "taksks", - ], -} diff --git a/examples/testing-suite/tsconfig.json b/examples/testing-suite/tsconfig.json index 0027ae6c..e51f262b 100644 --- a/examples/testing-suite/tsconfig.json +++ b/examples/testing-suite/tsconfig.json @@ -1,11 +1,28 @@ { - "extends": "./tsconfig.build.json", - "compilerOptions": { - "outDir": "./dist", + "target": "es2021", + "module": "esnext", + "declaration": true, + "lib": [ + "es2022", + "dom" + ], + "types": [ + "node", + "vitest/globals" + ], + "sourceMap": true, + "strict": true, + "strictPropertyInitialization": false, + "experimentalDecorators": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "esModuleInterop": true, + "skipLibCheck": true, }, - - "include": [ - "src/**/*", + "exclude": [ + "node_modules", + "dist", + "taksks", ], } diff --git a/examples/testing-suite/utils/keys.ts b/examples/testing-suite/utils/keys.ts new file mode 100644 index 00000000..0cfb3c71 --- /dev/null +++ b/examples/testing-suite/utils/keys.ts @@ -0,0 +1,29 @@ +import { hash160 } from '@cashscript/utils'; +import { + deriveHdPrivateNodeFromSeed, + deriveHdPath, + secp256k1, + encodeCashAddress, + deriveSeedFromBip39Mnemonic, +} from '@bitauth/libauth'; + +// Generate entropy from BIP39 mnemonic phrase and initialise a root HD-wallet node +const seed = deriveSeedFromBip39Mnemonic('CashScript Examples'); +const rootNode = deriveHdPrivateNodeFromSeed(seed, { assumeValidity: true, throwErrors: true }); +const baseDerivationPath = "m/44'/145'/0'/0"; + +// Derive Alice's private key, public key, public key hash and address +const aliceNode = deriveHdPath(rootNode, `${baseDerivationPath}/0`); +if (typeof aliceNode === 'string') throw new Error(); +export const alicePub = secp256k1.derivePublicKeyCompressed(aliceNode.privateKey) as Uint8Array; +export const alicePriv = aliceNode.privateKey; +export const alicePkh = hash160(alicePub); +export const aliceAddress = encodeCashAddress({ prefix: 'bchtest', type: 'p2pkhWithTokens', payload: alicePkh, throwErrors: true }).address; + +// Derive Bob's private key, public key, public key hash and address +const bobNode = deriveHdPath(rootNode, `${baseDerivationPath}/1`); +if (typeof bobNode === 'string') throw new Error(); +export const bobPub = secp256k1.derivePublicKeyCompressed(bobNode.privateKey) as Uint8Array; +export const bobPriv = bobNode.privateKey; +export const bobPkh = hash160(bobPub); +export const bobAddress = encodeCashAddress({ prefix: 'bchtest', type: 'p2pkhWithTokens', payload: bobPkh, throwErrors: true }).address; diff --git a/examples/transfer_with_timeout.cash b/examples/transfer_with_timeout.cash index 98723e44..ab06c01a 100644 --- a/examples/transfer_with_timeout.cash +++ b/examples/transfer_with_timeout.cash @@ -1,4 +1,4 @@ -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract TransferWithTimeout( pubkey sender, diff --git a/examples/transfer_with_timeout.ts b/examples/transfer_with_timeout.ts index 12a55918..524685ba 100644 --- a/examples/transfer_with_timeout.ts +++ b/examples/transfer_with_timeout.ts @@ -1,6 +1,6 @@ import { stringify } from '@bitauth/libauth'; import { compileFile } from 'cashc'; -import { Contract, ElectrumNetworkProvider, Output, SignatureTemplate, TransactionBuilder } from 'cashscript'; +import { Contract, MockNetworkProvider, Output, randomUtxo, SignatureTemplate, TransactionBuilder } from 'cashscript'; import { URL } from 'url'; // Import Bob and Alice's keys from common.ts @@ -14,14 +14,18 @@ import { // Compile the TransferWithTimeout contract const artifact = compileFile(new URL('transfer_with_timeout.cash', import.meta.url)); -// Initialise a network provider for network operations on CHIPNET -const provider = new ElectrumNetworkProvider('chipnet'); +// Once you're ready to send transactions on a real network (like chipnet or mainnet), use the ElectrumNetworkProvider +// const provider = new ElectrumNetworkProvider(); +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters: // { sender: alicePk, recipient: bobPk, timeout: 1000000 } - timeout is a past block const contract = new Contract(artifact, [alicePub, bobPub, 100000n], { provider }); +// Add a mock UTXO to the mock network provider +provider.addUtxo(contract.address, randomUtxo()); + // Get contract balance & output address + balance console.log('contract address:', contract.address); const contractUtxos = await contract.getUtxos(); diff --git a/packages/cashc/package.json b/packages/cashc/package.json index 2a020870..56ea9675 100644 --- a/packages/cashc/package.json +++ b/packages/cashc/package.json @@ -1,6 +1,6 @@ { "name": "cashc", - "version": "0.12.1", + "version": "0.13.0-next.3", "description": "Compile Bitcoin Cash contracts to Bitcoin Cash Script or artifacts", "keywords": [ "bitcoin", @@ -48,7 +48,7 @@ }, "dependencies": { "@bitauth/libauth": "^3.1.0-next.8", - "@cashscript/utils": "^0.12.1", + "@cashscript/utils": "^0.13.0-next.3", "antlr4": "^4.13.2", "commander": "^14.0.0", "semver": "^7.7.2" @@ -62,7 +62,6 @@ "eslint-plugin-import": "^2.31.0", "tsx": "^4.20.3", "typescript": "^5.9.2", - "url-join": "^5.0.0", "vitest": "^4.0.15" }, "gitHead": "bf02a4b641d5d03c035d052247a545109c17b708" diff --git a/packages/cashc/src/Errors.ts b/packages/cashc/src/Errors.ts index 692a8550..eff20c9d 100644 --- a/packages/cashc/src/Errors.ts +++ b/packages/cashc/src/Errors.ts @@ -202,14 +202,6 @@ export class CastTypeError extends TypeError { } } -export class CastSizeError extends CashScriptError { - constructor( - node: CastNode, - ) { - super(node, 'Unexpected cast size argument found'); - } -} - export class AssignTypeError extends TypeError { constructor( node: AssignNode | VariableDefinitionNode, @@ -273,6 +265,15 @@ export class IndexOutOfBoundsError extends CashScriptError { } } +export class BitshiftBitcountNegativeError extends CashScriptError { + constructor( + node: BinaryOpNode, + bitcount: number, + ) { + super(node, `Bitshift bitcount cannot be negative: ${bitcount}`); + } +} + export class VersionError extends Error { constructor( actual: string, diff --git a/packages/cashc/src/ast/AST.ts b/packages/cashc/src/ast/AST.ts index b43935dd..c9c0d55a 100644 --- a/packages/cashc/src/ast/AST.ts +++ b/packages/cashc/src/ast/AST.ts @@ -165,6 +165,19 @@ export class BranchNode extends StatementNode { } } +export class DoWhileNode extends StatementNode { + constructor( + public condition: ExpressionNode, + public block: BlockNode, + ) { + super(); + } + + accept(visitor: AstVisitor): T { + return visitor.visitDoWhile(this); + } +} + export class BlockNode extends Node { symbolTable?: SymbolTable; @@ -187,7 +200,7 @@ export class CastNode extends ExpressionNode implements Typed { constructor( public type: Type, public expression: ExpressionNode, - public size?: ExpressionNode, + public isUnsafe: boolean, ) { super(); } diff --git a/packages/cashc/src/ast/AstBuilder.ts b/packages/cashc/src/ast/AstBuilder.ts index 7f5bc994..21077252 100644 --- a/packages/cashc/src/ast/AstBuilder.ts +++ b/packages/cashc/src/ast/AstBuilder.ts @@ -34,6 +34,7 @@ import { ConsoleStatementNode, ConsoleParameterNode, SliceNode, + DoWhileNode, } from './AST.js'; import { UnaryOperator, BinaryOperator, NullaryOperator } from './Operator.js'; import type { @@ -68,6 +69,8 @@ import type { StatementContext, RequireMessageContext, SliceContext, + DoWhileStatementContext, + LoopStatementContext, } from '../grammar/CashScriptParser.js'; import CashScriptVisitor from '../grammar/CashScriptVisitor.js'; import { Location } from './Location.js'; @@ -214,6 +217,18 @@ export default class AstBuilder return branch; } + visitLoopStatement(ctx: LoopStatementContext): DoWhileNode { + return this.visit(ctx.doWhileStatement()) as DoWhileNode; + } + + visitDoWhileStatement(ctx: DoWhileStatementContext): DoWhileNode { + const condition = this.visit(ctx.expression()); + const block = this.visit(ctx.block()) as StatementNode; + const doWhile = new DoWhileNode(condition, block); + doWhile.location = Location.fromCtx(ctx); + return doWhile; + } + visitBlock(ctx: BlockContext): BlockNode { const statements = ctx.statement_list().map((s) => this.visit(s) as StatementNode); const block = new BlockNode(statements); @@ -226,10 +241,11 @@ export default class AstBuilder } visitCast(ctx: CastContext): CastNode { - const type = parseType(ctx.typeName().getText()); + const rawType = ctx.typeCast().getText(); + const type = parseType(rawType.replace('unsafe_', '')); + const isUnsafe = rawType.startsWith('unsafe_'); const expression = this.visit(ctx._castable); - const size = ctx._size && this.visit(ctx._size); - const cast = new CastNode(type, expression, size); + const cast = new CastNode(type, expression, isUnsafe); cast.location = Location.fromCtx(ctx); return cast; } diff --git a/packages/cashc/src/ast/AstTraversal.ts b/packages/cashc/src/ast/AstTraversal.ts index 4d94df61..639141a6 100644 --- a/packages/cashc/src/ast/AstTraversal.ts +++ b/packages/cashc/src/ast/AstTraversal.ts @@ -28,6 +28,7 @@ import { ConsoleStatementNode, ConsoleParameterNode, SliceNode, + DoWhileNode, } from './AST.js'; import AstVisitor from './AstVisitor.js'; @@ -86,6 +87,12 @@ export default class AstTraversal extends AstVisitor { return node; } + visitDoWhile(node: DoWhileNode): Node { + node.condition = this.visit(node.condition); + node.block = this.visit(node.block) as StatementNode; + return node; + } + visitBlock(node: BlockNode): Node { node.statements = this.visitOptionalList(node.statements) as StatementNode[]; return node; @@ -93,7 +100,6 @@ export default class AstTraversal extends AstVisitor { visitCast(node: CastNode): Node { node.expression = this.visit(node.expression); - node.size = this.visitOptional(node.size); return node; } diff --git a/packages/cashc/src/ast/AstVisitor.ts b/packages/cashc/src/ast/AstVisitor.ts index 8e558ed0..8b47528a 100644 --- a/packages/cashc/src/ast/AstVisitor.ts +++ b/packages/cashc/src/ast/AstVisitor.ts @@ -26,6 +26,7 @@ import { NullaryOpNode, ConsoleStatementNode, SliceNode, + DoWhileNode, } from './AST.js'; export default abstract class AstVisitor { @@ -39,6 +40,7 @@ export default abstract class AstVisitor { abstract visitTimeOp(node: TimeOpNode): T; abstract visitRequire(node: RequireNode): T; abstract visitBranch(node: BranchNode): T; + abstract visitDoWhile(node: DoWhileNode): T; abstract visitBlock(node: BlockNode): T; abstract visitCast(node: CastNode): T; abstract visitFunctionCall(node: FunctionCallNode): T; diff --git a/packages/cashc/src/ast/Globals.ts b/packages/cashc/src/ast/Globals.ts index cec809e4..cc1273d7 100644 --- a/packages/cashc/src/ast/Globals.ts +++ b/packages/cashc/src/ast/Globals.ts @@ -1,7 +1,7 @@ import { PrimitiveType, ArrayType, BytesType } from '@cashscript/utils'; import { SymbolTable, Symbol } from './SymbolTable.js'; -export const NumberUnit: { [index:string] : number } = { +export const NumberUnit: { [index: string]: number } = { SATOSHIS: 1, SATS: 1, FINNEY: 10, @@ -27,6 +27,7 @@ export enum GlobalFunction { CHECKSIG = 'checkSig', CHECKMULTISIG = 'checkMultiSig', CHECKDATASIG = 'checkDataSig', + TO_PADDED_BYTES = 'toPaddedBytes', } export enum TimeOp { @@ -102,3 +103,7 @@ GLOBAL_SYMBOL_TABLE.set(Symbol.function( GlobalFunction.CHECKDATASIG, PrimitiveType.BOOL, [PrimitiveType.DATASIG, new BytesType(), PrimitiveType.PUBKEY], )); +GLOBAL_SYMBOL_TABLE.set(Symbol.function( + GlobalFunction.TO_PADDED_BYTES, new BytesType(), + [PrimitiveType.INT, PrimitiveType.INT], +)); diff --git a/packages/cashc/src/ast/Operator.ts b/packages/cashc/src/ast/Operator.ts index 191aa8c3..0761d975 100644 --- a/packages/cashc/src/ast/Operator.ts +++ b/packages/cashc/src/ast/Operator.ts @@ -10,6 +10,7 @@ export enum NullaryOperator { export enum UnaryOperator { NOT = '!', NEGATE = '-', + INVERT = '~', SIZE = '.length', REVERSE = '.reverse()', INPUT_VALUE = 'tx.inputs[i].value', @@ -34,15 +35,17 @@ export enum BinaryOperator { MOD = '%', PLUS = '+', MINUS = '-', + SHIFT_LEFT = '<<', + SHIFT_RIGHT = '>>', LT = '<', + BIT_AND = '&', + BIT_XOR = '^', + BIT_OR = '|', LE = '<=', GT = '>', GE = '>=', EQ = '==', NE = '!=', - BIT_AND = '&', - BIT_XOR = '^', - BIT_OR = '|', AND = '&&', OR = '||', SPLIT = '.split', diff --git a/packages/cashc/src/constants.ts b/packages/cashc/src/constants.ts index 097767c3..2e134259 100644 --- a/packages/cashc/src/constants.ts +++ b/packages/cashc/src/constants.ts @@ -1 +1 @@ -export const MAX_INPUT_BYTESIZE = 1650; +export const MAX_INPUT_BYTESIZE = 10_000; diff --git a/packages/cashc/src/generation/GenerateTargetTraversal.ts b/packages/cashc/src/generation/GenerateTargetTraversal.ts index 6f17eda6..49f0d098 100644 --- a/packages/cashc/src/generation/GenerateTargetTraversal.ts +++ b/packages/cashc/src/generation/GenerateTargetTraversal.ts @@ -7,7 +7,6 @@ import { Op, OpOrData, PrimitiveType, - resultingType, Script, scriptToAsm, generateSourceMap, @@ -47,6 +46,7 @@ import { ConsoleParameterNode, ConsoleStatementNode, SliceNode, + DoWhileNode, } from '../ast/AST.js'; import AstTraversal from '../ast/AstTraversal.js'; import { GlobalFunction, Class } from '../ast/Globals.js'; @@ -59,6 +59,7 @@ import { compileTimeOp, compileUnaryOp, } from './utils.js'; +import { resultingTypeForBinaryOp } from '../utils.js'; export default class GenerateTargetTraversalWithLocation extends AstTraversal { private locationData: FullLocationData = []; // detailed location data needed for sourcemap creation @@ -197,7 +198,7 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { removeFinalVerifyFromFunction(functionBodyNode: Node): void { // After EnsureFinalRequireTraversal, we know that the final opcodes are either - // "OP_VERIFY", "OP_CHECK{LOCKTIME|SEQUENCE}VERIFY OP_DROP" or "OP_ENDIF" + // "OP_VERIFY", "OP_CHECK{LOCKTIME|SEQUENCE}VERIFY OP_DROP", "OP_ENDIF" or "OP_UNTIL" const finalOp = this.output.pop() as Op; const { location, positionHint } = this.locationData.pop()!; @@ -219,7 +220,7 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { this.emit(finalOp, { location, positionHint: PositionHint.END }); // At this point there is no verification value left on the stack: - // - scoped stack is cleared inside branch ended by OP_ENDIF + // - scoped stack is cleared inside block ended by OP_ENDIF or OP_UNTIL // - OP_CHECK{LOCKTIME|SEQUENCE}VERIFY OP_DROP does not leave a verification value // - OP_VERIFY does not leave a verification value // so we add OP_1 to the script (indicating success) @@ -381,6 +382,25 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { return node; } + visitDoWhile(node: DoWhileNode): Node { + this.scopeDepth += 1; + this.emit(Op.OP_BEGIN, { location: node.location, positionHint: PositionHint.START }); + + const stackDepth = this.stack.length; + node.block = this.visit(node.block); + this.removeScopedVariables(stackDepth, node.block); + + node.condition = this.visit(node.condition); + this.emit(Op.OP_NOT, { location: node.location, positionHint: PositionHint.END }); + + this.emit(Op.OP_UNTIL, { location: node.location, positionHint: PositionHint.END }); + this.popFromStack(); + + this.scopeDepth -= 1; + + return node; + } + removeScopedVariables(depthBeforeScope: number, node: Node): void { const dropCount = this.stack.length - depthBeforeScope; for (let i = 0; i < dropCount; i += 1) { @@ -392,15 +412,8 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { visitCast(node: CastNode): Node { node.expression = this.visit(node.expression); - // Special case for sized bytes cast, since it has another node to traverse - if (node.size) { - node.size = this.visit(node.size); - this.emit(Op.OP_NUM2BIN, { location: node.location, positionHint: PositionHint.END }); - this.popFromStack(); - } - this.emit( - compileCast(node.expression.type as PrimitiveType, node.type), + compileCast(node.expression.type as PrimitiveType, node.type, node.isUnsafe), { location: node.location, positionHint: PositionHint.END }, ); this.popFromStack(); @@ -562,7 +575,7 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { visitBinaryOp(node: BinaryOpNode): Node { node.left = this.visit(node.left); node.right = this.visit(node.right); - const isNumeric = resultingType(node.left.type, node.right.type) === PrimitiveType.INT; + const isNumeric = resultingTypeForBinaryOp(node.operator, node.left.type!, node.right.type!) === PrimitiveType.INT; this.emit(compileBinaryOp(node.operator, isNumeric), { location: node.location, positionHint: PositionHint.END }); this.popFromStack(2); this.pushToStack('(value)'); diff --git a/packages/cashc/src/generation/utils.ts b/packages/cashc/src/generation/utils.ts index f4aab3cb..fa017aac 100644 --- a/packages/cashc/src/generation/utils.ts +++ b/packages/cashc/src/generation/utils.ts @@ -18,12 +18,18 @@ export function compileTimeOp(op: TimeOp): Script { return mapping[op]; } -export function compileCast(from: Type, to: Type): Script { +export function compileCast(from: Type, to: Type, isUnsafe: boolean): Script { + if (isUnsafe) return []; + if (from === PrimitiveType.INT && to instanceof BytesType && to.bound !== undefined) { return [encodeInt(BigInt(to.bound)), Op.OP_NUM2BIN]; } - if (from !== PrimitiveType.INT && to === PrimitiveType.INT) { + if (from === PrimitiveType.INT && to === PrimitiveType.BOOL) { + return [Op.OP_0NOTEQUAL]; + } + + if (from instanceof BytesType && to === PrimitiveType.INT) { return [Op.OP_BIN2NUM]; } @@ -44,6 +50,7 @@ export function compileGlobalFunction(fn: GlobalFunction): Script { [GlobalFunction.HASH160]: [Op.OP_HASH160], [GlobalFunction.HASH256]: [Op.OP_HASH256], [GlobalFunction.WITHIN]: [Op.OP_WITHIN], + [GlobalFunction.TO_PADDED_BYTES]: [Op.OP_NUM2BIN], }; return mapping[fn]; @@ -56,6 +63,11 @@ export function compileBinaryOp(op: BinaryOperator, numeric: boolean = false): S [BinaryOperator.MOD]: [Op.OP_MOD], [BinaryOperator.PLUS]: [Op.OP_CAT], [BinaryOperator.MINUS]: [Op.OP_SUB], + [BinaryOperator.SHIFT_LEFT]: [Op.OP_LSHIFTBIN], + [BinaryOperator.SHIFT_RIGHT]: [Op.OP_RSHIFTBIN], + [BinaryOperator.BIT_AND]: [Op.OP_AND], + [BinaryOperator.BIT_OR]: [Op.OP_OR], + [BinaryOperator.BIT_XOR]: [Op.OP_XOR], [BinaryOperator.LT]: [Op.OP_LESSTHAN], [BinaryOperator.LE]: [Op.OP_LESSTHANOREQUAL], [BinaryOperator.GT]: [Op.OP_GREATERTHAN], @@ -64,9 +76,6 @@ export function compileBinaryOp(op: BinaryOperator, numeric: boolean = false): S [BinaryOperator.NE]: [Op.OP_EQUAL, Op.OP_NOT], [BinaryOperator.AND]: [Op.OP_BOOLAND], [BinaryOperator.OR]: [Op.OP_BOOLOR], - [BinaryOperator.BIT_AND]: [Op.OP_AND], - [BinaryOperator.BIT_OR]: [Op.OP_OR], - [BinaryOperator.BIT_XOR]: [Op.OP_XOR], [BinaryOperator.SPLIT]: [Op.OP_SPLIT], }; @@ -74,6 +83,8 @@ export function compileBinaryOp(op: BinaryOperator, numeric: boolean = false): S mapping[BinaryOperator.PLUS] = [Op.OP_ADD]; mapping[BinaryOperator.EQ] = [Op.OP_NUMEQUAL]; mapping[BinaryOperator.NE] = [Op.OP_NUMNOTEQUAL]; + mapping[BinaryOperator.SHIFT_LEFT] = [Op.OP_LSHIFTNUM]; + mapping[BinaryOperator.SHIFT_RIGHT] = [Op.OP_RSHIFTNUM]; } return mapping[op]; @@ -83,6 +94,7 @@ export function compileUnaryOp(op: UnaryOperator): Op[] { const mapping = { [UnaryOperator.NOT]: [Op.OP_NOT], [UnaryOperator.NEGATE]: [Op.OP_NEGATE], + [UnaryOperator.INVERT]: [Op.OP_INVERT], [UnaryOperator.SIZE]: [Op.OP_SIZE, Op.OP_NIP], [UnaryOperator.REVERSE]: [Op.OP_REVERSEBYTES], [UnaryOperator.INPUT_VALUE]: [Op.OP_UTXOVALUE], diff --git a/packages/cashc/src/grammar/CashScript.g4 b/packages/cashc/src/grammar/CashScript.g4 index 6b79d54e..ca247bab 100644 --- a/packages/cashc/src/grammar/CashScript.g4 +++ b/packages/cashc/src/grammar/CashScript.g4 @@ -52,6 +52,7 @@ statement | timeOpStatement | requireStatement | ifStatement + | loopStatement | consoleStatement ; @@ -79,6 +80,14 @@ ifStatement : 'if' '(' expression ')' ifBlock=block ('else' elseBlock=block)? ; +loopStatement + : doWhileStatement + ; + +doWhileStatement + : 'do' block 'while' '(' expression ')' ';' + ; + consoleStatement : 'console.log' consoleParameterList ';' ; @@ -106,7 +115,7 @@ expressionList expression : '(' expression ')' # Parenthesised - | typeName '(' castable=expression (',' size=expression)? ','? ')' # Cast + | typeCast '(' castable=expression ','? ')' # Cast | functionCall # FunctionCallExpression | 'new' Identifier expressionList #Instantiation | expression '[' index=NumberLiteral ']' # TupleIndexOp @@ -115,10 +124,10 @@ expression | expression op=('.reverse()' | '.length') # UnaryOp | left=expression op='.split' '(' right=expression ')' # BinaryOp | element=expression '.slice' '(' start=expression ',' end=expression ')' # Slice - | op=('!' | '-') expression # UnaryOp + | op=('!' | '-' | '~') expression # UnaryOp | left=expression op=('*' | '/' | '%') right=expression # BinaryOp | left=expression op=('+' | '-') right=expression # BinaryOp - // | expression ('>>' | '<<') expression --- OP_LSHIFT & RSHIFT are disabled in BCH Script + | left=expression op=('>>' | '<<') right=expression # BinaryOp | left=expression op=('<' | '<=' | '>' | '>=') right=expression # BinaryOp | left=expression op=('==' | '!=') right=expression # BinaryOp | left=expression op='&' right=expression # BinaryOp @@ -149,7 +158,15 @@ numberLiteral ; typeName - : 'int' | 'bool' | 'string' | 'pubkey' | 'sig' | 'datasig' | Bytes + : PrimitiveType + | BoundedBytes + | UnboundedBytes + ; + +typeCast + : PrimitiveType + | UnboundedBytes + | UnsafeCast ; VersionLiteral @@ -177,8 +194,21 @@ ExponentPart : [eE] NumberPart ; -Bytes - : 'bytes' Bound? | 'byte' +PrimitiveType + : 'int' + | 'bool' + | 'string' + | 'pubkey' + | 'sig' + | 'datasig' + ; + +UnboundedBytes + : 'bytes' + ; + +BoundedBytes + : 'bytes' Bound | 'byte' ; Bound @@ -203,6 +233,13 @@ TxVar | 'tx.time' ; +UnsafeCast + : 'unsafe_int' + | 'unsafe_bool' + | 'unsafe_bytes' Bound? + | 'unsafe_byte' + ; + NullaryOp : 'this.activeInputIndex' | 'this.activeBytecode' diff --git a/packages/cashc/src/grammar/CashScript.interp b/packages/cashc/src/grammar/CashScript.interp index f59a2136..31fc71ce 100644 --- a/packages/cashc/src/grammar/CashScript.interp +++ b/packages/cashc/src/grammar/CashScript.interp @@ -20,6 +20,8 @@ null 'require' 'if' 'else' +'do' +'while' 'console.log' 'new' '[' @@ -45,6 +47,8 @@ null '/' '%' '+' +'>>' +'<<' '==' '!=' '&' @@ -52,12 +56,6 @@ null '&&' '||' 'constant' -'int' -'bool' -'string' -'pubkey' -'sig' -'datasig' null null null @@ -65,6 +63,7 @@ null null null null +'bytes' null null null @@ -75,10 +74,10 @@ null null null null - -token symbolic names: null null + +token symbolic names: null null null @@ -142,12 +141,15 @@ NumberUnit NumberLiteral NumberPart ExponentPart -Bytes +PrimitiveType +UnboundedBytes +BoundedBytes Bound StringLiteral DateLiteral HexLiteral TxVar +UnsafeCast NullaryOp Identifier WHITESPACE @@ -173,6 +175,8 @@ assignStatement timeOpStatement requireStatement ifStatement +loopStatement +doWhileStatement consoleStatement requireMessage consoleParameter @@ -184,7 +188,8 @@ modifier literal numberLiteral typeName +typeCast atn: -[4, 1, 75, 373, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 1, 0, 5, 0, 60, 8, 0, 10, 0, 12, 0, 63, 9, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 3, 3, 77, 8, 3, 1, 4, 3, 4, 80, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 91, 8, 6, 10, 6, 12, 6, 94, 9, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 5, 7, 103, 8, 7, 10, 7, 12, 7, 106, 9, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 114, 8, 8, 10, 8, 12, 8, 117, 9, 8, 1, 8, 3, 8, 120, 8, 8, 3, 8, 122, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 5, 10, 131, 8, 10, 10, 10, 12, 10, 134, 9, 10, 1, 10, 1, 10, 3, 10, 138, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 147, 8, 11, 1, 12, 1, 12, 5, 12, 151, 8, 12, 10, 12, 12, 12, 154, 9, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 182, 8, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 192, 8, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 204, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 3, 20, 214, 8, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 220, 8, 21, 10, 21, 12, 21, 223, 9, 21, 1, 21, 3, 21, 226, 8, 21, 3, 21, 228, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 239, 8, 23, 10, 23, 12, 23, 242, 9, 23, 1, 23, 3, 23, 245, 8, 23, 3, 23, 247, 8, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 261, 8, 24, 1, 24, 3, 24, 264, 8, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 5, 24, 290, 8, 24, 10, 24, 12, 24, 293, 9, 24, 1, 24, 3, 24, 296, 8, 24, 3, 24, 298, 8, 24, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 304, 8, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 5, 24, 353, 8, 24, 10, 24, 12, 24, 356, 9, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 365, 8, 26, 1, 27, 1, 27, 3, 27, 369, 8, 27, 1, 28, 1, 28, 1, 28, 0, 1, 48, 29, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 0, 10, 1, 0, 4, 10, 1, 0, 26, 30, 2, 0, 26, 30, 32, 35, 1, 0, 40, 41, 1, 0, 42, 44, 2, 0, 41, 41, 45, 45, 1, 0, 6, 9, 1, 0, 46, 47, 1, 0, 36, 37, 2, 0, 53, 58, 65, 65, 403, 0, 61, 1, 0, 0, 0, 2, 67, 1, 0, 0, 0, 4, 72, 1, 0, 0, 0, 6, 74, 1, 0, 0, 0, 8, 79, 1, 0, 0, 0, 10, 83, 1, 0, 0, 0, 12, 85, 1, 0, 0, 0, 14, 97, 1, 0, 0, 0, 16, 109, 1, 0, 0, 0, 18, 125, 1, 0, 0, 0, 20, 137, 1, 0, 0, 0, 22, 146, 1, 0, 0, 0, 24, 148, 1, 0, 0, 0, 26, 160, 1, 0, 0, 0, 28, 169, 1, 0, 0, 0, 30, 174, 1, 0, 0, 0, 32, 186, 1, 0, 0, 0, 34, 196, 1, 0, 0, 0, 36, 205, 1, 0, 0, 0, 38, 209, 1, 0, 0, 0, 40, 213, 1, 0, 0, 0, 42, 215, 1, 0, 0, 0, 44, 231, 1, 0, 0, 0, 46, 234, 1, 0, 0, 0, 48, 303, 1, 0, 0, 0, 50, 357, 1, 0, 0, 0, 52, 364, 1, 0, 0, 0, 54, 366, 1, 0, 0, 0, 56, 370, 1, 0, 0, 0, 58, 60, 3, 2, 1, 0, 59, 58, 1, 0, 0, 0, 60, 63, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 64, 1, 0, 0, 0, 63, 61, 1, 0, 0, 0, 64, 65, 3, 12, 6, 0, 65, 66, 5, 0, 0, 1, 66, 1, 1, 0, 0, 0, 67, 68, 5, 1, 0, 0, 68, 69, 3, 4, 2, 0, 69, 70, 3, 6, 3, 0, 70, 71, 5, 2, 0, 0, 71, 3, 1, 0, 0, 0, 72, 73, 5, 3, 0, 0, 73, 5, 1, 0, 0, 0, 74, 76, 3, 8, 4, 0, 75, 77, 3, 8, 4, 0, 76, 75, 1, 0, 0, 0, 76, 77, 1, 0, 0, 0, 77, 7, 1, 0, 0, 0, 78, 80, 3, 10, 5, 0, 79, 78, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 81, 1, 0, 0, 0, 81, 82, 5, 59, 0, 0, 82, 9, 1, 0, 0, 0, 83, 84, 7, 0, 0, 0, 84, 11, 1, 0, 0, 0, 85, 86, 5, 11, 0, 0, 86, 87, 5, 72, 0, 0, 87, 88, 3, 16, 8, 0, 88, 92, 5, 12, 0, 0, 89, 91, 3, 14, 7, 0, 90, 89, 1, 0, 0, 0, 91, 94, 1, 0, 0, 0, 92, 90, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 95, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 95, 96, 5, 13, 0, 0, 96, 13, 1, 0, 0, 0, 97, 98, 5, 14, 0, 0, 98, 99, 5, 72, 0, 0, 99, 100, 3, 16, 8, 0, 100, 104, 5, 12, 0, 0, 101, 103, 3, 22, 11, 0, 102, 101, 1, 0, 0, 0, 103, 106, 1, 0, 0, 0, 104, 102, 1, 0, 0, 0, 104, 105, 1, 0, 0, 0, 105, 107, 1, 0, 0, 0, 106, 104, 1, 0, 0, 0, 107, 108, 5, 13, 0, 0, 108, 15, 1, 0, 0, 0, 109, 121, 5, 15, 0, 0, 110, 115, 3, 18, 9, 0, 111, 112, 5, 16, 0, 0, 112, 114, 3, 18, 9, 0, 113, 111, 1, 0, 0, 0, 114, 117, 1, 0, 0, 0, 115, 113, 1, 0, 0, 0, 115, 116, 1, 0, 0, 0, 116, 119, 1, 0, 0, 0, 117, 115, 1, 0, 0, 0, 118, 120, 5, 16, 0, 0, 119, 118, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 120, 122, 1, 0, 0, 0, 121, 110, 1, 0, 0, 0, 121, 122, 1, 0, 0, 0, 122, 123, 1, 0, 0, 0, 123, 124, 5, 17, 0, 0, 124, 17, 1, 0, 0, 0, 125, 126, 3, 56, 28, 0, 126, 127, 5, 72, 0, 0, 127, 19, 1, 0, 0, 0, 128, 132, 5, 12, 0, 0, 129, 131, 3, 22, 11, 0, 130, 129, 1, 0, 0, 0, 131, 134, 1, 0, 0, 0, 132, 130, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 135, 1, 0, 0, 0, 134, 132, 1, 0, 0, 0, 135, 138, 5, 13, 0, 0, 136, 138, 3, 22, 11, 0, 137, 128, 1, 0, 0, 0, 137, 136, 1, 0, 0, 0, 138, 21, 1, 0, 0, 0, 139, 147, 3, 24, 12, 0, 140, 147, 3, 26, 13, 0, 141, 147, 3, 28, 14, 0, 142, 147, 3, 30, 15, 0, 143, 147, 3, 32, 16, 0, 144, 147, 3, 34, 17, 0, 145, 147, 3, 36, 18, 0, 146, 139, 1, 0, 0, 0, 146, 140, 1, 0, 0, 0, 146, 141, 1, 0, 0, 0, 146, 142, 1, 0, 0, 0, 146, 143, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 146, 145, 1, 0, 0, 0, 147, 23, 1, 0, 0, 0, 148, 152, 3, 56, 28, 0, 149, 151, 3, 50, 25, 0, 150, 149, 1, 0, 0, 0, 151, 154, 1, 0, 0, 0, 152, 150, 1, 0, 0, 0, 152, 153, 1, 0, 0, 0, 153, 155, 1, 0, 0, 0, 154, 152, 1, 0, 0, 0, 155, 156, 5, 72, 0, 0, 156, 157, 5, 10, 0, 0, 157, 158, 3, 48, 24, 0, 158, 159, 5, 2, 0, 0, 159, 25, 1, 0, 0, 0, 160, 161, 3, 56, 28, 0, 161, 162, 5, 72, 0, 0, 162, 163, 5, 16, 0, 0, 163, 164, 3, 56, 28, 0, 164, 165, 5, 72, 0, 0, 165, 166, 5, 10, 0, 0, 166, 167, 3, 48, 24, 0, 167, 168, 5, 2, 0, 0, 168, 27, 1, 0, 0, 0, 169, 170, 5, 72, 0, 0, 170, 171, 5, 10, 0, 0, 171, 172, 3, 48, 24, 0, 172, 173, 5, 2, 0, 0, 173, 29, 1, 0, 0, 0, 174, 175, 5, 18, 0, 0, 175, 176, 5, 15, 0, 0, 176, 177, 5, 70, 0, 0, 177, 178, 5, 6, 0, 0, 178, 181, 3, 48, 24, 0, 179, 180, 5, 16, 0, 0, 180, 182, 3, 38, 19, 0, 181, 179, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 183, 1, 0, 0, 0, 183, 184, 5, 17, 0, 0, 184, 185, 5, 2, 0, 0, 185, 31, 1, 0, 0, 0, 186, 187, 5, 18, 0, 0, 187, 188, 5, 15, 0, 0, 188, 191, 3, 48, 24, 0, 189, 190, 5, 16, 0, 0, 190, 192, 3, 38, 19, 0, 191, 189, 1, 0, 0, 0, 191, 192, 1, 0, 0, 0, 192, 193, 1, 0, 0, 0, 193, 194, 5, 17, 0, 0, 194, 195, 5, 2, 0, 0, 195, 33, 1, 0, 0, 0, 196, 197, 5, 19, 0, 0, 197, 198, 5, 15, 0, 0, 198, 199, 3, 48, 24, 0, 199, 200, 5, 17, 0, 0, 200, 203, 3, 20, 10, 0, 201, 202, 5, 20, 0, 0, 202, 204, 3, 20, 10, 0, 203, 201, 1, 0, 0, 0, 203, 204, 1, 0, 0, 0, 204, 35, 1, 0, 0, 0, 205, 206, 5, 21, 0, 0, 206, 207, 3, 42, 21, 0, 207, 208, 5, 2, 0, 0, 208, 37, 1, 0, 0, 0, 209, 210, 5, 67, 0, 0, 210, 39, 1, 0, 0, 0, 211, 214, 5, 72, 0, 0, 212, 214, 3, 52, 26, 0, 213, 211, 1, 0, 0, 0, 213, 212, 1, 0, 0, 0, 214, 41, 1, 0, 0, 0, 215, 227, 5, 15, 0, 0, 216, 221, 3, 40, 20, 0, 217, 218, 5, 16, 0, 0, 218, 220, 3, 40, 20, 0, 219, 217, 1, 0, 0, 0, 220, 223, 1, 0, 0, 0, 221, 219, 1, 0, 0, 0, 221, 222, 1, 0, 0, 0, 222, 225, 1, 0, 0, 0, 223, 221, 1, 0, 0, 0, 224, 226, 5, 16, 0, 0, 225, 224, 1, 0, 0, 0, 225, 226, 1, 0, 0, 0, 226, 228, 1, 0, 0, 0, 227, 216, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 230, 5, 17, 0, 0, 230, 43, 1, 0, 0, 0, 231, 232, 5, 72, 0, 0, 232, 233, 3, 46, 23, 0, 233, 45, 1, 0, 0, 0, 234, 246, 5, 15, 0, 0, 235, 240, 3, 48, 24, 0, 236, 237, 5, 16, 0, 0, 237, 239, 3, 48, 24, 0, 238, 236, 1, 0, 0, 0, 239, 242, 1, 0, 0, 0, 240, 238, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 244, 1, 0, 0, 0, 242, 240, 1, 0, 0, 0, 243, 245, 5, 16, 0, 0, 244, 243, 1, 0, 0, 0, 244, 245, 1, 0, 0, 0, 245, 247, 1, 0, 0, 0, 246, 235, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 249, 5, 17, 0, 0, 249, 47, 1, 0, 0, 0, 250, 251, 6, 24, -1, 0, 251, 252, 5, 15, 0, 0, 252, 253, 3, 48, 24, 0, 253, 254, 5, 17, 0, 0, 254, 304, 1, 0, 0, 0, 255, 256, 3, 56, 28, 0, 256, 257, 5, 15, 0, 0, 257, 260, 3, 48, 24, 0, 258, 259, 5, 16, 0, 0, 259, 261, 3, 48, 24, 0, 260, 258, 1, 0, 0, 0, 260, 261, 1, 0, 0, 0, 261, 263, 1, 0, 0, 0, 262, 264, 5, 16, 0, 0, 263, 262, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 265, 1, 0, 0, 0, 265, 266, 5, 17, 0, 0, 266, 304, 1, 0, 0, 0, 267, 304, 3, 44, 22, 0, 268, 269, 5, 22, 0, 0, 269, 270, 5, 72, 0, 0, 270, 304, 3, 46, 23, 0, 271, 272, 5, 25, 0, 0, 272, 273, 5, 23, 0, 0, 273, 274, 3, 48, 24, 0, 274, 275, 5, 24, 0, 0, 275, 276, 7, 1, 0, 0, 276, 304, 1, 0, 0, 0, 277, 278, 5, 31, 0, 0, 278, 279, 5, 23, 0, 0, 279, 280, 3, 48, 24, 0, 280, 281, 5, 24, 0, 0, 281, 282, 7, 2, 0, 0, 282, 304, 1, 0, 0, 0, 283, 284, 7, 3, 0, 0, 284, 304, 3, 48, 24, 14, 285, 297, 5, 23, 0, 0, 286, 291, 3, 48, 24, 0, 287, 288, 5, 16, 0, 0, 288, 290, 3, 48, 24, 0, 289, 287, 1, 0, 0, 0, 290, 293, 1, 0, 0, 0, 291, 289, 1, 0, 0, 0, 291, 292, 1, 0, 0, 0, 292, 295, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 294, 296, 5, 16, 0, 0, 295, 294, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 298, 1, 0, 0, 0, 297, 286, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 304, 5, 24, 0, 0, 300, 304, 5, 71, 0, 0, 301, 304, 5, 72, 0, 0, 302, 304, 3, 52, 26, 0, 303, 250, 1, 0, 0, 0, 303, 255, 1, 0, 0, 0, 303, 267, 1, 0, 0, 0, 303, 268, 1, 0, 0, 0, 303, 271, 1, 0, 0, 0, 303, 277, 1, 0, 0, 0, 303, 283, 1, 0, 0, 0, 303, 285, 1, 0, 0, 0, 303, 300, 1, 0, 0, 0, 303, 301, 1, 0, 0, 0, 303, 302, 1, 0, 0, 0, 304, 354, 1, 0, 0, 0, 305, 306, 10, 13, 0, 0, 306, 307, 7, 4, 0, 0, 307, 353, 3, 48, 24, 14, 308, 309, 10, 12, 0, 0, 309, 310, 7, 5, 0, 0, 310, 353, 3, 48, 24, 13, 311, 312, 10, 11, 0, 0, 312, 313, 7, 6, 0, 0, 313, 353, 3, 48, 24, 12, 314, 315, 10, 10, 0, 0, 315, 316, 7, 7, 0, 0, 316, 353, 3, 48, 24, 11, 317, 318, 10, 9, 0, 0, 318, 319, 5, 48, 0, 0, 319, 353, 3, 48, 24, 10, 320, 321, 10, 8, 0, 0, 321, 322, 5, 4, 0, 0, 322, 353, 3, 48, 24, 9, 323, 324, 10, 7, 0, 0, 324, 325, 5, 49, 0, 0, 325, 353, 3, 48, 24, 8, 326, 327, 10, 6, 0, 0, 327, 328, 5, 50, 0, 0, 328, 353, 3, 48, 24, 7, 329, 330, 10, 5, 0, 0, 330, 331, 5, 51, 0, 0, 331, 353, 3, 48, 24, 6, 332, 333, 10, 20, 0, 0, 333, 334, 5, 23, 0, 0, 334, 335, 5, 62, 0, 0, 335, 353, 5, 24, 0, 0, 336, 337, 10, 17, 0, 0, 337, 353, 7, 8, 0, 0, 338, 339, 10, 16, 0, 0, 339, 340, 5, 38, 0, 0, 340, 341, 5, 15, 0, 0, 341, 342, 3, 48, 24, 0, 342, 343, 5, 17, 0, 0, 343, 353, 1, 0, 0, 0, 344, 345, 10, 15, 0, 0, 345, 346, 5, 39, 0, 0, 346, 347, 5, 15, 0, 0, 347, 348, 3, 48, 24, 0, 348, 349, 5, 16, 0, 0, 349, 350, 3, 48, 24, 0, 350, 351, 5, 17, 0, 0, 351, 353, 1, 0, 0, 0, 352, 305, 1, 0, 0, 0, 352, 308, 1, 0, 0, 0, 352, 311, 1, 0, 0, 0, 352, 314, 1, 0, 0, 0, 352, 317, 1, 0, 0, 0, 352, 320, 1, 0, 0, 0, 352, 323, 1, 0, 0, 0, 352, 326, 1, 0, 0, 0, 352, 329, 1, 0, 0, 0, 352, 332, 1, 0, 0, 0, 352, 336, 1, 0, 0, 0, 352, 338, 1, 0, 0, 0, 352, 344, 1, 0, 0, 0, 353, 356, 1, 0, 0, 0, 354, 352, 1, 0, 0, 0, 354, 355, 1, 0, 0, 0, 355, 49, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 357, 358, 5, 52, 0, 0, 358, 51, 1, 0, 0, 0, 359, 365, 5, 60, 0, 0, 360, 365, 3, 54, 27, 0, 361, 365, 5, 67, 0, 0, 362, 365, 5, 68, 0, 0, 363, 365, 5, 69, 0, 0, 364, 359, 1, 0, 0, 0, 364, 360, 1, 0, 0, 0, 364, 361, 1, 0, 0, 0, 364, 362, 1, 0, 0, 0, 364, 363, 1, 0, 0, 0, 365, 53, 1, 0, 0, 0, 366, 368, 5, 62, 0, 0, 367, 369, 5, 61, 0, 0, 368, 367, 1, 0, 0, 0, 368, 369, 1, 0, 0, 0, 369, 55, 1, 0, 0, 0, 370, 371, 7, 9, 0, 0, 371, 57, 1, 0, 0, 0, 32, 61, 76, 79, 92, 104, 115, 119, 121, 132, 137, 146, 152, 181, 191, 203, 213, 221, 225, 227, 240, 244, 246, 260, 263, 291, 295, 297, 303, 352, 354, 364, 368] \ No newline at end of file +[4, 1, 76, 391, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 1, 0, 5, 0, 66, 8, 0, 10, 0, 12, 0, 69, 9, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 3, 3, 83, 8, 3, 1, 4, 3, 4, 86, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 97, 8, 6, 10, 6, 12, 6, 100, 9, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 5, 7, 109, 8, 7, 10, 7, 12, 7, 112, 9, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 120, 8, 8, 10, 8, 12, 8, 123, 9, 8, 1, 8, 3, 8, 126, 8, 8, 3, 8, 128, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 5, 10, 137, 8, 10, 10, 10, 12, 10, 140, 9, 10, 1, 10, 1, 10, 3, 10, 144, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 154, 8, 11, 1, 12, 1, 12, 5, 12, 158, 8, 12, 10, 12, 12, 12, 161, 9, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 189, 8, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 199, 8, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 211, 8, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 3, 22, 231, 8, 22, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 237, 8, 23, 10, 23, 12, 23, 240, 9, 23, 1, 23, 3, 23, 243, 8, 23, 3, 23, 245, 8, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 5, 25, 256, 8, 25, 10, 25, 12, 25, 259, 9, 25, 1, 25, 3, 25, 262, 8, 25, 3, 25, 264, 8, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 277, 8, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 303, 8, 26, 10, 26, 12, 26, 306, 9, 26, 1, 26, 3, 26, 309, 8, 26, 3, 26, 311, 8, 26, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 317, 8, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 369, 8, 26, 10, 26, 12, 26, 372, 9, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 381, 8, 28, 1, 29, 1, 29, 3, 29, 385, 8, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 0, 1, 52, 32, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 0, 12, 1, 0, 4, 10, 1, 0, 28, 32, 2, 0, 28, 32, 34, 37, 2, 0, 5, 5, 42, 43, 1, 0, 44, 46, 2, 0, 43, 43, 47, 47, 1, 0, 48, 49, 1, 0, 6, 9, 1, 0, 50, 51, 1, 0, 38, 39, 1, 0, 63, 65, 2, 0, 63, 64, 71, 71, 419, 0, 67, 1, 0, 0, 0, 2, 73, 1, 0, 0, 0, 4, 78, 1, 0, 0, 0, 6, 80, 1, 0, 0, 0, 8, 85, 1, 0, 0, 0, 10, 89, 1, 0, 0, 0, 12, 91, 1, 0, 0, 0, 14, 103, 1, 0, 0, 0, 16, 115, 1, 0, 0, 0, 18, 131, 1, 0, 0, 0, 20, 143, 1, 0, 0, 0, 22, 153, 1, 0, 0, 0, 24, 155, 1, 0, 0, 0, 26, 167, 1, 0, 0, 0, 28, 176, 1, 0, 0, 0, 30, 181, 1, 0, 0, 0, 32, 193, 1, 0, 0, 0, 34, 203, 1, 0, 0, 0, 36, 212, 1, 0, 0, 0, 38, 214, 1, 0, 0, 0, 40, 222, 1, 0, 0, 0, 42, 226, 1, 0, 0, 0, 44, 230, 1, 0, 0, 0, 46, 232, 1, 0, 0, 0, 48, 248, 1, 0, 0, 0, 50, 251, 1, 0, 0, 0, 52, 316, 1, 0, 0, 0, 54, 373, 1, 0, 0, 0, 56, 380, 1, 0, 0, 0, 58, 382, 1, 0, 0, 0, 60, 386, 1, 0, 0, 0, 62, 388, 1, 0, 0, 0, 64, 66, 3, 2, 1, 0, 65, 64, 1, 0, 0, 0, 66, 69, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 70, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 70, 71, 3, 12, 6, 0, 71, 72, 5, 0, 0, 1, 72, 1, 1, 0, 0, 0, 73, 74, 5, 1, 0, 0, 74, 75, 3, 4, 2, 0, 75, 76, 3, 6, 3, 0, 76, 77, 5, 2, 0, 0, 77, 3, 1, 0, 0, 0, 78, 79, 5, 3, 0, 0, 79, 5, 1, 0, 0, 0, 80, 82, 3, 8, 4, 0, 81, 83, 3, 8, 4, 0, 82, 81, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 7, 1, 0, 0, 0, 84, 86, 3, 10, 5, 0, 85, 84, 1, 0, 0, 0, 85, 86, 1, 0, 0, 0, 86, 87, 1, 0, 0, 0, 87, 88, 5, 57, 0, 0, 88, 9, 1, 0, 0, 0, 89, 90, 7, 0, 0, 0, 90, 11, 1, 0, 0, 0, 91, 92, 5, 11, 0, 0, 92, 93, 5, 73, 0, 0, 93, 94, 3, 16, 8, 0, 94, 98, 5, 12, 0, 0, 95, 97, 3, 14, 7, 0, 96, 95, 1, 0, 0, 0, 97, 100, 1, 0, 0, 0, 98, 96, 1, 0, 0, 0, 98, 99, 1, 0, 0, 0, 99, 101, 1, 0, 0, 0, 100, 98, 1, 0, 0, 0, 101, 102, 5, 13, 0, 0, 102, 13, 1, 0, 0, 0, 103, 104, 5, 14, 0, 0, 104, 105, 5, 73, 0, 0, 105, 106, 3, 16, 8, 0, 106, 110, 5, 12, 0, 0, 107, 109, 3, 22, 11, 0, 108, 107, 1, 0, 0, 0, 109, 112, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 110, 111, 1, 0, 0, 0, 111, 113, 1, 0, 0, 0, 112, 110, 1, 0, 0, 0, 113, 114, 5, 13, 0, 0, 114, 15, 1, 0, 0, 0, 115, 127, 5, 15, 0, 0, 116, 121, 3, 18, 9, 0, 117, 118, 5, 16, 0, 0, 118, 120, 3, 18, 9, 0, 119, 117, 1, 0, 0, 0, 120, 123, 1, 0, 0, 0, 121, 119, 1, 0, 0, 0, 121, 122, 1, 0, 0, 0, 122, 125, 1, 0, 0, 0, 123, 121, 1, 0, 0, 0, 124, 126, 5, 16, 0, 0, 125, 124, 1, 0, 0, 0, 125, 126, 1, 0, 0, 0, 126, 128, 1, 0, 0, 0, 127, 116, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, 129, 1, 0, 0, 0, 129, 130, 5, 17, 0, 0, 130, 17, 1, 0, 0, 0, 131, 132, 3, 60, 30, 0, 132, 133, 5, 73, 0, 0, 133, 19, 1, 0, 0, 0, 134, 138, 5, 12, 0, 0, 135, 137, 3, 22, 11, 0, 136, 135, 1, 0, 0, 0, 137, 140, 1, 0, 0, 0, 138, 136, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 141, 1, 0, 0, 0, 140, 138, 1, 0, 0, 0, 141, 144, 5, 13, 0, 0, 142, 144, 3, 22, 11, 0, 143, 134, 1, 0, 0, 0, 143, 142, 1, 0, 0, 0, 144, 21, 1, 0, 0, 0, 145, 154, 3, 24, 12, 0, 146, 154, 3, 26, 13, 0, 147, 154, 3, 28, 14, 0, 148, 154, 3, 30, 15, 0, 149, 154, 3, 32, 16, 0, 150, 154, 3, 34, 17, 0, 151, 154, 3, 36, 18, 0, 152, 154, 3, 40, 20, 0, 153, 145, 1, 0, 0, 0, 153, 146, 1, 0, 0, 0, 153, 147, 1, 0, 0, 0, 153, 148, 1, 0, 0, 0, 153, 149, 1, 0, 0, 0, 153, 150, 1, 0, 0, 0, 153, 151, 1, 0, 0, 0, 153, 152, 1, 0, 0, 0, 154, 23, 1, 0, 0, 0, 155, 159, 3, 60, 30, 0, 156, 158, 3, 54, 27, 0, 157, 156, 1, 0, 0, 0, 158, 161, 1, 0, 0, 0, 159, 157, 1, 0, 0, 0, 159, 160, 1, 0, 0, 0, 160, 162, 1, 0, 0, 0, 161, 159, 1, 0, 0, 0, 162, 163, 5, 73, 0, 0, 163, 164, 5, 10, 0, 0, 164, 165, 3, 52, 26, 0, 165, 166, 5, 2, 0, 0, 166, 25, 1, 0, 0, 0, 167, 168, 3, 60, 30, 0, 168, 169, 5, 73, 0, 0, 169, 170, 5, 16, 0, 0, 170, 171, 3, 60, 30, 0, 171, 172, 5, 73, 0, 0, 172, 173, 5, 10, 0, 0, 173, 174, 3, 52, 26, 0, 174, 175, 5, 2, 0, 0, 175, 27, 1, 0, 0, 0, 176, 177, 5, 73, 0, 0, 177, 178, 5, 10, 0, 0, 178, 179, 3, 52, 26, 0, 179, 180, 5, 2, 0, 0, 180, 29, 1, 0, 0, 0, 181, 182, 5, 18, 0, 0, 182, 183, 5, 15, 0, 0, 183, 184, 5, 70, 0, 0, 184, 185, 5, 6, 0, 0, 185, 188, 3, 52, 26, 0, 186, 187, 5, 16, 0, 0, 187, 189, 3, 42, 21, 0, 188, 186, 1, 0, 0, 0, 188, 189, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 191, 5, 17, 0, 0, 191, 192, 5, 2, 0, 0, 192, 31, 1, 0, 0, 0, 193, 194, 5, 18, 0, 0, 194, 195, 5, 15, 0, 0, 195, 198, 3, 52, 26, 0, 196, 197, 5, 16, 0, 0, 197, 199, 3, 42, 21, 0, 198, 196, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 201, 5, 17, 0, 0, 201, 202, 5, 2, 0, 0, 202, 33, 1, 0, 0, 0, 203, 204, 5, 19, 0, 0, 204, 205, 5, 15, 0, 0, 205, 206, 3, 52, 26, 0, 206, 207, 5, 17, 0, 0, 207, 210, 3, 20, 10, 0, 208, 209, 5, 20, 0, 0, 209, 211, 3, 20, 10, 0, 210, 208, 1, 0, 0, 0, 210, 211, 1, 0, 0, 0, 211, 35, 1, 0, 0, 0, 212, 213, 3, 38, 19, 0, 213, 37, 1, 0, 0, 0, 214, 215, 5, 21, 0, 0, 215, 216, 3, 20, 10, 0, 216, 217, 5, 22, 0, 0, 217, 218, 5, 15, 0, 0, 218, 219, 3, 52, 26, 0, 219, 220, 5, 17, 0, 0, 220, 221, 5, 2, 0, 0, 221, 39, 1, 0, 0, 0, 222, 223, 5, 23, 0, 0, 223, 224, 3, 46, 23, 0, 224, 225, 5, 2, 0, 0, 225, 41, 1, 0, 0, 0, 226, 227, 5, 67, 0, 0, 227, 43, 1, 0, 0, 0, 228, 231, 5, 73, 0, 0, 229, 231, 3, 56, 28, 0, 230, 228, 1, 0, 0, 0, 230, 229, 1, 0, 0, 0, 231, 45, 1, 0, 0, 0, 232, 244, 5, 15, 0, 0, 233, 238, 3, 44, 22, 0, 234, 235, 5, 16, 0, 0, 235, 237, 3, 44, 22, 0, 236, 234, 1, 0, 0, 0, 237, 240, 1, 0, 0, 0, 238, 236, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 242, 1, 0, 0, 0, 240, 238, 1, 0, 0, 0, 241, 243, 5, 16, 0, 0, 242, 241, 1, 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 245, 1, 0, 0, 0, 244, 233, 1, 0, 0, 0, 244, 245, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, 5, 17, 0, 0, 247, 47, 1, 0, 0, 0, 248, 249, 5, 73, 0, 0, 249, 250, 3, 50, 25, 0, 250, 49, 1, 0, 0, 0, 251, 263, 5, 15, 0, 0, 252, 257, 3, 52, 26, 0, 253, 254, 5, 16, 0, 0, 254, 256, 3, 52, 26, 0, 255, 253, 1, 0, 0, 0, 256, 259, 1, 0, 0, 0, 257, 255, 1, 0, 0, 0, 257, 258, 1, 0, 0, 0, 258, 261, 1, 0, 0, 0, 259, 257, 1, 0, 0, 0, 260, 262, 5, 16, 0, 0, 261, 260, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 264, 1, 0, 0, 0, 263, 252, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 265, 1, 0, 0, 0, 265, 266, 5, 17, 0, 0, 266, 51, 1, 0, 0, 0, 267, 268, 6, 26, -1, 0, 268, 269, 5, 15, 0, 0, 269, 270, 3, 52, 26, 0, 270, 271, 5, 17, 0, 0, 271, 317, 1, 0, 0, 0, 272, 273, 3, 62, 31, 0, 273, 274, 5, 15, 0, 0, 274, 276, 3, 52, 26, 0, 275, 277, 5, 16, 0, 0, 276, 275, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 279, 5, 17, 0, 0, 279, 317, 1, 0, 0, 0, 280, 317, 3, 48, 24, 0, 281, 282, 5, 24, 0, 0, 282, 283, 5, 73, 0, 0, 283, 317, 3, 50, 25, 0, 284, 285, 5, 27, 0, 0, 285, 286, 5, 25, 0, 0, 286, 287, 3, 52, 26, 0, 287, 288, 5, 26, 0, 0, 288, 289, 7, 1, 0, 0, 289, 317, 1, 0, 0, 0, 290, 291, 5, 33, 0, 0, 291, 292, 5, 25, 0, 0, 292, 293, 3, 52, 26, 0, 293, 294, 5, 26, 0, 0, 294, 295, 7, 2, 0, 0, 295, 317, 1, 0, 0, 0, 296, 297, 7, 3, 0, 0, 297, 317, 3, 52, 26, 15, 298, 310, 5, 25, 0, 0, 299, 304, 3, 52, 26, 0, 300, 301, 5, 16, 0, 0, 301, 303, 3, 52, 26, 0, 302, 300, 1, 0, 0, 0, 303, 306, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 308, 1, 0, 0, 0, 306, 304, 1, 0, 0, 0, 307, 309, 5, 16, 0, 0, 308, 307, 1, 0, 0, 0, 308, 309, 1, 0, 0, 0, 309, 311, 1, 0, 0, 0, 310, 299, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 312, 1, 0, 0, 0, 312, 317, 5, 26, 0, 0, 313, 317, 5, 72, 0, 0, 314, 317, 5, 73, 0, 0, 315, 317, 3, 56, 28, 0, 316, 267, 1, 0, 0, 0, 316, 272, 1, 0, 0, 0, 316, 280, 1, 0, 0, 0, 316, 281, 1, 0, 0, 0, 316, 284, 1, 0, 0, 0, 316, 290, 1, 0, 0, 0, 316, 296, 1, 0, 0, 0, 316, 298, 1, 0, 0, 0, 316, 313, 1, 0, 0, 0, 316, 314, 1, 0, 0, 0, 316, 315, 1, 0, 0, 0, 317, 370, 1, 0, 0, 0, 318, 319, 10, 14, 0, 0, 319, 320, 7, 4, 0, 0, 320, 369, 3, 52, 26, 15, 321, 322, 10, 13, 0, 0, 322, 323, 7, 5, 0, 0, 323, 369, 3, 52, 26, 14, 324, 325, 10, 12, 0, 0, 325, 326, 7, 6, 0, 0, 326, 369, 3, 52, 26, 13, 327, 328, 10, 11, 0, 0, 328, 329, 7, 7, 0, 0, 329, 369, 3, 52, 26, 12, 330, 331, 10, 10, 0, 0, 331, 332, 7, 8, 0, 0, 332, 369, 3, 52, 26, 11, 333, 334, 10, 9, 0, 0, 334, 335, 5, 52, 0, 0, 335, 369, 3, 52, 26, 10, 336, 337, 10, 8, 0, 0, 337, 338, 5, 4, 0, 0, 338, 369, 3, 52, 26, 9, 339, 340, 10, 7, 0, 0, 340, 341, 5, 53, 0, 0, 341, 369, 3, 52, 26, 8, 342, 343, 10, 6, 0, 0, 343, 344, 5, 54, 0, 0, 344, 369, 3, 52, 26, 7, 345, 346, 10, 5, 0, 0, 346, 347, 5, 55, 0, 0, 347, 369, 3, 52, 26, 6, 348, 349, 10, 21, 0, 0, 349, 350, 5, 25, 0, 0, 350, 351, 5, 60, 0, 0, 351, 369, 5, 26, 0, 0, 352, 353, 10, 18, 0, 0, 353, 369, 7, 9, 0, 0, 354, 355, 10, 17, 0, 0, 355, 356, 5, 40, 0, 0, 356, 357, 5, 15, 0, 0, 357, 358, 3, 52, 26, 0, 358, 359, 5, 17, 0, 0, 359, 369, 1, 0, 0, 0, 360, 361, 10, 16, 0, 0, 361, 362, 5, 41, 0, 0, 362, 363, 5, 15, 0, 0, 363, 364, 3, 52, 26, 0, 364, 365, 5, 16, 0, 0, 365, 366, 3, 52, 26, 0, 366, 367, 5, 17, 0, 0, 367, 369, 1, 0, 0, 0, 368, 318, 1, 0, 0, 0, 368, 321, 1, 0, 0, 0, 368, 324, 1, 0, 0, 0, 368, 327, 1, 0, 0, 0, 368, 330, 1, 0, 0, 0, 368, 333, 1, 0, 0, 0, 368, 336, 1, 0, 0, 0, 368, 339, 1, 0, 0, 0, 368, 342, 1, 0, 0, 0, 368, 345, 1, 0, 0, 0, 368, 348, 1, 0, 0, 0, 368, 352, 1, 0, 0, 0, 368, 354, 1, 0, 0, 0, 368, 360, 1, 0, 0, 0, 369, 372, 1, 0, 0, 0, 370, 368, 1, 0, 0, 0, 370, 371, 1, 0, 0, 0, 371, 53, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 373, 374, 5, 56, 0, 0, 374, 55, 1, 0, 0, 0, 375, 381, 5, 58, 0, 0, 376, 381, 3, 58, 29, 0, 377, 381, 5, 67, 0, 0, 378, 381, 5, 68, 0, 0, 379, 381, 5, 69, 0, 0, 380, 375, 1, 0, 0, 0, 380, 376, 1, 0, 0, 0, 380, 377, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 380, 379, 1, 0, 0, 0, 381, 57, 1, 0, 0, 0, 382, 384, 5, 60, 0, 0, 383, 385, 5, 59, 0, 0, 384, 383, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 59, 1, 0, 0, 0, 386, 387, 7, 10, 0, 0, 387, 61, 1, 0, 0, 0, 388, 389, 7, 11, 0, 0, 389, 63, 1, 0, 0, 0, 31, 67, 82, 85, 98, 110, 121, 125, 127, 138, 143, 153, 159, 188, 198, 210, 230, 238, 242, 244, 257, 261, 263, 276, 304, 308, 310, 316, 368, 370, 380, 384] \ No newline at end of file diff --git a/packages/cashc/src/grammar/CashScript.tokens b/packages/cashc/src/grammar/CashScript.tokens index 4e0173da..e3e7d443 100644 --- a/packages/cashc/src/grammar/CashScript.tokens +++ b/packages/cashc/src/grammar/CashScript.tokens @@ -54,25 +54,26 @@ T__52=53 T__53=54 T__54=55 T__55=56 -T__56=57 -T__57=58 -VersionLiteral=59 -BooleanLiteral=60 -NumberUnit=61 -NumberLiteral=62 -NumberPart=63 -ExponentPart=64 -Bytes=65 +VersionLiteral=57 +BooleanLiteral=58 +NumberUnit=59 +NumberLiteral=60 +NumberPart=61 +ExponentPart=62 +PrimitiveType=63 +UnboundedBytes=64 +BoundedBytes=65 Bound=66 StringLiteral=67 DateLiteral=68 HexLiteral=69 TxVar=70 -NullaryOp=71 -Identifier=72 -WHITESPACE=73 -COMMENT=74 -LINE_COMMENT=75 +UnsafeCast=71 +NullaryOp=72 +Identifier=73 +WHITESPACE=74 +COMMENT=75 +LINE_COMMENT=76 'pragma'=1 ';'=2 'cashscript'=3 @@ -93,41 +94,40 @@ LINE_COMMENT=75 'require'=18 'if'=19 'else'=20 -'console.log'=21 -'new'=22 -'['=23 -']'=24 -'tx.outputs'=25 -'.value'=26 -'.lockingBytecode'=27 -'.tokenCategory'=28 -'.nftCommitment'=29 -'.tokenAmount'=30 -'tx.inputs'=31 -'.outpointTransactionHash'=32 -'.outpointIndex'=33 -'.unlockingBytecode'=34 -'.sequenceNumber'=35 -'.reverse()'=36 -'.length'=37 -'.split'=38 -'.slice'=39 -'!'=40 -'-'=41 -'*'=42 -'/'=43 -'%'=44 -'+'=45 -'=='=46 -'!='=47 -'&'=48 -'|'=49 -'&&'=50 -'||'=51 -'constant'=52 -'int'=53 -'bool'=54 -'string'=55 -'pubkey'=56 -'sig'=57 -'datasig'=58 +'do'=21 +'while'=22 +'console.log'=23 +'new'=24 +'['=25 +']'=26 +'tx.outputs'=27 +'.value'=28 +'.lockingBytecode'=29 +'.tokenCategory'=30 +'.nftCommitment'=31 +'.tokenAmount'=32 +'tx.inputs'=33 +'.outpointTransactionHash'=34 +'.outpointIndex'=35 +'.unlockingBytecode'=36 +'.sequenceNumber'=37 +'.reverse()'=38 +'.length'=39 +'.split'=40 +'.slice'=41 +'!'=42 +'-'=43 +'*'=44 +'/'=45 +'%'=46 +'+'=47 +'>>'=48 +'<<'=49 +'=='=50 +'!='=51 +'&'=52 +'|'=53 +'&&'=54 +'||'=55 +'constant'=56 +'bytes'=64 diff --git a/packages/cashc/src/grammar/CashScriptLexer.interp b/packages/cashc/src/grammar/CashScriptLexer.interp index a4c165f2..d618bea7 100644 --- a/packages/cashc/src/grammar/CashScriptLexer.interp +++ b/packages/cashc/src/grammar/CashScriptLexer.interp @@ -20,6 +20,8 @@ null 'require' 'if' 'else' +'do' +'while' 'console.log' 'new' '[' @@ -45,6 +47,8 @@ null '/' '%' '+' +'>>' +'<<' '==' '!=' '&' @@ -52,12 +56,6 @@ null '&&' '||' 'constant' -'int' -'bool' -'string' -'pubkey' -'sig' -'datasig' null null null @@ -65,6 +63,7 @@ null null null null +'bytes' null null null @@ -75,10 +74,10 @@ null null null null - -token symbolic names: null null + +token symbolic names: null null null @@ -142,12 +141,15 @@ NumberUnit NumberLiteral NumberPart ExponentPart -Bytes +PrimitiveType +UnboundedBytes +BoundedBytes Bound StringLiteral DateLiteral HexLiteral TxVar +UnsafeCast NullaryOp Identifier WHITESPACE @@ -211,20 +213,21 @@ T__52 T__53 T__54 T__55 -T__56 -T__57 VersionLiteral BooleanLiteral NumberUnit NumberLiteral NumberPart ExponentPart -Bytes +PrimitiveType +UnboundedBytes +BoundedBytes Bound StringLiteral DateLiteral HexLiteral TxVar +UnsafeCast NullaryOp Identifier WHITESPACE @@ -239,4 +242,4 @@ mode names: DEFAULT_MODE atn: -[4, 0, 75, 845, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 4, 58, 521, 8, 58, 11, 58, 12, 58, 522, 1, 58, 1, 58, 4, 58, 527, 8, 58, 11, 58, 12, 58, 528, 1, 58, 1, 58, 4, 58, 533, 8, 58, 11, 58, 12, 58, 534, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 3, 59, 546, 8, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 3, 60, 605, 8, 60, 1, 61, 3, 61, 608, 8, 61, 1, 61, 1, 61, 3, 61, 612, 8, 61, 1, 62, 4, 62, 615, 8, 62, 11, 62, 12, 62, 616, 1, 62, 1, 62, 4, 62, 621, 8, 62, 11, 62, 12, 62, 622, 5, 62, 625, 8, 62, 10, 62, 12, 62, 628, 9, 62, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 3, 64, 640, 8, 64, 1, 64, 1, 64, 1, 64, 1, 64, 3, 64, 646, 8, 64, 1, 65, 1, 65, 5, 65, 650, 8, 65, 10, 65, 12, 65, 653, 9, 65, 1, 66, 1, 66, 1, 66, 1, 66, 5, 66, 659, 8, 66, 10, 66, 12, 66, 662, 9, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 5, 66, 669, 8, 66, 10, 66, 12, 66, 672, 9, 66, 1, 66, 3, 66, 675, 8, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 5, 68, 689, 8, 68, 10, 68, 12, 68, 692, 9, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 3, 69, 709, 8, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 805, 8, 70, 1, 71, 1, 71, 5, 71, 809, 8, 71, 10, 71, 12, 71, 812, 9, 71, 1, 72, 4, 72, 815, 8, 72, 11, 72, 12, 72, 816, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 5, 73, 825, 8, 73, 10, 73, 12, 73, 828, 9, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 5, 74, 839, 8, 74, 10, 74, 12, 74, 842, 9, 74, 1, 74, 1, 74, 3, 660, 670, 826, 0, 75, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 67, 135, 68, 137, 69, 139, 70, 141, 71, 143, 72, 145, 73, 147, 74, 149, 75, 1, 0, 11, 1, 0, 48, 57, 2, 0, 69, 69, 101, 101, 1, 0, 49, 57, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, 39, 2, 0, 88, 88, 120, 120, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 3, 0, 9, 10, 12, 13, 32, 32, 2, 0, 10, 10, 13, 13, 881, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133, 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, 1, 0, 0, 0, 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, 0, 147, 1, 0, 0, 0, 0, 149, 1, 0, 0, 0, 1, 151, 1, 0, 0, 0, 3, 158, 1, 0, 0, 0, 5, 160, 1, 0, 0, 0, 7, 171, 1, 0, 0, 0, 9, 173, 1, 0, 0, 0, 11, 175, 1, 0, 0, 0, 13, 178, 1, 0, 0, 0, 15, 180, 1, 0, 0, 0, 17, 182, 1, 0, 0, 0, 19, 185, 1, 0, 0, 0, 21, 187, 1, 0, 0, 0, 23, 196, 1, 0, 0, 0, 25, 198, 1, 0, 0, 0, 27, 200, 1, 0, 0, 0, 29, 209, 1, 0, 0, 0, 31, 211, 1, 0, 0, 0, 33, 213, 1, 0, 0, 0, 35, 215, 1, 0, 0, 0, 37, 223, 1, 0, 0, 0, 39, 226, 1, 0, 0, 0, 41, 231, 1, 0, 0, 0, 43, 243, 1, 0, 0, 0, 45, 247, 1, 0, 0, 0, 47, 249, 1, 0, 0, 0, 49, 251, 1, 0, 0, 0, 51, 262, 1, 0, 0, 0, 53, 269, 1, 0, 0, 0, 55, 286, 1, 0, 0, 0, 57, 301, 1, 0, 0, 0, 59, 316, 1, 0, 0, 0, 61, 329, 1, 0, 0, 0, 63, 339, 1, 0, 0, 0, 65, 364, 1, 0, 0, 0, 67, 379, 1, 0, 0, 0, 69, 398, 1, 0, 0, 0, 71, 414, 1, 0, 0, 0, 73, 425, 1, 0, 0, 0, 75, 433, 1, 0, 0, 0, 77, 440, 1, 0, 0, 0, 79, 447, 1, 0, 0, 0, 81, 449, 1, 0, 0, 0, 83, 451, 1, 0, 0, 0, 85, 453, 1, 0, 0, 0, 87, 455, 1, 0, 0, 0, 89, 457, 1, 0, 0, 0, 91, 459, 1, 0, 0, 0, 93, 462, 1, 0, 0, 0, 95, 465, 1, 0, 0, 0, 97, 467, 1, 0, 0, 0, 99, 469, 1, 0, 0, 0, 101, 472, 1, 0, 0, 0, 103, 475, 1, 0, 0, 0, 105, 484, 1, 0, 0, 0, 107, 488, 1, 0, 0, 0, 109, 493, 1, 0, 0, 0, 111, 500, 1, 0, 0, 0, 113, 507, 1, 0, 0, 0, 115, 511, 1, 0, 0, 0, 117, 520, 1, 0, 0, 0, 119, 545, 1, 0, 0, 0, 121, 604, 1, 0, 0, 0, 123, 607, 1, 0, 0, 0, 125, 614, 1, 0, 0, 0, 127, 629, 1, 0, 0, 0, 129, 645, 1, 0, 0, 0, 131, 647, 1, 0, 0, 0, 133, 674, 1, 0, 0, 0, 135, 676, 1, 0, 0, 0, 137, 685, 1, 0, 0, 0, 139, 708, 1, 0, 0, 0, 141, 804, 1, 0, 0, 0, 143, 806, 1, 0, 0, 0, 145, 814, 1, 0, 0, 0, 147, 820, 1, 0, 0, 0, 149, 834, 1, 0, 0, 0, 151, 152, 5, 112, 0, 0, 152, 153, 5, 114, 0, 0, 153, 154, 5, 97, 0, 0, 154, 155, 5, 103, 0, 0, 155, 156, 5, 109, 0, 0, 156, 157, 5, 97, 0, 0, 157, 2, 1, 0, 0, 0, 158, 159, 5, 59, 0, 0, 159, 4, 1, 0, 0, 0, 160, 161, 5, 99, 0, 0, 161, 162, 5, 97, 0, 0, 162, 163, 5, 115, 0, 0, 163, 164, 5, 104, 0, 0, 164, 165, 5, 115, 0, 0, 165, 166, 5, 99, 0, 0, 166, 167, 5, 114, 0, 0, 167, 168, 5, 105, 0, 0, 168, 169, 5, 112, 0, 0, 169, 170, 5, 116, 0, 0, 170, 6, 1, 0, 0, 0, 171, 172, 5, 94, 0, 0, 172, 8, 1, 0, 0, 0, 173, 174, 5, 126, 0, 0, 174, 10, 1, 0, 0, 0, 175, 176, 5, 62, 0, 0, 176, 177, 5, 61, 0, 0, 177, 12, 1, 0, 0, 0, 178, 179, 5, 62, 0, 0, 179, 14, 1, 0, 0, 0, 180, 181, 5, 60, 0, 0, 181, 16, 1, 0, 0, 0, 182, 183, 5, 60, 0, 0, 183, 184, 5, 61, 0, 0, 184, 18, 1, 0, 0, 0, 185, 186, 5, 61, 0, 0, 186, 20, 1, 0, 0, 0, 187, 188, 5, 99, 0, 0, 188, 189, 5, 111, 0, 0, 189, 190, 5, 110, 0, 0, 190, 191, 5, 116, 0, 0, 191, 192, 5, 114, 0, 0, 192, 193, 5, 97, 0, 0, 193, 194, 5, 99, 0, 0, 194, 195, 5, 116, 0, 0, 195, 22, 1, 0, 0, 0, 196, 197, 5, 123, 0, 0, 197, 24, 1, 0, 0, 0, 198, 199, 5, 125, 0, 0, 199, 26, 1, 0, 0, 0, 200, 201, 5, 102, 0, 0, 201, 202, 5, 117, 0, 0, 202, 203, 5, 110, 0, 0, 203, 204, 5, 99, 0, 0, 204, 205, 5, 116, 0, 0, 205, 206, 5, 105, 0, 0, 206, 207, 5, 111, 0, 0, 207, 208, 5, 110, 0, 0, 208, 28, 1, 0, 0, 0, 209, 210, 5, 40, 0, 0, 210, 30, 1, 0, 0, 0, 211, 212, 5, 44, 0, 0, 212, 32, 1, 0, 0, 0, 213, 214, 5, 41, 0, 0, 214, 34, 1, 0, 0, 0, 215, 216, 5, 114, 0, 0, 216, 217, 5, 101, 0, 0, 217, 218, 5, 113, 0, 0, 218, 219, 5, 117, 0, 0, 219, 220, 5, 105, 0, 0, 220, 221, 5, 114, 0, 0, 221, 222, 5, 101, 0, 0, 222, 36, 1, 0, 0, 0, 223, 224, 5, 105, 0, 0, 224, 225, 5, 102, 0, 0, 225, 38, 1, 0, 0, 0, 226, 227, 5, 101, 0, 0, 227, 228, 5, 108, 0, 0, 228, 229, 5, 115, 0, 0, 229, 230, 5, 101, 0, 0, 230, 40, 1, 0, 0, 0, 231, 232, 5, 99, 0, 0, 232, 233, 5, 111, 0, 0, 233, 234, 5, 110, 0, 0, 234, 235, 5, 115, 0, 0, 235, 236, 5, 111, 0, 0, 236, 237, 5, 108, 0, 0, 237, 238, 5, 101, 0, 0, 238, 239, 5, 46, 0, 0, 239, 240, 5, 108, 0, 0, 240, 241, 5, 111, 0, 0, 241, 242, 5, 103, 0, 0, 242, 42, 1, 0, 0, 0, 243, 244, 5, 110, 0, 0, 244, 245, 5, 101, 0, 0, 245, 246, 5, 119, 0, 0, 246, 44, 1, 0, 0, 0, 247, 248, 5, 91, 0, 0, 248, 46, 1, 0, 0, 0, 249, 250, 5, 93, 0, 0, 250, 48, 1, 0, 0, 0, 251, 252, 5, 116, 0, 0, 252, 253, 5, 120, 0, 0, 253, 254, 5, 46, 0, 0, 254, 255, 5, 111, 0, 0, 255, 256, 5, 117, 0, 0, 256, 257, 5, 116, 0, 0, 257, 258, 5, 112, 0, 0, 258, 259, 5, 117, 0, 0, 259, 260, 5, 116, 0, 0, 260, 261, 5, 115, 0, 0, 261, 50, 1, 0, 0, 0, 262, 263, 5, 46, 0, 0, 263, 264, 5, 118, 0, 0, 264, 265, 5, 97, 0, 0, 265, 266, 5, 108, 0, 0, 266, 267, 5, 117, 0, 0, 267, 268, 5, 101, 0, 0, 268, 52, 1, 0, 0, 0, 269, 270, 5, 46, 0, 0, 270, 271, 5, 108, 0, 0, 271, 272, 5, 111, 0, 0, 272, 273, 5, 99, 0, 0, 273, 274, 5, 107, 0, 0, 274, 275, 5, 105, 0, 0, 275, 276, 5, 110, 0, 0, 276, 277, 5, 103, 0, 0, 277, 278, 5, 66, 0, 0, 278, 279, 5, 121, 0, 0, 279, 280, 5, 116, 0, 0, 280, 281, 5, 101, 0, 0, 281, 282, 5, 99, 0, 0, 282, 283, 5, 111, 0, 0, 283, 284, 5, 100, 0, 0, 284, 285, 5, 101, 0, 0, 285, 54, 1, 0, 0, 0, 286, 287, 5, 46, 0, 0, 287, 288, 5, 116, 0, 0, 288, 289, 5, 111, 0, 0, 289, 290, 5, 107, 0, 0, 290, 291, 5, 101, 0, 0, 291, 292, 5, 110, 0, 0, 292, 293, 5, 67, 0, 0, 293, 294, 5, 97, 0, 0, 294, 295, 5, 116, 0, 0, 295, 296, 5, 101, 0, 0, 296, 297, 5, 103, 0, 0, 297, 298, 5, 111, 0, 0, 298, 299, 5, 114, 0, 0, 299, 300, 5, 121, 0, 0, 300, 56, 1, 0, 0, 0, 301, 302, 5, 46, 0, 0, 302, 303, 5, 110, 0, 0, 303, 304, 5, 102, 0, 0, 304, 305, 5, 116, 0, 0, 305, 306, 5, 67, 0, 0, 306, 307, 5, 111, 0, 0, 307, 308, 5, 109, 0, 0, 308, 309, 5, 109, 0, 0, 309, 310, 5, 105, 0, 0, 310, 311, 5, 116, 0, 0, 311, 312, 5, 109, 0, 0, 312, 313, 5, 101, 0, 0, 313, 314, 5, 110, 0, 0, 314, 315, 5, 116, 0, 0, 315, 58, 1, 0, 0, 0, 316, 317, 5, 46, 0, 0, 317, 318, 5, 116, 0, 0, 318, 319, 5, 111, 0, 0, 319, 320, 5, 107, 0, 0, 320, 321, 5, 101, 0, 0, 321, 322, 5, 110, 0, 0, 322, 323, 5, 65, 0, 0, 323, 324, 5, 109, 0, 0, 324, 325, 5, 111, 0, 0, 325, 326, 5, 117, 0, 0, 326, 327, 5, 110, 0, 0, 327, 328, 5, 116, 0, 0, 328, 60, 1, 0, 0, 0, 329, 330, 5, 116, 0, 0, 330, 331, 5, 120, 0, 0, 331, 332, 5, 46, 0, 0, 332, 333, 5, 105, 0, 0, 333, 334, 5, 110, 0, 0, 334, 335, 5, 112, 0, 0, 335, 336, 5, 117, 0, 0, 336, 337, 5, 116, 0, 0, 337, 338, 5, 115, 0, 0, 338, 62, 1, 0, 0, 0, 339, 340, 5, 46, 0, 0, 340, 341, 5, 111, 0, 0, 341, 342, 5, 117, 0, 0, 342, 343, 5, 116, 0, 0, 343, 344, 5, 112, 0, 0, 344, 345, 5, 111, 0, 0, 345, 346, 5, 105, 0, 0, 346, 347, 5, 110, 0, 0, 347, 348, 5, 116, 0, 0, 348, 349, 5, 84, 0, 0, 349, 350, 5, 114, 0, 0, 350, 351, 5, 97, 0, 0, 351, 352, 5, 110, 0, 0, 352, 353, 5, 115, 0, 0, 353, 354, 5, 97, 0, 0, 354, 355, 5, 99, 0, 0, 355, 356, 5, 116, 0, 0, 356, 357, 5, 105, 0, 0, 357, 358, 5, 111, 0, 0, 358, 359, 5, 110, 0, 0, 359, 360, 5, 72, 0, 0, 360, 361, 5, 97, 0, 0, 361, 362, 5, 115, 0, 0, 362, 363, 5, 104, 0, 0, 363, 64, 1, 0, 0, 0, 364, 365, 5, 46, 0, 0, 365, 366, 5, 111, 0, 0, 366, 367, 5, 117, 0, 0, 367, 368, 5, 116, 0, 0, 368, 369, 5, 112, 0, 0, 369, 370, 5, 111, 0, 0, 370, 371, 5, 105, 0, 0, 371, 372, 5, 110, 0, 0, 372, 373, 5, 116, 0, 0, 373, 374, 5, 73, 0, 0, 374, 375, 5, 110, 0, 0, 375, 376, 5, 100, 0, 0, 376, 377, 5, 101, 0, 0, 377, 378, 5, 120, 0, 0, 378, 66, 1, 0, 0, 0, 379, 380, 5, 46, 0, 0, 380, 381, 5, 117, 0, 0, 381, 382, 5, 110, 0, 0, 382, 383, 5, 108, 0, 0, 383, 384, 5, 111, 0, 0, 384, 385, 5, 99, 0, 0, 385, 386, 5, 107, 0, 0, 386, 387, 5, 105, 0, 0, 387, 388, 5, 110, 0, 0, 388, 389, 5, 103, 0, 0, 389, 390, 5, 66, 0, 0, 390, 391, 5, 121, 0, 0, 391, 392, 5, 116, 0, 0, 392, 393, 5, 101, 0, 0, 393, 394, 5, 99, 0, 0, 394, 395, 5, 111, 0, 0, 395, 396, 5, 100, 0, 0, 396, 397, 5, 101, 0, 0, 397, 68, 1, 0, 0, 0, 398, 399, 5, 46, 0, 0, 399, 400, 5, 115, 0, 0, 400, 401, 5, 101, 0, 0, 401, 402, 5, 113, 0, 0, 402, 403, 5, 117, 0, 0, 403, 404, 5, 101, 0, 0, 404, 405, 5, 110, 0, 0, 405, 406, 5, 99, 0, 0, 406, 407, 5, 101, 0, 0, 407, 408, 5, 78, 0, 0, 408, 409, 5, 117, 0, 0, 409, 410, 5, 109, 0, 0, 410, 411, 5, 98, 0, 0, 411, 412, 5, 101, 0, 0, 412, 413, 5, 114, 0, 0, 413, 70, 1, 0, 0, 0, 414, 415, 5, 46, 0, 0, 415, 416, 5, 114, 0, 0, 416, 417, 5, 101, 0, 0, 417, 418, 5, 118, 0, 0, 418, 419, 5, 101, 0, 0, 419, 420, 5, 114, 0, 0, 420, 421, 5, 115, 0, 0, 421, 422, 5, 101, 0, 0, 422, 423, 5, 40, 0, 0, 423, 424, 5, 41, 0, 0, 424, 72, 1, 0, 0, 0, 425, 426, 5, 46, 0, 0, 426, 427, 5, 108, 0, 0, 427, 428, 5, 101, 0, 0, 428, 429, 5, 110, 0, 0, 429, 430, 5, 103, 0, 0, 430, 431, 5, 116, 0, 0, 431, 432, 5, 104, 0, 0, 432, 74, 1, 0, 0, 0, 433, 434, 5, 46, 0, 0, 434, 435, 5, 115, 0, 0, 435, 436, 5, 112, 0, 0, 436, 437, 5, 108, 0, 0, 437, 438, 5, 105, 0, 0, 438, 439, 5, 116, 0, 0, 439, 76, 1, 0, 0, 0, 440, 441, 5, 46, 0, 0, 441, 442, 5, 115, 0, 0, 442, 443, 5, 108, 0, 0, 443, 444, 5, 105, 0, 0, 444, 445, 5, 99, 0, 0, 445, 446, 5, 101, 0, 0, 446, 78, 1, 0, 0, 0, 447, 448, 5, 33, 0, 0, 448, 80, 1, 0, 0, 0, 449, 450, 5, 45, 0, 0, 450, 82, 1, 0, 0, 0, 451, 452, 5, 42, 0, 0, 452, 84, 1, 0, 0, 0, 453, 454, 5, 47, 0, 0, 454, 86, 1, 0, 0, 0, 455, 456, 5, 37, 0, 0, 456, 88, 1, 0, 0, 0, 457, 458, 5, 43, 0, 0, 458, 90, 1, 0, 0, 0, 459, 460, 5, 61, 0, 0, 460, 461, 5, 61, 0, 0, 461, 92, 1, 0, 0, 0, 462, 463, 5, 33, 0, 0, 463, 464, 5, 61, 0, 0, 464, 94, 1, 0, 0, 0, 465, 466, 5, 38, 0, 0, 466, 96, 1, 0, 0, 0, 467, 468, 5, 124, 0, 0, 468, 98, 1, 0, 0, 0, 469, 470, 5, 38, 0, 0, 470, 471, 5, 38, 0, 0, 471, 100, 1, 0, 0, 0, 472, 473, 5, 124, 0, 0, 473, 474, 5, 124, 0, 0, 474, 102, 1, 0, 0, 0, 475, 476, 5, 99, 0, 0, 476, 477, 5, 111, 0, 0, 477, 478, 5, 110, 0, 0, 478, 479, 5, 115, 0, 0, 479, 480, 5, 116, 0, 0, 480, 481, 5, 97, 0, 0, 481, 482, 5, 110, 0, 0, 482, 483, 5, 116, 0, 0, 483, 104, 1, 0, 0, 0, 484, 485, 5, 105, 0, 0, 485, 486, 5, 110, 0, 0, 486, 487, 5, 116, 0, 0, 487, 106, 1, 0, 0, 0, 488, 489, 5, 98, 0, 0, 489, 490, 5, 111, 0, 0, 490, 491, 5, 111, 0, 0, 491, 492, 5, 108, 0, 0, 492, 108, 1, 0, 0, 0, 493, 494, 5, 115, 0, 0, 494, 495, 5, 116, 0, 0, 495, 496, 5, 114, 0, 0, 496, 497, 5, 105, 0, 0, 497, 498, 5, 110, 0, 0, 498, 499, 5, 103, 0, 0, 499, 110, 1, 0, 0, 0, 500, 501, 5, 112, 0, 0, 501, 502, 5, 117, 0, 0, 502, 503, 5, 98, 0, 0, 503, 504, 5, 107, 0, 0, 504, 505, 5, 101, 0, 0, 505, 506, 5, 121, 0, 0, 506, 112, 1, 0, 0, 0, 507, 508, 5, 115, 0, 0, 508, 509, 5, 105, 0, 0, 509, 510, 5, 103, 0, 0, 510, 114, 1, 0, 0, 0, 511, 512, 5, 100, 0, 0, 512, 513, 5, 97, 0, 0, 513, 514, 5, 116, 0, 0, 514, 515, 5, 97, 0, 0, 515, 516, 5, 115, 0, 0, 516, 517, 5, 105, 0, 0, 517, 518, 5, 103, 0, 0, 518, 116, 1, 0, 0, 0, 519, 521, 7, 0, 0, 0, 520, 519, 1, 0, 0, 0, 521, 522, 1, 0, 0, 0, 522, 520, 1, 0, 0, 0, 522, 523, 1, 0, 0, 0, 523, 524, 1, 0, 0, 0, 524, 526, 5, 46, 0, 0, 525, 527, 7, 0, 0, 0, 526, 525, 1, 0, 0, 0, 527, 528, 1, 0, 0, 0, 528, 526, 1, 0, 0, 0, 528, 529, 1, 0, 0, 0, 529, 530, 1, 0, 0, 0, 530, 532, 5, 46, 0, 0, 531, 533, 7, 0, 0, 0, 532, 531, 1, 0, 0, 0, 533, 534, 1, 0, 0, 0, 534, 532, 1, 0, 0, 0, 534, 535, 1, 0, 0, 0, 535, 118, 1, 0, 0, 0, 536, 537, 5, 116, 0, 0, 537, 538, 5, 114, 0, 0, 538, 539, 5, 117, 0, 0, 539, 546, 5, 101, 0, 0, 540, 541, 5, 102, 0, 0, 541, 542, 5, 97, 0, 0, 542, 543, 5, 108, 0, 0, 543, 544, 5, 115, 0, 0, 544, 546, 5, 101, 0, 0, 545, 536, 1, 0, 0, 0, 545, 540, 1, 0, 0, 0, 546, 120, 1, 0, 0, 0, 547, 548, 5, 115, 0, 0, 548, 549, 5, 97, 0, 0, 549, 550, 5, 116, 0, 0, 550, 551, 5, 111, 0, 0, 551, 552, 5, 115, 0, 0, 552, 553, 5, 104, 0, 0, 553, 554, 5, 105, 0, 0, 554, 605, 5, 115, 0, 0, 555, 556, 5, 115, 0, 0, 556, 557, 5, 97, 0, 0, 557, 558, 5, 116, 0, 0, 558, 605, 5, 115, 0, 0, 559, 560, 5, 102, 0, 0, 560, 561, 5, 105, 0, 0, 561, 562, 5, 110, 0, 0, 562, 563, 5, 110, 0, 0, 563, 564, 5, 101, 0, 0, 564, 605, 5, 121, 0, 0, 565, 566, 5, 98, 0, 0, 566, 567, 5, 105, 0, 0, 567, 568, 5, 116, 0, 0, 568, 605, 5, 115, 0, 0, 569, 570, 5, 98, 0, 0, 570, 571, 5, 105, 0, 0, 571, 572, 5, 116, 0, 0, 572, 573, 5, 99, 0, 0, 573, 574, 5, 111, 0, 0, 574, 575, 5, 105, 0, 0, 575, 605, 5, 110, 0, 0, 576, 577, 5, 115, 0, 0, 577, 578, 5, 101, 0, 0, 578, 579, 5, 99, 0, 0, 579, 580, 5, 111, 0, 0, 580, 581, 5, 110, 0, 0, 581, 582, 5, 100, 0, 0, 582, 605, 5, 115, 0, 0, 583, 584, 5, 109, 0, 0, 584, 585, 5, 105, 0, 0, 585, 586, 5, 110, 0, 0, 586, 587, 5, 117, 0, 0, 587, 588, 5, 116, 0, 0, 588, 589, 5, 101, 0, 0, 589, 605, 5, 115, 0, 0, 590, 591, 5, 104, 0, 0, 591, 592, 5, 111, 0, 0, 592, 593, 5, 117, 0, 0, 593, 594, 5, 114, 0, 0, 594, 605, 5, 115, 0, 0, 595, 596, 5, 100, 0, 0, 596, 597, 5, 97, 0, 0, 597, 598, 5, 121, 0, 0, 598, 605, 5, 115, 0, 0, 599, 600, 5, 119, 0, 0, 600, 601, 5, 101, 0, 0, 601, 602, 5, 101, 0, 0, 602, 603, 5, 107, 0, 0, 603, 605, 5, 115, 0, 0, 604, 547, 1, 0, 0, 0, 604, 555, 1, 0, 0, 0, 604, 559, 1, 0, 0, 0, 604, 565, 1, 0, 0, 0, 604, 569, 1, 0, 0, 0, 604, 576, 1, 0, 0, 0, 604, 583, 1, 0, 0, 0, 604, 590, 1, 0, 0, 0, 604, 595, 1, 0, 0, 0, 604, 599, 1, 0, 0, 0, 605, 122, 1, 0, 0, 0, 606, 608, 5, 45, 0, 0, 607, 606, 1, 0, 0, 0, 607, 608, 1, 0, 0, 0, 608, 609, 1, 0, 0, 0, 609, 611, 3, 125, 62, 0, 610, 612, 3, 127, 63, 0, 611, 610, 1, 0, 0, 0, 611, 612, 1, 0, 0, 0, 612, 124, 1, 0, 0, 0, 613, 615, 7, 0, 0, 0, 614, 613, 1, 0, 0, 0, 615, 616, 1, 0, 0, 0, 616, 614, 1, 0, 0, 0, 616, 617, 1, 0, 0, 0, 617, 626, 1, 0, 0, 0, 618, 620, 5, 95, 0, 0, 619, 621, 7, 0, 0, 0, 620, 619, 1, 0, 0, 0, 621, 622, 1, 0, 0, 0, 622, 620, 1, 0, 0, 0, 622, 623, 1, 0, 0, 0, 623, 625, 1, 0, 0, 0, 624, 618, 1, 0, 0, 0, 625, 628, 1, 0, 0, 0, 626, 624, 1, 0, 0, 0, 626, 627, 1, 0, 0, 0, 627, 126, 1, 0, 0, 0, 628, 626, 1, 0, 0, 0, 629, 630, 7, 1, 0, 0, 630, 631, 3, 125, 62, 0, 631, 128, 1, 0, 0, 0, 632, 633, 5, 98, 0, 0, 633, 634, 5, 121, 0, 0, 634, 635, 5, 116, 0, 0, 635, 636, 5, 101, 0, 0, 636, 637, 5, 115, 0, 0, 637, 639, 1, 0, 0, 0, 638, 640, 3, 131, 65, 0, 639, 638, 1, 0, 0, 0, 639, 640, 1, 0, 0, 0, 640, 646, 1, 0, 0, 0, 641, 642, 5, 98, 0, 0, 642, 643, 5, 121, 0, 0, 643, 644, 5, 116, 0, 0, 644, 646, 5, 101, 0, 0, 645, 632, 1, 0, 0, 0, 645, 641, 1, 0, 0, 0, 646, 130, 1, 0, 0, 0, 647, 651, 7, 2, 0, 0, 648, 650, 7, 0, 0, 0, 649, 648, 1, 0, 0, 0, 650, 653, 1, 0, 0, 0, 651, 649, 1, 0, 0, 0, 651, 652, 1, 0, 0, 0, 652, 132, 1, 0, 0, 0, 653, 651, 1, 0, 0, 0, 654, 660, 5, 34, 0, 0, 655, 656, 5, 92, 0, 0, 656, 659, 5, 34, 0, 0, 657, 659, 8, 3, 0, 0, 658, 655, 1, 0, 0, 0, 658, 657, 1, 0, 0, 0, 659, 662, 1, 0, 0, 0, 660, 661, 1, 0, 0, 0, 660, 658, 1, 0, 0, 0, 661, 663, 1, 0, 0, 0, 662, 660, 1, 0, 0, 0, 663, 675, 5, 34, 0, 0, 664, 670, 5, 39, 0, 0, 665, 666, 5, 92, 0, 0, 666, 669, 5, 39, 0, 0, 667, 669, 8, 4, 0, 0, 668, 665, 1, 0, 0, 0, 668, 667, 1, 0, 0, 0, 669, 672, 1, 0, 0, 0, 670, 671, 1, 0, 0, 0, 670, 668, 1, 0, 0, 0, 671, 673, 1, 0, 0, 0, 672, 670, 1, 0, 0, 0, 673, 675, 5, 39, 0, 0, 674, 654, 1, 0, 0, 0, 674, 664, 1, 0, 0, 0, 675, 134, 1, 0, 0, 0, 676, 677, 5, 100, 0, 0, 677, 678, 5, 97, 0, 0, 678, 679, 5, 116, 0, 0, 679, 680, 5, 101, 0, 0, 680, 681, 5, 40, 0, 0, 681, 682, 1, 0, 0, 0, 682, 683, 3, 133, 66, 0, 683, 684, 5, 41, 0, 0, 684, 136, 1, 0, 0, 0, 685, 686, 5, 48, 0, 0, 686, 690, 7, 5, 0, 0, 687, 689, 7, 6, 0, 0, 688, 687, 1, 0, 0, 0, 689, 692, 1, 0, 0, 0, 690, 688, 1, 0, 0, 0, 690, 691, 1, 0, 0, 0, 691, 138, 1, 0, 0, 0, 692, 690, 1, 0, 0, 0, 693, 694, 5, 116, 0, 0, 694, 695, 5, 104, 0, 0, 695, 696, 5, 105, 0, 0, 696, 697, 5, 115, 0, 0, 697, 698, 5, 46, 0, 0, 698, 699, 5, 97, 0, 0, 699, 700, 5, 103, 0, 0, 700, 709, 5, 101, 0, 0, 701, 702, 5, 116, 0, 0, 702, 703, 5, 120, 0, 0, 703, 704, 5, 46, 0, 0, 704, 705, 5, 116, 0, 0, 705, 706, 5, 105, 0, 0, 706, 707, 5, 109, 0, 0, 707, 709, 5, 101, 0, 0, 708, 693, 1, 0, 0, 0, 708, 701, 1, 0, 0, 0, 709, 140, 1, 0, 0, 0, 710, 711, 5, 116, 0, 0, 711, 712, 5, 104, 0, 0, 712, 713, 5, 105, 0, 0, 713, 714, 5, 115, 0, 0, 714, 715, 5, 46, 0, 0, 715, 716, 5, 97, 0, 0, 716, 717, 5, 99, 0, 0, 717, 718, 5, 116, 0, 0, 718, 719, 5, 105, 0, 0, 719, 720, 5, 118, 0, 0, 720, 721, 5, 101, 0, 0, 721, 722, 5, 73, 0, 0, 722, 723, 5, 110, 0, 0, 723, 724, 5, 112, 0, 0, 724, 725, 5, 117, 0, 0, 725, 726, 5, 116, 0, 0, 726, 727, 5, 73, 0, 0, 727, 728, 5, 110, 0, 0, 728, 729, 5, 100, 0, 0, 729, 730, 5, 101, 0, 0, 730, 805, 5, 120, 0, 0, 731, 732, 5, 116, 0, 0, 732, 733, 5, 104, 0, 0, 733, 734, 5, 105, 0, 0, 734, 735, 5, 115, 0, 0, 735, 736, 5, 46, 0, 0, 736, 737, 5, 97, 0, 0, 737, 738, 5, 99, 0, 0, 738, 739, 5, 116, 0, 0, 739, 740, 5, 105, 0, 0, 740, 741, 5, 118, 0, 0, 741, 742, 5, 101, 0, 0, 742, 743, 5, 66, 0, 0, 743, 744, 5, 121, 0, 0, 744, 745, 5, 116, 0, 0, 745, 746, 5, 101, 0, 0, 746, 747, 5, 99, 0, 0, 747, 748, 5, 111, 0, 0, 748, 749, 5, 100, 0, 0, 749, 805, 5, 101, 0, 0, 750, 751, 5, 116, 0, 0, 751, 752, 5, 120, 0, 0, 752, 753, 5, 46, 0, 0, 753, 754, 5, 105, 0, 0, 754, 755, 5, 110, 0, 0, 755, 756, 5, 112, 0, 0, 756, 757, 5, 117, 0, 0, 757, 758, 5, 116, 0, 0, 758, 759, 5, 115, 0, 0, 759, 760, 5, 46, 0, 0, 760, 761, 5, 108, 0, 0, 761, 762, 5, 101, 0, 0, 762, 763, 5, 110, 0, 0, 763, 764, 5, 103, 0, 0, 764, 765, 5, 116, 0, 0, 765, 805, 5, 104, 0, 0, 766, 767, 5, 116, 0, 0, 767, 768, 5, 120, 0, 0, 768, 769, 5, 46, 0, 0, 769, 770, 5, 111, 0, 0, 770, 771, 5, 117, 0, 0, 771, 772, 5, 116, 0, 0, 772, 773, 5, 112, 0, 0, 773, 774, 5, 117, 0, 0, 774, 775, 5, 116, 0, 0, 775, 776, 5, 115, 0, 0, 776, 777, 5, 46, 0, 0, 777, 778, 5, 108, 0, 0, 778, 779, 5, 101, 0, 0, 779, 780, 5, 110, 0, 0, 780, 781, 5, 103, 0, 0, 781, 782, 5, 116, 0, 0, 782, 805, 5, 104, 0, 0, 783, 784, 5, 116, 0, 0, 784, 785, 5, 120, 0, 0, 785, 786, 5, 46, 0, 0, 786, 787, 5, 118, 0, 0, 787, 788, 5, 101, 0, 0, 788, 789, 5, 114, 0, 0, 789, 790, 5, 115, 0, 0, 790, 791, 5, 105, 0, 0, 791, 792, 5, 111, 0, 0, 792, 805, 5, 110, 0, 0, 793, 794, 5, 116, 0, 0, 794, 795, 5, 120, 0, 0, 795, 796, 5, 46, 0, 0, 796, 797, 5, 108, 0, 0, 797, 798, 5, 111, 0, 0, 798, 799, 5, 99, 0, 0, 799, 800, 5, 107, 0, 0, 800, 801, 5, 116, 0, 0, 801, 802, 5, 105, 0, 0, 802, 803, 5, 109, 0, 0, 803, 805, 5, 101, 0, 0, 804, 710, 1, 0, 0, 0, 804, 731, 1, 0, 0, 0, 804, 750, 1, 0, 0, 0, 804, 766, 1, 0, 0, 0, 804, 783, 1, 0, 0, 0, 804, 793, 1, 0, 0, 0, 805, 142, 1, 0, 0, 0, 806, 810, 7, 7, 0, 0, 807, 809, 7, 8, 0, 0, 808, 807, 1, 0, 0, 0, 809, 812, 1, 0, 0, 0, 810, 808, 1, 0, 0, 0, 810, 811, 1, 0, 0, 0, 811, 144, 1, 0, 0, 0, 812, 810, 1, 0, 0, 0, 813, 815, 7, 9, 0, 0, 814, 813, 1, 0, 0, 0, 815, 816, 1, 0, 0, 0, 816, 814, 1, 0, 0, 0, 816, 817, 1, 0, 0, 0, 817, 818, 1, 0, 0, 0, 818, 819, 6, 72, 0, 0, 819, 146, 1, 0, 0, 0, 820, 821, 5, 47, 0, 0, 821, 822, 5, 42, 0, 0, 822, 826, 1, 0, 0, 0, 823, 825, 9, 0, 0, 0, 824, 823, 1, 0, 0, 0, 825, 828, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 826, 824, 1, 0, 0, 0, 827, 829, 1, 0, 0, 0, 828, 826, 1, 0, 0, 0, 829, 830, 5, 42, 0, 0, 830, 831, 5, 47, 0, 0, 831, 832, 1, 0, 0, 0, 832, 833, 6, 73, 1, 0, 833, 148, 1, 0, 0, 0, 834, 835, 5, 47, 0, 0, 835, 836, 5, 47, 0, 0, 836, 840, 1, 0, 0, 0, 837, 839, 8, 10, 0, 0, 838, 837, 1, 0, 0, 0, 839, 842, 1, 0, 0, 0, 840, 838, 1, 0, 0, 0, 840, 841, 1, 0, 0, 0, 841, 843, 1, 0, 0, 0, 842, 840, 1, 0, 0, 0, 843, 844, 6, 74, 1, 0, 844, 150, 1, 0, 0, 0, 26, 0, 522, 528, 534, 545, 604, 607, 611, 616, 622, 626, 639, 645, 651, 658, 660, 668, 670, 674, 690, 708, 804, 810, 816, 826, 840, 2, 6, 0, 0, 0, 1, 0] \ No newline at end of file +[4, 0, 76, 912, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 4, 56, 503, 8, 56, 11, 56, 12, 56, 504, 1, 56, 1, 56, 4, 56, 509, 8, 56, 11, 56, 12, 56, 510, 1, 56, 1, 56, 4, 56, 515, 8, 56, 11, 56, 12, 56, 516, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 528, 8, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 587, 8, 58, 1, 59, 3, 59, 590, 8, 59, 1, 59, 1, 59, 3, 59, 594, 8, 59, 1, 60, 4, 60, 597, 8, 60, 11, 60, 12, 60, 598, 1, 60, 1, 60, 4, 60, 603, 8, 60, 11, 60, 12, 60, 604, 5, 60, 607, 8, 60, 10, 60, 12, 60, 610, 9, 60, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 644, 8, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 3, 64, 663, 8, 64, 1, 65, 1, 65, 5, 65, 667, 8, 65, 10, 65, 12, 65, 670, 9, 65, 1, 66, 1, 66, 1, 66, 1, 66, 5, 66, 676, 8, 66, 10, 66, 12, 66, 679, 9, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 5, 66, 686, 8, 66, 10, 66, 12, 66, 689, 9, 66, 1, 66, 3, 66, 692, 8, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 5, 68, 706, 8, 68, 10, 68, 12, 68, 709, 9, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 3, 69, 726, 8, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 763, 8, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 776, 8, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 3, 71, 872, 8, 71, 1, 72, 1, 72, 5, 72, 876, 8, 72, 10, 72, 12, 72, 879, 9, 72, 1, 73, 4, 73, 882, 8, 73, 11, 73, 12, 73, 883, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 5, 74, 892, 8, 74, 10, 74, 12, 74, 895, 9, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 5, 75, 906, 8, 75, 10, 75, 12, 75, 909, 9, 75, 1, 75, 1, 75, 3, 677, 687, 893, 0, 76, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 67, 135, 68, 137, 69, 139, 70, 141, 71, 143, 72, 145, 73, 147, 74, 149, 75, 151, 76, 1, 0, 11, 1, 0, 48, 57, 2, 0, 69, 69, 101, 101, 1, 0, 49, 57, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, 39, 2, 0, 88, 88, 120, 120, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 3, 0, 9, 10, 12, 13, 32, 32, 2, 0, 10, 10, 13, 13, 956, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133, 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, 1, 0, 0, 0, 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, 0, 147, 1, 0, 0, 0, 0, 149, 1, 0, 0, 0, 0, 151, 1, 0, 0, 0, 1, 153, 1, 0, 0, 0, 3, 160, 1, 0, 0, 0, 5, 162, 1, 0, 0, 0, 7, 173, 1, 0, 0, 0, 9, 175, 1, 0, 0, 0, 11, 177, 1, 0, 0, 0, 13, 180, 1, 0, 0, 0, 15, 182, 1, 0, 0, 0, 17, 184, 1, 0, 0, 0, 19, 187, 1, 0, 0, 0, 21, 189, 1, 0, 0, 0, 23, 198, 1, 0, 0, 0, 25, 200, 1, 0, 0, 0, 27, 202, 1, 0, 0, 0, 29, 211, 1, 0, 0, 0, 31, 213, 1, 0, 0, 0, 33, 215, 1, 0, 0, 0, 35, 217, 1, 0, 0, 0, 37, 225, 1, 0, 0, 0, 39, 228, 1, 0, 0, 0, 41, 233, 1, 0, 0, 0, 43, 236, 1, 0, 0, 0, 45, 242, 1, 0, 0, 0, 47, 254, 1, 0, 0, 0, 49, 258, 1, 0, 0, 0, 51, 260, 1, 0, 0, 0, 53, 262, 1, 0, 0, 0, 55, 273, 1, 0, 0, 0, 57, 280, 1, 0, 0, 0, 59, 297, 1, 0, 0, 0, 61, 312, 1, 0, 0, 0, 63, 327, 1, 0, 0, 0, 65, 340, 1, 0, 0, 0, 67, 350, 1, 0, 0, 0, 69, 375, 1, 0, 0, 0, 71, 390, 1, 0, 0, 0, 73, 409, 1, 0, 0, 0, 75, 425, 1, 0, 0, 0, 77, 436, 1, 0, 0, 0, 79, 444, 1, 0, 0, 0, 81, 451, 1, 0, 0, 0, 83, 458, 1, 0, 0, 0, 85, 460, 1, 0, 0, 0, 87, 462, 1, 0, 0, 0, 89, 464, 1, 0, 0, 0, 91, 466, 1, 0, 0, 0, 93, 468, 1, 0, 0, 0, 95, 470, 1, 0, 0, 0, 97, 473, 1, 0, 0, 0, 99, 476, 1, 0, 0, 0, 101, 479, 1, 0, 0, 0, 103, 482, 1, 0, 0, 0, 105, 484, 1, 0, 0, 0, 107, 486, 1, 0, 0, 0, 109, 489, 1, 0, 0, 0, 111, 492, 1, 0, 0, 0, 113, 502, 1, 0, 0, 0, 115, 527, 1, 0, 0, 0, 117, 586, 1, 0, 0, 0, 119, 589, 1, 0, 0, 0, 121, 596, 1, 0, 0, 0, 123, 611, 1, 0, 0, 0, 125, 643, 1, 0, 0, 0, 127, 645, 1, 0, 0, 0, 129, 662, 1, 0, 0, 0, 131, 664, 1, 0, 0, 0, 133, 691, 1, 0, 0, 0, 135, 693, 1, 0, 0, 0, 137, 702, 1, 0, 0, 0, 139, 725, 1, 0, 0, 0, 141, 775, 1, 0, 0, 0, 143, 871, 1, 0, 0, 0, 145, 873, 1, 0, 0, 0, 147, 881, 1, 0, 0, 0, 149, 887, 1, 0, 0, 0, 151, 901, 1, 0, 0, 0, 153, 154, 5, 112, 0, 0, 154, 155, 5, 114, 0, 0, 155, 156, 5, 97, 0, 0, 156, 157, 5, 103, 0, 0, 157, 158, 5, 109, 0, 0, 158, 159, 5, 97, 0, 0, 159, 2, 1, 0, 0, 0, 160, 161, 5, 59, 0, 0, 161, 4, 1, 0, 0, 0, 162, 163, 5, 99, 0, 0, 163, 164, 5, 97, 0, 0, 164, 165, 5, 115, 0, 0, 165, 166, 5, 104, 0, 0, 166, 167, 5, 115, 0, 0, 167, 168, 5, 99, 0, 0, 168, 169, 5, 114, 0, 0, 169, 170, 5, 105, 0, 0, 170, 171, 5, 112, 0, 0, 171, 172, 5, 116, 0, 0, 172, 6, 1, 0, 0, 0, 173, 174, 5, 94, 0, 0, 174, 8, 1, 0, 0, 0, 175, 176, 5, 126, 0, 0, 176, 10, 1, 0, 0, 0, 177, 178, 5, 62, 0, 0, 178, 179, 5, 61, 0, 0, 179, 12, 1, 0, 0, 0, 180, 181, 5, 62, 0, 0, 181, 14, 1, 0, 0, 0, 182, 183, 5, 60, 0, 0, 183, 16, 1, 0, 0, 0, 184, 185, 5, 60, 0, 0, 185, 186, 5, 61, 0, 0, 186, 18, 1, 0, 0, 0, 187, 188, 5, 61, 0, 0, 188, 20, 1, 0, 0, 0, 189, 190, 5, 99, 0, 0, 190, 191, 5, 111, 0, 0, 191, 192, 5, 110, 0, 0, 192, 193, 5, 116, 0, 0, 193, 194, 5, 114, 0, 0, 194, 195, 5, 97, 0, 0, 195, 196, 5, 99, 0, 0, 196, 197, 5, 116, 0, 0, 197, 22, 1, 0, 0, 0, 198, 199, 5, 123, 0, 0, 199, 24, 1, 0, 0, 0, 200, 201, 5, 125, 0, 0, 201, 26, 1, 0, 0, 0, 202, 203, 5, 102, 0, 0, 203, 204, 5, 117, 0, 0, 204, 205, 5, 110, 0, 0, 205, 206, 5, 99, 0, 0, 206, 207, 5, 116, 0, 0, 207, 208, 5, 105, 0, 0, 208, 209, 5, 111, 0, 0, 209, 210, 5, 110, 0, 0, 210, 28, 1, 0, 0, 0, 211, 212, 5, 40, 0, 0, 212, 30, 1, 0, 0, 0, 213, 214, 5, 44, 0, 0, 214, 32, 1, 0, 0, 0, 215, 216, 5, 41, 0, 0, 216, 34, 1, 0, 0, 0, 217, 218, 5, 114, 0, 0, 218, 219, 5, 101, 0, 0, 219, 220, 5, 113, 0, 0, 220, 221, 5, 117, 0, 0, 221, 222, 5, 105, 0, 0, 222, 223, 5, 114, 0, 0, 223, 224, 5, 101, 0, 0, 224, 36, 1, 0, 0, 0, 225, 226, 5, 105, 0, 0, 226, 227, 5, 102, 0, 0, 227, 38, 1, 0, 0, 0, 228, 229, 5, 101, 0, 0, 229, 230, 5, 108, 0, 0, 230, 231, 5, 115, 0, 0, 231, 232, 5, 101, 0, 0, 232, 40, 1, 0, 0, 0, 233, 234, 5, 100, 0, 0, 234, 235, 5, 111, 0, 0, 235, 42, 1, 0, 0, 0, 236, 237, 5, 119, 0, 0, 237, 238, 5, 104, 0, 0, 238, 239, 5, 105, 0, 0, 239, 240, 5, 108, 0, 0, 240, 241, 5, 101, 0, 0, 241, 44, 1, 0, 0, 0, 242, 243, 5, 99, 0, 0, 243, 244, 5, 111, 0, 0, 244, 245, 5, 110, 0, 0, 245, 246, 5, 115, 0, 0, 246, 247, 5, 111, 0, 0, 247, 248, 5, 108, 0, 0, 248, 249, 5, 101, 0, 0, 249, 250, 5, 46, 0, 0, 250, 251, 5, 108, 0, 0, 251, 252, 5, 111, 0, 0, 252, 253, 5, 103, 0, 0, 253, 46, 1, 0, 0, 0, 254, 255, 5, 110, 0, 0, 255, 256, 5, 101, 0, 0, 256, 257, 5, 119, 0, 0, 257, 48, 1, 0, 0, 0, 258, 259, 5, 91, 0, 0, 259, 50, 1, 0, 0, 0, 260, 261, 5, 93, 0, 0, 261, 52, 1, 0, 0, 0, 262, 263, 5, 116, 0, 0, 263, 264, 5, 120, 0, 0, 264, 265, 5, 46, 0, 0, 265, 266, 5, 111, 0, 0, 266, 267, 5, 117, 0, 0, 267, 268, 5, 116, 0, 0, 268, 269, 5, 112, 0, 0, 269, 270, 5, 117, 0, 0, 270, 271, 5, 116, 0, 0, 271, 272, 5, 115, 0, 0, 272, 54, 1, 0, 0, 0, 273, 274, 5, 46, 0, 0, 274, 275, 5, 118, 0, 0, 275, 276, 5, 97, 0, 0, 276, 277, 5, 108, 0, 0, 277, 278, 5, 117, 0, 0, 278, 279, 5, 101, 0, 0, 279, 56, 1, 0, 0, 0, 280, 281, 5, 46, 0, 0, 281, 282, 5, 108, 0, 0, 282, 283, 5, 111, 0, 0, 283, 284, 5, 99, 0, 0, 284, 285, 5, 107, 0, 0, 285, 286, 5, 105, 0, 0, 286, 287, 5, 110, 0, 0, 287, 288, 5, 103, 0, 0, 288, 289, 5, 66, 0, 0, 289, 290, 5, 121, 0, 0, 290, 291, 5, 116, 0, 0, 291, 292, 5, 101, 0, 0, 292, 293, 5, 99, 0, 0, 293, 294, 5, 111, 0, 0, 294, 295, 5, 100, 0, 0, 295, 296, 5, 101, 0, 0, 296, 58, 1, 0, 0, 0, 297, 298, 5, 46, 0, 0, 298, 299, 5, 116, 0, 0, 299, 300, 5, 111, 0, 0, 300, 301, 5, 107, 0, 0, 301, 302, 5, 101, 0, 0, 302, 303, 5, 110, 0, 0, 303, 304, 5, 67, 0, 0, 304, 305, 5, 97, 0, 0, 305, 306, 5, 116, 0, 0, 306, 307, 5, 101, 0, 0, 307, 308, 5, 103, 0, 0, 308, 309, 5, 111, 0, 0, 309, 310, 5, 114, 0, 0, 310, 311, 5, 121, 0, 0, 311, 60, 1, 0, 0, 0, 312, 313, 5, 46, 0, 0, 313, 314, 5, 110, 0, 0, 314, 315, 5, 102, 0, 0, 315, 316, 5, 116, 0, 0, 316, 317, 5, 67, 0, 0, 317, 318, 5, 111, 0, 0, 318, 319, 5, 109, 0, 0, 319, 320, 5, 109, 0, 0, 320, 321, 5, 105, 0, 0, 321, 322, 5, 116, 0, 0, 322, 323, 5, 109, 0, 0, 323, 324, 5, 101, 0, 0, 324, 325, 5, 110, 0, 0, 325, 326, 5, 116, 0, 0, 326, 62, 1, 0, 0, 0, 327, 328, 5, 46, 0, 0, 328, 329, 5, 116, 0, 0, 329, 330, 5, 111, 0, 0, 330, 331, 5, 107, 0, 0, 331, 332, 5, 101, 0, 0, 332, 333, 5, 110, 0, 0, 333, 334, 5, 65, 0, 0, 334, 335, 5, 109, 0, 0, 335, 336, 5, 111, 0, 0, 336, 337, 5, 117, 0, 0, 337, 338, 5, 110, 0, 0, 338, 339, 5, 116, 0, 0, 339, 64, 1, 0, 0, 0, 340, 341, 5, 116, 0, 0, 341, 342, 5, 120, 0, 0, 342, 343, 5, 46, 0, 0, 343, 344, 5, 105, 0, 0, 344, 345, 5, 110, 0, 0, 345, 346, 5, 112, 0, 0, 346, 347, 5, 117, 0, 0, 347, 348, 5, 116, 0, 0, 348, 349, 5, 115, 0, 0, 349, 66, 1, 0, 0, 0, 350, 351, 5, 46, 0, 0, 351, 352, 5, 111, 0, 0, 352, 353, 5, 117, 0, 0, 353, 354, 5, 116, 0, 0, 354, 355, 5, 112, 0, 0, 355, 356, 5, 111, 0, 0, 356, 357, 5, 105, 0, 0, 357, 358, 5, 110, 0, 0, 358, 359, 5, 116, 0, 0, 359, 360, 5, 84, 0, 0, 360, 361, 5, 114, 0, 0, 361, 362, 5, 97, 0, 0, 362, 363, 5, 110, 0, 0, 363, 364, 5, 115, 0, 0, 364, 365, 5, 97, 0, 0, 365, 366, 5, 99, 0, 0, 366, 367, 5, 116, 0, 0, 367, 368, 5, 105, 0, 0, 368, 369, 5, 111, 0, 0, 369, 370, 5, 110, 0, 0, 370, 371, 5, 72, 0, 0, 371, 372, 5, 97, 0, 0, 372, 373, 5, 115, 0, 0, 373, 374, 5, 104, 0, 0, 374, 68, 1, 0, 0, 0, 375, 376, 5, 46, 0, 0, 376, 377, 5, 111, 0, 0, 377, 378, 5, 117, 0, 0, 378, 379, 5, 116, 0, 0, 379, 380, 5, 112, 0, 0, 380, 381, 5, 111, 0, 0, 381, 382, 5, 105, 0, 0, 382, 383, 5, 110, 0, 0, 383, 384, 5, 116, 0, 0, 384, 385, 5, 73, 0, 0, 385, 386, 5, 110, 0, 0, 386, 387, 5, 100, 0, 0, 387, 388, 5, 101, 0, 0, 388, 389, 5, 120, 0, 0, 389, 70, 1, 0, 0, 0, 390, 391, 5, 46, 0, 0, 391, 392, 5, 117, 0, 0, 392, 393, 5, 110, 0, 0, 393, 394, 5, 108, 0, 0, 394, 395, 5, 111, 0, 0, 395, 396, 5, 99, 0, 0, 396, 397, 5, 107, 0, 0, 397, 398, 5, 105, 0, 0, 398, 399, 5, 110, 0, 0, 399, 400, 5, 103, 0, 0, 400, 401, 5, 66, 0, 0, 401, 402, 5, 121, 0, 0, 402, 403, 5, 116, 0, 0, 403, 404, 5, 101, 0, 0, 404, 405, 5, 99, 0, 0, 405, 406, 5, 111, 0, 0, 406, 407, 5, 100, 0, 0, 407, 408, 5, 101, 0, 0, 408, 72, 1, 0, 0, 0, 409, 410, 5, 46, 0, 0, 410, 411, 5, 115, 0, 0, 411, 412, 5, 101, 0, 0, 412, 413, 5, 113, 0, 0, 413, 414, 5, 117, 0, 0, 414, 415, 5, 101, 0, 0, 415, 416, 5, 110, 0, 0, 416, 417, 5, 99, 0, 0, 417, 418, 5, 101, 0, 0, 418, 419, 5, 78, 0, 0, 419, 420, 5, 117, 0, 0, 420, 421, 5, 109, 0, 0, 421, 422, 5, 98, 0, 0, 422, 423, 5, 101, 0, 0, 423, 424, 5, 114, 0, 0, 424, 74, 1, 0, 0, 0, 425, 426, 5, 46, 0, 0, 426, 427, 5, 114, 0, 0, 427, 428, 5, 101, 0, 0, 428, 429, 5, 118, 0, 0, 429, 430, 5, 101, 0, 0, 430, 431, 5, 114, 0, 0, 431, 432, 5, 115, 0, 0, 432, 433, 5, 101, 0, 0, 433, 434, 5, 40, 0, 0, 434, 435, 5, 41, 0, 0, 435, 76, 1, 0, 0, 0, 436, 437, 5, 46, 0, 0, 437, 438, 5, 108, 0, 0, 438, 439, 5, 101, 0, 0, 439, 440, 5, 110, 0, 0, 440, 441, 5, 103, 0, 0, 441, 442, 5, 116, 0, 0, 442, 443, 5, 104, 0, 0, 443, 78, 1, 0, 0, 0, 444, 445, 5, 46, 0, 0, 445, 446, 5, 115, 0, 0, 446, 447, 5, 112, 0, 0, 447, 448, 5, 108, 0, 0, 448, 449, 5, 105, 0, 0, 449, 450, 5, 116, 0, 0, 450, 80, 1, 0, 0, 0, 451, 452, 5, 46, 0, 0, 452, 453, 5, 115, 0, 0, 453, 454, 5, 108, 0, 0, 454, 455, 5, 105, 0, 0, 455, 456, 5, 99, 0, 0, 456, 457, 5, 101, 0, 0, 457, 82, 1, 0, 0, 0, 458, 459, 5, 33, 0, 0, 459, 84, 1, 0, 0, 0, 460, 461, 5, 45, 0, 0, 461, 86, 1, 0, 0, 0, 462, 463, 5, 42, 0, 0, 463, 88, 1, 0, 0, 0, 464, 465, 5, 47, 0, 0, 465, 90, 1, 0, 0, 0, 466, 467, 5, 37, 0, 0, 467, 92, 1, 0, 0, 0, 468, 469, 5, 43, 0, 0, 469, 94, 1, 0, 0, 0, 470, 471, 5, 62, 0, 0, 471, 472, 5, 62, 0, 0, 472, 96, 1, 0, 0, 0, 473, 474, 5, 60, 0, 0, 474, 475, 5, 60, 0, 0, 475, 98, 1, 0, 0, 0, 476, 477, 5, 61, 0, 0, 477, 478, 5, 61, 0, 0, 478, 100, 1, 0, 0, 0, 479, 480, 5, 33, 0, 0, 480, 481, 5, 61, 0, 0, 481, 102, 1, 0, 0, 0, 482, 483, 5, 38, 0, 0, 483, 104, 1, 0, 0, 0, 484, 485, 5, 124, 0, 0, 485, 106, 1, 0, 0, 0, 486, 487, 5, 38, 0, 0, 487, 488, 5, 38, 0, 0, 488, 108, 1, 0, 0, 0, 489, 490, 5, 124, 0, 0, 490, 491, 5, 124, 0, 0, 491, 110, 1, 0, 0, 0, 492, 493, 5, 99, 0, 0, 493, 494, 5, 111, 0, 0, 494, 495, 5, 110, 0, 0, 495, 496, 5, 115, 0, 0, 496, 497, 5, 116, 0, 0, 497, 498, 5, 97, 0, 0, 498, 499, 5, 110, 0, 0, 499, 500, 5, 116, 0, 0, 500, 112, 1, 0, 0, 0, 501, 503, 7, 0, 0, 0, 502, 501, 1, 0, 0, 0, 503, 504, 1, 0, 0, 0, 504, 502, 1, 0, 0, 0, 504, 505, 1, 0, 0, 0, 505, 506, 1, 0, 0, 0, 506, 508, 5, 46, 0, 0, 507, 509, 7, 0, 0, 0, 508, 507, 1, 0, 0, 0, 509, 510, 1, 0, 0, 0, 510, 508, 1, 0, 0, 0, 510, 511, 1, 0, 0, 0, 511, 512, 1, 0, 0, 0, 512, 514, 5, 46, 0, 0, 513, 515, 7, 0, 0, 0, 514, 513, 1, 0, 0, 0, 515, 516, 1, 0, 0, 0, 516, 514, 1, 0, 0, 0, 516, 517, 1, 0, 0, 0, 517, 114, 1, 0, 0, 0, 518, 519, 5, 116, 0, 0, 519, 520, 5, 114, 0, 0, 520, 521, 5, 117, 0, 0, 521, 528, 5, 101, 0, 0, 522, 523, 5, 102, 0, 0, 523, 524, 5, 97, 0, 0, 524, 525, 5, 108, 0, 0, 525, 526, 5, 115, 0, 0, 526, 528, 5, 101, 0, 0, 527, 518, 1, 0, 0, 0, 527, 522, 1, 0, 0, 0, 528, 116, 1, 0, 0, 0, 529, 530, 5, 115, 0, 0, 530, 531, 5, 97, 0, 0, 531, 532, 5, 116, 0, 0, 532, 533, 5, 111, 0, 0, 533, 534, 5, 115, 0, 0, 534, 535, 5, 104, 0, 0, 535, 536, 5, 105, 0, 0, 536, 587, 5, 115, 0, 0, 537, 538, 5, 115, 0, 0, 538, 539, 5, 97, 0, 0, 539, 540, 5, 116, 0, 0, 540, 587, 5, 115, 0, 0, 541, 542, 5, 102, 0, 0, 542, 543, 5, 105, 0, 0, 543, 544, 5, 110, 0, 0, 544, 545, 5, 110, 0, 0, 545, 546, 5, 101, 0, 0, 546, 587, 5, 121, 0, 0, 547, 548, 5, 98, 0, 0, 548, 549, 5, 105, 0, 0, 549, 550, 5, 116, 0, 0, 550, 587, 5, 115, 0, 0, 551, 552, 5, 98, 0, 0, 552, 553, 5, 105, 0, 0, 553, 554, 5, 116, 0, 0, 554, 555, 5, 99, 0, 0, 555, 556, 5, 111, 0, 0, 556, 557, 5, 105, 0, 0, 557, 587, 5, 110, 0, 0, 558, 559, 5, 115, 0, 0, 559, 560, 5, 101, 0, 0, 560, 561, 5, 99, 0, 0, 561, 562, 5, 111, 0, 0, 562, 563, 5, 110, 0, 0, 563, 564, 5, 100, 0, 0, 564, 587, 5, 115, 0, 0, 565, 566, 5, 109, 0, 0, 566, 567, 5, 105, 0, 0, 567, 568, 5, 110, 0, 0, 568, 569, 5, 117, 0, 0, 569, 570, 5, 116, 0, 0, 570, 571, 5, 101, 0, 0, 571, 587, 5, 115, 0, 0, 572, 573, 5, 104, 0, 0, 573, 574, 5, 111, 0, 0, 574, 575, 5, 117, 0, 0, 575, 576, 5, 114, 0, 0, 576, 587, 5, 115, 0, 0, 577, 578, 5, 100, 0, 0, 578, 579, 5, 97, 0, 0, 579, 580, 5, 121, 0, 0, 580, 587, 5, 115, 0, 0, 581, 582, 5, 119, 0, 0, 582, 583, 5, 101, 0, 0, 583, 584, 5, 101, 0, 0, 584, 585, 5, 107, 0, 0, 585, 587, 5, 115, 0, 0, 586, 529, 1, 0, 0, 0, 586, 537, 1, 0, 0, 0, 586, 541, 1, 0, 0, 0, 586, 547, 1, 0, 0, 0, 586, 551, 1, 0, 0, 0, 586, 558, 1, 0, 0, 0, 586, 565, 1, 0, 0, 0, 586, 572, 1, 0, 0, 0, 586, 577, 1, 0, 0, 0, 586, 581, 1, 0, 0, 0, 587, 118, 1, 0, 0, 0, 588, 590, 5, 45, 0, 0, 589, 588, 1, 0, 0, 0, 589, 590, 1, 0, 0, 0, 590, 591, 1, 0, 0, 0, 591, 593, 3, 121, 60, 0, 592, 594, 3, 123, 61, 0, 593, 592, 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 120, 1, 0, 0, 0, 595, 597, 7, 0, 0, 0, 596, 595, 1, 0, 0, 0, 597, 598, 1, 0, 0, 0, 598, 596, 1, 0, 0, 0, 598, 599, 1, 0, 0, 0, 599, 608, 1, 0, 0, 0, 600, 602, 5, 95, 0, 0, 601, 603, 7, 0, 0, 0, 602, 601, 1, 0, 0, 0, 603, 604, 1, 0, 0, 0, 604, 602, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 607, 1, 0, 0, 0, 606, 600, 1, 0, 0, 0, 607, 610, 1, 0, 0, 0, 608, 606, 1, 0, 0, 0, 608, 609, 1, 0, 0, 0, 609, 122, 1, 0, 0, 0, 610, 608, 1, 0, 0, 0, 611, 612, 7, 1, 0, 0, 612, 613, 3, 121, 60, 0, 613, 124, 1, 0, 0, 0, 614, 615, 5, 105, 0, 0, 615, 616, 5, 110, 0, 0, 616, 644, 5, 116, 0, 0, 617, 618, 5, 98, 0, 0, 618, 619, 5, 111, 0, 0, 619, 620, 5, 111, 0, 0, 620, 644, 5, 108, 0, 0, 621, 622, 5, 115, 0, 0, 622, 623, 5, 116, 0, 0, 623, 624, 5, 114, 0, 0, 624, 625, 5, 105, 0, 0, 625, 626, 5, 110, 0, 0, 626, 644, 5, 103, 0, 0, 627, 628, 5, 112, 0, 0, 628, 629, 5, 117, 0, 0, 629, 630, 5, 98, 0, 0, 630, 631, 5, 107, 0, 0, 631, 632, 5, 101, 0, 0, 632, 644, 5, 121, 0, 0, 633, 634, 5, 115, 0, 0, 634, 635, 5, 105, 0, 0, 635, 644, 5, 103, 0, 0, 636, 637, 5, 100, 0, 0, 637, 638, 5, 97, 0, 0, 638, 639, 5, 116, 0, 0, 639, 640, 5, 97, 0, 0, 640, 641, 5, 115, 0, 0, 641, 642, 5, 105, 0, 0, 642, 644, 5, 103, 0, 0, 643, 614, 1, 0, 0, 0, 643, 617, 1, 0, 0, 0, 643, 621, 1, 0, 0, 0, 643, 627, 1, 0, 0, 0, 643, 633, 1, 0, 0, 0, 643, 636, 1, 0, 0, 0, 644, 126, 1, 0, 0, 0, 645, 646, 5, 98, 0, 0, 646, 647, 5, 121, 0, 0, 647, 648, 5, 116, 0, 0, 648, 649, 5, 101, 0, 0, 649, 650, 5, 115, 0, 0, 650, 128, 1, 0, 0, 0, 651, 652, 5, 98, 0, 0, 652, 653, 5, 121, 0, 0, 653, 654, 5, 116, 0, 0, 654, 655, 5, 101, 0, 0, 655, 656, 5, 115, 0, 0, 656, 657, 1, 0, 0, 0, 657, 663, 3, 131, 65, 0, 658, 659, 5, 98, 0, 0, 659, 660, 5, 121, 0, 0, 660, 661, 5, 116, 0, 0, 661, 663, 5, 101, 0, 0, 662, 651, 1, 0, 0, 0, 662, 658, 1, 0, 0, 0, 663, 130, 1, 0, 0, 0, 664, 668, 7, 2, 0, 0, 665, 667, 7, 0, 0, 0, 666, 665, 1, 0, 0, 0, 667, 670, 1, 0, 0, 0, 668, 666, 1, 0, 0, 0, 668, 669, 1, 0, 0, 0, 669, 132, 1, 0, 0, 0, 670, 668, 1, 0, 0, 0, 671, 677, 5, 34, 0, 0, 672, 673, 5, 92, 0, 0, 673, 676, 5, 34, 0, 0, 674, 676, 8, 3, 0, 0, 675, 672, 1, 0, 0, 0, 675, 674, 1, 0, 0, 0, 676, 679, 1, 0, 0, 0, 677, 678, 1, 0, 0, 0, 677, 675, 1, 0, 0, 0, 678, 680, 1, 0, 0, 0, 679, 677, 1, 0, 0, 0, 680, 692, 5, 34, 0, 0, 681, 687, 5, 39, 0, 0, 682, 683, 5, 92, 0, 0, 683, 686, 5, 39, 0, 0, 684, 686, 8, 4, 0, 0, 685, 682, 1, 0, 0, 0, 685, 684, 1, 0, 0, 0, 686, 689, 1, 0, 0, 0, 687, 688, 1, 0, 0, 0, 687, 685, 1, 0, 0, 0, 688, 690, 1, 0, 0, 0, 689, 687, 1, 0, 0, 0, 690, 692, 5, 39, 0, 0, 691, 671, 1, 0, 0, 0, 691, 681, 1, 0, 0, 0, 692, 134, 1, 0, 0, 0, 693, 694, 5, 100, 0, 0, 694, 695, 5, 97, 0, 0, 695, 696, 5, 116, 0, 0, 696, 697, 5, 101, 0, 0, 697, 698, 5, 40, 0, 0, 698, 699, 1, 0, 0, 0, 699, 700, 3, 133, 66, 0, 700, 701, 5, 41, 0, 0, 701, 136, 1, 0, 0, 0, 702, 703, 5, 48, 0, 0, 703, 707, 7, 5, 0, 0, 704, 706, 7, 6, 0, 0, 705, 704, 1, 0, 0, 0, 706, 709, 1, 0, 0, 0, 707, 705, 1, 0, 0, 0, 707, 708, 1, 0, 0, 0, 708, 138, 1, 0, 0, 0, 709, 707, 1, 0, 0, 0, 710, 711, 5, 116, 0, 0, 711, 712, 5, 104, 0, 0, 712, 713, 5, 105, 0, 0, 713, 714, 5, 115, 0, 0, 714, 715, 5, 46, 0, 0, 715, 716, 5, 97, 0, 0, 716, 717, 5, 103, 0, 0, 717, 726, 5, 101, 0, 0, 718, 719, 5, 116, 0, 0, 719, 720, 5, 120, 0, 0, 720, 721, 5, 46, 0, 0, 721, 722, 5, 116, 0, 0, 722, 723, 5, 105, 0, 0, 723, 724, 5, 109, 0, 0, 724, 726, 5, 101, 0, 0, 725, 710, 1, 0, 0, 0, 725, 718, 1, 0, 0, 0, 726, 140, 1, 0, 0, 0, 727, 728, 5, 117, 0, 0, 728, 729, 5, 110, 0, 0, 729, 730, 5, 115, 0, 0, 730, 731, 5, 97, 0, 0, 731, 732, 5, 102, 0, 0, 732, 733, 5, 101, 0, 0, 733, 734, 5, 95, 0, 0, 734, 735, 5, 105, 0, 0, 735, 736, 5, 110, 0, 0, 736, 776, 5, 116, 0, 0, 737, 738, 5, 117, 0, 0, 738, 739, 5, 110, 0, 0, 739, 740, 5, 115, 0, 0, 740, 741, 5, 97, 0, 0, 741, 742, 5, 102, 0, 0, 742, 743, 5, 101, 0, 0, 743, 744, 5, 95, 0, 0, 744, 745, 5, 98, 0, 0, 745, 746, 5, 111, 0, 0, 746, 747, 5, 111, 0, 0, 747, 776, 5, 108, 0, 0, 748, 749, 5, 117, 0, 0, 749, 750, 5, 110, 0, 0, 750, 751, 5, 115, 0, 0, 751, 752, 5, 97, 0, 0, 752, 753, 5, 102, 0, 0, 753, 754, 5, 101, 0, 0, 754, 755, 5, 95, 0, 0, 755, 756, 5, 98, 0, 0, 756, 757, 5, 121, 0, 0, 757, 758, 5, 116, 0, 0, 758, 759, 5, 101, 0, 0, 759, 760, 5, 115, 0, 0, 760, 762, 1, 0, 0, 0, 761, 763, 3, 131, 65, 0, 762, 761, 1, 0, 0, 0, 762, 763, 1, 0, 0, 0, 763, 776, 1, 0, 0, 0, 764, 765, 5, 117, 0, 0, 765, 766, 5, 110, 0, 0, 766, 767, 5, 115, 0, 0, 767, 768, 5, 97, 0, 0, 768, 769, 5, 102, 0, 0, 769, 770, 5, 101, 0, 0, 770, 771, 5, 95, 0, 0, 771, 772, 5, 98, 0, 0, 772, 773, 5, 121, 0, 0, 773, 774, 5, 116, 0, 0, 774, 776, 5, 101, 0, 0, 775, 727, 1, 0, 0, 0, 775, 737, 1, 0, 0, 0, 775, 748, 1, 0, 0, 0, 775, 764, 1, 0, 0, 0, 776, 142, 1, 0, 0, 0, 777, 778, 5, 116, 0, 0, 778, 779, 5, 104, 0, 0, 779, 780, 5, 105, 0, 0, 780, 781, 5, 115, 0, 0, 781, 782, 5, 46, 0, 0, 782, 783, 5, 97, 0, 0, 783, 784, 5, 99, 0, 0, 784, 785, 5, 116, 0, 0, 785, 786, 5, 105, 0, 0, 786, 787, 5, 118, 0, 0, 787, 788, 5, 101, 0, 0, 788, 789, 5, 73, 0, 0, 789, 790, 5, 110, 0, 0, 790, 791, 5, 112, 0, 0, 791, 792, 5, 117, 0, 0, 792, 793, 5, 116, 0, 0, 793, 794, 5, 73, 0, 0, 794, 795, 5, 110, 0, 0, 795, 796, 5, 100, 0, 0, 796, 797, 5, 101, 0, 0, 797, 872, 5, 120, 0, 0, 798, 799, 5, 116, 0, 0, 799, 800, 5, 104, 0, 0, 800, 801, 5, 105, 0, 0, 801, 802, 5, 115, 0, 0, 802, 803, 5, 46, 0, 0, 803, 804, 5, 97, 0, 0, 804, 805, 5, 99, 0, 0, 805, 806, 5, 116, 0, 0, 806, 807, 5, 105, 0, 0, 807, 808, 5, 118, 0, 0, 808, 809, 5, 101, 0, 0, 809, 810, 5, 66, 0, 0, 810, 811, 5, 121, 0, 0, 811, 812, 5, 116, 0, 0, 812, 813, 5, 101, 0, 0, 813, 814, 5, 99, 0, 0, 814, 815, 5, 111, 0, 0, 815, 816, 5, 100, 0, 0, 816, 872, 5, 101, 0, 0, 817, 818, 5, 116, 0, 0, 818, 819, 5, 120, 0, 0, 819, 820, 5, 46, 0, 0, 820, 821, 5, 105, 0, 0, 821, 822, 5, 110, 0, 0, 822, 823, 5, 112, 0, 0, 823, 824, 5, 117, 0, 0, 824, 825, 5, 116, 0, 0, 825, 826, 5, 115, 0, 0, 826, 827, 5, 46, 0, 0, 827, 828, 5, 108, 0, 0, 828, 829, 5, 101, 0, 0, 829, 830, 5, 110, 0, 0, 830, 831, 5, 103, 0, 0, 831, 832, 5, 116, 0, 0, 832, 872, 5, 104, 0, 0, 833, 834, 5, 116, 0, 0, 834, 835, 5, 120, 0, 0, 835, 836, 5, 46, 0, 0, 836, 837, 5, 111, 0, 0, 837, 838, 5, 117, 0, 0, 838, 839, 5, 116, 0, 0, 839, 840, 5, 112, 0, 0, 840, 841, 5, 117, 0, 0, 841, 842, 5, 116, 0, 0, 842, 843, 5, 115, 0, 0, 843, 844, 5, 46, 0, 0, 844, 845, 5, 108, 0, 0, 845, 846, 5, 101, 0, 0, 846, 847, 5, 110, 0, 0, 847, 848, 5, 103, 0, 0, 848, 849, 5, 116, 0, 0, 849, 872, 5, 104, 0, 0, 850, 851, 5, 116, 0, 0, 851, 852, 5, 120, 0, 0, 852, 853, 5, 46, 0, 0, 853, 854, 5, 118, 0, 0, 854, 855, 5, 101, 0, 0, 855, 856, 5, 114, 0, 0, 856, 857, 5, 115, 0, 0, 857, 858, 5, 105, 0, 0, 858, 859, 5, 111, 0, 0, 859, 872, 5, 110, 0, 0, 860, 861, 5, 116, 0, 0, 861, 862, 5, 120, 0, 0, 862, 863, 5, 46, 0, 0, 863, 864, 5, 108, 0, 0, 864, 865, 5, 111, 0, 0, 865, 866, 5, 99, 0, 0, 866, 867, 5, 107, 0, 0, 867, 868, 5, 116, 0, 0, 868, 869, 5, 105, 0, 0, 869, 870, 5, 109, 0, 0, 870, 872, 5, 101, 0, 0, 871, 777, 1, 0, 0, 0, 871, 798, 1, 0, 0, 0, 871, 817, 1, 0, 0, 0, 871, 833, 1, 0, 0, 0, 871, 850, 1, 0, 0, 0, 871, 860, 1, 0, 0, 0, 872, 144, 1, 0, 0, 0, 873, 877, 7, 7, 0, 0, 874, 876, 7, 8, 0, 0, 875, 874, 1, 0, 0, 0, 876, 879, 1, 0, 0, 0, 877, 875, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 146, 1, 0, 0, 0, 879, 877, 1, 0, 0, 0, 880, 882, 7, 9, 0, 0, 881, 880, 1, 0, 0, 0, 882, 883, 1, 0, 0, 0, 883, 881, 1, 0, 0, 0, 883, 884, 1, 0, 0, 0, 884, 885, 1, 0, 0, 0, 885, 886, 6, 73, 0, 0, 886, 148, 1, 0, 0, 0, 887, 888, 5, 47, 0, 0, 888, 889, 5, 42, 0, 0, 889, 893, 1, 0, 0, 0, 890, 892, 9, 0, 0, 0, 891, 890, 1, 0, 0, 0, 892, 895, 1, 0, 0, 0, 893, 894, 1, 0, 0, 0, 893, 891, 1, 0, 0, 0, 894, 896, 1, 0, 0, 0, 895, 893, 1, 0, 0, 0, 896, 897, 5, 42, 0, 0, 897, 898, 5, 47, 0, 0, 898, 899, 1, 0, 0, 0, 899, 900, 6, 74, 1, 0, 900, 150, 1, 0, 0, 0, 901, 902, 5, 47, 0, 0, 902, 903, 5, 47, 0, 0, 903, 907, 1, 0, 0, 0, 904, 906, 8, 10, 0, 0, 905, 904, 1, 0, 0, 0, 906, 909, 1, 0, 0, 0, 907, 905, 1, 0, 0, 0, 907, 908, 1, 0, 0, 0, 908, 910, 1, 0, 0, 0, 909, 907, 1, 0, 0, 0, 910, 911, 6, 75, 1, 0, 911, 152, 1, 0, 0, 0, 28, 0, 504, 510, 516, 527, 586, 589, 593, 598, 604, 608, 643, 662, 668, 675, 677, 685, 687, 691, 707, 725, 762, 775, 871, 877, 883, 893, 907, 2, 6, 0, 0, 0, 1, 0] \ No newline at end of file diff --git a/packages/cashc/src/grammar/CashScriptLexer.tokens b/packages/cashc/src/grammar/CashScriptLexer.tokens index 4e0173da..e3e7d443 100644 --- a/packages/cashc/src/grammar/CashScriptLexer.tokens +++ b/packages/cashc/src/grammar/CashScriptLexer.tokens @@ -54,25 +54,26 @@ T__52=53 T__53=54 T__54=55 T__55=56 -T__56=57 -T__57=58 -VersionLiteral=59 -BooleanLiteral=60 -NumberUnit=61 -NumberLiteral=62 -NumberPart=63 -ExponentPart=64 -Bytes=65 +VersionLiteral=57 +BooleanLiteral=58 +NumberUnit=59 +NumberLiteral=60 +NumberPart=61 +ExponentPart=62 +PrimitiveType=63 +UnboundedBytes=64 +BoundedBytes=65 Bound=66 StringLiteral=67 DateLiteral=68 HexLiteral=69 TxVar=70 -NullaryOp=71 -Identifier=72 -WHITESPACE=73 -COMMENT=74 -LINE_COMMENT=75 +UnsafeCast=71 +NullaryOp=72 +Identifier=73 +WHITESPACE=74 +COMMENT=75 +LINE_COMMENT=76 'pragma'=1 ';'=2 'cashscript'=3 @@ -93,41 +94,40 @@ LINE_COMMENT=75 'require'=18 'if'=19 'else'=20 -'console.log'=21 -'new'=22 -'['=23 -']'=24 -'tx.outputs'=25 -'.value'=26 -'.lockingBytecode'=27 -'.tokenCategory'=28 -'.nftCommitment'=29 -'.tokenAmount'=30 -'tx.inputs'=31 -'.outpointTransactionHash'=32 -'.outpointIndex'=33 -'.unlockingBytecode'=34 -'.sequenceNumber'=35 -'.reverse()'=36 -'.length'=37 -'.split'=38 -'.slice'=39 -'!'=40 -'-'=41 -'*'=42 -'/'=43 -'%'=44 -'+'=45 -'=='=46 -'!='=47 -'&'=48 -'|'=49 -'&&'=50 -'||'=51 -'constant'=52 -'int'=53 -'bool'=54 -'string'=55 -'pubkey'=56 -'sig'=57 -'datasig'=58 +'do'=21 +'while'=22 +'console.log'=23 +'new'=24 +'['=25 +']'=26 +'tx.outputs'=27 +'.value'=28 +'.lockingBytecode'=29 +'.tokenCategory'=30 +'.nftCommitment'=31 +'.tokenAmount'=32 +'tx.inputs'=33 +'.outpointTransactionHash'=34 +'.outpointIndex'=35 +'.unlockingBytecode'=36 +'.sequenceNumber'=37 +'.reverse()'=38 +'.length'=39 +'.split'=40 +'.slice'=41 +'!'=42 +'-'=43 +'*'=44 +'/'=45 +'%'=46 +'+'=47 +'>>'=48 +'<<'=49 +'=='=50 +'!='=51 +'&'=52 +'|'=53 +'&&'=54 +'||'=55 +'constant'=56 +'bytes'=64 diff --git a/packages/cashc/src/grammar/CashScriptLexer.ts b/packages/cashc/src/grammar/CashScriptLexer.ts index 73ad0dcb..b801f22c 100644 --- a/packages/cashc/src/grammar/CashScriptLexer.ts +++ b/packages/cashc/src/grammar/CashScriptLexer.ts @@ -68,25 +68,26 @@ export default class CashScriptLexer extends Lexer { public static readonly T__53 = 54; public static readonly T__54 = 55; public static readonly T__55 = 56; - public static readonly T__56 = 57; - public static readonly T__57 = 58; - public static readonly VersionLiteral = 59; - public static readonly BooleanLiteral = 60; - public static readonly NumberUnit = 61; - public static readonly NumberLiteral = 62; - public static readonly NumberPart = 63; - public static readonly ExponentPart = 64; - public static readonly Bytes = 65; + public static readonly VersionLiteral = 57; + public static readonly BooleanLiteral = 58; + public static readonly NumberUnit = 59; + public static readonly NumberLiteral = 60; + public static readonly NumberPart = 61; + public static readonly ExponentPart = 62; + public static readonly PrimitiveType = 63; + public static readonly UnboundedBytes = 64; + public static readonly BoundedBytes = 65; public static readonly Bound = 66; public static readonly StringLiteral = 67; public static readonly DateLiteral = 68; public static readonly HexLiteral = 69; public static readonly TxVar = 70; - public static readonly NullaryOp = 71; - public static readonly Identifier = 72; - public static readonly WHITESPACE = 73; - public static readonly COMMENT = 74; - public static readonly LINE_COMMENT = 75; + public static readonly UnsafeCast = 71; + public static readonly NullaryOp = 72; + public static readonly Identifier = 73; + public static readonly WHITESPACE = 74; + public static readonly COMMENT = 75; + public static readonly LINE_COMMENT = 76; public static readonly EOF = Token.EOF; public static readonly channelNames: string[] = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN" ]; @@ -101,6 +102,7 @@ export default class CashScriptLexer extends Lexer { "'('", "','", "')'", "'require'", "'if'", "'else'", + "'do'", "'while'", "'console.log'", "'new'", "'['", "']'", "'tx.outputs'", @@ -121,14 +123,15 @@ export default class CashScriptLexer extends Lexer { "'!'", "'-'", "'*'", "'/'", "'%'", "'+'", + "'>>'", "'<<'", "'=='", "'!='", "'&'", "'|'", "'&&'", "'||'", "'constant'", - "'int'", "'bool'", - "'string'", - "'pubkey'", - "'sig'", "'datasig'" ]; + null, null, + null, null, + null, null, + null, "'bytes'" ]; public static readonly symbolicNames: (string | null)[] = [ null, null, null, null, null, null, @@ -157,18 +160,20 @@ export default class CashScriptLexer extends Lexer { null, null, null, null, null, null, - null, null, null, "VersionLiteral", "BooleanLiteral", "NumberUnit", "NumberLiteral", "NumberPart", "ExponentPart", - "Bytes", "Bound", - "StringLiteral", + "PrimitiveType", + "UnboundedBytes", + "BoundedBytes", + "Bound", "StringLiteral", "DateLiteral", "HexLiteral", - "TxVar", "NullaryOp", + "TxVar", "UnsafeCast", + "NullaryOp", "Identifier", "WHITESPACE", "COMMENT", @@ -182,11 +187,11 @@ export default class CashScriptLexer extends Lexer { "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40", "T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48", - "T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56", - "T__57", "VersionLiteral", "BooleanLiteral", "NumberUnit", "NumberLiteral", - "NumberPart", "ExponentPart", "Bytes", "Bound", "StringLiteral", "DateLiteral", - "HexLiteral", "TxVar", "NullaryOp", "Identifier", "WHITESPACE", "COMMENT", - "LINE_COMMENT", + "T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "VersionLiteral", + "BooleanLiteral", "NumberUnit", "NumberLiteral", "NumberPart", "ExponentPart", + "PrimitiveType", "UnboundedBytes", "BoundedBytes", "Bound", "StringLiteral", + "DateLiteral", "HexLiteral", "TxVar", "UnsafeCast", "NullaryOp", "Identifier", + "WHITESPACE", "COMMENT", "LINE_COMMENT", ]; @@ -207,7 +212,7 @@ export default class CashScriptLexer extends Lexer { public get modeNames(): string[] { return CashScriptLexer.modeNames; } - public static readonly _serializedATN: number[] = [4,0,75,845,6,-1,2,0, + public static readonly _serializedATN: number[] = [4,0,76,912,6,-1,2,0, 7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9, 7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7, 16,2,17,7,17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23, @@ -218,272 +223,296 @@ export default class CashScriptLexer extends Lexer { 2,53,7,53,2,54,7,54,2,55,7,55,2,56,7,56,2,57,7,57,2,58,7,58,2,59,7,59,2, 60,7,60,2,61,7,61,2,62,7,62,2,63,7,63,2,64,7,64,2,65,7,65,2,66,7,66,2,67, 7,67,2,68,7,68,2,69,7,69,2,70,7,70,2,71,7,71,2,72,7,72,2,73,7,73,2,74,7, - 74,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2, - 1,2,1,2,1,2,1,3,1,3,1,4,1,4,1,5,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1,8,1,9, - 1,9,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,12,1,12,1, - 13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,14,1,14,1,15,1,15,1,16,1,16, - 1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,18,1,19,1,19,1,19,1, - 19,1,19,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,21, - 1,21,1,21,1,21,1,22,1,22,1,23,1,23,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1, - 24,1,24,1,24,1,24,1,25,1,25,1,25,1,25,1,25,1,25,1,25,1,26,1,26,1,26,1,26, - 1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,27,1, - 27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,28, - 1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1, - 29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,30,1,30, - 1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31,1,31,1,31,1, - 31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31, - 1,31,1,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1, + 74,2,75,7,75,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1, + 2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,4,1,4,1,5,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1, + 8,1,8,1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1, + 12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,14,1,14,1,15,1,15, + 1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,18,1,19,1, + 19,1,19,1,19,1,19,1,20,1,20,1,20,1,21,1,21,1,21,1,21,1,21,1,21,1,22,1,22, + 1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,23,1,23,1,23,1,23,1, + 24,1,24,1,25,1,25,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26, + 1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1, + 28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,29,1,29,1,29,1,29,1,29, + 1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1, + 30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31, + 1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1, 32,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33, - 1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,34,1,34,1,34,1,34,1,34,1, - 34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35, - 1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1, - 36,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,1,38, - 1,39,1,39,1,40,1,40,1,41,1,41,1,42,1,42,1,43,1,43,1,44,1,44,1,45,1,45,1, - 45,1,46,1,46,1,46,1,47,1,47,1,48,1,48,1,49,1,49,1,49,1,50,1,50,1,50,1,51, - 1,51,1,51,1,51,1,51,1,51,1,51,1,51,1,51,1,52,1,52,1,52,1,52,1,53,1,53,1, - 53,1,53,1,53,1,54,1,54,1,54,1,54,1,54,1,54,1,54,1,55,1,55,1,55,1,55,1,55, - 1,55,1,55,1,56,1,56,1,56,1,56,1,57,1,57,1,57,1,57,1,57,1,57,1,57,1,57,1, - 58,4,58,521,8,58,11,58,12,58,522,1,58,1,58,4,58,527,8,58,11,58,12,58,528, - 1,58,1,58,4,58,533,8,58,11,58,12,58,534,1,59,1,59,1,59,1,59,1,59,1,59,1, - 59,1,59,1,59,3,59,546,8,59,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60, - 1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1, - 60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60, - 1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1, - 60,1,60,1,60,1,60,1,60,3,60,605,8,60,1,61,3,61,608,8,61,1,61,1,61,3,61, - 612,8,61,1,62,4,62,615,8,62,11,62,12,62,616,1,62,1,62,4,62,621,8,62,11, - 62,12,62,622,5,62,625,8,62,10,62,12,62,628,9,62,1,63,1,63,1,63,1,64,1,64, - 1,64,1,64,1,64,1,64,1,64,3,64,640,8,64,1,64,1,64,1,64,1,64,3,64,646,8,64, - 1,65,1,65,5,65,650,8,65,10,65,12,65,653,9,65,1,66,1,66,1,66,1,66,5,66,659, - 8,66,10,66,12,66,662,9,66,1,66,1,66,1,66,1,66,1,66,5,66,669,8,66,10,66, - 12,66,672,9,66,1,66,3,66,675,8,66,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1, - 67,1,67,1,68,1,68,1,68,5,68,689,8,68,10,68,12,68,692,9,68,1,69,1,69,1,69, - 1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,3,69,709,8, - 69,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70, - 1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1, - 70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70, - 1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1, - 70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70, + 1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1, + 33,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34, + 1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1, + 35,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,36, + 1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1, + 37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,39,1,39,1,39, + 1,39,1,39,1,39,1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,41,1,41,1,42,1, + 42,1,43,1,43,1,44,1,44,1,45,1,45,1,46,1,46,1,47,1,47,1,47,1,48,1,48,1,48, + 1,49,1,49,1,49,1,50,1,50,1,50,1,51,1,51,1,52,1,52,1,53,1,53,1,53,1,54,1, + 54,1,54,1,55,1,55,1,55,1,55,1,55,1,55,1,55,1,55,1,55,1,56,4,56,503,8,56, + 11,56,12,56,504,1,56,1,56,4,56,509,8,56,11,56,12,56,510,1,56,1,56,4,56, + 515,8,56,11,56,12,56,516,1,57,1,57,1,57,1,57,1,57,1,57,1,57,1,57,1,57,3, + 57,528,8,57,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58, + 1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1, + 58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58, + 1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1,58,1, + 58,1,58,3,58,587,8,58,1,59,3,59,590,8,59,1,59,1,59,3,59,594,8,59,1,60,4, + 60,597,8,60,11,60,12,60,598,1,60,1,60,4,60,603,8,60,11,60,12,60,604,5,60, + 607,8,60,10,60,12,60,610,9,60,1,61,1,61,1,61,1,62,1,62,1,62,1,62,1,62,1, + 62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62, + 1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,3,62,644,8,62,1,63,1,63,1, + 63,1,63,1,63,1,63,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64, + 3,64,663,8,64,1,65,1,65,5,65,667,8,65,10,65,12,65,670,9,65,1,66,1,66,1, + 66,1,66,5,66,676,8,66,10,66,12,66,679,9,66,1,66,1,66,1,66,1,66,1,66,5,66, + 686,8,66,10,66,12,66,689,9,66,1,66,3,66,692,8,66,1,67,1,67,1,67,1,67,1, + 67,1,67,1,67,1,67,1,67,1,68,1,68,1,68,5,68,706,8,68,10,68,12,68,709,9,68, + 1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1, + 69,3,69,726,8,69,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70, 1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1, - 70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,3,70,805,8,70,1,71,1,71,5,71,809, - 8,71,10,71,12,71,812,9,71,1,72,4,72,815,8,72,11,72,12,72,816,1,72,1,72, - 1,73,1,73,1,73,1,73,5,73,825,8,73,10,73,12,73,828,9,73,1,73,1,73,1,73,1, - 73,1,73,1,74,1,74,1,74,1,74,5,74,839,8,74,10,74,12,74,842,9,74,1,74,1,74, - 3,660,670,826,0,75,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11, - 23,12,25,13,27,14,29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23, - 47,24,49,25,51,26,53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35, - 71,36,73,37,75,38,77,39,79,40,81,41,83,42,85,43,87,44,89,45,91,46,93,47, - 95,48,97,49,99,50,101,51,103,52,105,53,107,54,109,55,111,56,113,57,115, - 58,117,59,119,60,121,61,123,62,125,63,127,64,129,65,131,66,133,67,135,68, - 137,69,139,70,141,71,143,72,145,73,147,74,149,75,1,0,11,1,0,48,57,2,0,69, - 69,101,101,1,0,49,57,3,0,10,10,13,13,34,34,3,0,10,10,13,13,39,39,2,0,88, - 88,120,120,3,0,48,57,65,70,97,102,2,0,65,90,97,122,4,0,48,57,65,90,95,95, - 97,122,3,0,9,10,12,13,32,32,2,0,10,10,13,13,881,0,1,1,0,0,0,0,3,1,0,0,0, - 0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0, - 0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0, - 27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0, - 0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0, - 49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0, - 0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0,0,0, - 71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0, - 0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,0,89,1,0,0,0,0,91,1,0,0,0,0, - 93,1,0,0,0,0,95,1,0,0,0,0,97,1,0,0,0,0,99,1,0,0,0,0,101,1,0,0,0,0,103,1, - 0,0,0,0,105,1,0,0,0,0,107,1,0,0,0,0,109,1,0,0,0,0,111,1,0,0,0,0,113,1,0, - 0,0,0,115,1,0,0,0,0,117,1,0,0,0,0,119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0, - 0,0,125,1,0,0,0,0,127,1,0,0,0,0,129,1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0, - 0,135,1,0,0,0,0,137,1,0,0,0,0,139,1,0,0,0,0,141,1,0,0,0,0,143,1,0,0,0,0, - 145,1,0,0,0,0,147,1,0,0,0,0,149,1,0,0,0,1,151,1,0,0,0,3,158,1,0,0,0,5,160, - 1,0,0,0,7,171,1,0,0,0,9,173,1,0,0,0,11,175,1,0,0,0,13,178,1,0,0,0,15,180, - 1,0,0,0,17,182,1,0,0,0,19,185,1,0,0,0,21,187,1,0,0,0,23,196,1,0,0,0,25, - 198,1,0,0,0,27,200,1,0,0,0,29,209,1,0,0,0,31,211,1,0,0,0,33,213,1,0,0,0, - 35,215,1,0,0,0,37,223,1,0,0,0,39,226,1,0,0,0,41,231,1,0,0,0,43,243,1,0, - 0,0,45,247,1,0,0,0,47,249,1,0,0,0,49,251,1,0,0,0,51,262,1,0,0,0,53,269, - 1,0,0,0,55,286,1,0,0,0,57,301,1,0,0,0,59,316,1,0,0,0,61,329,1,0,0,0,63, - 339,1,0,0,0,65,364,1,0,0,0,67,379,1,0,0,0,69,398,1,0,0,0,71,414,1,0,0,0, - 73,425,1,0,0,0,75,433,1,0,0,0,77,440,1,0,0,0,79,447,1,0,0,0,81,449,1,0, - 0,0,83,451,1,0,0,0,85,453,1,0,0,0,87,455,1,0,0,0,89,457,1,0,0,0,91,459, - 1,0,0,0,93,462,1,0,0,0,95,465,1,0,0,0,97,467,1,0,0,0,99,469,1,0,0,0,101, - 472,1,0,0,0,103,475,1,0,0,0,105,484,1,0,0,0,107,488,1,0,0,0,109,493,1,0, - 0,0,111,500,1,0,0,0,113,507,1,0,0,0,115,511,1,0,0,0,117,520,1,0,0,0,119, - 545,1,0,0,0,121,604,1,0,0,0,123,607,1,0,0,0,125,614,1,0,0,0,127,629,1,0, - 0,0,129,645,1,0,0,0,131,647,1,0,0,0,133,674,1,0,0,0,135,676,1,0,0,0,137, - 685,1,0,0,0,139,708,1,0,0,0,141,804,1,0,0,0,143,806,1,0,0,0,145,814,1,0, - 0,0,147,820,1,0,0,0,149,834,1,0,0,0,151,152,5,112,0,0,152,153,5,114,0,0, - 153,154,5,97,0,0,154,155,5,103,0,0,155,156,5,109,0,0,156,157,5,97,0,0,157, - 2,1,0,0,0,158,159,5,59,0,0,159,4,1,0,0,0,160,161,5,99,0,0,161,162,5,97, - 0,0,162,163,5,115,0,0,163,164,5,104,0,0,164,165,5,115,0,0,165,166,5,99, - 0,0,166,167,5,114,0,0,167,168,5,105,0,0,168,169,5,112,0,0,169,170,5,116, - 0,0,170,6,1,0,0,0,171,172,5,94,0,0,172,8,1,0,0,0,173,174,5,126,0,0,174, - 10,1,0,0,0,175,176,5,62,0,0,176,177,5,61,0,0,177,12,1,0,0,0,178,179,5,62, - 0,0,179,14,1,0,0,0,180,181,5,60,0,0,181,16,1,0,0,0,182,183,5,60,0,0,183, - 184,5,61,0,0,184,18,1,0,0,0,185,186,5,61,0,0,186,20,1,0,0,0,187,188,5,99, - 0,0,188,189,5,111,0,0,189,190,5,110,0,0,190,191,5,116,0,0,191,192,5,114, - 0,0,192,193,5,97,0,0,193,194,5,99,0,0,194,195,5,116,0,0,195,22,1,0,0,0, - 196,197,5,123,0,0,197,24,1,0,0,0,198,199,5,125,0,0,199,26,1,0,0,0,200,201, - 5,102,0,0,201,202,5,117,0,0,202,203,5,110,0,0,203,204,5,99,0,0,204,205, - 5,116,0,0,205,206,5,105,0,0,206,207,5,111,0,0,207,208,5,110,0,0,208,28, - 1,0,0,0,209,210,5,40,0,0,210,30,1,0,0,0,211,212,5,44,0,0,212,32,1,0,0,0, - 213,214,5,41,0,0,214,34,1,0,0,0,215,216,5,114,0,0,216,217,5,101,0,0,217, - 218,5,113,0,0,218,219,5,117,0,0,219,220,5,105,0,0,220,221,5,114,0,0,221, - 222,5,101,0,0,222,36,1,0,0,0,223,224,5,105,0,0,224,225,5,102,0,0,225,38, - 1,0,0,0,226,227,5,101,0,0,227,228,5,108,0,0,228,229,5,115,0,0,229,230,5, - 101,0,0,230,40,1,0,0,0,231,232,5,99,0,0,232,233,5,111,0,0,233,234,5,110, - 0,0,234,235,5,115,0,0,235,236,5,111,0,0,236,237,5,108,0,0,237,238,5,101, - 0,0,238,239,5,46,0,0,239,240,5,108,0,0,240,241,5,111,0,0,241,242,5,103, - 0,0,242,42,1,0,0,0,243,244,5,110,0,0,244,245,5,101,0,0,245,246,5,119,0, - 0,246,44,1,0,0,0,247,248,5,91,0,0,248,46,1,0,0,0,249,250,5,93,0,0,250,48, - 1,0,0,0,251,252,5,116,0,0,252,253,5,120,0,0,253,254,5,46,0,0,254,255,5, - 111,0,0,255,256,5,117,0,0,256,257,5,116,0,0,257,258,5,112,0,0,258,259,5, - 117,0,0,259,260,5,116,0,0,260,261,5,115,0,0,261,50,1,0,0,0,262,263,5,46, - 0,0,263,264,5,118,0,0,264,265,5,97,0,0,265,266,5,108,0,0,266,267,5,117, - 0,0,267,268,5,101,0,0,268,52,1,0,0,0,269,270,5,46,0,0,270,271,5,108,0,0, - 271,272,5,111,0,0,272,273,5,99,0,0,273,274,5,107,0,0,274,275,5,105,0,0, - 275,276,5,110,0,0,276,277,5,103,0,0,277,278,5,66,0,0,278,279,5,121,0,0, - 279,280,5,116,0,0,280,281,5,101,0,0,281,282,5,99,0,0,282,283,5,111,0,0, - 283,284,5,100,0,0,284,285,5,101,0,0,285,54,1,0,0,0,286,287,5,46,0,0,287, - 288,5,116,0,0,288,289,5,111,0,0,289,290,5,107,0,0,290,291,5,101,0,0,291, - 292,5,110,0,0,292,293,5,67,0,0,293,294,5,97,0,0,294,295,5,116,0,0,295,296, - 5,101,0,0,296,297,5,103,0,0,297,298,5,111,0,0,298,299,5,114,0,0,299,300, - 5,121,0,0,300,56,1,0,0,0,301,302,5,46,0,0,302,303,5,110,0,0,303,304,5,102, - 0,0,304,305,5,116,0,0,305,306,5,67,0,0,306,307,5,111,0,0,307,308,5,109, - 0,0,308,309,5,109,0,0,309,310,5,105,0,0,310,311,5,116,0,0,311,312,5,109, - 0,0,312,313,5,101,0,0,313,314,5,110,0,0,314,315,5,116,0,0,315,58,1,0,0, - 0,316,317,5,46,0,0,317,318,5,116,0,0,318,319,5,111,0,0,319,320,5,107,0, - 0,320,321,5,101,0,0,321,322,5,110,0,0,322,323,5,65,0,0,323,324,5,109,0, - 0,324,325,5,111,0,0,325,326,5,117,0,0,326,327,5,110,0,0,327,328,5,116,0, - 0,328,60,1,0,0,0,329,330,5,116,0,0,330,331,5,120,0,0,331,332,5,46,0,0,332, - 333,5,105,0,0,333,334,5,110,0,0,334,335,5,112,0,0,335,336,5,117,0,0,336, - 337,5,116,0,0,337,338,5,115,0,0,338,62,1,0,0,0,339,340,5,46,0,0,340,341, - 5,111,0,0,341,342,5,117,0,0,342,343,5,116,0,0,343,344,5,112,0,0,344,345, - 5,111,0,0,345,346,5,105,0,0,346,347,5,110,0,0,347,348,5,116,0,0,348,349, - 5,84,0,0,349,350,5,114,0,0,350,351,5,97,0,0,351,352,5,110,0,0,352,353,5, - 115,0,0,353,354,5,97,0,0,354,355,5,99,0,0,355,356,5,116,0,0,356,357,5,105, - 0,0,357,358,5,111,0,0,358,359,5,110,0,0,359,360,5,72,0,0,360,361,5,97,0, - 0,361,362,5,115,0,0,362,363,5,104,0,0,363,64,1,0,0,0,364,365,5,46,0,0,365, - 366,5,111,0,0,366,367,5,117,0,0,367,368,5,116,0,0,368,369,5,112,0,0,369, - 370,5,111,0,0,370,371,5,105,0,0,371,372,5,110,0,0,372,373,5,116,0,0,373, - 374,5,73,0,0,374,375,5,110,0,0,375,376,5,100,0,0,376,377,5,101,0,0,377, - 378,5,120,0,0,378,66,1,0,0,0,379,380,5,46,0,0,380,381,5,117,0,0,381,382, - 5,110,0,0,382,383,5,108,0,0,383,384,5,111,0,0,384,385,5,99,0,0,385,386, - 5,107,0,0,386,387,5,105,0,0,387,388,5,110,0,0,388,389,5,103,0,0,389,390, - 5,66,0,0,390,391,5,121,0,0,391,392,5,116,0,0,392,393,5,101,0,0,393,394, - 5,99,0,0,394,395,5,111,0,0,395,396,5,100,0,0,396,397,5,101,0,0,397,68,1, - 0,0,0,398,399,5,46,0,0,399,400,5,115,0,0,400,401,5,101,0,0,401,402,5,113, - 0,0,402,403,5,117,0,0,403,404,5,101,0,0,404,405,5,110,0,0,405,406,5,99, - 0,0,406,407,5,101,0,0,407,408,5,78,0,0,408,409,5,117,0,0,409,410,5,109, - 0,0,410,411,5,98,0,0,411,412,5,101,0,0,412,413,5,114,0,0,413,70,1,0,0,0, - 414,415,5,46,0,0,415,416,5,114,0,0,416,417,5,101,0,0,417,418,5,118,0,0, - 418,419,5,101,0,0,419,420,5,114,0,0,420,421,5,115,0,0,421,422,5,101,0,0, - 422,423,5,40,0,0,423,424,5,41,0,0,424,72,1,0,0,0,425,426,5,46,0,0,426,427, - 5,108,0,0,427,428,5,101,0,0,428,429,5,110,0,0,429,430,5,103,0,0,430,431, - 5,116,0,0,431,432,5,104,0,0,432,74,1,0,0,0,433,434,5,46,0,0,434,435,5,115, - 0,0,435,436,5,112,0,0,436,437,5,108,0,0,437,438,5,105,0,0,438,439,5,116, - 0,0,439,76,1,0,0,0,440,441,5,46,0,0,441,442,5,115,0,0,442,443,5,108,0,0, - 443,444,5,105,0,0,444,445,5,99,0,0,445,446,5,101,0,0,446,78,1,0,0,0,447, - 448,5,33,0,0,448,80,1,0,0,0,449,450,5,45,0,0,450,82,1,0,0,0,451,452,5,42, - 0,0,452,84,1,0,0,0,453,454,5,47,0,0,454,86,1,0,0,0,455,456,5,37,0,0,456, - 88,1,0,0,0,457,458,5,43,0,0,458,90,1,0,0,0,459,460,5,61,0,0,460,461,5,61, - 0,0,461,92,1,0,0,0,462,463,5,33,0,0,463,464,5,61,0,0,464,94,1,0,0,0,465, - 466,5,38,0,0,466,96,1,0,0,0,467,468,5,124,0,0,468,98,1,0,0,0,469,470,5, - 38,0,0,470,471,5,38,0,0,471,100,1,0,0,0,472,473,5,124,0,0,473,474,5,124, - 0,0,474,102,1,0,0,0,475,476,5,99,0,0,476,477,5,111,0,0,477,478,5,110,0, - 0,478,479,5,115,0,0,479,480,5,116,0,0,480,481,5,97,0,0,481,482,5,110,0, - 0,482,483,5,116,0,0,483,104,1,0,0,0,484,485,5,105,0,0,485,486,5,110,0,0, - 486,487,5,116,0,0,487,106,1,0,0,0,488,489,5,98,0,0,489,490,5,111,0,0,490, - 491,5,111,0,0,491,492,5,108,0,0,492,108,1,0,0,0,493,494,5,115,0,0,494,495, - 5,116,0,0,495,496,5,114,0,0,496,497,5,105,0,0,497,498,5,110,0,0,498,499, - 5,103,0,0,499,110,1,0,0,0,500,501,5,112,0,0,501,502,5,117,0,0,502,503,5, - 98,0,0,503,504,5,107,0,0,504,505,5,101,0,0,505,506,5,121,0,0,506,112,1, - 0,0,0,507,508,5,115,0,0,508,509,5,105,0,0,509,510,5,103,0,0,510,114,1,0, - 0,0,511,512,5,100,0,0,512,513,5,97,0,0,513,514,5,116,0,0,514,515,5,97,0, - 0,515,516,5,115,0,0,516,517,5,105,0,0,517,518,5,103,0,0,518,116,1,0,0,0, - 519,521,7,0,0,0,520,519,1,0,0,0,521,522,1,0,0,0,522,520,1,0,0,0,522,523, - 1,0,0,0,523,524,1,0,0,0,524,526,5,46,0,0,525,527,7,0,0,0,526,525,1,0,0, - 0,527,528,1,0,0,0,528,526,1,0,0,0,528,529,1,0,0,0,529,530,1,0,0,0,530,532, - 5,46,0,0,531,533,7,0,0,0,532,531,1,0,0,0,533,534,1,0,0,0,534,532,1,0,0, - 0,534,535,1,0,0,0,535,118,1,0,0,0,536,537,5,116,0,0,537,538,5,114,0,0,538, - 539,5,117,0,0,539,546,5,101,0,0,540,541,5,102,0,0,541,542,5,97,0,0,542, - 543,5,108,0,0,543,544,5,115,0,0,544,546,5,101,0,0,545,536,1,0,0,0,545,540, - 1,0,0,0,546,120,1,0,0,0,547,548,5,115,0,0,548,549,5,97,0,0,549,550,5,116, - 0,0,550,551,5,111,0,0,551,552,5,115,0,0,552,553,5,104,0,0,553,554,5,105, - 0,0,554,605,5,115,0,0,555,556,5,115,0,0,556,557,5,97,0,0,557,558,5,116, - 0,0,558,605,5,115,0,0,559,560,5,102,0,0,560,561,5,105,0,0,561,562,5,110, - 0,0,562,563,5,110,0,0,563,564,5,101,0,0,564,605,5,121,0,0,565,566,5,98, - 0,0,566,567,5,105,0,0,567,568,5,116,0,0,568,605,5,115,0,0,569,570,5,98, - 0,0,570,571,5,105,0,0,571,572,5,116,0,0,572,573,5,99,0,0,573,574,5,111, - 0,0,574,575,5,105,0,0,575,605,5,110,0,0,576,577,5,115,0,0,577,578,5,101, - 0,0,578,579,5,99,0,0,579,580,5,111,0,0,580,581,5,110,0,0,581,582,5,100, - 0,0,582,605,5,115,0,0,583,584,5,109,0,0,584,585,5,105,0,0,585,586,5,110, - 0,0,586,587,5,117,0,0,587,588,5,116,0,0,588,589,5,101,0,0,589,605,5,115, - 0,0,590,591,5,104,0,0,591,592,5,111,0,0,592,593,5,117,0,0,593,594,5,114, - 0,0,594,605,5,115,0,0,595,596,5,100,0,0,596,597,5,97,0,0,597,598,5,121, - 0,0,598,605,5,115,0,0,599,600,5,119,0,0,600,601,5,101,0,0,601,602,5,101, - 0,0,602,603,5,107,0,0,603,605,5,115,0,0,604,547,1,0,0,0,604,555,1,0,0,0, - 604,559,1,0,0,0,604,565,1,0,0,0,604,569,1,0,0,0,604,576,1,0,0,0,604,583, - 1,0,0,0,604,590,1,0,0,0,604,595,1,0,0,0,604,599,1,0,0,0,605,122,1,0,0,0, - 606,608,5,45,0,0,607,606,1,0,0,0,607,608,1,0,0,0,608,609,1,0,0,0,609,611, - 3,125,62,0,610,612,3,127,63,0,611,610,1,0,0,0,611,612,1,0,0,0,612,124,1, - 0,0,0,613,615,7,0,0,0,614,613,1,0,0,0,615,616,1,0,0,0,616,614,1,0,0,0,616, - 617,1,0,0,0,617,626,1,0,0,0,618,620,5,95,0,0,619,621,7,0,0,0,620,619,1, - 0,0,0,621,622,1,0,0,0,622,620,1,0,0,0,622,623,1,0,0,0,623,625,1,0,0,0,624, - 618,1,0,0,0,625,628,1,0,0,0,626,624,1,0,0,0,626,627,1,0,0,0,627,126,1,0, - 0,0,628,626,1,0,0,0,629,630,7,1,0,0,630,631,3,125,62,0,631,128,1,0,0,0, - 632,633,5,98,0,0,633,634,5,121,0,0,634,635,5,116,0,0,635,636,5,101,0,0, - 636,637,5,115,0,0,637,639,1,0,0,0,638,640,3,131,65,0,639,638,1,0,0,0,639, - 640,1,0,0,0,640,646,1,0,0,0,641,642,5,98,0,0,642,643,5,121,0,0,643,644, - 5,116,0,0,644,646,5,101,0,0,645,632,1,0,0,0,645,641,1,0,0,0,646,130,1,0, - 0,0,647,651,7,2,0,0,648,650,7,0,0,0,649,648,1,0,0,0,650,653,1,0,0,0,651, - 649,1,0,0,0,651,652,1,0,0,0,652,132,1,0,0,0,653,651,1,0,0,0,654,660,5,34, - 0,0,655,656,5,92,0,0,656,659,5,34,0,0,657,659,8,3,0,0,658,655,1,0,0,0,658, - 657,1,0,0,0,659,662,1,0,0,0,660,661,1,0,0,0,660,658,1,0,0,0,661,663,1,0, - 0,0,662,660,1,0,0,0,663,675,5,34,0,0,664,670,5,39,0,0,665,666,5,92,0,0, - 666,669,5,39,0,0,667,669,8,4,0,0,668,665,1,0,0,0,668,667,1,0,0,0,669,672, - 1,0,0,0,670,671,1,0,0,0,670,668,1,0,0,0,671,673,1,0,0,0,672,670,1,0,0,0, - 673,675,5,39,0,0,674,654,1,0,0,0,674,664,1,0,0,0,675,134,1,0,0,0,676,677, - 5,100,0,0,677,678,5,97,0,0,678,679,5,116,0,0,679,680,5,101,0,0,680,681, - 5,40,0,0,681,682,1,0,0,0,682,683,3,133,66,0,683,684,5,41,0,0,684,136,1, - 0,0,0,685,686,5,48,0,0,686,690,7,5,0,0,687,689,7,6,0,0,688,687,1,0,0,0, - 689,692,1,0,0,0,690,688,1,0,0,0,690,691,1,0,0,0,691,138,1,0,0,0,692,690, - 1,0,0,0,693,694,5,116,0,0,694,695,5,104,0,0,695,696,5,105,0,0,696,697,5, - 115,0,0,697,698,5,46,0,0,698,699,5,97,0,0,699,700,5,103,0,0,700,709,5,101, - 0,0,701,702,5,116,0,0,702,703,5,120,0,0,703,704,5,46,0,0,704,705,5,116, - 0,0,705,706,5,105,0,0,706,707,5,109,0,0,707,709,5,101,0,0,708,693,1,0,0, - 0,708,701,1,0,0,0,709,140,1,0,0,0,710,711,5,116,0,0,711,712,5,104,0,0,712, - 713,5,105,0,0,713,714,5,115,0,0,714,715,5,46,0,0,715,716,5,97,0,0,716,717, - 5,99,0,0,717,718,5,116,0,0,718,719,5,105,0,0,719,720,5,118,0,0,720,721, - 5,101,0,0,721,722,5,73,0,0,722,723,5,110,0,0,723,724,5,112,0,0,724,725, - 5,117,0,0,725,726,5,116,0,0,726,727,5,73,0,0,727,728,5,110,0,0,728,729, - 5,100,0,0,729,730,5,101,0,0,730,805,5,120,0,0,731,732,5,116,0,0,732,733, - 5,104,0,0,733,734,5,105,0,0,734,735,5,115,0,0,735,736,5,46,0,0,736,737, - 5,97,0,0,737,738,5,99,0,0,738,739,5,116,0,0,739,740,5,105,0,0,740,741,5, - 118,0,0,741,742,5,101,0,0,742,743,5,66,0,0,743,744,5,121,0,0,744,745,5, - 116,0,0,745,746,5,101,0,0,746,747,5,99,0,0,747,748,5,111,0,0,748,749,5, - 100,0,0,749,805,5,101,0,0,750,751,5,116,0,0,751,752,5,120,0,0,752,753,5, - 46,0,0,753,754,5,105,0,0,754,755,5,110,0,0,755,756,5,112,0,0,756,757,5, - 117,0,0,757,758,5,116,0,0,758,759,5,115,0,0,759,760,5,46,0,0,760,761,5, - 108,0,0,761,762,5,101,0,0,762,763,5,110,0,0,763,764,5,103,0,0,764,765,5, - 116,0,0,765,805,5,104,0,0,766,767,5,116,0,0,767,768,5,120,0,0,768,769,5, - 46,0,0,769,770,5,111,0,0,770,771,5,117,0,0,771,772,5,116,0,0,772,773,5, - 112,0,0,773,774,5,117,0,0,774,775,5,116,0,0,775,776,5,115,0,0,776,777,5, - 46,0,0,777,778,5,108,0,0,778,779,5,101,0,0,779,780,5,110,0,0,780,781,5, - 103,0,0,781,782,5,116,0,0,782,805,5,104,0,0,783,784,5,116,0,0,784,785,5, - 120,0,0,785,786,5,46,0,0,786,787,5,118,0,0,787,788,5,101,0,0,788,789,5, - 114,0,0,789,790,5,115,0,0,790,791,5,105,0,0,791,792,5,111,0,0,792,805,5, - 110,0,0,793,794,5,116,0,0,794,795,5,120,0,0,795,796,5,46,0,0,796,797,5, - 108,0,0,797,798,5,111,0,0,798,799,5,99,0,0,799,800,5,107,0,0,800,801,5, - 116,0,0,801,802,5,105,0,0,802,803,5,109,0,0,803,805,5,101,0,0,804,710,1, - 0,0,0,804,731,1,0,0,0,804,750,1,0,0,0,804,766,1,0,0,0,804,783,1,0,0,0,804, - 793,1,0,0,0,805,142,1,0,0,0,806,810,7,7,0,0,807,809,7,8,0,0,808,807,1,0, - 0,0,809,812,1,0,0,0,810,808,1,0,0,0,810,811,1,0,0,0,811,144,1,0,0,0,812, - 810,1,0,0,0,813,815,7,9,0,0,814,813,1,0,0,0,815,816,1,0,0,0,816,814,1,0, - 0,0,816,817,1,0,0,0,817,818,1,0,0,0,818,819,6,72,0,0,819,146,1,0,0,0,820, - 821,5,47,0,0,821,822,5,42,0,0,822,826,1,0,0,0,823,825,9,0,0,0,824,823,1, - 0,0,0,825,828,1,0,0,0,826,827,1,0,0,0,826,824,1,0,0,0,827,829,1,0,0,0,828, - 826,1,0,0,0,829,830,5,42,0,0,830,831,5,47,0,0,831,832,1,0,0,0,832,833,6, - 73,1,0,833,148,1,0,0,0,834,835,5,47,0,0,835,836,5,47,0,0,836,840,1,0,0, - 0,837,839,8,10,0,0,838,837,1,0,0,0,839,842,1,0,0,0,840,838,1,0,0,0,840, - 841,1,0,0,0,841,843,1,0,0,0,842,840,1,0,0,0,843,844,6,74,1,0,844,150,1, - 0,0,0,26,0,522,528,534,545,604,607,611,616,622,626,639,645,651,658,660, - 668,670,674,690,708,804,810,816,826,840,2,6,0,0,0,1,0]; + 70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,3,70,763,8,70,1,70,1,70, + 1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,1,70,3,70,776,8,70,1,71,1,71,1, + 71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71, + 1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1, + 71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71, + 1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1, + 71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71, + 1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1,71,1, + 71,1,71,1,71,1,71,1,71,3,71,872,8,71,1,72,1,72,5,72,876,8,72,10,72,12,72, + 879,9,72,1,73,4,73,882,8,73,11,73,12,73,883,1,73,1,73,1,74,1,74,1,74,1, + 74,5,74,892,8,74,10,74,12,74,895,9,74,1,74,1,74,1,74,1,74,1,74,1,75,1,75, + 1,75,1,75,5,75,906,8,75,10,75,12,75,909,9,75,1,75,1,75,3,677,687,893,0, + 76,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14, + 29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49,25,51,26, + 53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,71,36,73,37,75,38, + 77,39,79,40,81,41,83,42,85,43,87,44,89,45,91,46,93,47,95,48,97,49,99,50, + 101,51,103,52,105,53,107,54,109,55,111,56,113,57,115,58,117,59,119,60,121, + 61,123,62,125,63,127,64,129,65,131,66,133,67,135,68,137,69,139,70,141,71, + 143,72,145,73,147,74,149,75,151,76,1,0,11,1,0,48,57,2,0,69,69,101,101,1, + 0,49,57,3,0,10,10,13,13,34,34,3,0,10,10,13,13,39,39,2,0,88,88,120,120,3, + 0,48,57,65,70,97,102,2,0,65,90,97,122,4,0,48,57,65,90,95,95,97,122,3,0, + 9,10,12,13,32,32,2,0,10,10,13,13,956,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0, + 0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1, + 0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0, + 0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1, + 0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0, + 0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1, + 0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0, + 0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1, + 0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,0,89,1,0,0,0,0,91,1,0,0,0,0,93,1,0,0,0, + 0,95,1,0,0,0,0,97,1,0,0,0,0,99,1,0,0,0,0,101,1,0,0,0,0,103,1,0,0,0,0,105, + 1,0,0,0,0,107,1,0,0,0,0,109,1,0,0,0,0,111,1,0,0,0,0,113,1,0,0,0,0,115,1, + 0,0,0,0,117,1,0,0,0,0,119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0, + 0,0,0,127,1,0,0,0,0,129,1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0,0,135,1,0,0, + 0,0,137,1,0,0,0,0,139,1,0,0,0,0,141,1,0,0,0,0,143,1,0,0,0,0,145,1,0,0,0, + 0,147,1,0,0,0,0,149,1,0,0,0,0,151,1,0,0,0,1,153,1,0,0,0,3,160,1,0,0,0,5, + 162,1,0,0,0,7,173,1,0,0,0,9,175,1,0,0,0,11,177,1,0,0,0,13,180,1,0,0,0,15, + 182,1,0,0,0,17,184,1,0,0,0,19,187,1,0,0,0,21,189,1,0,0,0,23,198,1,0,0,0, + 25,200,1,0,0,0,27,202,1,0,0,0,29,211,1,0,0,0,31,213,1,0,0,0,33,215,1,0, + 0,0,35,217,1,0,0,0,37,225,1,0,0,0,39,228,1,0,0,0,41,233,1,0,0,0,43,236, + 1,0,0,0,45,242,1,0,0,0,47,254,1,0,0,0,49,258,1,0,0,0,51,260,1,0,0,0,53, + 262,1,0,0,0,55,273,1,0,0,0,57,280,1,0,0,0,59,297,1,0,0,0,61,312,1,0,0,0, + 63,327,1,0,0,0,65,340,1,0,0,0,67,350,1,0,0,0,69,375,1,0,0,0,71,390,1,0, + 0,0,73,409,1,0,0,0,75,425,1,0,0,0,77,436,1,0,0,0,79,444,1,0,0,0,81,451, + 1,0,0,0,83,458,1,0,0,0,85,460,1,0,0,0,87,462,1,0,0,0,89,464,1,0,0,0,91, + 466,1,0,0,0,93,468,1,0,0,0,95,470,1,0,0,0,97,473,1,0,0,0,99,476,1,0,0,0, + 101,479,1,0,0,0,103,482,1,0,0,0,105,484,1,0,0,0,107,486,1,0,0,0,109,489, + 1,0,0,0,111,492,1,0,0,0,113,502,1,0,0,0,115,527,1,0,0,0,117,586,1,0,0,0, + 119,589,1,0,0,0,121,596,1,0,0,0,123,611,1,0,0,0,125,643,1,0,0,0,127,645, + 1,0,0,0,129,662,1,0,0,0,131,664,1,0,0,0,133,691,1,0,0,0,135,693,1,0,0,0, + 137,702,1,0,0,0,139,725,1,0,0,0,141,775,1,0,0,0,143,871,1,0,0,0,145,873, + 1,0,0,0,147,881,1,0,0,0,149,887,1,0,0,0,151,901,1,0,0,0,153,154,5,112,0, + 0,154,155,5,114,0,0,155,156,5,97,0,0,156,157,5,103,0,0,157,158,5,109,0, + 0,158,159,5,97,0,0,159,2,1,0,0,0,160,161,5,59,0,0,161,4,1,0,0,0,162,163, + 5,99,0,0,163,164,5,97,0,0,164,165,5,115,0,0,165,166,5,104,0,0,166,167,5, + 115,0,0,167,168,5,99,0,0,168,169,5,114,0,0,169,170,5,105,0,0,170,171,5, + 112,0,0,171,172,5,116,0,0,172,6,1,0,0,0,173,174,5,94,0,0,174,8,1,0,0,0, + 175,176,5,126,0,0,176,10,1,0,0,0,177,178,5,62,0,0,178,179,5,61,0,0,179, + 12,1,0,0,0,180,181,5,62,0,0,181,14,1,0,0,0,182,183,5,60,0,0,183,16,1,0, + 0,0,184,185,5,60,0,0,185,186,5,61,0,0,186,18,1,0,0,0,187,188,5,61,0,0,188, + 20,1,0,0,0,189,190,5,99,0,0,190,191,5,111,0,0,191,192,5,110,0,0,192,193, + 5,116,0,0,193,194,5,114,0,0,194,195,5,97,0,0,195,196,5,99,0,0,196,197,5, + 116,0,0,197,22,1,0,0,0,198,199,5,123,0,0,199,24,1,0,0,0,200,201,5,125,0, + 0,201,26,1,0,0,0,202,203,5,102,0,0,203,204,5,117,0,0,204,205,5,110,0,0, + 205,206,5,99,0,0,206,207,5,116,0,0,207,208,5,105,0,0,208,209,5,111,0,0, + 209,210,5,110,0,0,210,28,1,0,0,0,211,212,5,40,0,0,212,30,1,0,0,0,213,214, + 5,44,0,0,214,32,1,0,0,0,215,216,5,41,0,0,216,34,1,0,0,0,217,218,5,114,0, + 0,218,219,5,101,0,0,219,220,5,113,0,0,220,221,5,117,0,0,221,222,5,105,0, + 0,222,223,5,114,0,0,223,224,5,101,0,0,224,36,1,0,0,0,225,226,5,105,0,0, + 226,227,5,102,0,0,227,38,1,0,0,0,228,229,5,101,0,0,229,230,5,108,0,0,230, + 231,5,115,0,0,231,232,5,101,0,0,232,40,1,0,0,0,233,234,5,100,0,0,234,235, + 5,111,0,0,235,42,1,0,0,0,236,237,5,119,0,0,237,238,5,104,0,0,238,239,5, + 105,0,0,239,240,5,108,0,0,240,241,5,101,0,0,241,44,1,0,0,0,242,243,5,99, + 0,0,243,244,5,111,0,0,244,245,5,110,0,0,245,246,5,115,0,0,246,247,5,111, + 0,0,247,248,5,108,0,0,248,249,5,101,0,0,249,250,5,46,0,0,250,251,5,108, + 0,0,251,252,5,111,0,0,252,253,5,103,0,0,253,46,1,0,0,0,254,255,5,110,0, + 0,255,256,5,101,0,0,256,257,5,119,0,0,257,48,1,0,0,0,258,259,5,91,0,0,259, + 50,1,0,0,0,260,261,5,93,0,0,261,52,1,0,0,0,262,263,5,116,0,0,263,264,5, + 120,0,0,264,265,5,46,0,0,265,266,5,111,0,0,266,267,5,117,0,0,267,268,5, + 116,0,0,268,269,5,112,0,0,269,270,5,117,0,0,270,271,5,116,0,0,271,272,5, + 115,0,0,272,54,1,0,0,0,273,274,5,46,0,0,274,275,5,118,0,0,275,276,5,97, + 0,0,276,277,5,108,0,0,277,278,5,117,0,0,278,279,5,101,0,0,279,56,1,0,0, + 0,280,281,5,46,0,0,281,282,5,108,0,0,282,283,5,111,0,0,283,284,5,99,0,0, + 284,285,5,107,0,0,285,286,5,105,0,0,286,287,5,110,0,0,287,288,5,103,0,0, + 288,289,5,66,0,0,289,290,5,121,0,0,290,291,5,116,0,0,291,292,5,101,0,0, + 292,293,5,99,0,0,293,294,5,111,0,0,294,295,5,100,0,0,295,296,5,101,0,0, + 296,58,1,0,0,0,297,298,5,46,0,0,298,299,5,116,0,0,299,300,5,111,0,0,300, + 301,5,107,0,0,301,302,5,101,0,0,302,303,5,110,0,0,303,304,5,67,0,0,304, + 305,5,97,0,0,305,306,5,116,0,0,306,307,5,101,0,0,307,308,5,103,0,0,308, + 309,5,111,0,0,309,310,5,114,0,0,310,311,5,121,0,0,311,60,1,0,0,0,312,313, + 5,46,0,0,313,314,5,110,0,0,314,315,5,102,0,0,315,316,5,116,0,0,316,317, + 5,67,0,0,317,318,5,111,0,0,318,319,5,109,0,0,319,320,5,109,0,0,320,321, + 5,105,0,0,321,322,5,116,0,0,322,323,5,109,0,0,323,324,5,101,0,0,324,325, + 5,110,0,0,325,326,5,116,0,0,326,62,1,0,0,0,327,328,5,46,0,0,328,329,5,116, + 0,0,329,330,5,111,0,0,330,331,5,107,0,0,331,332,5,101,0,0,332,333,5,110, + 0,0,333,334,5,65,0,0,334,335,5,109,0,0,335,336,5,111,0,0,336,337,5,117, + 0,0,337,338,5,110,0,0,338,339,5,116,0,0,339,64,1,0,0,0,340,341,5,116,0, + 0,341,342,5,120,0,0,342,343,5,46,0,0,343,344,5,105,0,0,344,345,5,110,0, + 0,345,346,5,112,0,0,346,347,5,117,0,0,347,348,5,116,0,0,348,349,5,115,0, + 0,349,66,1,0,0,0,350,351,5,46,0,0,351,352,5,111,0,0,352,353,5,117,0,0,353, + 354,5,116,0,0,354,355,5,112,0,0,355,356,5,111,0,0,356,357,5,105,0,0,357, + 358,5,110,0,0,358,359,5,116,0,0,359,360,5,84,0,0,360,361,5,114,0,0,361, + 362,5,97,0,0,362,363,5,110,0,0,363,364,5,115,0,0,364,365,5,97,0,0,365,366, + 5,99,0,0,366,367,5,116,0,0,367,368,5,105,0,0,368,369,5,111,0,0,369,370, + 5,110,0,0,370,371,5,72,0,0,371,372,5,97,0,0,372,373,5,115,0,0,373,374,5, + 104,0,0,374,68,1,0,0,0,375,376,5,46,0,0,376,377,5,111,0,0,377,378,5,117, + 0,0,378,379,5,116,0,0,379,380,5,112,0,0,380,381,5,111,0,0,381,382,5,105, + 0,0,382,383,5,110,0,0,383,384,5,116,0,0,384,385,5,73,0,0,385,386,5,110, + 0,0,386,387,5,100,0,0,387,388,5,101,0,0,388,389,5,120,0,0,389,70,1,0,0, + 0,390,391,5,46,0,0,391,392,5,117,0,0,392,393,5,110,0,0,393,394,5,108,0, + 0,394,395,5,111,0,0,395,396,5,99,0,0,396,397,5,107,0,0,397,398,5,105,0, + 0,398,399,5,110,0,0,399,400,5,103,0,0,400,401,5,66,0,0,401,402,5,121,0, + 0,402,403,5,116,0,0,403,404,5,101,0,0,404,405,5,99,0,0,405,406,5,111,0, + 0,406,407,5,100,0,0,407,408,5,101,0,0,408,72,1,0,0,0,409,410,5,46,0,0,410, + 411,5,115,0,0,411,412,5,101,0,0,412,413,5,113,0,0,413,414,5,117,0,0,414, + 415,5,101,0,0,415,416,5,110,0,0,416,417,5,99,0,0,417,418,5,101,0,0,418, + 419,5,78,0,0,419,420,5,117,0,0,420,421,5,109,0,0,421,422,5,98,0,0,422,423, + 5,101,0,0,423,424,5,114,0,0,424,74,1,0,0,0,425,426,5,46,0,0,426,427,5,114, + 0,0,427,428,5,101,0,0,428,429,5,118,0,0,429,430,5,101,0,0,430,431,5,114, + 0,0,431,432,5,115,0,0,432,433,5,101,0,0,433,434,5,40,0,0,434,435,5,41,0, + 0,435,76,1,0,0,0,436,437,5,46,0,0,437,438,5,108,0,0,438,439,5,101,0,0,439, + 440,5,110,0,0,440,441,5,103,0,0,441,442,5,116,0,0,442,443,5,104,0,0,443, + 78,1,0,0,0,444,445,5,46,0,0,445,446,5,115,0,0,446,447,5,112,0,0,447,448, + 5,108,0,0,448,449,5,105,0,0,449,450,5,116,0,0,450,80,1,0,0,0,451,452,5, + 46,0,0,452,453,5,115,0,0,453,454,5,108,0,0,454,455,5,105,0,0,455,456,5, + 99,0,0,456,457,5,101,0,0,457,82,1,0,0,0,458,459,5,33,0,0,459,84,1,0,0,0, + 460,461,5,45,0,0,461,86,1,0,0,0,462,463,5,42,0,0,463,88,1,0,0,0,464,465, + 5,47,0,0,465,90,1,0,0,0,466,467,5,37,0,0,467,92,1,0,0,0,468,469,5,43,0, + 0,469,94,1,0,0,0,470,471,5,62,0,0,471,472,5,62,0,0,472,96,1,0,0,0,473,474, + 5,60,0,0,474,475,5,60,0,0,475,98,1,0,0,0,476,477,5,61,0,0,477,478,5,61, + 0,0,478,100,1,0,0,0,479,480,5,33,0,0,480,481,5,61,0,0,481,102,1,0,0,0,482, + 483,5,38,0,0,483,104,1,0,0,0,484,485,5,124,0,0,485,106,1,0,0,0,486,487, + 5,38,0,0,487,488,5,38,0,0,488,108,1,0,0,0,489,490,5,124,0,0,490,491,5,124, + 0,0,491,110,1,0,0,0,492,493,5,99,0,0,493,494,5,111,0,0,494,495,5,110,0, + 0,495,496,5,115,0,0,496,497,5,116,0,0,497,498,5,97,0,0,498,499,5,110,0, + 0,499,500,5,116,0,0,500,112,1,0,0,0,501,503,7,0,0,0,502,501,1,0,0,0,503, + 504,1,0,0,0,504,502,1,0,0,0,504,505,1,0,0,0,505,506,1,0,0,0,506,508,5,46, + 0,0,507,509,7,0,0,0,508,507,1,0,0,0,509,510,1,0,0,0,510,508,1,0,0,0,510, + 511,1,0,0,0,511,512,1,0,0,0,512,514,5,46,0,0,513,515,7,0,0,0,514,513,1, + 0,0,0,515,516,1,0,0,0,516,514,1,0,0,0,516,517,1,0,0,0,517,114,1,0,0,0,518, + 519,5,116,0,0,519,520,5,114,0,0,520,521,5,117,0,0,521,528,5,101,0,0,522, + 523,5,102,0,0,523,524,5,97,0,0,524,525,5,108,0,0,525,526,5,115,0,0,526, + 528,5,101,0,0,527,518,1,0,0,0,527,522,1,0,0,0,528,116,1,0,0,0,529,530,5, + 115,0,0,530,531,5,97,0,0,531,532,5,116,0,0,532,533,5,111,0,0,533,534,5, + 115,0,0,534,535,5,104,0,0,535,536,5,105,0,0,536,587,5,115,0,0,537,538,5, + 115,0,0,538,539,5,97,0,0,539,540,5,116,0,0,540,587,5,115,0,0,541,542,5, + 102,0,0,542,543,5,105,0,0,543,544,5,110,0,0,544,545,5,110,0,0,545,546,5, + 101,0,0,546,587,5,121,0,0,547,548,5,98,0,0,548,549,5,105,0,0,549,550,5, + 116,0,0,550,587,5,115,0,0,551,552,5,98,0,0,552,553,5,105,0,0,553,554,5, + 116,0,0,554,555,5,99,0,0,555,556,5,111,0,0,556,557,5,105,0,0,557,587,5, + 110,0,0,558,559,5,115,0,0,559,560,5,101,0,0,560,561,5,99,0,0,561,562,5, + 111,0,0,562,563,5,110,0,0,563,564,5,100,0,0,564,587,5,115,0,0,565,566,5, + 109,0,0,566,567,5,105,0,0,567,568,5,110,0,0,568,569,5,117,0,0,569,570,5, + 116,0,0,570,571,5,101,0,0,571,587,5,115,0,0,572,573,5,104,0,0,573,574,5, + 111,0,0,574,575,5,117,0,0,575,576,5,114,0,0,576,587,5,115,0,0,577,578,5, + 100,0,0,578,579,5,97,0,0,579,580,5,121,0,0,580,587,5,115,0,0,581,582,5, + 119,0,0,582,583,5,101,0,0,583,584,5,101,0,0,584,585,5,107,0,0,585,587,5, + 115,0,0,586,529,1,0,0,0,586,537,1,0,0,0,586,541,1,0,0,0,586,547,1,0,0,0, + 586,551,1,0,0,0,586,558,1,0,0,0,586,565,1,0,0,0,586,572,1,0,0,0,586,577, + 1,0,0,0,586,581,1,0,0,0,587,118,1,0,0,0,588,590,5,45,0,0,589,588,1,0,0, + 0,589,590,1,0,0,0,590,591,1,0,0,0,591,593,3,121,60,0,592,594,3,123,61,0, + 593,592,1,0,0,0,593,594,1,0,0,0,594,120,1,0,0,0,595,597,7,0,0,0,596,595, + 1,0,0,0,597,598,1,0,0,0,598,596,1,0,0,0,598,599,1,0,0,0,599,608,1,0,0,0, + 600,602,5,95,0,0,601,603,7,0,0,0,602,601,1,0,0,0,603,604,1,0,0,0,604,602, + 1,0,0,0,604,605,1,0,0,0,605,607,1,0,0,0,606,600,1,0,0,0,607,610,1,0,0,0, + 608,606,1,0,0,0,608,609,1,0,0,0,609,122,1,0,0,0,610,608,1,0,0,0,611,612, + 7,1,0,0,612,613,3,121,60,0,613,124,1,0,0,0,614,615,5,105,0,0,615,616,5, + 110,0,0,616,644,5,116,0,0,617,618,5,98,0,0,618,619,5,111,0,0,619,620,5, + 111,0,0,620,644,5,108,0,0,621,622,5,115,0,0,622,623,5,116,0,0,623,624,5, + 114,0,0,624,625,5,105,0,0,625,626,5,110,0,0,626,644,5,103,0,0,627,628,5, + 112,0,0,628,629,5,117,0,0,629,630,5,98,0,0,630,631,5,107,0,0,631,632,5, + 101,0,0,632,644,5,121,0,0,633,634,5,115,0,0,634,635,5,105,0,0,635,644,5, + 103,0,0,636,637,5,100,0,0,637,638,5,97,0,0,638,639,5,116,0,0,639,640,5, + 97,0,0,640,641,5,115,0,0,641,642,5,105,0,0,642,644,5,103,0,0,643,614,1, + 0,0,0,643,617,1,0,0,0,643,621,1,0,0,0,643,627,1,0,0,0,643,633,1,0,0,0,643, + 636,1,0,0,0,644,126,1,0,0,0,645,646,5,98,0,0,646,647,5,121,0,0,647,648, + 5,116,0,0,648,649,5,101,0,0,649,650,5,115,0,0,650,128,1,0,0,0,651,652,5, + 98,0,0,652,653,5,121,0,0,653,654,5,116,0,0,654,655,5,101,0,0,655,656,5, + 115,0,0,656,657,1,0,0,0,657,663,3,131,65,0,658,659,5,98,0,0,659,660,5,121, + 0,0,660,661,5,116,0,0,661,663,5,101,0,0,662,651,1,0,0,0,662,658,1,0,0,0, + 663,130,1,0,0,0,664,668,7,2,0,0,665,667,7,0,0,0,666,665,1,0,0,0,667,670, + 1,0,0,0,668,666,1,0,0,0,668,669,1,0,0,0,669,132,1,0,0,0,670,668,1,0,0,0, + 671,677,5,34,0,0,672,673,5,92,0,0,673,676,5,34,0,0,674,676,8,3,0,0,675, + 672,1,0,0,0,675,674,1,0,0,0,676,679,1,0,0,0,677,678,1,0,0,0,677,675,1,0, + 0,0,678,680,1,0,0,0,679,677,1,0,0,0,680,692,5,34,0,0,681,687,5,39,0,0,682, + 683,5,92,0,0,683,686,5,39,0,0,684,686,8,4,0,0,685,682,1,0,0,0,685,684,1, + 0,0,0,686,689,1,0,0,0,687,688,1,0,0,0,687,685,1,0,0,0,688,690,1,0,0,0,689, + 687,1,0,0,0,690,692,5,39,0,0,691,671,1,0,0,0,691,681,1,0,0,0,692,134,1, + 0,0,0,693,694,5,100,0,0,694,695,5,97,0,0,695,696,5,116,0,0,696,697,5,101, + 0,0,697,698,5,40,0,0,698,699,1,0,0,0,699,700,3,133,66,0,700,701,5,41,0, + 0,701,136,1,0,0,0,702,703,5,48,0,0,703,707,7,5,0,0,704,706,7,6,0,0,705, + 704,1,0,0,0,706,709,1,0,0,0,707,705,1,0,0,0,707,708,1,0,0,0,708,138,1,0, + 0,0,709,707,1,0,0,0,710,711,5,116,0,0,711,712,5,104,0,0,712,713,5,105,0, + 0,713,714,5,115,0,0,714,715,5,46,0,0,715,716,5,97,0,0,716,717,5,103,0,0, + 717,726,5,101,0,0,718,719,5,116,0,0,719,720,5,120,0,0,720,721,5,46,0,0, + 721,722,5,116,0,0,722,723,5,105,0,0,723,724,5,109,0,0,724,726,5,101,0,0, + 725,710,1,0,0,0,725,718,1,0,0,0,726,140,1,0,0,0,727,728,5,117,0,0,728,729, + 5,110,0,0,729,730,5,115,0,0,730,731,5,97,0,0,731,732,5,102,0,0,732,733, + 5,101,0,0,733,734,5,95,0,0,734,735,5,105,0,0,735,736,5,110,0,0,736,776, + 5,116,0,0,737,738,5,117,0,0,738,739,5,110,0,0,739,740,5,115,0,0,740,741, + 5,97,0,0,741,742,5,102,0,0,742,743,5,101,0,0,743,744,5,95,0,0,744,745,5, + 98,0,0,745,746,5,111,0,0,746,747,5,111,0,0,747,776,5,108,0,0,748,749,5, + 117,0,0,749,750,5,110,0,0,750,751,5,115,0,0,751,752,5,97,0,0,752,753,5, + 102,0,0,753,754,5,101,0,0,754,755,5,95,0,0,755,756,5,98,0,0,756,757,5,121, + 0,0,757,758,5,116,0,0,758,759,5,101,0,0,759,760,5,115,0,0,760,762,1,0,0, + 0,761,763,3,131,65,0,762,761,1,0,0,0,762,763,1,0,0,0,763,776,1,0,0,0,764, + 765,5,117,0,0,765,766,5,110,0,0,766,767,5,115,0,0,767,768,5,97,0,0,768, + 769,5,102,0,0,769,770,5,101,0,0,770,771,5,95,0,0,771,772,5,98,0,0,772,773, + 5,121,0,0,773,774,5,116,0,0,774,776,5,101,0,0,775,727,1,0,0,0,775,737,1, + 0,0,0,775,748,1,0,0,0,775,764,1,0,0,0,776,142,1,0,0,0,777,778,5,116,0,0, + 778,779,5,104,0,0,779,780,5,105,0,0,780,781,5,115,0,0,781,782,5,46,0,0, + 782,783,5,97,0,0,783,784,5,99,0,0,784,785,5,116,0,0,785,786,5,105,0,0,786, + 787,5,118,0,0,787,788,5,101,0,0,788,789,5,73,0,0,789,790,5,110,0,0,790, + 791,5,112,0,0,791,792,5,117,0,0,792,793,5,116,0,0,793,794,5,73,0,0,794, + 795,5,110,0,0,795,796,5,100,0,0,796,797,5,101,0,0,797,872,5,120,0,0,798, + 799,5,116,0,0,799,800,5,104,0,0,800,801,5,105,0,0,801,802,5,115,0,0,802, + 803,5,46,0,0,803,804,5,97,0,0,804,805,5,99,0,0,805,806,5,116,0,0,806,807, + 5,105,0,0,807,808,5,118,0,0,808,809,5,101,0,0,809,810,5,66,0,0,810,811, + 5,121,0,0,811,812,5,116,0,0,812,813,5,101,0,0,813,814,5,99,0,0,814,815, + 5,111,0,0,815,816,5,100,0,0,816,872,5,101,0,0,817,818,5,116,0,0,818,819, + 5,120,0,0,819,820,5,46,0,0,820,821,5,105,0,0,821,822,5,110,0,0,822,823, + 5,112,0,0,823,824,5,117,0,0,824,825,5,116,0,0,825,826,5,115,0,0,826,827, + 5,46,0,0,827,828,5,108,0,0,828,829,5,101,0,0,829,830,5,110,0,0,830,831, + 5,103,0,0,831,832,5,116,0,0,832,872,5,104,0,0,833,834,5,116,0,0,834,835, + 5,120,0,0,835,836,5,46,0,0,836,837,5,111,0,0,837,838,5,117,0,0,838,839, + 5,116,0,0,839,840,5,112,0,0,840,841,5,117,0,0,841,842,5,116,0,0,842,843, + 5,115,0,0,843,844,5,46,0,0,844,845,5,108,0,0,845,846,5,101,0,0,846,847, + 5,110,0,0,847,848,5,103,0,0,848,849,5,116,0,0,849,872,5,104,0,0,850,851, + 5,116,0,0,851,852,5,120,0,0,852,853,5,46,0,0,853,854,5,118,0,0,854,855, + 5,101,0,0,855,856,5,114,0,0,856,857,5,115,0,0,857,858,5,105,0,0,858,859, + 5,111,0,0,859,872,5,110,0,0,860,861,5,116,0,0,861,862,5,120,0,0,862,863, + 5,46,0,0,863,864,5,108,0,0,864,865,5,111,0,0,865,866,5,99,0,0,866,867,5, + 107,0,0,867,868,5,116,0,0,868,869,5,105,0,0,869,870,5,109,0,0,870,872,5, + 101,0,0,871,777,1,0,0,0,871,798,1,0,0,0,871,817,1,0,0,0,871,833,1,0,0,0, + 871,850,1,0,0,0,871,860,1,0,0,0,872,144,1,0,0,0,873,877,7,7,0,0,874,876, + 7,8,0,0,875,874,1,0,0,0,876,879,1,0,0,0,877,875,1,0,0,0,877,878,1,0,0,0, + 878,146,1,0,0,0,879,877,1,0,0,0,880,882,7,9,0,0,881,880,1,0,0,0,882,883, + 1,0,0,0,883,881,1,0,0,0,883,884,1,0,0,0,884,885,1,0,0,0,885,886,6,73,0, + 0,886,148,1,0,0,0,887,888,5,47,0,0,888,889,5,42,0,0,889,893,1,0,0,0,890, + 892,9,0,0,0,891,890,1,0,0,0,892,895,1,0,0,0,893,894,1,0,0,0,893,891,1,0, + 0,0,894,896,1,0,0,0,895,893,1,0,0,0,896,897,5,42,0,0,897,898,5,47,0,0,898, + 899,1,0,0,0,899,900,6,74,1,0,900,150,1,0,0,0,901,902,5,47,0,0,902,903,5, + 47,0,0,903,907,1,0,0,0,904,906,8,10,0,0,905,904,1,0,0,0,906,909,1,0,0,0, + 907,905,1,0,0,0,907,908,1,0,0,0,908,910,1,0,0,0,909,907,1,0,0,0,910,911, + 6,75,1,0,911,152,1,0,0,0,28,0,504,510,516,527,586,589,593,598,604,608,643, + 662,668,675,677,685,687,691,707,725,762,775,871,877,883,893,907,2,6,0,0, + 0,1,0]; private static __ATN: ATN; public static get _ATN(): ATN { diff --git a/packages/cashc/src/grammar/CashScriptParser.ts b/packages/cashc/src/grammar/CashScriptParser.ts index 24ec7f97..5fbbfc40 100644 --- a/packages/cashc/src/grammar/CashScriptParser.ts +++ b/packages/cashc/src/grammar/CashScriptParser.ts @@ -74,25 +74,26 @@ export default class CashScriptParser extends Parser { public static readonly T__53 = 54; public static readonly T__54 = 55; public static readonly T__55 = 56; - public static readonly T__56 = 57; - public static readonly T__57 = 58; - public static readonly VersionLiteral = 59; - public static readonly BooleanLiteral = 60; - public static readonly NumberUnit = 61; - public static readonly NumberLiteral = 62; - public static readonly NumberPart = 63; - public static readonly ExponentPart = 64; - public static readonly Bytes = 65; + public static readonly VersionLiteral = 57; + public static readonly BooleanLiteral = 58; + public static readonly NumberUnit = 59; + public static readonly NumberLiteral = 60; + public static readonly NumberPart = 61; + public static readonly ExponentPart = 62; + public static readonly PrimitiveType = 63; + public static readonly UnboundedBytes = 64; + public static readonly BoundedBytes = 65; public static readonly Bound = 66; public static readonly StringLiteral = 67; public static readonly DateLiteral = 68; public static readonly HexLiteral = 69; public static readonly TxVar = 70; - public static readonly NullaryOp = 71; - public static readonly Identifier = 72; - public static readonly WHITESPACE = 73; - public static readonly COMMENT = 74; - public static readonly LINE_COMMENT = 75; + public static readonly UnsafeCast = 71; + public static readonly NullaryOp = 72; + public static readonly Identifier = 73; + public static readonly WHITESPACE = 74; + public static readonly COMMENT = 75; + public static readonly LINE_COMMENT = 76; public static readonly EOF = Token.EOF; public static readonly RULE_sourceFile = 0; public static readonly RULE_pragmaDirective = 1; @@ -112,17 +113,20 @@ export default class CashScriptParser extends Parser { public static readonly RULE_timeOpStatement = 15; public static readonly RULE_requireStatement = 16; public static readonly RULE_ifStatement = 17; - public static readonly RULE_consoleStatement = 18; - public static readonly RULE_requireMessage = 19; - public static readonly RULE_consoleParameter = 20; - public static readonly RULE_consoleParameterList = 21; - public static readonly RULE_functionCall = 22; - public static readonly RULE_expressionList = 23; - public static readonly RULE_expression = 24; - public static readonly RULE_modifier = 25; - public static readonly RULE_literal = 26; - public static readonly RULE_numberLiteral = 27; - public static readonly RULE_typeName = 28; + public static readonly RULE_loopStatement = 18; + public static readonly RULE_doWhileStatement = 19; + public static readonly RULE_consoleStatement = 20; + public static readonly RULE_requireMessage = 21; + public static readonly RULE_consoleParameter = 22; + public static readonly RULE_consoleParameterList = 23; + public static readonly RULE_functionCall = 24; + public static readonly RULE_expressionList = 25; + public static readonly RULE_expression = 26; + public static readonly RULE_modifier = 27; + public static readonly RULE_literal = 28; + public static readonly RULE_numberLiteral = 29; + public static readonly RULE_typeName = 30; + public static readonly RULE_typeCast = 31; public static readonly literalNames: (string | null)[] = [ null, "'pragma'", "';'", "'cashscript'", "'^'", "'~'", @@ -134,6 +138,7 @@ export default class CashScriptParser extends Parser { "'('", "','", "')'", "'require'", "'if'", "'else'", + "'do'", "'while'", "'console.log'", "'new'", "'['", "']'", "'tx.outputs'", @@ -154,14 +159,15 @@ export default class CashScriptParser extends Parser { "'!'", "'-'", "'*'", "'/'", "'%'", "'+'", + "'>>'", "'<<'", "'=='", "'!='", "'&'", "'|'", "'&&'", "'||'", "'constant'", - "'int'", "'bool'", - "'string'", - "'pubkey'", - "'sig'", "'datasig'" ]; + null, null, + null, null, + null, null, + null, "'bytes'" ]; public static readonly symbolicNames: (string | null)[] = [ null, null, null, null, null, null, @@ -190,18 +196,20 @@ export default class CashScriptParser extends Parser { null, null, null, null, null, null, - null, null, null, "VersionLiteral", "BooleanLiteral", "NumberUnit", "NumberLiteral", "NumberPart", "ExponentPart", - "Bytes", "Bound", - "StringLiteral", + "PrimitiveType", + "UnboundedBytes", + "BoundedBytes", + "Bound", "StringLiteral", "DateLiteral", "HexLiteral", - "TxVar", "NullaryOp", + "TxVar", "UnsafeCast", + "NullaryOp", "Identifier", "WHITESPACE", "COMMENT", @@ -212,9 +220,9 @@ export default class CashScriptParser extends Parser { "versionOperator", "contractDefinition", "functionDefinition", "parameterList", "parameter", "block", "statement", "variableDefinition", "tupleAssignment", "assignStatement", "timeOpStatement", "requireStatement", "ifStatement", - "consoleStatement", "requireMessage", "consoleParameter", "consoleParameterList", - "functionCall", "expressionList", "expression", "modifier", "literal", - "numberLiteral", "typeName", + "loopStatement", "doWhileStatement", "consoleStatement", "requireMessage", + "consoleParameter", "consoleParameterList", "functionCall", "expressionList", + "expression", "modifier", "literal", "numberLiteral", "typeName", "typeCast", ]; public get grammarFileName(): string { return "CashScript.g4"; } public get literalNames(): (string | null)[] { return CashScriptParser.literalNames; } @@ -238,23 +246,23 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 61; + this.state = 67; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===1) { { { - this.state = 58; + this.state = 64; this.pragmaDirective(); } } - this.state = 63; + this.state = 69; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 64; + this.state = 70; this.contractDefinition(); - this.state = 65; + this.state = 71; this.match(CashScriptParser.EOF); } } @@ -279,13 +287,13 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 67; + this.state = 73; this.match(CashScriptParser.T__0); - this.state = 68; + this.state = 74; this.pragmaName(); - this.state = 69; + this.state = 75; this.pragmaValue(); - this.state = 70; + this.state = 76; this.match(CashScriptParser.T__1); } } @@ -310,7 +318,7 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 72; + this.state = 78; this.match(CashScriptParser.T__2); } } @@ -336,14 +344,14 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 74; + this.state = 80; this.versionConstraint(); - this.state = 76; + this.state = 82; this._errHandler.sync(this); _la = this._input.LA(1); - if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0) || _la===59) { + if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0) || _la===57) { { - this.state = 75; + this.state = 81; this.versionConstraint(); } } @@ -372,17 +380,17 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 79; + this.state = 85; this._errHandler.sync(this); _la = this._input.LA(1); if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0)) { { - this.state = 78; + this.state = 84; this.versionOperator(); } } - this.state = 81; + this.state = 87; this.match(CashScriptParser.VersionLiteral); } } @@ -408,7 +416,7 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 83; + this.state = 89; _la = this._input.LA(1); if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0))) { this._errHandler.recoverInline(this); @@ -441,29 +449,29 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 85; + this.state = 91; this.match(CashScriptParser.T__10); - this.state = 86; + this.state = 92; this.match(CashScriptParser.Identifier); - this.state = 87; + this.state = 93; this.parameterList(); - this.state = 88; + this.state = 94; this.match(CashScriptParser.T__11); - this.state = 92; + this.state = 98; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===14) { { { - this.state = 89; + this.state = 95; this.functionDefinition(); } } - this.state = 94; + this.state = 100; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 95; + this.state = 101; this.match(CashScriptParser.T__12); } } @@ -489,29 +497,29 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 97; + this.state = 103; this.match(CashScriptParser.T__13); - this.state = 98; + this.state = 104; this.match(CashScriptParser.Identifier); - this.state = 99; + this.state = 105; this.parameterList(); - this.state = 100; + this.state = 106; this.match(CashScriptParser.T__11); - this.state = 104; + this.state = 110; this._errHandler.sync(this); _la = this._input.LA(1); - while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2883584) !== 0) || ((((_la - 53)) & ~0x1F) === 0 && ((1 << (_la - 53)) & 528447) !== 0)) { + while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 11272192) !== 0) || ((((_la - 63)) & ~0x1F) === 0 && ((1 << (_la - 63)) & 1031) !== 0)) { { { - this.state = 101; + this.state = 107; this.statement(); } } - this.state = 106; + this.state = 112; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 107; + this.state = 113; this.match(CashScriptParser.T__12); } } @@ -538,39 +546,39 @@ export default class CashScriptParser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 109; + this.state = 115; this.match(CashScriptParser.T__14); - this.state = 121; + this.state = 127; this._errHandler.sync(this); _la = this._input.LA(1); - if (((((_la - 53)) & ~0x1F) === 0 && ((1 << (_la - 53)) & 4159) !== 0)) { + if (((((_la - 63)) & ~0x1F) === 0 && ((1 << (_la - 63)) & 7) !== 0)) { { - this.state = 110; + this.state = 116; this.parameter(); - this.state = 115; + this.state = 121; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 5, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 111; + this.state = 117; this.match(CashScriptParser.T__15); - this.state = 112; + this.state = 118; this.parameter(); } } } - this.state = 117; + this.state = 123; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 5, this._ctx); } - this.state = 119; + this.state = 125; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===16) { { - this.state = 118; + this.state = 124; this.match(CashScriptParser.T__15); } } @@ -578,7 +586,7 @@ export default class CashScriptParser extends Parser { } } - this.state = 123; + this.state = 129; this.match(CashScriptParser.T__16); } } @@ -603,9 +611,9 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 125; + this.state = 131; this.typeName(); - this.state = 126; + this.state = 132; this.match(CashScriptParser.Identifier); } } @@ -629,46 +637,43 @@ export default class CashScriptParser extends Parser { this.enterRule(localctx, 20, CashScriptParser.RULE_block); let _la: number; try { - this.state = 137; + this.state = 143; this._errHandler.sync(this); switch (this._input.LA(1)) { case 12: this.enterOuterAlt(localctx, 1); { - this.state = 128; + this.state = 134; this.match(CashScriptParser.T__11); - this.state = 132; + this.state = 138; this._errHandler.sync(this); _la = this._input.LA(1); - while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2883584) !== 0) || ((((_la - 53)) & ~0x1F) === 0 && ((1 << (_la - 53)) & 528447) !== 0)) { + while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 11272192) !== 0) || ((((_la - 63)) & ~0x1F) === 0 && ((1 << (_la - 63)) & 1031) !== 0)) { { { - this.state = 129; + this.state = 135; this.statement(); } } - this.state = 134; + this.state = 140; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 135; + this.state = 141; this.match(CashScriptParser.T__12); } break; case 18: case 19: case 21: - case 53: - case 54: - case 55: - case 56: - case 57: - case 58: + case 23: + case 63: + case 64: case 65: - case 72: + case 73: this.enterOuterAlt(localctx, 2); { - this.state = 136; + this.state = 142; this.statement(); } break; @@ -695,55 +700,62 @@ export default class CashScriptParser extends Parser { let localctx: StatementContext = new StatementContext(this, this._ctx, this.state); this.enterRule(localctx, 22, CashScriptParser.RULE_statement); try { - this.state = 146; + this.state = 153; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 10, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 139; + this.state = 145; this.variableDefinition(); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 140; + this.state = 146; this.tupleAssignment(); } break; case 3: this.enterOuterAlt(localctx, 3); { - this.state = 141; + this.state = 147; this.assignStatement(); } break; case 4: this.enterOuterAlt(localctx, 4); { - this.state = 142; + this.state = 148; this.timeOpStatement(); } break; case 5: this.enterOuterAlt(localctx, 5); { - this.state = 143; + this.state = 149; this.requireStatement(); } break; case 6: this.enterOuterAlt(localctx, 6); { - this.state = 144; + this.state = 150; this.ifStatement(); } break; case 7: this.enterOuterAlt(localctx, 7); { - this.state = 145; + this.state = 151; + this.loopStatement(); + } + break; + case 8: + this.enterOuterAlt(localctx, 8); + { + this.state = 152; this.consoleStatement(); } break; @@ -771,29 +783,29 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 148; + this.state = 155; this.typeName(); - this.state = 152; + this.state = 159; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===52) { + while (_la===56) { { { - this.state = 149; + this.state = 156; this.modifier(); } } - this.state = 154; + this.state = 161; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 155; + this.state = 162; this.match(CashScriptParser.Identifier); - this.state = 156; + this.state = 163; this.match(CashScriptParser.T__9); - this.state = 157; + this.state = 164; this.expression(0); - this.state = 158; + this.state = 165; this.match(CashScriptParser.T__1); } } @@ -818,21 +830,21 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 160; + this.state = 167; this.typeName(); - this.state = 161; + this.state = 168; this.match(CashScriptParser.Identifier); - this.state = 162; + this.state = 169; this.match(CashScriptParser.T__15); - this.state = 163; + this.state = 170; this.typeName(); - this.state = 164; + this.state = 171; this.match(CashScriptParser.Identifier); - this.state = 165; + this.state = 172; this.match(CashScriptParser.T__9); - this.state = 166; + this.state = 173; this.expression(0); - this.state = 167; + this.state = 174; this.match(CashScriptParser.T__1); } } @@ -857,13 +869,13 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 169; + this.state = 176; this.match(CashScriptParser.Identifier); - this.state = 170; + this.state = 177; this.match(CashScriptParser.T__9); - this.state = 171; + this.state = 178; this.expression(0); - this.state = 172; + this.state = 179; this.match(CashScriptParser.T__1); } } @@ -889,31 +901,31 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 174; + this.state = 181; this.match(CashScriptParser.T__17); - this.state = 175; + this.state = 182; this.match(CashScriptParser.T__14); - this.state = 176; + this.state = 183; this.match(CashScriptParser.TxVar); - this.state = 177; + this.state = 184; this.match(CashScriptParser.T__5); - this.state = 178; + this.state = 185; this.expression(0); - this.state = 181; + this.state = 188; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===16) { { - this.state = 179; + this.state = 186; this.match(CashScriptParser.T__15); - this.state = 180; + this.state = 187; this.requireMessage(); } } - this.state = 183; + this.state = 190; this.match(CashScriptParser.T__16); - this.state = 184; + this.state = 191; this.match(CashScriptParser.T__1); } } @@ -939,27 +951,27 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 186; + this.state = 193; this.match(CashScriptParser.T__17); - this.state = 187; + this.state = 194; this.match(CashScriptParser.T__14); - this.state = 188; + this.state = 195; this.expression(0); - this.state = 191; + this.state = 198; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===16) { { - this.state = 189; + this.state = 196; this.match(CashScriptParser.T__15); - this.state = 190; + this.state = 197; this.requireMessage(); } } - this.state = 193; + this.state = 200; this.match(CashScriptParser.T__16); - this.state = 194; + this.state = 201; this.match(CashScriptParser.T__1); } } @@ -984,24 +996,24 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 196; + this.state = 203; this.match(CashScriptParser.T__18); - this.state = 197; + this.state = 204; this.match(CashScriptParser.T__14); - this.state = 198; + this.state = 205; this.expression(0); - this.state = 199; + this.state = 206; this.match(CashScriptParser.T__16); - this.state = 200; + this.state = 207; localctx._ifBlock = this.block(); - this.state = 203; + this.state = 210; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 14, this._ctx) ) { case 1: { - this.state = 201; + this.state = 208; this.match(CashScriptParser.T__19); - this.state = 202; + this.state = 209; localctx._elseBlock = this.block(); } break; @@ -1023,17 +1035,79 @@ export default class CashScriptParser extends Parser { return localctx; } // @RuleVersion(0) + public loopStatement(): LoopStatementContext { + let localctx: LoopStatementContext = new LoopStatementContext(this, this._ctx, this.state); + this.enterRule(localctx, 36, CashScriptParser.RULE_loopStatement); + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 212; + this.doWhileStatement(); + } + } + catch (re) { + if (re instanceof RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return localctx; + } + // @RuleVersion(0) + public doWhileStatement(): DoWhileStatementContext { + let localctx: DoWhileStatementContext = new DoWhileStatementContext(this, this._ctx, this.state); + this.enterRule(localctx, 38, CashScriptParser.RULE_doWhileStatement); + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 214; + this.match(CashScriptParser.T__20); + this.state = 215; + this.block(); + this.state = 216; + this.match(CashScriptParser.T__21); + this.state = 217; + this.match(CashScriptParser.T__14); + this.state = 218; + this.expression(0); + this.state = 219; + this.match(CashScriptParser.T__16); + this.state = 220; + this.match(CashScriptParser.T__1); + } + } + catch (re) { + if (re instanceof RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return localctx; + } + // @RuleVersion(0) public consoleStatement(): ConsoleStatementContext { let localctx: ConsoleStatementContext = new ConsoleStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 36, CashScriptParser.RULE_consoleStatement); + this.enterRule(localctx, 40, CashScriptParser.RULE_consoleStatement); try { this.enterOuterAlt(localctx, 1); { - this.state = 205; - this.match(CashScriptParser.T__20); - this.state = 206; + this.state = 222; + this.match(CashScriptParser.T__22); + this.state = 223; this.consoleParameterList(); - this.state = 207; + this.state = 224; this.match(CashScriptParser.T__1); } } @@ -1054,11 +1128,11 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public requireMessage(): RequireMessageContext { let localctx: RequireMessageContext = new RequireMessageContext(this, this._ctx, this.state); - this.enterRule(localctx, 38, CashScriptParser.RULE_requireMessage); + this.enterRule(localctx, 42, CashScriptParser.RULE_requireMessage); try { this.enterOuterAlt(localctx, 1); { - this.state = 209; + this.state = 226; this.match(CashScriptParser.StringLiteral); } } @@ -1079,26 +1153,26 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public consoleParameter(): ConsoleParameterContext { let localctx: ConsoleParameterContext = new ConsoleParameterContext(this, this._ctx, this.state); - this.enterRule(localctx, 40, CashScriptParser.RULE_consoleParameter); + this.enterRule(localctx, 44, CashScriptParser.RULE_consoleParameter); try { - this.state = 213; + this.state = 230; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 72: + case 73: this.enterOuterAlt(localctx, 1); { - this.state = 211; + this.state = 228; this.match(CashScriptParser.Identifier); } break; + case 58: case 60: - case 62: case 67: case 68: case 69: this.enterOuterAlt(localctx, 2); { - this.state = 212; + this.state = 229; this.literal(); } break; @@ -1123,45 +1197,45 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public consoleParameterList(): ConsoleParameterListContext { let localctx: ConsoleParameterListContext = new ConsoleParameterListContext(this, this._ctx, this.state); - this.enterRule(localctx, 42, CashScriptParser.RULE_consoleParameterList); + this.enterRule(localctx, 46, CashScriptParser.RULE_consoleParameterList); let _la: number; try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 215; + this.state = 232; this.match(CashScriptParser.T__14); - this.state = 227; + this.state = 244; this._errHandler.sync(this); _la = this._input.LA(1); - if (((((_la - 60)) & ~0x1F) === 0 && ((1 << (_la - 60)) & 4997) !== 0)) { + if (((((_la - 58)) & ~0x1F) === 0 && ((1 << (_la - 58)) & 36357) !== 0)) { { - this.state = 216; + this.state = 233; this.consoleParameter(); - this.state = 221; + this.state = 238; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 16, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 217; + this.state = 234; this.match(CashScriptParser.T__15); - this.state = 218; + this.state = 235; this.consoleParameter(); } } } - this.state = 223; + this.state = 240; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 16, this._ctx); } - this.state = 225; + this.state = 242; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===16) { { - this.state = 224; + this.state = 241; this.match(CashScriptParser.T__15); } } @@ -1169,7 +1243,7 @@ export default class CashScriptParser extends Parser { } } - this.state = 229; + this.state = 246; this.match(CashScriptParser.T__16); } } @@ -1190,13 +1264,13 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public functionCall(): FunctionCallContext { let localctx: FunctionCallContext = new FunctionCallContext(this, this._ctx, this.state); - this.enterRule(localctx, 44, CashScriptParser.RULE_functionCall); + this.enterRule(localctx, 48, CashScriptParser.RULE_functionCall); try { this.enterOuterAlt(localctx, 1); { - this.state = 231; + this.state = 248; this.match(CashScriptParser.Identifier); - this.state = 232; + this.state = 249; this.expressionList(); } } @@ -1217,45 +1291,45 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public expressionList(): ExpressionListContext { let localctx: ExpressionListContext = new ExpressionListContext(this, this._ctx, this.state); - this.enterRule(localctx, 46, CashScriptParser.RULE_expressionList); + this.enterRule(localctx, 50, CashScriptParser.RULE_expressionList); let _la: number; try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 234; + this.state = 251; this.match(CashScriptParser.T__14); - this.state = 246; + this.state = 263; this._errHandler.sync(this); _la = this._input.LA(1); - if (((((_la - 15)) & ~0x1F) === 0 && ((1 << (_la - 15)) & 100730241) !== 0) || ((((_la - 53)) & ~0x1F) === 0 && ((1 << (_la - 53)) & 905919) !== 0)) { + if (((((_la - 5)) & ~0x1F) === 0 && ((1 << (_la - 5)) & 274203649) !== 0) || ((((_la - 42)) & ~0x1F) === 0 && ((1 << (_la - 42)) & 3999596547) !== 0)) { { - this.state = 235; + this.state = 252; this.expression(0); - this.state = 240; + this.state = 257; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 19, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 236; + this.state = 253; this.match(CashScriptParser.T__15); - this.state = 237; + this.state = 254; this.expression(0); } } } - this.state = 242; + this.state = 259; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 19, this._ctx); } - this.state = 244; + this.state = 261; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===16) { { - this.state = 243; + this.state = 260; this.match(CashScriptParser.T__15); } } @@ -1263,7 +1337,7 @@ export default class CashScriptParser extends Parser { } } - this.state = 248; + this.state = 265; this.match(CashScriptParser.T__16); } } @@ -1294,27 +1368,27 @@ export default class CashScriptParser extends Parser { let _parentState: number = this.state; let localctx: ExpressionContext = new ExpressionContext(this, this._ctx, _parentState); let _prevctx: ExpressionContext = localctx; - let _startState: number = 48; - this.enterRecursionRule(localctx, 48, CashScriptParser.RULE_expression, _p); + let _startState: number = 52; + this.enterRecursionRule(localctx, 52, CashScriptParser.RULE_expression, _p); let _la: number; try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 303; + this.state = 316; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 27, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 26, this._ctx) ) { case 1: { localctx = new ParenthesisedContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 251; + this.state = 268; this.match(CashScriptParser.T__14); - this.state = 252; + this.state = 269; this.expression(0); - this.state = 253; + this.state = 270; this.match(CashScriptParser.T__16); } break; @@ -1323,35 +1397,23 @@ export default class CashScriptParser extends Parser { localctx = new CastContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 255; - this.typeName(); - this.state = 256; + this.state = 272; + this.typeCast(); + this.state = 273; this.match(CashScriptParser.T__14); - this.state = 257; + this.state = 274; (localctx as CastContext)._castable = this.expression(0); - this.state = 260; - this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 22, this._ctx) ) { - case 1: - { - this.state = 258; - this.match(CashScriptParser.T__15); - this.state = 259; - (localctx as CastContext)._size = this.expression(0); - } - break; - } - this.state = 263; + this.state = 276; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===16) { { - this.state = 262; + this.state = 275; this.match(CashScriptParser.T__15); } } - this.state = 265; + this.state = 278; this.match(CashScriptParser.T__16); } break; @@ -1360,7 +1422,7 @@ export default class CashScriptParser extends Parser { localctx = new FunctionCallExpressionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 267; + this.state = 280; this.functionCall(); } break; @@ -1369,11 +1431,11 @@ export default class CashScriptParser extends Parser { localctx = new InstantiationContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 268; - this.match(CashScriptParser.T__21); - this.state = 269; + this.state = 281; + this.match(CashScriptParser.T__23); + this.state = 282; this.match(CashScriptParser.Identifier); - this.state = 270; + this.state = 283; this.expressionList(); } break; @@ -1382,18 +1444,18 @@ export default class CashScriptParser extends Parser { localctx = new UnaryIntrospectionOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 271; - (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__24); - this.state = 272; - this.match(CashScriptParser.T__22); - this.state = 273; + this.state = 284; + (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__26); + this.state = 285; + this.match(CashScriptParser.T__24); + this.state = 286; this.expression(0); - this.state = 274; - this.match(CashScriptParser.T__23); - this.state = 275; + this.state = 287; + this.match(CashScriptParser.T__25); + this.state = 288; (localctx as UnaryIntrospectionOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 2080374784) !== 0))) { + if(!(((((_la - 28)) & ~0x1F) === 0 && ((1 << (_la - 28)) & 31) !== 0))) { (localctx as UnaryIntrospectionOpContext)._op = this._errHandler.recoverInline(this); } else { @@ -1407,18 +1469,18 @@ export default class CashScriptParser extends Parser { localctx = new UnaryIntrospectionOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 277; - (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__30); - this.state = 278; - this.match(CashScriptParser.T__22); - this.state = 279; + this.state = 290; + (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__32); + this.state = 291; + this.match(CashScriptParser.T__24); + this.state = 292; this.expression(0); - this.state = 280; - this.match(CashScriptParser.T__23); - this.state = 281; + this.state = 293; + this.match(CashScriptParser.T__25); + this.state = 294; (localctx as UnaryIntrospectionOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(((((_la - 26)) & ~0x1F) === 0 && ((1 << (_la - 26)) & 991) !== 0))) { + if(!(((((_la - 28)) & ~0x1F) === 0 && ((1 << (_la - 28)) & 991) !== 0))) { (localctx as UnaryIntrospectionOpContext)._op = this._errHandler.recoverInline(this); } else { @@ -1432,18 +1494,18 @@ export default class CashScriptParser extends Parser { localctx = new UnaryOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 283; + this.state = 296; (localctx as UnaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===40 || _la===41)) { + if(!(_la===5 || _la===42 || _la===43)) { (localctx as UnaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 284; - this.expression(14); + this.state = 297; + this.expression(15); } break; case 8: @@ -1451,39 +1513,39 @@ export default class CashScriptParser extends Parser { localctx = new ArrayContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 285; - this.match(CashScriptParser.T__22); - this.state = 297; + this.state = 298; + this.match(CashScriptParser.T__24); + this.state = 310; this._errHandler.sync(this); _la = this._input.LA(1); - if (((((_la - 15)) & ~0x1F) === 0 && ((1 << (_la - 15)) & 100730241) !== 0) || ((((_la - 53)) & ~0x1F) === 0 && ((1 << (_la - 53)) & 905919) !== 0)) { + if (((((_la - 5)) & ~0x1F) === 0 && ((1 << (_la - 5)) & 274203649) !== 0) || ((((_la - 42)) & ~0x1F) === 0 && ((1 << (_la - 42)) & 3999596547) !== 0)) { { - this.state = 286; + this.state = 299; this.expression(0); - this.state = 291; + this.state = 304; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 24, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 23, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 287; + this.state = 300; this.match(CashScriptParser.T__15); - this.state = 288; + this.state = 301; this.expression(0); } } } - this.state = 293; + this.state = 306; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 24, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 23, this._ctx); } - this.state = 295; + this.state = 308; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===16) { { - this.state = 294; + this.state = 307; this.match(CashScriptParser.T__15); } } @@ -1491,8 +1553,8 @@ export default class CashScriptParser extends Parser { } } - this.state = 299; - this.match(CashScriptParser.T__23); + this.state = 312; + this.match(CashScriptParser.T__25); } break; case 9: @@ -1500,7 +1562,7 @@ export default class CashScriptParser extends Parser { localctx = new NullaryOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 300; + this.state = 313; this.match(CashScriptParser.NullaryOp); } break; @@ -1509,7 +1571,7 @@ export default class CashScriptParser extends Parser { localctx = new IdentifierContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 301; + this.state = 314; this.match(CashScriptParser.Identifier); } break; @@ -1518,15 +1580,15 @@ export default class CashScriptParser extends Parser { localctx = new LiteralExpressionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 302; + this.state = 315; this.literal(); } break; } this._ctx.stop = this._input.LT(-1); - this.state = 354; + this.state = 370; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 29, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 28, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { if (this._parseListeners != null) { @@ -1534,65 +1596,88 @@ export default class CashScriptParser extends Parser { } _prevctx = localctx; { - this.state = 352; + this.state = 368; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 28, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 27, this._ctx) ) { case 1: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 305; + this.state = 318; + if (!(this.precpred(this._ctx, 14))) { + throw this.createFailedPredicateException("this.precpred(this._ctx, 14)"); + } + this.state = 319; + (localctx as BinaryOpContext)._op = this._input.LT(1); + _la = this._input.LA(1); + if(!(((((_la - 44)) & ~0x1F) === 0 && ((1 << (_la - 44)) & 7) !== 0))) { + (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 320; + (localctx as BinaryOpContext)._right = this.expression(15); + } + break; + case 2: + { + localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); + (localctx as BinaryOpContext)._left = _prevctx; + this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); + this.state = 321; if (!(this.precpred(this._ctx, 13))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 13)"); } - this.state = 306; + this.state = 322; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(((((_la - 42)) & ~0x1F) === 0 && ((1 << (_la - 42)) & 7) !== 0))) { + if(!(_la===43 || _la===47)) { (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 307; + this.state = 323; (localctx as BinaryOpContext)._right = this.expression(14); } break; - case 2: + case 3: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 308; + this.state = 324; if (!(this.precpred(this._ctx, 12))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 12)"); } - this.state = 309; + this.state = 325; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===41 || _la===45)) { + if(!(_la===48 || _la===49)) { (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 310; + this.state = 326; (localctx as BinaryOpContext)._right = this.expression(13); } break; - case 3: + case 4: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 311; + this.state = 327; if (!(this.precpred(this._ctx, 11))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 11)"); } - this.state = 312; + this.state = 328; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 960) !== 0))) { @@ -1602,136 +1687,136 @@ export default class CashScriptParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 313; + this.state = 329; (localctx as BinaryOpContext)._right = this.expression(12); } break; - case 4: + case 5: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 314; + this.state = 330; if (!(this.precpred(this._ctx, 10))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 10)"); } - this.state = 315; + this.state = 331; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===46 || _la===47)) { + if(!(_la===50 || _la===51)) { (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 316; + this.state = 332; (localctx as BinaryOpContext)._right = this.expression(11); } break; - case 5: + case 6: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 317; + this.state = 333; if (!(this.precpred(this._ctx, 9))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 9)"); } - this.state = 318; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__47); - this.state = 319; + this.state = 334; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__51); + this.state = 335; (localctx as BinaryOpContext)._right = this.expression(10); } break; - case 6: + case 7: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 320; + this.state = 336; if (!(this.precpred(this._ctx, 8))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 8)"); } - this.state = 321; + this.state = 337; (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__3); - this.state = 322; + this.state = 338; (localctx as BinaryOpContext)._right = this.expression(9); } break; - case 7: + case 8: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 323; + this.state = 339; if (!(this.precpred(this._ctx, 7))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 7)"); } - this.state = 324; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__48); - this.state = 325; + this.state = 340; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__52); + this.state = 341; (localctx as BinaryOpContext)._right = this.expression(8); } break; - case 8: + case 9: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 326; + this.state = 342; if (!(this.precpred(this._ctx, 6))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 6)"); } - this.state = 327; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__49); - this.state = 328; + this.state = 343; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__53); + this.state = 344; (localctx as BinaryOpContext)._right = this.expression(7); } break; - case 9: + case 10: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 329; + this.state = 345; if (!(this.precpred(this._ctx, 5))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 5)"); } - this.state = 330; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__50); - this.state = 331; + this.state = 346; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__54); + this.state = 347; (localctx as BinaryOpContext)._right = this.expression(6); } break; - case 10: + case 11: { localctx = new TupleIndexOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 332; - if (!(this.precpred(this._ctx, 20))) { - throw this.createFailedPredicateException("this.precpred(this._ctx, 20)"); + this.state = 348; + if (!(this.precpred(this._ctx, 21))) { + throw this.createFailedPredicateException("this.precpred(this._ctx, 21)"); } - this.state = 333; - this.match(CashScriptParser.T__22); - this.state = 334; + this.state = 349; + this.match(CashScriptParser.T__24); + this.state = 350; (localctx as TupleIndexOpContext)._index = this.match(CashScriptParser.NumberLiteral); - this.state = 335; - this.match(CashScriptParser.T__23); + this.state = 351; + this.match(CashScriptParser.T__25); } break; - case 11: + case 12: { localctx = new UnaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 336; - if (!(this.precpred(this._ctx, 17))) { - throw this.createFailedPredicateException("this.precpred(this._ctx, 17)"); + this.state = 352; + if (!(this.precpred(this._ctx, 18))) { + throw this.createFailedPredicateException("this.precpred(this._ctx, 18)"); } - this.state = 337; + this.state = 353; (localctx as UnaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===36 || _la===37)) { + if(!(_la===38 || _la===39)) { (localctx as UnaryOpContext)._op = this._errHandler.recoverInline(this); } else { @@ -1740,54 +1825,54 @@ export default class CashScriptParser extends Parser { } } break; - case 12: + case 13: { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 338; - if (!(this.precpred(this._ctx, 16))) { - throw this.createFailedPredicateException("this.precpred(this._ctx, 16)"); + this.state = 354; + if (!(this.precpred(this._ctx, 17))) { + throw this.createFailedPredicateException("this.precpred(this._ctx, 17)"); } - this.state = 339; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__37); - this.state = 340; + this.state = 355; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__39); + this.state = 356; this.match(CashScriptParser.T__14); - this.state = 341; + this.state = 357; (localctx as BinaryOpContext)._right = this.expression(0); - this.state = 342; + this.state = 358; this.match(CashScriptParser.T__16); } break; - case 13: + case 14: { localctx = new SliceContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as SliceContext)._element = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 344; - if (!(this.precpred(this._ctx, 15))) { - throw this.createFailedPredicateException("this.precpred(this._ctx, 15)"); + this.state = 360; + if (!(this.precpred(this._ctx, 16))) { + throw this.createFailedPredicateException("this.precpred(this._ctx, 16)"); } - this.state = 345; - this.match(CashScriptParser.T__38); - this.state = 346; + this.state = 361; + this.match(CashScriptParser.T__40); + this.state = 362; this.match(CashScriptParser.T__14); - this.state = 347; + this.state = 363; (localctx as SliceContext)._start = this.expression(0); - this.state = 348; + this.state = 364; this.match(CashScriptParser.T__15); - this.state = 349; + this.state = 365; (localctx as SliceContext)._end = this.expression(0); - this.state = 350; + this.state = 366; this.match(CashScriptParser.T__16); } break; } } } - this.state = 356; + this.state = 372; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 29, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 28, this._ctx); } } } @@ -1808,12 +1893,12 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public modifier(): ModifierContext { let localctx: ModifierContext = new ModifierContext(this, this._ctx, this.state); - this.enterRule(localctx, 50, CashScriptParser.RULE_modifier); + this.enterRule(localctx, 54, CashScriptParser.RULE_modifier); try { this.enterOuterAlt(localctx, 1); { - this.state = 357; - this.match(CashScriptParser.T__51); + this.state = 373; + this.match(CashScriptParser.T__55); } } catch (re) { @@ -1833,43 +1918,43 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public literal(): LiteralContext { let localctx: LiteralContext = new LiteralContext(this, this._ctx, this.state); - this.enterRule(localctx, 52, CashScriptParser.RULE_literal); + this.enterRule(localctx, 56, CashScriptParser.RULE_literal); try { - this.state = 364; + this.state = 380; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 60: + case 58: this.enterOuterAlt(localctx, 1); { - this.state = 359; + this.state = 375; this.match(CashScriptParser.BooleanLiteral); } break; - case 62: + case 60: this.enterOuterAlt(localctx, 2); { - this.state = 360; + this.state = 376; this.numberLiteral(); } break; case 67: this.enterOuterAlt(localctx, 3); { - this.state = 361; + this.state = 377; this.match(CashScriptParser.StringLiteral); } break; case 68: this.enterOuterAlt(localctx, 4); { - this.state = 362; + this.state = 378; this.match(CashScriptParser.DateLiteral); } break; case 69: this.enterOuterAlt(localctx, 5); { - this.state = 363; + this.state = 379; this.match(CashScriptParser.HexLiteral); } break; @@ -1894,18 +1979,18 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public numberLiteral(): NumberLiteralContext { let localctx: NumberLiteralContext = new NumberLiteralContext(this, this._ctx, this.state); - this.enterRule(localctx, 54, CashScriptParser.RULE_numberLiteral); + this.enterRule(localctx, 58, CashScriptParser.RULE_numberLiteral); try { this.enterOuterAlt(localctx, 1); { - this.state = 366; + this.state = 382; this.match(CashScriptParser.NumberLiteral); - this.state = 368; + this.state = 384; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 31, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 30, this._ctx) ) { case 1: { - this.state = 367; + this.state = 383; this.match(CashScriptParser.NumberUnit); } break; @@ -1929,14 +2014,47 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public typeName(): TypeNameContext { let localctx: TypeNameContext = new TypeNameContext(this, this._ctx, this.state); - this.enterRule(localctx, 56, CashScriptParser.RULE_typeName); + this.enterRule(localctx, 60, CashScriptParser.RULE_typeName); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 370; + this.state = 386; _la = this._input.LA(1); - if(!(((((_la - 53)) & ~0x1F) === 0 && ((1 << (_la - 53)) & 4159) !== 0))) { + if(!(((((_la - 63)) & ~0x1F) === 0 && ((1 << (_la - 63)) & 7) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return localctx; + } + // @RuleVersion(0) + public typeCast(): TypeCastContext { + let localctx: TypeCastContext = new TypeCastContext(this, this._ctx, this.state); + this.enterRule(localctx, 62, CashScriptParser.RULE_typeCast); + let _la: number; + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 388; + _la = this._input.LA(1); + if(!(((((_la - 63)) & ~0x1F) === 0 && ((1 << (_la - 63)) & 259) !== 0))) { this._errHandler.recoverInline(this); } else { @@ -1962,7 +2080,7 @@ export default class CashScriptParser extends Parser { public sempred(localctx: RuleContext, ruleIndex: number, predIndex: number): boolean { switch (ruleIndex) { - case 24: + case 26: return this.expression_sempred(localctx as ExpressionContext, predIndex); } return true; @@ -1970,159 +2088,166 @@ export default class CashScriptParser extends Parser { private expression_sempred(localctx: ExpressionContext, predIndex: number): boolean { switch (predIndex) { case 0: - return this.precpred(this._ctx, 13); + return this.precpred(this._ctx, 14); case 1: - return this.precpred(this._ctx, 12); + return this.precpred(this._ctx, 13); case 2: - return this.precpred(this._ctx, 11); + return this.precpred(this._ctx, 12); case 3: - return this.precpred(this._ctx, 10); + return this.precpred(this._ctx, 11); case 4: - return this.precpred(this._ctx, 9); + return this.precpred(this._ctx, 10); case 5: - return this.precpred(this._ctx, 8); + return this.precpred(this._ctx, 9); case 6: - return this.precpred(this._ctx, 7); + return this.precpred(this._ctx, 8); case 7: - return this.precpred(this._ctx, 6); + return this.precpred(this._ctx, 7); case 8: - return this.precpred(this._ctx, 5); + return this.precpred(this._ctx, 6); case 9: - return this.precpred(this._ctx, 20); + return this.precpred(this._ctx, 5); case 10: - return this.precpred(this._ctx, 17); + return this.precpred(this._ctx, 21); case 11: - return this.precpred(this._ctx, 16); + return this.precpred(this._ctx, 18); case 12: - return this.precpred(this._ctx, 15); + return this.precpred(this._ctx, 17); + case 13: + return this.precpred(this._ctx, 16); } return true; } - public static readonly _serializedATN: number[] = [4,1,75,373,2,0,7,0,2, + public static readonly _serializedATN: number[] = [4,1,76,391,2,0,7,0,2, 1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2, 10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17, 7,17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7, - 24,2,25,7,25,2,26,7,26,2,27,7,27,2,28,7,28,1,0,5,0,60,8,0,10,0,12,0,63, - 9,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,3,1,3,3,3,77,8,3,1,4,3,4, - 80,8,4,1,4,1,4,1,5,1,5,1,6,1,6,1,6,1,6,1,6,5,6,91,8,6,10,6,12,6,94,9,6, - 1,6,1,6,1,7,1,7,1,7,1,7,1,7,5,7,103,8,7,10,7,12,7,106,9,7,1,7,1,7,1,8,1, - 8,1,8,1,8,5,8,114,8,8,10,8,12,8,117,9,8,1,8,3,8,120,8,8,3,8,122,8,8,1,8, - 1,8,1,9,1,9,1,9,1,10,1,10,5,10,131,8,10,10,10,12,10,134,9,10,1,10,1,10, - 3,10,138,8,10,1,11,1,11,1,11,1,11,1,11,1,11,1,11,3,11,147,8,11,1,12,1,12, - 5,12,151,8,12,10,12,12,12,154,9,12,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1, - 13,1,13,1,13,1,13,1,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15, - 1,15,1,15,1,15,1,15,3,15,182,8,15,1,15,1,15,1,15,1,16,1,16,1,16,1,16,1, - 16,3,16,192,8,16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,17,1,17,3,17, - 204,8,17,1,18,1,18,1,18,1,18,1,19,1,19,1,20,1,20,3,20,214,8,20,1,21,1,21, - 1,21,1,21,5,21,220,8,21,10,21,12,21,223,9,21,1,21,3,21,226,8,21,3,21,228, - 8,21,1,21,1,21,1,22,1,22,1,22,1,23,1,23,1,23,1,23,5,23,239,8,23,10,23,12, - 23,242,9,23,1,23,3,23,245,8,23,3,23,247,8,23,1,23,1,23,1,24,1,24,1,24,1, - 24,1,24,1,24,1,24,1,24,1,24,1,24,3,24,261,8,24,1,24,3,24,264,8,24,1,24, - 1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1, - 24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,5,24,290,8,24,10,24,12,24,293, - 9,24,1,24,3,24,296,8,24,3,24,298,8,24,1,24,1,24,1,24,1,24,3,24,304,8,24, - 1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1, - 24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24, - 1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1, - 24,1,24,1,24,1,24,5,24,353,8,24,10,24,12,24,356,9,24,1,25,1,25,1,26,1,26, - 1,26,1,26,1,26,3,26,365,8,26,1,27,1,27,3,27,369,8,27,1,28,1,28,1,28,0,1, - 48,29,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46, - 48,50,52,54,56,0,10,1,0,4,10,1,0,26,30,2,0,26,30,32,35,1,0,40,41,1,0,42, - 44,2,0,41,41,45,45,1,0,6,9,1,0,46,47,1,0,36,37,2,0,53,58,65,65,403,0,61, - 1,0,0,0,2,67,1,0,0,0,4,72,1,0,0,0,6,74,1,0,0,0,8,79,1,0,0,0,10,83,1,0,0, - 0,12,85,1,0,0,0,14,97,1,0,0,0,16,109,1,0,0,0,18,125,1,0,0,0,20,137,1,0, - 0,0,22,146,1,0,0,0,24,148,1,0,0,0,26,160,1,0,0,0,28,169,1,0,0,0,30,174, - 1,0,0,0,32,186,1,0,0,0,34,196,1,0,0,0,36,205,1,0,0,0,38,209,1,0,0,0,40, - 213,1,0,0,0,42,215,1,0,0,0,44,231,1,0,0,0,46,234,1,0,0,0,48,303,1,0,0,0, - 50,357,1,0,0,0,52,364,1,0,0,0,54,366,1,0,0,0,56,370,1,0,0,0,58,60,3,2,1, - 0,59,58,1,0,0,0,60,63,1,0,0,0,61,59,1,0,0,0,61,62,1,0,0,0,62,64,1,0,0,0, - 63,61,1,0,0,0,64,65,3,12,6,0,65,66,5,0,0,1,66,1,1,0,0,0,67,68,5,1,0,0,68, - 69,3,4,2,0,69,70,3,6,3,0,70,71,5,2,0,0,71,3,1,0,0,0,72,73,5,3,0,0,73,5, - 1,0,0,0,74,76,3,8,4,0,75,77,3,8,4,0,76,75,1,0,0,0,76,77,1,0,0,0,77,7,1, - 0,0,0,78,80,3,10,5,0,79,78,1,0,0,0,79,80,1,0,0,0,80,81,1,0,0,0,81,82,5, - 59,0,0,82,9,1,0,0,0,83,84,7,0,0,0,84,11,1,0,0,0,85,86,5,11,0,0,86,87,5, - 72,0,0,87,88,3,16,8,0,88,92,5,12,0,0,89,91,3,14,7,0,90,89,1,0,0,0,91,94, - 1,0,0,0,92,90,1,0,0,0,92,93,1,0,0,0,93,95,1,0,0,0,94,92,1,0,0,0,95,96,5, - 13,0,0,96,13,1,0,0,0,97,98,5,14,0,0,98,99,5,72,0,0,99,100,3,16,8,0,100, - 104,5,12,0,0,101,103,3,22,11,0,102,101,1,0,0,0,103,106,1,0,0,0,104,102, - 1,0,0,0,104,105,1,0,0,0,105,107,1,0,0,0,106,104,1,0,0,0,107,108,5,13,0, - 0,108,15,1,0,0,0,109,121,5,15,0,0,110,115,3,18,9,0,111,112,5,16,0,0,112, - 114,3,18,9,0,113,111,1,0,0,0,114,117,1,0,0,0,115,113,1,0,0,0,115,116,1, - 0,0,0,116,119,1,0,0,0,117,115,1,0,0,0,118,120,5,16,0,0,119,118,1,0,0,0, - 119,120,1,0,0,0,120,122,1,0,0,0,121,110,1,0,0,0,121,122,1,0,0,0,122,123, - 1,0,0,0,123,124,5,17,0,0,124,17,1,0,0,0,125,126,3,56,28,0,126,127,5,72, - 0,0,127,19,1,0,0,0,128,132,5,12,0,0,129,131,3,22,11,0,130,129,1,0,0,0,131, - 134,1,0,0,0,132,130,1,0,0,0,132,133,1,0,0,0,133,135,1,0,0,0,134,132,1,0, - 0,0,135,138,5,13,0,0,136,138,3,22,11,0,137,128,1,0,0,0,137,136,1,0,0,0, - 138,21,1,0,0,0,139,147,3,24,12,0,140,147,3,26,13,0,141,147,3,28,14,0,142, - 147,3,30,15,0,143,147,3,32,16,0,144,147,3,34,17,0,145,147,3,36,18,0,146, - 139,1,0,0,0,146,140,1,0,0,0,146,141,1,0,0,0,146,142,1,0,0,0,146,143,1,0, - 0,0,146,144,1,0,0,0,146,145,1,0,0,0,147,23,1,0,0,0,148,152,3,56,28,0,149, - 151,3,50,25,0,150,149,1,0,0,0,151,154,1,0,0,0,152,150,1,0,0,0,152,153,1, - 0,0,0,153,155,1,0,0,0,154,152,1,0,0,0,155,156,5,72,0,0,156,157,5,10,0,0, - 157,158,3,48,24,0,158,159,5,2,0,0,159,25,1,0,0,0,160,161,3,56,28,0,161, - 162,5,72,0,0,162,163,5,16,0,0,163,164,3,56,28,0,164,165,5,72,0,0,165,166, - 5,10,0,0,166,167,3,48,24,0,167,168,5,2,0,0,168,27,1,0,0,0,169,170,5,72, - 0,0,170,171,5,10,0,0,171,172,3,48,24,0,172,173,5,2,0,0,173,29,1,0,0,0,174, - 175,5,18,0,0,175,176,5,15,0,0,176,177,5,70,0,0,177,178,5,6,0,0,178,181, - 3,48,24,0,179,180,5,16,0,0,180,182,3,38,19,0,181,179,1,0,0,0,181,182,1, - 0,0,0,182,183,1,0,0,0,183,184,5,17,0,0,184,185,5,2,0,0,185,31,1,0,0,0,186, - 187,5,18,0,0,187,188,5,15,0,0,188,191,3,48,24,0,189,190,5,16,0,0,190,192, - 3,38,19,0,191,189,1,0,0,0,191,192,1,0,0,0,192,193,1,0,0,0,193,194,5,17, - 0,0,194,195,5,2,0,0,195,33,1,0,0,0,196,197,5,19,0,0,197,198,5,15,0,0,198, - 199,3,48,24,0,199,200,5,17,0,0,200,203,3,20,10,0,201,202,5,20,0,0,202,204, - 3,20,10,0,203,201,1,0,0,0,203,204,1,0,0,0,204,35,1,0,0,0,205,206,5,21,0, - 0,206,207,3,42,21,0,207,208,5,2,0,0,208,37,1,0,0,0,209,210,5,67,0,0,210, - 39,1,0,0,0,211,214,5,72,0,0,212,214,3,52,26,0,213,211,1,0,0,0,213,212,1, - 0,0,0,214,41,1,0,0,0,215,227,5,15,0,0,216,221,3,40,20,0,217,218,5,16,0, - 0,218,220,3,40,20,0,219,217,1,0,0,0,220,223,1,0,0,0,221,219,1,0,0,0,221, - 222,1,0,0,0,222,225,1,0,0,0,223,221,1,0,0,0,224,226,5,16,0,0,225,224,1, - 0,0,0,225,226,1,0,0,0,226,228,1,0,0,0,227,216,1,0,0,0,227,228,1,0,0,0,228, - 229,1,0,0,0,229,230,5,17,0,0,230,43,1,0,0,0,231,232,5,72,0,0,232,233,3, - 46,23,0,233,45,1,0,0,0,234,246,5,15,0,0,235,240,3,48,24,0,236,237,5,16, - 0,0,237,239,3,48,24,0,238,236,1,0,0,0,239,242,1,0,0,0,240,238,1,0,0,0,240, - 241,1,0,0,0,241,244,1,0,0,0,242,240,1,0,0,0,243,245,5,16,0,0,244,243,1, - 0,0,0,244,245,1,0,0,0,245,247,1,0,0,0,246,235,1,0,0,0,246,247,1,0,0,0,247, - 248,1,0,0,0,248,249,5,17,0,0,249,47,1,0,0,0,250,251,6,24,-1,0,251,252,5, - 15,0,0,252,253,3,48,24,0,253,254,5,17,0,0,254,304,1,0,0,0,255,256,3,56, - 28,0,256,257,5,15,0,0,257,260,3,48,24,0,258,259,5,16,0,0,259,261,3,48,24, - 0,260,258,1,0,0,0,260,261,1,0,0,0,261,263,1,0,0,0,262,264,5,16,0,0,263, - 262,1,0,0,0,263,264,1,0,0,0,264,265,1,0,0,0,265,266,5,17,0,0,266,304,1, - 0,0,0,267,304,3,44,22,0,268,269,5,22,0,0,269,270,5,72,0,0,270,304,3,46, - 23,0,271,272,5,25,0,0,272,273,5,23,0,0,273,274,3,48,24,0,274,275,5,24,0, - 0,275,276,7,1,0,0,276,304,1,0,0,0,277,278,5,31,0,0,278,279,5,23,0,0,279, - 280,3,48,24,0,280,281,5,24,0,0,281,282,7,2,0,0,282,304,1,0,0,0,283,284, - 7,3,0,0,284,304,3,48,24,14,285,297,5,23,0,0,286,291,3,48,24,0,287,288,5, - 16,0,0,288,290,3,48,24,0,289,287,1,0,0,0,290,293,1,0,0,0,291,289,1,0,0, - 0,291,292,1,0,0,0,292,295,1,0,0,0,293,291,1,0,0,0,294,296,5,16,0,0,295, - 294,1,0,0,0,295,296,1,0,0,0,296,298,1,0,0,0,297,286,1,0,0,0,297,298,1,0, - 0,0,298,299,1,0,0,0,299,304,5,24,0,0,300,304,5,71,0,0,301,304,5,72,0,0, - 302,304,3,52,26,0,303,250,1,0,0,0,303,255,1,0,0,0,303,267,1,0,0,0,303,268, - 1,0,0,0,303,271,1,0,0,0,303,277,1,0,0,0,303,283,1,0,0,0,303,285,1,0,0,0, - 303,300,1,0,0,0,303,301,1,0,0,0,303,302,1,0,0,0,304,354,1,0,0,0,305,306, - 10,13,0,0,306,307,7,4,0,0,307,353,3,48,24,14,308,309,10,12,0,0,309,310, - 7,5,0,0,310,353,3,48,24,13,311,312,10,11,0,0,312,313,7,6,0,0,313,353,3, - 48,24,12,314,315,10,10,0,0,315,316,7,7,0,0,316,353,3,48,24,11,317,318,10, - 9,0,0,318,319,5,48,0,0,319,353,3,48,24,10,320,321,10,8,0,0,321,322,5,4, - 0,0,322,353,3,48,24,9,323,324,10,7,0,0,324,325,5,49,0,0,325,353,3,48,24, - 8,326,327,10,6,0,0,327,328,5,50,0,0,328,353,3,48,24,7,329,330,10,5,0,0, - 330,331,5,51,0,0,331,353,3,48,24,6,332,333,10,20,0,0,333,334,5,23,0,0,334, - 335,5,62,0,0,335,353,5,24,0,0,336,337,10,17,0,0,337,353,7,8,0,0,338,339, - 10,16,0,0,339,340,5,38,0,0,340,341,5,15,0,0,341,342,3,48,24,0,342,343,5, - 17,0,0,343,353,1,0,0,0,344,345,10,15,0,0,345,346,5,39,0,0,346,347,5,15, - 0,0,347,348,3,48,24,0,348,349,5,16,0,0,349,350,3,48,24,0,350,351,5,17,0, - 0,351,353,1,0,0,0,352,305,1,0,0,0,352,308,1,0,0,0,352,311,1,0,0,0,352,314, - 1,0,0,0,352,317,1,0,0,0,352,320,1,0,0,0,352,323,1,0,0,0,352,326,1,0,0,0, - 352,329,1,0,0,0,352,332,1,0,0,0,352,336,1,0,0,0,352,338,1,0,0,0,352,344, - 1,0,0,0,353,356,1,0,0,0,354,352,1,0,0,0,354,355,1,0,0,0,355,49,1,0,0,0, - 356,354,1,0,0,0,357,358,5,52,0,0,358,51,1,0,0,0,359,365,5,60,0,0,360,365, - 3,54,27,0,361,365,5,67,0,0,362,365,5,68,0,0,363,365,5,69,0,0,364,359,1, - 0,0,0,364,360,1,0,0,0,364,361,1,0,0,0,364,362,1,0,0,0,364,363,1,0,0,0,365, - 53,1,0,0,0,366,368,5,62,0,0,367,369,5,61,0,0,368,367,1,0,0,0,368,369,1, - 0,0,0,369,55,1,0,0,0,370,371,7,9,0,0,371,57,1,0,0,0,32,61,76,79,92,104, - 115,119,121,132,137,146,152,181,191,203,213,221,225,227,240,244,246,260, - 263,291,295,297,303,352,354,364,368]; + 24,2,25,7,25,2,26,7,26,2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31, + 1,0,5,0,66,8,0,10,0,12,0,69,9,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,2,1,2, + 1,3,1,3,3,3,83,8,3,1,4,3,4,86,8,4,1,4,1,4,1,5,1,5,1,6,1,6,1,6,1,6,1,6,5, + 6,97,8,6,10,6,12,6,100,9,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,5,7,109,8,7,10,7, + 12,7,112,9,7,1,7,1,7,1,8,1,8,1,8,1,8,5,8,120,8,8,10,8,12,8,123,9,8,1,8, + 3,8,126,8,8,3,8,128,8,8,1,8,1,8,1,9,1,9,1,9,1,10,1,10,5,10,137,8,10,10, + 10,12,10,140,9,10,1,10,1,10,3,10,144,8,10,1,11,1,11,1,11,1,11,1,11,1,11, + 1,11,1,11,3,11,154,8,11,1,12,1,12,5,12,158,8,12,10,12,12,12,161,9,12,1, + 12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,14, + 1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,15,1,15,3,15,189,8,15,1, + 15,1,15,1,15,1,16,1,16,1,16,1,16,1,16,3,16,199,8,16,1,16,1,16,1,16,1,17, + 1,17,1,17,1,17,1,17,1,17,1,17,3,17,211,8,17,1,18,1,18,1,19,1,19,1,19,1, + 19,1,19,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,21,1,21,1,22,1,22,3,22,231, + 8,22,1,23,1,23,1,23,1,23,5,23,237,8,23,10,23,12,23,240,9,23,1,23,3,23,243, + 8,23,3,23,245,8,23,1,23,1,23,1,24,1,24,1,24,1,25,1,25,1,25,1,25,5,25,256, + 8,25,10,25,12,25,259,9,25,1,25,3,25,262,8,25,3,25,264,8,25,1,25,1,25,1, + 26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,3,26,277,8,26,1,26,1,26,1,26, + 1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1, + 26,1,26,1,26,1,26,1,26,1,26,1,26,5,26,303,8,26,10,26,12,26,306,9,26,1,26, + 3,26,309,8,26,3,26,311,8,26,1,26,1,26,1,26,1,26,3,26,317,8,26,1,26,1,26, + 1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1, + 26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26, + 1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1, + 26,1,26,1,26,1,26,1,26,5,26,369,8,26,10,26,12,26,372,9,26,1,27,1,27,1,28, + 1,28,1,28,1,28,1,28,3,28,381,8,28,1,29,1,29,3,29,385,8,29,1,30,1,30,1,31, + 1,31,1,31,0,1,52,32,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36, + 38,40,42,44,46,48,50,52,54,56,58,60,62,0,12,1,0,4,10,1,0,28,32,2,0,28,32, + 34,37,2,0,5,5,42,43,1,0,44,46,2,0,43,43,47,47,1,0,48,49,1,0,6,9,1,0,50, + 51,1,0,38,39,1,0,63,65,2,0,63,64,71,71,419,0,67,1,0,0,0,2,73,1,0,0,0,4, + 78,1,0,0,0,6,80,1,0,0,0,8,85,1,0,0,0,10,89,1,0,0,0,12,91,1,0,0,0,14,103, + 1,0,0,0,16,115,1,0,0,0,18,131,1,0,0,0,20,143,1,0,0,0,22,153,1,0,0,0,24, + 155,1,0,0,0,26,167,1,0,0,0,28,176,1,0,0,0,30,181,1,0,0,0,32,193,1,0,0,0, + 34,203,1,0,0,0,36,212,1,0,0,0,38,214,1,0,0,0,40,222,1,0,0,0,42,226,1,0, + 0,0,44,230,1,0,0,0,46,232,1,0,0,0,48,248,1,0,0,0,50,251,1,0,0,0,52,316, + 1,0,0,0,54,373,1,0,0,0,56,380,1,0,0,0,58,382,1,0,0,0,60,386,1,0,0,0,62, + 388,1,0,0,0,64,66,3,2,1,0,65,64,1,0,0,0,66,69,1,0,0,0,67,65,1,0,0,0,67, + 68,1,0,0,0,68,70,1,0,0,0,69,67,1,0,0,0,70,71,3,12,6,0,71,72,5,0,0,1,72, + 1,1,0,0,0,73,74,5,1,0,0,74,75,3,4,2,0,75,76,3,6,3,0,76,77,5,2,0,0,77,3, + 1,0,0,0,78,79,5,3,0,0,79,5,1,0,0,0,80,82,3,8,4,0,81,83,3,8,4,0,82,81,1, + 0,0,0,82,83,1,0,0,0,83,7,1,0,0,0,84,86,3,10,5,0,85,84,1,0,0,0,85,86,1,0, + 0,0,86,87,1,0,0,0,87,88,5,57,0,0,88,9,1,0,0,0,89,90,7,0,0,0,90,11,1,0,0, + 0,91,92,5,11,0,0,92,93,5,73,0,0,93,94,3,16,8,0,94,98,5,12,0,0,95,97,3,14, + 7,0,96,95,1,0,0,0,97,100,1,0,0,0,98,96,1,0,0,0,98,99,1,0,0,0,99,101,1,0, + 0,0,100,98,1,0,0,0,101,102,5,13,0,0,102,13,1,0,0,0,103,104,5,14,0,0,104, + 105,5,73,0,0,105,106,3,16,8,0,106,110,5,12,0,0,107,109,3,22,11,0,108,107, + 1,0,0,0,109,112,1,0,0,0,110,108,1,0,0,0,110,111,1,0,0,0,111,113,1,0,0,0, + 112,110,1,0,0,0,113,114,5,13,0,0,114,15,1,0,0,0,115,127,5,15,0,0,116,121, + 3,18,9,0,117,118,5,16,0,0,118,120,3,18,9,0,119,117,1,0,0,0,120,123,1,0, + 0,0,121,119,1,0,0,0,121,122,1,0,0,0,122,125,1,0,0,0,123,121,1,0,0,0,124, + 126,5,16,0,0,125,124,1,0,0,0,125,126,1,0,0,0,126,128,1,0,0,0,127,116,1, + 0,0,0,127,128,1,0,0,0,128,129,1,0,0,0,129,130,5,17,0,0,130,17,1,0,0,0,131, + 132,3,60,30,0,132,133,5,73,0,0,133,19,1,0,0,0,134,138,5,12,0,0,135,137, + 3,22,11,0,136,135,1,0,0,0,137,140,1,0,0,0,138,136,1,0,0,0,138,139,1,0,0, + 0,139,141,1,0,0,0,140,138,1,0,0,0,141,144,5,13,0,0,142,144,3,22,11,0,143, + 134,1,0,0,0,143,142,1,0,0,0,144,21,1,0,0,0,145,154,3,24,12,0,146,154,3, + 26,13,0,147,154,3,28,14,0,148,154,3,30,15,0,149,154,3,32,16,0,150,154,3, + 34,17,0,151,154,3,36,18,0,152,154,3,40,20,0,153,145,1,0,0,0,153,146,1,0, + 0,0,153,147,1,0,0,0,153,148,1,0,0,0,153,149,1,0,0,0,153,150,1,0,0,0,153, + 151,1,0,0,0,153,152,1,0,0,0,154,23,1,0,0,0,155,159,3,60,30,0,156,158,3, + 54,27,0,157,156,1,0,0,0,158,161,1,0,0,0,159,157,1,0,0,0,159,160,1,0,0,0, + 160,162,1,0,0,0,161,159,1,0,0,0,162,163,5,73,0,0,163,164,5,10,0,0,164,165, + 3,52,26,0,165,166,5,2,0,0,166,25,1,0,0,0,167,168,3,60,30,0,168,169,5,73, + 0,0,169,170,5,16,0,0,170,171,3,60,30,0,171,172,5,73,0,0,172,173,5,10,0, + 0,173,174,3,52,26,0,174,175,5,2,0,0,175,27,1,0,0,0,176,177,5,73,0,0,177, + 178,5,10,0,0,178,179,3,52,26,0,179,180,5,2,0,0,180,29,1,0,0,0,181,182,5, + 18,0,0,182,183,5,15,0,0,183,184,5,70,0,0,184,185,5,6,0,0,185,188,3,52,26, + 0,186,187,5,16,0,0,187,189,3,42,21,0,188,186,1,0,0,0,188,189,1,0,0,0,189, + 190,1,0,0,0,190,191,5,17,0,0,191,192,5,2,0,0,192,31,1,0,0,0,193,194,5,18, + 0,0,194,195,5,15,0,0,195,198,3,52,26,0,196,197,5,16,0,0,197,199,3,42,21, + 0,198,196,1,0,0,0,198,199,1,0,0,0,199,200,1,0,0,0,200,201,5,17,0,0,201, + 202,5,2,0,0,202,33,1,0,0,0,203,204,5,19,0,0,204,205,5,15,0,0,205,206,3, + 52,26,0,206,207,5,17,0,0,207,210,3,20,10,0,208,209,5,20,0,0,209,211,3,20, + 10,0,210,208,1,0,0,0,210,211,1,0,0,0,211,35,1,0,0,0,212,213,3,38,19,0,213, + 37,1,0,0,0,214,215,5,21,0,0,215,216,3,20,10,0,216,217,5,22,0,0,217,218, + 5,15,0,0,218,219,3,52,26,0,219,220,5,17,0,0,220,221,5,2,0,0,221,39,1,0, + 0,0,222,223,5,23,0,0,223,224,3,46,23,0,224,225,5,2,0,0,225,41,1,0,0,0,226, + 227,5,67,0,0,227,43,1,0,0,0,228,231,5,73,0,0,229,231,3,56,28,0,230,228, + 1,0,0,0,230,229,1,0,0,0,231,45,1,0,0,0,232,244,5,15,0,0,233,238,3,44,22, + 0,234,235,5,16,0,0,235,237,3,44,22,0,236,234,1,0,0,0,237,240,1,0,0,0,238, + 236,1,0,0,0,238,239,1,0,0,0,239,242,1,0,0,0,240,238,1,0,0,0,241,243,5,16, + 0,0,242,241,1,0,0,0,242,243,1,0,0,0,243,245,1,0,0,0,244,233,1,0,0,0,244, + 245,1,0,0,0,245,246,1,0,0,0,246,247,5,17,0,0,247,47,1,0,0,0,248,249,5,73, + 0,0,249,250,3,50,25,0,250,49,1,0,0,0,251,263,5,15,0,0,252,257,3,52,26,0, + 253,254,5,16,0,0,254,256,3,52,26,0,255,253,1,0,0,0,256,259,1,0,0,0,257, + 255,1,0,0,0,257,258,1,0,0,0,258,261,1,0,0,0,259,257,1,0,0,0,260,262,5,16, + 0,0,261,260,1,0,0,0,261,262,1,0,0,0,262,264,1,0,0,0,263,252,1,0,0,0,263, + 264,1,0,0,0,264,265,1,0,0,0,265,266,5,17,0,0,266,51,1,0,0,0,267,268,6,26, + -1,0,268,269,5,15,0,0,269,270,3,52,26,0,270,271,5,17,0,0,271,317,1,0,0, + 0,272,273,3,62,31,0,273,274,5,15,0,0,274,276,3,52,26,0,275,277,5,16,0,0, + 276,275,1,0,0,0,276,277,1,0,0,0,277,278,1,0,0,0,278,279,5,17,0,0,279,317, + 1,0,0,0,280,317,3,48,24,0,281,282,5,24,0,0,282,283,5,73,0,0,283,317,3,50, + 25,0,284,285,5,27,0,0,285,286,5,25,0,0,286,287,3,52,26,0,287,288,5,26,0, + 0,288,289,7,1,0,0,289,317,1,0,0,0,290,291,5,33,0,0,291,292,5,25,0,0,292, + 293,3,52,26,0,293,294,5,26,0,0,294,295,7,2,0,0,295,317,1,0,0,0,296,297, + 7,3,0,0,297,317,3,52,26,15,298,310,5,25,0,0,299,304,3,52,26,0,300,301,5, + 16,0,0,301,303,3,52,26,0,302,300,1,0,0,0,303,306,1,0,0,0,304,302,1,0,0, + 0,304,305,1,0,0,0,305,308,1,0,0,0,306,304,1,0,0,0,307,309,5,16,0,0,308, + 307,1,0,0,0,308,309,1,0,0,0,309,311,1,0,0,0,310,299,1,0,0,0,310,311,1,0, + 0,0,311,312,1,0,0,0,312,317,5,26,0,0,313,317,5,72,0,0,314,317,5,73,0,0, + 315,317,3,56,28,0,316,267,1,0,0,0,316,272,1,0,0,0,316,280,1,0,0,0,316,281, + 1,0,0,0,316,284,1,0,0,0,316,290,1,0,0,0,316,296,1,0,0,0,316,298,1,0,0,0, + 316,313,1,0,0,0,316,314,1,0,0,0,316,315,1,0,0,0,317,370,1,0,0,0,318,319, + 10,14,0,0,319,320,7,4,0,0,320,369,3,52,26,15,321,322,10,13,0,0,322,323, + 7,5,0,0,323,369,3,52,26,14,324,325,10,12,0,0,325,326,7,6,0,0,326,369,3, + 52,26,13,327,328,10,11,0,0,328,329,7,7,0,0,329,369,3,52,26,12,330,331,10, + 10,0,0,331,332,7,8,0,0,332,369,3,52,26,11,333,334,10,9,0,0,334,335,5,52, + 0,0,335,369,3,52,26,10,336,337,10,8,0,0,337,338,5,4,0,0,338,369,3,52,26, + 9,339,340,10,7,0,0,340,341,5,53,0,0,341,369,3,52,26,8,342,343,10,6,0,0, + 343,344,5,54,0,0,344,369,3,52,26,7,345,346,10,5,0,0,346,347,5,55,0,0,347, + 369,3,52,26,6,348,349,10,21,0,0,349,350,5,25,0,0,350,351,5,60,0,0,351,369, + 5,26,0,0,352,353,10,18,0,0,353,369,7,9,0,0,354,355,10,17,0,0,355,356,5, + 40,0,0,356,357,5,15,0,0,357,358,3,52,26,0,358,359,5,17,0,0,359,369,1,0, + 0,0,360,361,10,16,0,0,361,362,5,41,0,0,362,363,5,15,0,0,363,364,3,52,26, + 0,364,365,5,16,0,0,365,366,3,52,26,0,366,367,5,17,0,0,367,369,1,0,0,0,368, + 318,1,0,0,0,368,321,1,0,0,0,368,324,1,0,0,0,368,327,1,0,0,0,368,330,1,0, + 0,0,368,333,1,0,0,0,368,336,1,0,0,0,368,339,1,0,0,0,368,342,1,0,0,0,368, + 345,1,0,0,0,368,348,1,0,0,0,368,352,1,0,0,0,368,354,1,0,0,0,368,360,1,0, + 0,0,369,372,1,0,0,0,370,368,1,0,0,0,370,371,1,0,0,0,371,53,1,0,0,0,372, + 370,1,0,0,0,373,374,5,56,0,0,374,55,1,0,0,0,375,381,5,58,0,0,376,381,3, + 58,29,0,377,381,5,67,0,0,378,381,5,68,0,0,379,381,5,69,0,0,380,375,1,0, + 0,0,380,376,1,0,0,0,380,377,1,0,0,0,380,378,1,0,0,0,380,379,1,0,0,0,381, + 57,1,0,0,0,382,384,5,60,0,0,383,385,5,59,0,0,384,383,1,0,0,0,384,385,1, + 0,0,0,385,59,1,0,0,0,386,387,7,10,0,0,387,61,1,0,0,0,388,389,7,11,0,0,389, + 63,1,0,0,0,31,67,82,85,98,110,121,125,127,138,143,153,159,188,198,210,230, + 238,242,244,257,261,263,276,304,308,310,316,368,370,380,384]; private static __ATN: ATN; public static get _ATN(): ATN { @@ -2442,6 +2567,9 @@ export class StatementContext extends ParserRuleContext { public ifStatement(): IfStatementContext { return this.getTypedRuleContext(IfStatementContext, 0) as IfStatementContext; } + public loopStatement(): LoopStatementContext { + return this.getTypedRuleContext(LoopStatementContext, 0) as LoopStatementContext; + } public consoleStatement(): ConsoleStatementContext { return this.getTypedRuleContext(ConsoleStatementContext, 0) as ConsoleStatementContext; } @@ -2635,6 +2763,53 @@ export class IfStatementContext extends ParserRuleContext { } +export class LoopStatementContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public doWhileStatement(): DoWhileStatementContext { + return this.getTypedRuleContext(DoWhileStatementContext, 0) as DoWhileStatementContext; + } + public get ruleIndex(): number { + return CashScriptParser.RULE_loopStatement; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitLoopStatement) { + return visitor.visitLoopStatement(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class DoWhileStatementContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public block(): BlockContext { + return this.getTypedRuleContext(BlockContext, 0) as BlockContext; + } + public expression(): ExpressionContext { + return this.getTypedRuleContext(ExpressionContext, 0) as ExpressionContext; + } + public get ruleIndex(): number { + return CashScriptParser.RULE_doWhileStatement; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitDoWhileStatement) { + return visitor.visitDoWhileStatement(this); + } else { + return visitor.visitChildren(this); + } + } +} + + export class ConsoleStatementContext extends ParserRuleContext { constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { super(parent, invokingState); @@ -2793,19 +2968,15 @@ export class ExpressionContext extends ParserRuleContext { } export class CastContext extends ExpressionContext { public _castable!: ExpressionContext; - public _size!: ExpressionContext; constructor(parser: CashScriptParser, ctx: ExpressionContext) { super(parser, ctx.parentCtx, ctx.invokingState); super.copyFrom(ctx); } - public typeName(): TypeNameContext { - return this.getTypedRuleContext(TypeNameContext, 0) as TypeNameContext; - } - public expression_list(): ExpressionContext[] { - return this.getTypedRuleContexts(ExpressionContext) as ExpressionContext[]; + public typeCast(): TypeCastContext { + return this.getTypedRuleContext(TypeCastContext, 0) as TypeCastContext; } - public expression(i: number): ExpressionContext { - return this.getTypedRuleContext(ExpressionContext, i) as ExpressionContext; + public expression(): ExpressionContext { + return this.getTypedRuleContext(ExpressionContext, 0) as ExpressionContext; } // @Override public accept(visitor: CashScriptVisitor): Result { @@ -3130,8 +3301,14 @@ export class TypeNameContext extends ParserRuleContext { super(parent, invokingState); this.parser = parser; } - public Bytes(): TerminalNode { - return this.getToken(CashScriptParser.Bytes, 0); + public PrimitiveType(): TerminalNode { + return this.getToken(CashScriptParser.PrimitiveType, 0); + } + public BoundedBytes(): TerminalNode { + return this.getToken(CashScriptParser.BoundedBytes, 0); + } + public UnboundedBytes(): TerminalNode { + return this.getToken(CashScriptParser.UnboundedBytes, 0); } public get ruleIndex(): number { return CashScriptParser.RULE_typeName; @@ -3145,3 +3322,31 @@ export class TypeNameContext extends ParserRuleContext { } } } + + +export class TypeCastContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public PrimitiveType(): TerminalNode { + return this.getToken(CashScriptParser.PrimitiveType, 0); + } + public UnboundedBytes(): TerminalNode { + return this.getToken(CashScriptParser.UnboundedBytes, 0); + } + public UnsafeCast(): TerminalNode { + return this.getToken(CashScriptParser.UnsafeCast, 0); + } + public get ruleIndex(): number { + return CashScriptParser.RULE_typeCast; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitTypeCast) { + return visitor.visitTypeCast(this); + } else { + return visitor.visitChildren(this); + } + } +} diff --git a/packages/cashc/src/grammar/CashScriptVisitor.ts b/packages/cashc/src/grammar/CashScriptVisitor.ts index 4e161c03..513fea01 100644 --- a/packages/cashc/src/grammar/CashScriptVisitor.ts +++ b/packages/cashc/src/grammar/CashScriptVisitor.ts @@ -21,6 +21,8 @@ import { AssignStatementContext } from "./CashScriptParser.js"; import { TimeOpStatementContext } from "./CashScriptParser.js"; import { RequireStatementContext } from "./CashScriptParser.js"; import { IfStatementContext } from "./CashScriptParser.js"; +import { LoopStatementContext } from "./CashScriptParser.js"; +import { DoWhileStatementContext } from "./CashScriptParser.js"; import { ConsoleStatementContext } from "./CashScriptParser.js"; import { RequireMessageContext } from "./CashScriptParser.js"; import { ConsoleParameterContext } from "./CashScriptParser.js"; @@ -44,6 +46,7 @@ import { ModifierContext } from "./CashScriptParser.js"; import { LiteralContext } from "./CashScriptParser.js"; import { NumberLiteralContext } from "./CashScriptParser.js"; import { TypeNameContext } from "./CashScriptParser.js"; +import { TypeCastContext } from "./CashScriptParser.js"; /** @@ -162,6 +165,18 @@ export default class CashScriptVisitor extends ParseTreeVisitor * @return the visitor result */ visitIfStatement?: (ctx: IfStatementContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.loopStatement`. + * @param ctx the parse tree + * @return the visitor result + */ + visitLoopStatement?: (ctx: LoopStatementContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.doWhileStatement`. + * @param ctx the parse tree + * @return the visitor result + */ + visitDoWhileStatement?: (ctx: DoWhileStatementContext) => Result; /** * Visit a parse tree produced by `CashScriptParser.consoleStatement`. * @param ctx the parse tree @@ -313,5 +328,11 @@ export default class CashScriptVisitor extends ParseTreeVisitor * @return the visitor result */ visitTypeName?: (ctx: TypeNameContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.typeCast`. + * @param ctx the parse tree + * @return the visitor result + */ + visitTypeCast?: (ctx: TypeCastContext) => Result; } diff --git a/packages/cashc/src/index.ts b/packages/cashc/src/index.ts index e6de4dad..8aac4408 100644 --- a/packages/cashc/src/index.ts +++ b/packages/cashc/src/index.ts @@ -2,4 +2,4 @@ export * from './Errors.js'; export * as utils from '@cashscript/utils'; export { compileFile, compileString } from './compiler.js'; -export const version = '0.12.1'; +export const version = '0.13.0-next.3'; diff --git a/packages/cashc/src/print/OutputSourceCodeTraversal.ts b/packages/cashc/src/print/OutputSourceCodeTraversal.ts index df50ee54..e733c520 100644 --- a/packages/cashc/src/print/OutputSourceCodeTraversal.ts +++ b/packages/cashc/src/print/OutputSourceCodeTraversal.ts @@ -29,6 +29,7 @@ import { ConsoleStatementNode, ConsoleParameterNode, SliceNode, + DoWhileNode, } from '../ast/AST.js'; import AstTraversal from '../ast/AstTraversal.js'; @@ -163,6 +164,15 @@ export default class OutputSourceCodeTraversal extends AstTraversal { return node; } + visitDoWhile(node: DoWhileNode): Node { + this.addOutput('do ', true); + node.block = this.visit(node.block) as BlockNode; + this.addOutput(' while (', true); + node.condition = this.visit(node.condition); + this.addOutput(');\n'); + return node; + } + visitConsoleStatement(node: ConsoleStatementNode): Node { this.addOutput('console.log(', true); node.parameters = this.visitCommaList(node.parameters) as ConsoleParameterNode[]; @@ -184,7 +194,7 @@ export default class OutputSourceCodeTraversal extends AstTraversal { } visitCast(node: CastNode): Node { - this.addOutput(`${node.type}(`); + this.addOutput(`${node.isUnsafe ? 'unsafe_' : ''}${node.type}(`); node.expression = this.visit(node.expression); this.addOutput(')'); return node; diff --git a/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts b/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts index 52f29685..52e9f891 100644 --- a/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts +++ b/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts @@ -7,6 +7,7 @@ import { TimeOpNode, BranchNode, ConsoleStatementNode, + DoWhileNode, } from '../ast/AST.js'; import AstTraversal from '../ast/AstTraversal.js'; import { EmptyContractError, EmptyFunctionError, FinalRequireStatementError } from '../Errors.js'; @@ -50,6 +51,12 @@ function ensureFinalStatementIsRequire(statements: StatementNode[] = []): void { return; } + // TODO: Revisit this later, for now we allow do-while loops to not have a require() at the end + if (finalStatement instanceof DoWhileNode) { + // ensureFinalStatementIsRequire(finalStatement.block.statements); + return; + } + // The final statement needs to be a require() if (!(finalStatement instanceof RequireNode || finalStatement instanceof TimeOpNode)) { throw new FinalRequireStatementError(finalStatement); diff --git a/packages/cashc/src/semantic/TypeCheckTraversal.ts b/packages/cashc/src/semantic/TypeCheckTraversal.ts index 41bca3e8..7a5d281b 100644 --- a/packages/cashc/src/semantic/TypeCheckTraversal.ts +++ b/packages/cashc/src/semantic/TypeCheckTraversal.ts @@ -3,7 +3,6 @@ import { explicitlyCastable, implicitlyCastable, implicitlyCastableSignature, - resultingType, arrayType, ArrayType, TupleType, @@ -29,6 +28,7 @@ import { NullaryOpNode, SliceNode, IntLiteralNode, + DoWhileNode, } from '../ast/AST.js'; import AstTraversal from '../ast/AstTraversal.js'; import { @@ -40,11 +40,12 @@ import { AssignTypeError, ArrayElementError, IndexOutOfBoundsError, - CastSizeError, TupleAssignmentError, + BitshiftBitcountNegativeError, } from '../Errors.js'; import { BinaryOperator, NullaryOperator, UnaryOperator } from '../ast/Operator.js'; import { GlobalFunction } from '../ast/Globals.js'; +import { resultingTypeForBinaryOp } from '../utils.js'; export default class TypeCheckTraversal extends AstTraversal { visitVariableDefinition(node: VariableDefinitionNode): Node { @@ -101,21 +102,24 @@ export default class TypeCheckTraversal extends AstTraversal { return node; } + visitDoWhile(node: DoWhileNode): Node { + node.condition = this.visit(node.condition); + node.block = this.visit(node.block); + + if (!implicitlyCastable(node.condition.type, PrimitiveType.BOOL)) { + throw new TypeError(node, node.condition.type, PrimitiveType.BOOL); + } + + return node; + } + visitCast(node: CastNode): Node { node.expression = this.visit(node.expression); - node.size = this.visitOptional(node.size); if (!explicitlyCastable(node.expression.type, node.type)) { throw new CastTypeError(node); } - // Variable size cast is only possible from INT to unbounded BYTES - if (node.size) { - if (node.expression.type !== PrimitiveType.INT || node.type.toString() !== 'bytes') { - throw new CastSizeError(node); - } - } - return node; } @@ -126,7 +130,7 @@ export default class TypeCheckTraversal extends AstTraversal { const { definition, type } = node.identifier; if (!definition || !definition.parameters) return node; // already checked in symbol table - const parameterTypes = node.parameters.map((p) => p.type as Type); + const parameterTypes = node.parameters.map((p) => p.type!); expectParameters(node, parameterTypes, definition.parameters); // Additional array length check for checkMultiSig @@ -139,6 +143,12 @@ export default class TypeCheckTraversal extends AstTraversal { } node.type = type; + + // Infer the type of the toPaddedBytes function (depends on the second parameter) + if (node.identifier.name === GlobalFunction.TO_PADDED_BYTES) { + node.type = inferPaddedBytesType(node); + } + return node; } @@ -149,7 +159,7 @@ export default class TypeCheckTraversal extends AstTraversal { const { definition, type } = node.identifier; if (!definition || !definition.parameters) return node; // already checked in symbol table - const parameterTypes = node.parameters.map((p) => p.type as Type); + const parameterTypes = node.parameters.map((p) => p.type!); expectParameters(node, parameterTypes, definition.parameters); node.type = type; @@ -186,8 +196,8 @@ export default class TypeCheckTraversal extends AstTraversal { node.left = this.visit(node.left); node.right = this.visit(node.right); - const resType = resultingType(node.left.type, node.right.type); - if (!resType && !node.operator.startsWith('.')) { + const resType = resultingTypeForBinaryOp(node.operator, node.left.type!, node.right.type!); + if (!resType) { throw new UnequalTypeError(node); } @@ -231,6 +241,15 @@ export default class TypeCheckTraversal extends AstTraversal { expectSameSizeBytes(node, node.left.type, node.right.type); node.type = node.left.type; return node; + case BinaryOperator.SHIFT_LEFT: + case BinaryOperator.SHIFT_RIGHT: + expectAnyOfTypes(node, node.left.type, [new BytesType(), PrimitiveType.INT]); + expectInt(node, node.right.type); + if (node.right instanceof IntLiteralNode && Number(node.right.value) < 0) { + throw new BitshiftBitcountNegativeError(node, Number(node.right.value)); + } + node.type = node.left.type; + return node; case BinaryOperator.SPLIT: expectAnyOfTypes(node, node.left.type, [new BytesType(), PrimitiveType.STRING]); expectInt(node, node.right.type); @@ -253,6 +272,10 @@ export default class TypeCheckTraversal extends AstTraversal { expectInt(node, node.expression.type); node.type = PrimitiveType.INT; return node; + case UnaryOperator.INVERT: + expectBytes(node, node.expression.type); + node.type = node.expression.type; + return node; case UnaryOperator.SIZE: expectAnyOfTypes(node, node.expression.type, [new BytesType(), PrimitiveType.STRING]); node.type = PrimitiveType.INT; @@ -348,6 +371,10 @@ function expectInt(node: ExpectedNode, actual?: Type): void { expectAnyOfTypes(node, actual, [PrimitiveType.INT]); } +function expectBytes(node: ExpectedNode, actual?: Type): void { + expectAnyOfTypes(node, actual, [new BytesType()]); +} + function expectSameSizeBytes(node: BinaryOpNode, left?: Type, right?: Type): void { if (!(left instanceof BytesType) || !(right instanceof BytesType)) { throw new UnsupportedTypeError(node, left, new BytesType()); @@ -462,3 +489,11 @@ function inferSliceType(node: SliceNode): Type { // bytes.slice(NumberLiteral start, NumberLiteral end) -> bytes(end - start) return new BytesType(end - start); } + +const inferPaddedBytesType = (node: FunctionCallNode): Type => { + if (node.parameters[1] instanceof IntLiteralNode) { + return new BytesType(Number(node.parameters[1].value)); + } + + return new BytesType(); +}; diff --git a/packages/cashc/src/utils.ts b/packages/cashc/src/utils.ts new file mode 100644 index 00000000..c8fa1c8c --- /dev/null +++ b/packages/cashc/src/utils.ts @@ -0,0 +1,18 @@ +import { BytesType, implicitlyCastable, Type } from '@cashscript/utils'; +import { BinaryOperator } from './ast/Operator.js'; + +export function resultingTypeForBinaryOp( + operator: BinaryOperator, + left: Type, + right: Type, +): Type | undefined { + if ([BinaryOperator.SHIFT_LEFT, BinaryOperator.SHIFT_RIGHT, BinaryOperator.SPLIT].includes(operator)) return left; + + if (implicitlyCastable(left, right)) return right; + if (implicitlyCastable(right, left)) return left; + if (left instanceof BytesType && right instanceof BytesType) { + return new BytesType(); + } + + return undefined; +} diff --git a/packages/cashc/test/ast/AST.test.ts b/packages/cashc/test/ast/AST.test.ts index f764a561..7a7c0076 100644 --- a/packages/cashc/test/ast/AST.test.ts +++ b/packages/cashc/test/ast/AST.test.ts @@ -11,7 +11,6 @@ import fs from 'fs'; import { URL } from 'url'; -import urlJoin from 'url-join'; import { fixtures } from './fixtures.js'; import { parseCode } from '../../src/compiler.js'; import { readCashFiles } from '../test-utils.js'; @@ -24,7 +23,7 @@ describe('AST Builder', () => { describe('AST correctness', () => { fixtures.forEach((fixture) => { it(`should build correct AST for ${fixture.fn}`, () => { - const url = new URL(urlJoin(VALID_CONTRACT_FILES.toString(), fixture.fn)); + const url = new URL(fixture.fn, `${VALID_CONTRACT_FILES}/`); const code = fs.readFileSync(url, { encoding: 'utf-8' }); const ast = parseCode(code); expect(ast).toMatchObject(fixture.ast); diff --git a/packages/cashc/test/ast/fixtures.ts b/packages/cashc/test/ast/fixtures.ts index 20ed93b2..a0a59265 100644 --- a/packages/cashc/test/ast/fixtures.ts +++ b/packages/cashc/test/ast/fixtures.ts @@ -25,6 +25,7 @@ import { UnaryOpNode, InstantiationNode, ConsoleStatementNode, + DoWhileNode, } from '../../src/ast/AST.js'; import { BinaryOperator, NullaryOperator, UnaryOperator } from '../../src/ast/Operator.js'; import { Class, TimeOp } from '../../src/ast/Globals.js'; @@ -170,9 +171,13 @@ export const fixtures: Fixture[] = [ ), new BranchNode( new BinaryOpNode( - new IdentifierNode('d'), - BinaryOperator.EQ, - new IdentifierNode('x'), + new BinaryOpNode( + new IdentifierNode('d'), + BinaryOperator.EQ, + new IdentifierNode('x'), + ), + BinaryOperator.AND, + new CastNode(PrimitiveType.BOOL, new IdentifierNode('x'), false), ), new BlockNode([ new VariableDefinitionNode( @@ -367,6 +372,7 @@ export const fixtures: Fixture[] = [ new CastNode( PrimitiveType.INT, new IdentifierNode('blockHeightBin'), + false, ), ), new VariableDefinitionNode( @@ -376,6 +382,7 @@ export const fixtures: Fixture[] = [ new CastNode( PrimitiveType.INT, new IdentifierNode('priceBin'), + false, ), ), new RequireNode( @@ -808,6 +815,7 @@ export const fixtures: Fixture[] = [ new CastNode( new BytesType(), new StringLiteralNode('A contract may not injure a human being or, through inaction, allow a human being to come to harm.', '\''), + false, ), ])], ), @@ -933,4 +941,52 @@ export const fixtures: Fixture[] = [ ), ), }, + { + fn: 'do_while_loop.cash', + ast: new SourceFileNode( + new ContractNode( + 'Loopy', + [], + [new FunctionDefinitionNode( + 'doLoop', + [], + new BlockNode([ + new VariableDefinitionNode( + PrimitiveType.INT, + [], + 'i', + new IntLiteralNode(0n), + ), + new DoWhileNode( + new BinaryOpNode( + new IdentifierNode('i'), + BinaryOperator.LT, + new NullaryOpNode(NullaryOperator.INPUT_COUNT), + ), + new BlockNode([ + new AssignNode( + new IdentifierNode('i'), + new BinaryOpNode( + new IdentifierNode('i'), + BinaryOperator.PLUS, + new IntLiteralNode(1n), + ), + ), + ]), + ), + new ConsoleStatementNode([ + new IdentifierNode('i'), + ]), + new RequireNode( + new BinaryOpNode( + new IdentifierNode('i'), + BinaryOperator.GT, + new IntLiteralNode(2n), + ), + ), + ]), + )], + ), + ), + }, ]; diff --git a/packages/cashc/test/compiler/AssignTypeError/inferred_padded_bytes.cash b/packages/cashc/test/compiler/AssignTypeError/inferred_padded_bytes.cash new file mode 100644 index 00000000..a5885f1a --- /dev/null +++ b/packages/cashc/test/compiler/AssignTypeError/inferred_padded_bytes.cash @@ -0,0 +1,6 @@ +contract IntToByte() { + function hello(int a, bytes2 b) { + byte c = toPaddedBytes(a, 2); + require(b == c); + } +} diff --git a/packages/cashc/test/compiler/BitshiftBitcountNegativeError/bitshift_negative.cash b/packages/cashc/test/compiler/BitshiftBitcountNegativeError/bitshift_negative.cash new file mode 100644 index 00000000..d0de16d3 --- /dev/null +++ b/packages/cashc/test/compiler/BitshiftBitcountNegativeError/bitshift_negative.cash @@ -0,0 +1,7 @@ +contract Test() { + function spend() { + bytes8 x = 0x1122334455667788; + bytes8 y = x << -4; + require(y == 0x0000000055667788); + } +} diff --git a/packages/cashc/test/compiler/CastSizeError/bool_cast_size.cash b/packages/cashc/test/compiler/CastSizeError/bool_cast_size.cash deleted file mode 100644 index 26310d0d..00000000 --- a/packages/cashc/test/compiler/CastSizeError/bool_cast_size.cash +++ /dev/null @@ -1,5 +0,0 @@ -contract Test(int y) { - function hello() { - require(bool(y, 2) == true); - } -} diff --git a/packages/cashc/test/compiler/CastSizeError/bounded_bytes_cast_size.cash b/packages/cashc/test/compiler/CastSizeError/bounded_bytes_cast_size.cash deleted file mode 100644 index 9ed7ea8a..00000000 --- a/packages/cashc/test/compiler/CastSizeError/bounded_bytes_cast_size.cash +++ /dev/null @@ -1,5 +0,0 @@ -contract Test(int y) { - function hello() { - require(bytes2(y, 2) == 0x0000); - } -} diff --git a/packages/cashc/test/compiler/CastTypeError/cast_to_smaller_bytes.cash b/packages/cashc/test/compiler/CastTypeError/cast_to_smaller_bytes.cash index 5c211635..2af55761 100644 --- a/packages/cashc/test/compiler/CastTypeError/cast_to_smaller_bytes.cash +++ b/packages/cashc/test/compiler/CastTypeError/cast_to_smaller_bytes.cash @@ -1,6 +1,6 @@ contract Test() { function hello() { - bytes1 b = bytes1(0x1234); + bytes1 b = unsafe_bytes1(0x1234); require(b.length == 1); } } diff --git a/packages/cashc/test/compiler/CastTypeError/unsafe_bool_cast_bytes4.cash b/packages/cashc/test/compiler/CastTypeError/unsafe_bool_cast_bytes4.cash new file mode 100644 index 00000000..8fdd98e5 --- /dev/null +++ b/packages/cashc/test/compiler/CastTypeError/unsafe_bool_cast_bytes4.cash @@ -0,0 +1,5 @@ +contract Test(bytes4 x) { + function test() { + require(unsafe_bool(x)); + } +} diff --git a/packages/cashc/test/compiler/CastTypeError/unsafe_int_cast_sig.cash b/packages/cashc/test/compiler/CastTypeError/unsafe_int_cast_sig.cash new file mode 100644 index 00000000..fbd2b862 --- /dev/null +++ b/packages/cashc/test/compiler/CastTypeError/unsafe_int_cast_sig.cash @@ -0,0 +1,5 @@ +contract Test(sig x) { + function test(bytes4 y) { + require(unsafe_int(x) > unsafe_int(y)); + } +} diff --git a/packages/cashc/test/compiler/InvalidParameterTypeError/string_to_padded_bytes.cash b/packages/cashc/test/compiler/InvalidParameterTypeError/string_to_padded_bytes.cash new file mode 100644 index 00000000..fb5ec44d --- /dev/null +++ b/packages/cashc/test/compiler/InvalidParameterTypeError/string_to_padded_bytes.cash @@ -0,0 +1,6 @@ +contract IntToByte() { + function hello(string a, bytes2 b) { + bytes2 c = toPaddedBytes(a, 2); + require(b == c); + } +} diff --git a/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_function.cash b/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_function.cash index aad65da5..2e8a6290 100644 --- a/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_function.cash +++ b/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_function.cash @@ -1,5 +1,5 @@ contract Test() { function hello() { - require(LockingBytecodeP2PKH(bytes20(0)) == bytes34(0)); + require(LockingBytecodeP2PKH(toPaddedBytes(0, 20)) == toPaddedBytes(0, 34)); } } diff --git a/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_id.cash b/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_id.cash index f54f449f..9ba9931c 100644 --- a/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_id.cash +++ b/packages/cashc/test/compiler/InvalidSymbolTypeError/class_name_as_id.cash @@ -1,5 +1,5 @@ contract Test() { function hello() { - require(LockingBytecodeP2PKH == bytes34(0)); + require(LockingBytecodeP2PKH == toPaddedBytes(0, 34)); } } diff --git a/packages/cashc/test/compiler/ParseError/while_loop.cash b/packages/cashc/test/compiler/ParseError/while_loop.cash new file mode 100644 index 00000000..e88d0222 --- /dev/null +++ b/packages/cashc/test/compiler/ParseError/while_loop.cash @@ -0,0 +1,12 @@ +contract Loopy() { + function doLoop() { + int i = 0; + + while (i < tx.inputs.length) { + i = i + 1; + } + + console.log(i); + require(i > 2); + } +} diff --git a/packages/cashc/test/compiler/TypeError/do_while_loop_bytes32_condition.cash b/packages/cashc/test/compiler/TypeError/do_while_loop_bytes32_condition.cash new file mode 100644 index 00000000..d5a61eb9 --- /dev/null +++ b/packages/cashc/test/compiler/TypeError/do_while_loop_bytes32_condition.cash @@ -0,0 +1,12 @@ +contract Loopy() { + function doLoop() { + int i = 0; + + do { + i = i + 1; + } while (tx.inputs[0].outpointTransactionHash); + + console.log(i); + require(i > 2); + } +} diff --git a/packages/cashc/test/compiler/UnequalTypeError/bytes_size_comparison.cash.todo b/packages/cashc/test/compiler/UnequalTypeError/bytes_size_comparison.cash.todo new file mode 100644 index 00000000..bff6989f --- /dev/null +++ b/packages/cashc/test/compiler/UnequalTypeError/bytes_size_comparison.cash.todo @@ -0,0 +1,6 @@ +contract IntToByte() { + function hello(bytes2 b) { + byte c = 0x01; + require(b == c); + } +} diff --git a/packages/cashc/test/compiler/UnsupportedTypeError/bitshift_invalid_argument.cash b/packages/cashc/test/compiler/UnsupportedTypeError/bitshift_invalid_argument.cash new file mode 100644 index 00000000..9a4aa2d9 --- /dev/null +++ b/packages/cashc/test/compiler/UnsupportedTypeError/bitshift_invalid_argument.cash @@ -0,0 +1,7 @@ +contract Test() { + function spend() { + string x = "Hello World"; + string y = x << 4; + require(y == 0x0000000055667788); + } +} diff --git a/packages/cashc/test/compiler/UnsupportedTypeError/bitshift_invalid_bitcount.cash b/packages/cashc/test/compiler/UnsupportedTypeError/bitshift_invalid_bitcount.cash new file mode 100644 index 00000000..ec14530e --- /dev/null +++ b/packages/cashc/test/compiler/UnsupportedTypeError/bitshift_invalid_bitcount.cash @@ -0,0 +1,7 @@ +contract Test() { + function spend() { + bytes8 x = 0x1122334455667788; + bytes8 y = x << 0x04; + require(y == 0x0000000055667788); + } +} diff --git a/packages/cashc/test/compiler/UnsupportedTypeError/invert_number.cash b/packages/cashc/test/compiler/UnsupportedTypeError/invert_number.cash new file mode 100644 index 00000000..d22b7145 --- /dev/null +++ b/packages/cashc/test/compiler/UnsupportedTypeError/invert_number.cash @@ -0,0 +1,7 @@ +contract Test() { + function spend() { + int x = 16; + int y = ~x; + require(y == -17); + } +} diff --git a/packages/cashc/test/generation/fixtures.ts b/packages/cashc/test/generation/fixtures.ts index 899539a5..8f0d22ab 100644 --- a/packages/cashc/test/generation/fixtures.ts +++ b/packages/cashc/test/generation/fixtures.ts @@ -179,8 +179,8 @@ export const fixtures: Fixture[] = [ + 'OP_3 OP_PICK OP_5 OP_PICK OP_ADD ' // d = d - a + 'OP_DUP OP_5 OP_PICK OP_SUB ' - // if (d == x) { - + 'OP_DUP OP_3 OP_ROLL OP_NUMEQUAL OP_IF ' + // if (d == x && bool(x)) { + + 'OP_DUP OP_3 OP_PICK OP_NUMEQUAL OP_3 OP_ROLL OP_0NOTEQUAL OP_BOOLAND OP_IF ' // int c = d + b + 'OP_DUP OP_6 OP_PICK OP_ADD ' // d = a + c @@ -217,15 +217,15 @@ export const fixtures: Fixture[] = [ + 'OP_2SWAP OP_NUMEQUAL ' + 'OP_NIP OP_NIP OP_ENDIF', debug: { - bytecode: '5279009c6353795579937655799476537a9c6376567993557978937b757c6e9f6975675479776876557a93537a9d6d6d51677b519d527976529376537a9c63765479936e937b757c6e9f697568729c777768', + bytecode: '5279009c635379557993765579947653799c537a929a6376567993557978937b757c6e9f6975675479776876557a93537a9d6d6d51677b519d527976529376537a9c63765479936e937b757c6e9f697568729c777768', logs: [], requires: [ - { ip: 34, line: 8 }, - { ip: 47, line: 13 }, - { ip: 76, line: 22 }, - { ip: 81, line: 25 }, + { ip: 38, line: 8 }, + { ip: 51, line: 13 }, + { ip: 80, line: 22 }, + { ip: 85, line: 25 }, ], - sourceMap: '2:4:14:5;;;;;3:16:3:17;;:20::21;;:16:::1;4:12:4:13:0;:16::17;;:12:::1;5::5:13:0;:17::18;;:12:::1;:20:9:9:0;6::6:21;:24::25;;:20:::1;7:16:7:17:0;;:20::21;:16:::1;:12::22;;;8:20:8:25:0;::::1;:12::27;5:20:9:9;9:15:11::0;10:16:10:17;;:12::18:1;9:15:11:9;12:12:12:13:0;:16::17;;:12:::1;13:21:13:22:0;;:8::24:1;2:4:14:5;;;;16::26::0;;;17:16:17:17;;18:12:18:13;:16::17;:12:::1;19::19:13:0;:17::18;;:12:::1;:20:23:9:0;20::20:21;:24::25;;:20:::1;21:16:21:21:0;::::1;:12::22;;;22:20:22:25:0;::::1;:12::27;19:20:23:9;;24:12:25:22:0;25:8::24:1;16:4:26:5;;1:0:27:1', + sourceMap: '2:4:14:5;;;;;3:16:3:17;;:20::21;;:16:::1;4:12:4:13:0;:16::17;;:12:::1;5::5:13:0;:17::18;;:12:::1;:27::28:0;;:22::29:1;:12;:31:9:9:0;6:20:6:21;:24::25;;:20:::1;7:16:7:17:0;;:20::21;:16:::1;:12::22;;;8:20:8:25:0;::::1;:12::27;5:31:9:9;9:15:11::0;10:16:10:17;;:12::18:1;9:15:11:9;12:12:12:13:0;:16::17;;:12:::1;13:21:13:22:0;;:8::24:1;2:4:14:5;;;;16::26::0;;;17:16:17:17;;18:12:18:13;:16::17;:12:::1;19::19:13:0;:17::18;;:12:::1;:20:23:9:0;20::20:21;:24::25;;:20:::1;21:16:21:21:0;::::1;:12::22;;;22:20:22:25:0;::::1;:12::27;19:20:23:9;;24:12:25:22:0;25:8::24:1;16:4:26:5;;1:0:27:1', }, source: fs.readFileSync(new URL('../valid-contract-files/multifunction_if_statements.cash', import.meta.url), { encoding: 'utf-8' }), compiler: { @@ -411,12 +411,12 @@ export const fixtures: Fixture[] = [ contractName: 'BoundedBytes', constructorInputs: [], abi: [{ name: 'spend', inputs: [{ name: 'b', type: 'bytes4' }, { name: 'i', type: 'int' }] }], - bytecode: 'OP_SWAP OP_4 OP_NUM2BIN OP_EQUAL', // require(b == bytes4(i)) + bytecode: 'OP_SWAP OP_4 OP_NUM2BIN OP_EQUAL', // require(b == toPaddedBytes(i, 4)) debug: { bytecode: '7c548087', logs: [], requires: [{ ip: 4, line: 3 }], - sourceMap: '3:28:3:29;:21::30:1;;:8::32', + sourceMap: '3:35:3:36;:38::39;:21::40:1;:8::42', }, source: fs.readFileSync(new URL('../valid-contract-files/bounded_bytes.cash', import.meta.url), { encoding: 'utf-8' }), compiler: { @@ -701,7 +701,7 @@ export const fixtures: Fixture[] = [ bytecode: '5a7c80815a9c', logs: [], requires: [{ ip: 6, line: 4 }], - sourceMap: '3:28:3:30;:32::36;:22::37:1;4:16:4:26;:30::32:0;:8::34:1', + sourceMap: '3:36:3:38;:40::44;:22::45:1;4:16:4:26;:30::32:0;:8::34:1', }, source: fs.readFileSync(new URL('../valid-contract-files/num2bin_variable.cash', import.meta.url), { encoding: 'utf-8' }), compiler: { @@ -887,7 +887,7 @@ export const fixtures: Fixture[] = [ bytecode: '14 OP_SPLIT OP_DROP OP_0 14 OP_NUM2BIN OP_EQUAL', debug: { bytecode: '01147f750001148087', - sourceMap: '3:36:3:38;:22::39:1;;4:31:4:32:0;:23::33:1;;:8::35', + sourceMap: '3:36:3:38;:22::39:1;;4:37:4:38:0;:40::42;:23::43:1;:8::45', logs: [], requires: [ { @@ -905,4 +905,79 @@ export const fixtures: Fixture[] = [ updatedAt: '', }, }, + { + fn: 'complex_loop.cash', + artifact: { + contractName: 'Loopy', + constructorInputs: [], + abi: [{ name: 'doLoop', inputs: [] }], + bytecode: 'OP_0 OP_0 OP_0 OP_0 OP_BEGIN OP_DUP OP_UTXOVALUE OP_4 OP_ROLL OP_DROP OP_SWAP OP_TOALTSTACK OP_SWAP OP_TOALTSTACK OP_SWAP OP_FROMALTSTACK OP_FROMALTSTACK OP_DUP OP_1ADD OP_NIP OP_TXOUTPUTCOUNT OP_2DUP OP_LESSTHAN OP_DUP OP_IF OP_2 OP_PICK OP_OUTPUTTOKENCATEGORY OP_0 OP_EQUAL OP_NOT OP_NIP OP_DUP OP_IF OP_4 OP_PICK OP_3 OP_PICK OP_OUTPUTVALUE OP_ADD OP_5 OP_ROLL OP_DROP OP_SWAP OP_TOALTSTACK OP_SWAP OP_TOALTSTACK OP_SWAP OP_TOALTSTACK OP_SWAP OP_FROMALTSTACK OP_FROMALTSTACK OP_FROMALTSTACK OP_ELSE OP_3 OP_PICK OP_1ADD OP_4 OP_ROLL OP_DROP OP_SWAP OP_TOALTSTACK OP_SWAP OP_TOALTSTACK OP_SWAP OP_FROMALTSTACK OP_FROMALTSTACK OP_ENDIF OP_ENDIF OP_2DROP OP_DUP OP_TXINPUTCOUNT OP_GREATERTHANOREQUAL OP_UNTIL OP_2SWAP OP_GREATERTHAN OP_VERIFY OP_SWAP OP_0 OP_GREATERTHAN OP_NIP', + debug: { + bytecode: '000000006576c6547a757c6b7c6b7c6c6c768b77c46e9f76635279d100879177766354795379cc93557a757c6b7c6b7c6b7c6c6c6c6753798b547a757c6b7c6b7c6c6c68686d76c3a26672a0697c00a077', + sourceMap: '3:23:3:24;4:24:4:25;5:25:5:26;6:16:6:17;8:8:26:39;9:33:9:34;:23::41:1;:12::42;;;;;;;;;;10:16:10:17:0;:::21:1;:12::22;12:20:12:37:0;13:21:13:26;::::1;15:16:15:17:0;:19:25:13;16:31:16:32;;:20::47:1;:51::53:0;:20:::1;;:16::54;18:20:18:21:0;:23:20:17;19:32:19:41;;:55::56;;:44::63:1;:32;:20::64;;;;;;;;;;;;;20:23:22:17:0;21:33:21:43;;:::47:1;:20::48;;;;;;;;;;20:23:22:17;15:19:25:13;8:11:26:9;26:17::18:0;:21::37;8:8::39:1;;28:16:28:36:0;::::1;:8::38;29:16:29:26:0;:29::30;:8::32:1;2:4:30:5', + logs: [ + { ip: 68, line: 24, data: [{ stackIndex: 3, type: 'int', ip: 68 }] }, + ], + requires: [ + { ip: 76, line: 28 }, + { ip: 80, line: 29 }, + ], + }, + source: fs.readFileSync(new URL('../valid-contract-files/complex_loop.cash', import.meta.url), { encoding: 'utf-8' }), + compiler: { + name: 'cashc', + version, + }, + updatedAt: '', + }, + }, + { + fn: 'do_while_loop_no_introspection.cash', + artifact: { + contractName: 'Loopy', + constructorInputs: [], + abi: [{ name: 'doLoop', inputs: [] }], + bytecode: 'OP_0 OP_2 OP_BEGIN OP_OVER OP_1ADD OP_ROT OP_DROP OP_SWAP OP_2DUP OP_ADD OP_10 OP_LESSTHAN OP_VERIFY OP_OVER OP_10 OP_GREATERTHANOREQUAL OP_UNTIL OP_2DROP OP_1', + debug: { + bytecode: '005265788b7b757c6e935a9f69785aa2666d51', + sourceMap: '3:16:3:17;4::4;6:8:10:25;7:16:7:17;:::21:1;:12::22;;;9:20:9:25:0;::::1;:28::30:0;:20:::1;:12::32;10:17:10:18:0;:21::23;6:8::25:1;;2:4:11:5;', + logs: [ + { ip: 8, line: 8, data: [{ stackIndex: 1, type: 'int', ip: 8 }] }, + ], + requires: [ + { ip: 12, line: 9 }, + ], + }, + source: fs.readFileSync(new URL('../valid-contract-files/do_while_loop_no_introspection.cash', import.meta.url), { encoding: 'utf-8' }), + compiler: { + name: 'cashc', + version, + }, + updatedAt: '', + }, + }, + { + fn: 'bitshift.cash', + artifact: { + contractName: 'Bitshift', + constructorInputs: [], + abi: [{ name: 'spend', inputs: [] }], + bytecode: '1122334455667788 OP_4 OP_LSHIFTBIN OP_4 OP_RSHIFTBIN 0000000055667788 OP_EQUALVERIFY OP_8 OP_2 OP_RSHIFTNUM OP_1 OP_LSHIFTNUM OP_16 OP_NUMEQUAL', + debug: { + bytecode: '081122334455667788549854990800000000556677888858528e518d609c', + sourceMap: '3:19:3:37;4:24:4:25;:19:::1;:29::30:0;:19:::1;6:21:6:39:0;:8::41:1;8:16:8:17:0;9:21:9:22;:16:::1;:26::27:0;:16:::1;11:22:11:24:0;:8::26:1', + logs: [], + requires: [ + { ip: 6, line: 6 }, + { ip: 14, line: 11 }, + ], + }, + source: fs.readFileSync(new URL('../valid-contract-files/bitshift.cash', import.meta.url), { encoding: 'utf-8' }), + compiler: { + name: 'cashc', + version, + }, + updatedAt: '', + }, + }, ]; diff --git a/packages/cashc/test/test-utils.ts b/packages/cashc/test/test-utils.ts index 35d4943e..42db93b8 100644 --- a/packages/cashc/test/test-utils.ts +++ b/packages/cashc/test/test-utils.ts @@ -1,14 +1,13 @@ import fs from 'fs'; import { URL } from 'url'; -import urlJoin from 'url-join'; export function getSubdirectories(directory: URL): string[] { return fs.readdirSync(directory) - .filter((fn) => fs.statSync(new URL(urlJoin(directory.toString(), fn))).isDirectory()); + .filter((fn) => fs.statSync(new URL(fn, `${directory}/`)).isDirectory()); } export function readCashFiles(directory: URL): { fn: string, contents: string }[] { return fs.readdirSync(directory) .filter((fn) => fn.endsWith('.cash')) - .map((fn) => ({ fn, contents: fs.readFileSync(new URL(urlJoin(directory.toString(), fn)), { encoding: 'utf-8' }) })); + .map((fn) => ({ fn, contents: fs.readFileSync(new URL(fn, `${directory}/`), { encoding: 'utf-8' }) })); } diff --git a/packages/cashc/test/valid-contract-files/bitshift.cash b/packages/cashc/test/valid-contract-files/bitshift.cash new file mode 100644 index 00000000..bce4ad3a --- /dev/null +++ b/packages/cashc/test/valid-contract-files/bitshift.cash @@ -0,0 +1,13 @@ +contract Bitshift() { + function spend() { + bytes8 x = 0x1122334455667788; + bytes8 y = x << 4 >> 4; + + require(y == 0x0000000055667788); + + int a = 8; + int b = a >> 2 << 1; + + require (b == 16); + } +} diff --git a/packages/cashc/test/valid-contract-files/bounded_bytes.cash b/packages/cashc/test/valid-contract-files/bounded_bytes.cash index 7076f51e..2fc2e8b8 100644 --- a/packages/cashc/test/valid-contract-files/bounded_bytes.cash +++ b/packages/cashc/test/valid-contract-files/bounded_bytes.cash @@ -1,5 +1,5 @@ contract BoundedBytes() { function spend(bytes4 b, int i) { - require(b == bytes4(i)); + require(b == toPaddedBytes(i, 4)); } } diff --git a/packages/cashc/test/valid-contract-files/bytes1_equals_byte.cash b/packages/cashc/test/valid-contract-files/bytes1_equals_byte.cash index 4b7031e0..0dc54ca5 100644 --- a/packages/cashc/test/valid-contract-files/bytes1_equals_byte.cash +++ b/packages/cashc/test/valid-contract-files/bytes1_equals_byte.cash @@ -1,6 +1,6 @@ contract Bytes1EqualsByte() { function hello(int a, byte b) { - bytes1 c = byte(a); + bytes1 c = toPaddedBytes(a, 1); require(b == c); } } diff --git a/packages/cashc/test/valid-contract-files/complex_loop.cash b/packages/cashc/test/valid-contract-files/complex_loop.cash new file mode 100644 index 00000000..338d7525 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/complex_loop.cash @@ -0,0 +1,31 @@ +contract Loopy() { + function doLoop() { + int inputSum = 0; + int outputSum = 0; + int tokenCount = 0; + int i = 0; + + do { + inputSum = tx.inputs[i].value; + i = i + 1; + + int x = tx.outputs.length; + bool b = i < x; + + if (b) { + b = tx.outputs[i].tokenCategory != 0x; + + if (b) { + outputSum = outputSum + tx.outputs[i].value; + } else { + tokenCount = tokenCount + 1; + } + + console.log(tokenCount); + } + } while (i < tx.inputs.length); + + require(inputSum > outputSum); + require(tokenCount > 0); + } +} diff --git a/packages/cashc/test/valid-contract-files/do_while_loop.cash b/packages/cashc/test/valid-contract-files/do_while_loop.cash new file mode 100644 index 00000000..2cfb3292 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/do_while_loop.cash @@ -0,0 +1,12 @@ +contract Loopy() { + function doLoop() { + int i = 0; + + do { + i = i + 1; + } while (i < tx.inputs.length); + + console.log(i); + require(i > 2); + } +} diff --git a/packages/cashc/test/valid-contract-files/do_while_loop_no_introspection.cash b/packages/cashc/test/valid-contract-files/do_while_loop_no_introspection.cash new file mode 100644 index 00000000..a11a89b1 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/do_while_loop_no_introspection.cash @@ -0,0 +1,12 @@ +contract Loopy() { + function doLoop() { + int i = 0; + int x = 2; + + do { + i = i + 1; + console.log(i); + require(i + x < 10); + } while (i < 10); + } +} diff --git a/packages/cashc/test/valid-contract-files/do_while_loop_no_tokens_in_inputs.cash b/packages/cashc/test/valid-contract-files/do_while_loop_no_tokens_in_inputs.cash new file mode 100644 index 00000000..07290469 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/do_while_loop_no_tokens_in_inputs.cash @@ -0,0 +1,13 @@ +pragma cashscript ^0.13.0; + +contract Loopy() { + function doLoop() { + int inputIndex = 0; + + // Loop over all inputs (variable length), and make sure that none of them contain tokens + do { + require(tx.inputs[inputIndex].tokenCategory == 0x); + inputIndex = inputIndex + 1; + } while (inputIndex < tx.inputs.length); + } +} diff --git a/packages/cashc/test/valid-contract-files/do_while_loop_require_inside_loop.cash b/packages/cashc/test/valid-contract-files/do_while_loop_require_inside_loop.cash new file mode 100644 index 00000000..6a751cf4 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/do_while_loop_require_inside_loop.cash @@ -0,0 +1,10 @@ +contract Loopy() { + function doLoop() { + int i = 0; + + do { + i = i + 1; + require(i < 10); + } while (i < tx.inputs.length); + } +} diff --git a/packages/cashc/test/valid-contract-files/do_while_no_require.cash b/packages/cashc/test/valid-contract-files/do_while_no_require.cash new file mode 100644 index 00000000..4b4fa097 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/do_while_no_require.cash @@ -0,0 +1,11 @@ +contract Loopy() { + function doLoop() { + int i = 0; + + require(i < 1); + + do { + i = i + 1; + } while (i < tx.inputs.length); + } +} diff --git a/packages/cashc/test/valid-contract-files/force_cast_smaller_bytes.cash b/packages/cashc/test/valid-contract-files/force_cast_smaller_bytes.cash index 569517a5..ef83dd89 100644 --- a/packages/cashc/test/valid-contract-files/force_cast_smaller_bytes.cash +++ b/packages/cashc/test/valid-contract-files/force_cast_smaller_bytes.cash @@ -1,7 +1,7 @@ contract Test() { function hello() { // Have to know what you're doing to force cast - bytes3 byte_ = bytes3(bytes(0x1234)); + bytes3 byte_ = unsafe_bytes3(bytes(0x1234)); require(byte_.length == 1); } } diff --git a/packages/cashc/test/valid-contract-files/int_to_byte.cash b/packages/cashc/test/valid-contract-files/int_to_byte.cash index 53f7d456..18698eff 100644 --- a/packages/cashc/test/valid-contract-files/int_to_byte.cash +++ b/packages/cashc/test/valid-contract-files/int_to_byte.cash @@ -1,6 +1,6 @@ contract IntToByte() { function hello(int a, byte b) { - byte c = byte(a); + byte c = toPaddedBytes(a, 1); require(b == c); } } diff --git a/packages/cashc/test/valid-contract-files/invert.cash b/packages/cashc/test/valid-contract-files/invert.cash new file mode 100644 index 00000000..463c4ae0 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/invert.cash @@ -0,0 +1,8 @@ +contract Test() { + function spend() { + bytes4 x = 0x00000000; + bytes4 y = ~x; + + require(y == 0xffffffff); + } +} diff --git a/packages/cashc/test/valid-contract-files/multifunction_if_statements.cash b/packages/cashc/test/valid-contract-files/multifunction_if_statements.cash index 2aab4dc8..b3a1547a 100644 --- a/packages/cashc/test/valid-contract-files/multifunction_if_statements.cash +++ b/packages/cashc/test/valid-contract-files/multifunction_if_statements.cash @@ -2,7 +2,7 @@ contract MultiFunctionIfStatements(int x, int y) { function transfer(int a, int b) { int d = a + b; d = d - a; - if (d == x) { + if (d == x && bool(x)) { int c = d + b; d = a + c; require(c > d); diff --git a/packages/cashc/test/valid-contract-files/num2bin.cash b/packages/cashc/test/valid-contract-files/num2bin.cash index 1d75cacd..6d06a21d 100644 --- a/packages/cashc/test/valid-contract-files/num2bin.cash +++ b/packages/cashc/test/valid-contract-files/num2bin.cash @@ -1,6 +1,6 @@ contract Test() { function hello() { - bytes2 byte_ = bytes2(10); + bytes2 byte_ = toPaddedBytes(10, 2); require(int(byte_) == 10); } } diff --git a/packages/cashc/test/valid-contract-files/num2bin_variable.cash b/packages/cashc/test/valid-contract-files/num2bin_variable.cash index 611125a2..a86db2ba 100644 --- a/packages/cashc/test/valid-contract-files/num2bin_variable.cash +++ b/packages/cashc/test/valid-contract-files/num2bin_variable.cash @@ -1,6 +1,6 @@ contract Num2Bin() { function spend(int size) { - bytes byte_ = bytes(10, size); + bytes byte_ = toPaddedBytes(10, size); require(int(byte_) == 10); } } diff --git a/packages/cashc/test/valid-contract-files/simulating_state.cash b/packages/cashc/test/valid-contract-files/simulating_state.cash index d6cd1709..f2b0b3a9 100644 --- a/packages/cashc/test/valid-contract-files/simulating_state.cash +++ b/packages/cashc/test/valid-contract-files/simulating_state.cash @@ -36,7 +36,7 @@ contract SimulatingState( // Insert new initialBlock (OP_PUSHBYTES_8 ) // Note that constructor parameters are added in reverse order, // so initialBlock is the first statement in the contract bytecode. - bytes newContract = 0x08 + bytes8(tx.locktime) + this.activeBytecode.split(9)[1]; + bytes newContract = 0x08 + toPaddedBytes(tx.locktime, 8) + this.activeBytecode.split(9)[1]; // Create the locking bytecode for the new contract and check that // the change output sends to that contract @@ -49,4 +49,4 @@ contract SimulatingState( require(hash160(pk) == funder); require(checkSig(s, pk)); } -} \ No newline at end of file +} diff --git a/packages/cashc/test/valid-contract-files/slice_optimised.cash b/packages/cashc/test/valid-contract-files/slice_optimised.cash index 39762828..d6f92390 100644 --- a/packages/cashc/test/valid-contract-files/slice_optimised.cash +++ b/packages/cashc/test/valid-contract-files/slice_optimised.cash @@ -1,6 +1,6 @@ contract Slice(bytes32 data) { function spend() { bytes20 pkh = data.slice(0, 20); - require(pkh == bytes20(0)); + require(pkh == toPaddedBytes(0, 20)); } } diff --git a/packages/cashc/test/valid-contract-files/sum_input_amount.cash b/packages/cashc/test/valid-contract-files/sum_input_amount.cash new file mode 100644 index 00000000..ebfefd44 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/sum_input_amount.cash @@ -0,0 +1,14 @@ +contract Loopy() { + function doLoop() { + int sum = 0; + int i = 0; + + do { + sum = tx.inputs[i].value; + i = i + 1; + } while (i < tx.inputs.length); + + console.log(sum); + require(sum > 2000); + } +} diff --git a/packages/cashc/test/valid-contract-files/trailing_comma.cash b/packages/cashc/test/valid-contract-files/trailing_comma.cash index acbb37e6..29848b6b 100644 --- a/packages/cashc/test/valid-contract-files/trailing_comma.cash +++ b/packages/cashc/test/valid-contract-files/trailing_comma.cash @@ -7,7 +7,7 @@ contract Contract( datasig oracleMsgSig, sig oracleTxSig, ) { - bytes oracleMessage = bytes('Spend') + bytes(12, 10,); + bytes oracleMessage = bytes('Spend') + bytes(12,); require(checkDataSig( oracleMsgSig, oracleMessage, diff --git a/packages/cashc/test/valid-contract-files/unsafe_bool_cast.cash b/packages/cashc/test/valid-contract-files/unsafe_bool_cast.cash new file mode 100644 index 00000000..da63b155 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/unsafe_bool_cast.cash @@ -0,0 +1,5 @@ +contract Test(int x) { + function test() { + require(unsafe_bool(x)); + } +} diff --git a/packages/cashc/test/valid-contract-files/unsafe_int_cast.cash b/packages/cashc/test/valid-contract-files/unsafe_int_cast.cash new file mode 100644 index 00000000..97212d94 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/unsafe_int_cast.cash @@ -0,0 +1,5 @@ +contract Test(bytes4 x) { + function test(bytes4 y) { + require(unsafe_int(x) > unsafe_int(y)); + } +} diff --git a/packages/cashscript/package.json b/packages/cashscript/package.json index 2ee5c92f..5a1b502c 100644 --- a/packages/cashscript/package.json +++ b/packages/cashscript/package.json @@ -1,6 +1,6 @@ { "name": "cashscript", - "version": "0.12.1", + "version": "0.13.0-next.3", "description": "Easily write and interact with Bitcoin Cash contracts", "keywords": [ "bitcoin cash", @@ -42,15 +42,14 @@ }, "dependencies": { "@bitauth/libauth": "^3.1.0-next.8", - "@cashscript/utils": "^0.12.1", + "@cashscript/utils": "^0.13.0-next.3", "@electrum-cash/network": "^4.1.3", "@mr-zwets/bchn-api-wrapper": "^1.0.1", - "pako": "^2.1.0", + "fflate": "^0.8.2", "semver": "^7.7.2" }, "devDependencies": { "@psf/bch-js": "^6.8.0", - "@types/pako": "^2.0.3", "@types/semver": "^7.5.8", "@vitest/coverage-v8": "^4.0.15", "eslint": "^8.54.0", diff --git a/packages/cashscript/src/debugging.ts b/packages/cashscript/src/debugging.ts index e12a0442..d5bf3991 100644 --- a/packages/cashscript/src/debugging.ts +++ b/packages/cashscript/src/debugging.ts @@ -1,5 +1,5 @@ import { AuthenticationErrorCommon, AuthenticationInstruction, AuthenticationProgramCommon, AuthenticationProgramStateCommon, AuthenticationVirtualMachine, ResolvedTransactionCommon, WalletTemplate, WalletTemplateScriptUnlocking, binToHex, createCompiler, createVirtualMachineBch2023, createVirtualMachineBch2025, createVirtualMachineBch2026, createVirtualMachineBchSpec, decodeAuthenticationInstructions, encodeAuthenticationInstruction, walletTemplateToCompilerConfiguration } from '@bitauth/libauth'; -import { Artifact, LogEntry, Op, PrimitiveType, StackItem, asmToBytecode, bytecodeToAsm, decodeBool, decodeInt, decodeString } from '@cashscript/utils'; +import { Artifact, LogData, LogEntry, Op, PrimitiveType, StackItem, asmToBytecode, bytecodeToAsm, decodeBool, decodeInt, decodeString } from '@cashscript/utils'; import { findLastIndex, toRegExp } from './utils.js'; import { FailedRequireError, FailedTransactionError, FailedTransactionEvaluationError } from './Errors.js'; import { getBitauthUri } from './libauth-template/LibauthTemplate.js'; @@ -75,18 +75,35 @@ const debugSingleScenario = ( const lockingScriptDebugResult = fullDebugSteps.slice(findLastIndex(fullDebugSteps, (state) => state.ip === 0)); // The controlStack determines whether the current debug step is in the executed branch + // It also tracks loop / function usage, but for the purpose of determining whether a step was executed, + // we only need to check that there are no 'false' items in the control stack. // https://libauth.org/types/AuthenticationProgramStateControlStack.html + // https://github.com/bitjson/bch-loops#control-stack const executedDebugSteps = lockingScriptDebugResult - .filter((debugStep) => debugStep.controlStack.every(item => item === true)); + .filter((debugStep) => debugStep.controlStack.every(item => item !== false)); // P2PKH inputs do not have an artifact, so we skip the console.log handling if (artifact) { - const executedLogs = (artifact.debug?.logs ?? []) - .filter((log) => executedDebugSteps.some((debugStep) => log.ip === debugStep.ip)); - - for (const log of executedLogs) { + // Try to match each executed debug step to a log entry if it exists. Note that inside loops, + // the same log statement may be executed multiple times in different debug steps + // Also note that multiple log statements may exist for the same ip, so we need to handle all of them + const executedLogs = executedDebugSteps + .flatMap((debugStep, index) => { + const logEntries = artifact.debug?.logs?.filter((log) => log.ip === debugStep.ip); + if (!logEntries || logEntries.length === 0) return []; + + const reversedPriorDebugSteps = executedDebugSteps.slice(0, index + 1).reverse(); + + return logEntries.map((logEntry) => { + const decodedLogData = logEntry.data + .map((dataEntry) => decodeLogDataEntry(dataEntry, reversedPriorDebugSteps, vm)); + return { logEntry, decodedLogData }; + }); + }); + + for (const { logEntry, decodedLogData } of executedLogs) { const inputIndex = extractInputIndexFromScenario(scenarioId); - logConsoleLogStatement(log, executedDebugSteps, artifact, inputIndex, vm); + logConsoleLogStatement(logEntry, decodedLogData, artifact.contractName, inputIndex); } } @@ -218,20 +235,28 @@ const createProgram = (template: WalletTemplate, unlockingScriptId: string, scen const logConsoleLogStatement = ( log: LogEntry, - debugSteps: AuthenticationProgramStateCommon[], - artifact: Artifact, + decodedLogData: Array, + contractName: string, inputIndex: number, - vm: VM, ): void => { - let line = `${artifact.contractName}.cash:${log.line}`; - const decodedData = log.data.map((element) => { - if (typeof element === 'string') return element; + console.log(`[Input #${inputIndex}] ${contractName}.cash:${log.line} ${decodedLogData.join(' ')}`); +}; - const debugStep = debugSteps.find((step) => step.ip === element.ip)!; - const transformedDebugStep = applyStackItemTransformations(element, debugStep, vm); - return decodeStackItem(element, transformedDebugStep.stack); - }); - console.log(`[Input #${inputIndex}] ${line} ${decodedData.join(' ')}`); +const decodeLogDataEntry = ( + dataEntry: LogData, + reversedPriorDebugSteps: AuthenticationProgramStateCommon[], + vm: VM, +): string | bigint | boolean => { + if (typeof dataEntry === 'string') return dataEntry; + + const dataEntryDebugStep = reversedPriorDebugSteps.find((step) => step.ip === dataEntry.ip); + + if (!dataEntryDebugStep) { + throw new Error(`Should not happen: corresponding data entry debug step not found for entry at ip ${dataEntry.ip}`); + } + + const transformedDebugStep = applyStackItemTransformations(dataEntry, dataEntryDebugStep, vm); + return decodeStackItem(dataEntry, transformedDebugStep.stack); }; const applyStackItemTransformations = ( @@ -264,7 +289,7 @@ const applyStackItemTransformations = ( return transformationsEndState; }; -const decodeStackItem = (element: StackItem, stack: Uint8Array[]): any => { +const decodeStackItem = (element: StackItem, stack: Uint8Array[]): string | bigint | boolean => { // Reversed since stack is in reverse order const stackItem = [...stack].reverse()[element.stackIndex]; diff --git a/packages/cashscript/src/libauth-template/LibauthTemplate.ts b/packages/cashscript/src/libauth-template/LibauthTemplate.ts index 27d15a50..ec61f293 100644 --- a/packages/cashscript/src/libauth-template/LibauthTemplate.ts +++ b/packages/cashscript/src/libauth-template/LibauthTemplate.ts @@ -25,17 +25,17 @@ import { isP2PKHUnlocker, isStandardUnlockableUtxo, isUnlockableUtxo, + LibauthOutput, Output, StandardUnlockableUtxo, Utxo, - VmTarget, } from '../interfaces.js'; import SignatureTemplate from '../SignatureTemplate.js'; import { addressToLockScript, extendedStringify, zip } from '../utils.js'; import { TransactionBuilder } from '../TransactionBuilder.js'; -import { deflate } from 'pako'; +import { zlibSync } from 'fflate'; import MockNetworkProvider from '../network/MockNetworkProvider.js'; -import { addHexPrefixExceptEmpty, formatBytecodeForDebugging, formatParametersForDebugging, getLockScriptName, getSignatureAndPubkeyFromP2PKHInput, getUnlockScriptName, lockingBytecodeIsSetToSlot, serialiseTokenDetails } from './utils.js'; +import { addHexPrefixExceptEmpty, DEFAULT_VM_TARGET, formatBytecodeForDebugging, formatParametersForDebugging, getLockScriptName, getSignatureAndPubkeyFromP2PKHInput, getUnlockScriptName, serialiseTokenDetails } from './utils.js'; // TODO: Add / improve descriptions throughout the template generation @@ -50,7 +50,7 @@ export const getLibauthTemplate = ( const vmTarget = transactionBuilder.provider instanceof MockNetworkProvider ? transactionBuilder.provider.vmTarget - : VmTarget.BCH_2025_05; + : DEFAULT_VM_TARGET; const template: WalletTemplate = { $schema: 'https://ide.bitauth.com/authentication-template-v0.schema.json', @@ -63,70 +63,6 @@ export const getLibauthTemplate = ( scenarios: generateAllTemplateScenarios(libauthTransaction, transactionBuilder), }; - // TODO: Refactor the below code to not have deep reassignment of scenario.sourceOutputs and scenario.transaction.outputs - - // Initialize bytecode mappings, these will be used to map the locking and unlocking scripts and naming the scripts - const unlockingBytecodeToLockingBytecodeParams: Record = {}; - const lockingBytecodeToLockingBytecodeParams: Record = {}; - - // We can typecast this because we check that all inputs are standard unlockable at the top of this function - for (const [inputIndex, input] of (transactionBuilder.inputs as StandardUnlockableUtxo[]).entries()) { - if (isContractUnlocker(input.unlocker)) { - const lockScriptName = getLockScriptName(input.unlocker.contract); - if (!lockScriptName) continue; - - const lockingScriptParams = generateLockingScriptParams(input.unlocker.contract, input, lockScriptName); - - const unlockingBytecode = binToHex(libauthTransaction.inputs[inputIndex].unlockingBytecode); - unlockingBytecodeToLockingBytecodeParams[unlockingBytecode] = lockingScriptParams; - - const lockingBytecode = binToHex(addressToLockScript(input.unlocker.contract.address)); - lockingBytecodeToLockingBytecodeParams[lockingBytecode] = lockingScriptParams; - } - } - - for (const scenario of Object.values(template.scenarios!)) { - // For Inputs - for (const [idx, input] of libauthTransaction.inputs.entries()) { - const unlockingBytecode = binToHex(input.unlockingBytecode); - const lockingBytecodeParams = unlockingBytecodeToLockingBytecodeParams[unlockingBytecode]; - - // If lockingBytecodeParams is unknown, then it stays at default: {} - if (!lockingBytecodeParams) continue; - - // If locking bytecode is set to ['slot'] then this is being evaluated by the scenario, so we don't replace bytecode - if (lockingBytecodeIsSetToSlot(scenario?.sourceOutputs?.[idx]?.lockingBytecode)) continue; - - // If lockingBytecodeParams is known, and this input is not ['slot'] then assign a locking bytecode as source output - if (scenario.sourceOutputs?.[idx]) { - scenario.sourceOutputs[idx] = { - ...scenario.sourceOutputs[idx], - lockingBytecode: lockingBytecodeParams, - }; - } - } - - // For Outputs - for (const [idx, output] of libauthTransaction.outputs.entries()) { - const lockingBytecode = binToHex(output.lockingBytecode); - const lockingBytecodeParams = lockingBytecodeToLockingBytecodeParams[lockingBytecode]; - - // If lockingBytecodeParams is unknown, then it stays at default: {} - if (!lockingBytecodeParams) continue; - - // If locking bytecode is set to ['slot'] then this is being evaluated by the scenario, so we don't replace bytecode - if (lockingBytecodeIsSetToSlot(scenario?.transaction?.outputs?.[idx]?.lockingBytecode)) continue; - - // If lockingBytecodeParams is known, and this input is not ['slot'] then assign a locking bytecode as source output - if (scenario?.transaction?.outputs?.[idx]) { - scenario.transaction.outputs[idx] = { - ...scenario.transaction.outputs[idx], - lockingBytecode: lockingBytecodeParams, - }; - } - } - } - return template; }; @@ -141,7 +77,7 @@ export const debugLibauthTemplate = (template: WalletTemplate, transaction: Tran export const getBitauthUri = (template: WalletTemplate): string => { const base64toBase64Url = (base64: string): string => base64.replace(/\+/g, '-').replace(/\//g, '_'); - const payload = base64toBase64Url(binToBase64(deflate(utf8ToBin(extendedStringify(template))))); + const payload = base64toBase64Url(binToBase64(zlibSync(utf8ToBin(extendedStringify(template))))); return `https://ide.bitauth.com/import-template/${payload}`; }; @@ -189,6 +125,25 @@ const generateAllTemplateScripts = ( return scripts.reduce((acc, script) => ({ ...acc, ...script }), {}); }; +const generateLockingBytecodeParamsMapping = ( + transactionBuilder: TransactionBuilder, +): Record => { + // Initialize bytecode mapping, this will be used to map the locking bytecode to the locking bytecode params + const mapping: Record = {}; + + // We can typecast this because we check that all inputs are standard unlockable at the top of this function + for (const input of (transactionBuilder.inputs as StandardUnlockableUtxo[])) { + if (isContractUnlocker(input.unlocker)) { + const lockScriptName = getLockScriptName(input.unlocker.contract); + const lockingScriptParams = generateLockingScriptParams(input.unlocker.contract, input, lockScriptName); + const lockingBytecode = binToHex(addressToLockScript(input.unlocker.contract.address)); + mapping[lockingBytecode] = lockingScriptParams; + } + } + + return mapping; +}; + const generateAllTemplateScenarios = ( libauthTransaction: TransactionBch, transactionBuilder: TransactionBuilder, @@ -452,6 +407,8 @@ const generateTemplateScenarioTransaction = ( transactionBuilder: TransactionBuilder, slotIndex: number, ): WalletTemplateScenario['transaction'] => { + const lockingBytecodeParamsMapping = generateLockingBytecodeParamsMapping(transactionBuilder); + const zippedInputs = zip(transactionBuilder.inputs, libauthTransaction.inputs); const inputs = zippedInputs.map(([csInput, libauthInput], inputIndex) => { return { @@ -466,16 +423,10 @@ const generateTemplateScenarioTransaction = ( const zippedOutputs = zip(transactionBuilder.outputs, libauthTransaction.outputs); const outputs = zippedOutputs.map(([csOutput, libauthOutput]) => { - if (csOutput && contract) { - return { - lockingBytecode: generateTemplateScenarioTransactionOutputLockingBytecode(csOutput, contract), - token: serialiseTokenDetails(libauthOutput.token), - valueSatoshis: Number(libauthOutput.valueSatoshis), - }; - } - return { - lockingBytecode: `${binToHex(libauthOutput.lockingBytecode)}`, + lockingBytecode: generateTemplateScenarioTransactionOutputLockingBytecode( + csOutput, libauthOutput, contract, lockingBytecodeParamsMapping, + ), token: serialiseTokenDetails(libauthOutput.token), valueSatoshis: Number(libauthOutput.valueSatoshis), }; @@ -494,7 +445,7 @@ const generateTemplateScenarioSourceOutputs = ( const zippedInputs = zip(transactionBuilder.inputs, libauthTransaction.inputs); return zippedInputs.map(([csInput, libauthInput], inputIndex) => { return { - lockingBytecode: generateTemplateScenarioBytecode(csInput, libauthInput, inputIndex, 'p2pkh_placeholder_lock', inputIndex === slotIndex), + lockingBytecode: generateTemplateScenarioBytecodeForSourceOutputs(csInput, libauthInput, inputIndex, 'p2pkh_placeholder_lock', inputIndex === slotIndex), valueSatoshis: Number(csInput.satoshis), token: serialiseTokenDetails(csInput.token), }; @@ -620,12 +571,45 @@ const generateTemplateScenarioBytecode = ( return {}; }; +const generateTemplateScenarioBytecodeForSourceOutputs = ( + input: Utxo, + libauthInput: Input, + inputIndex: number, + p2pkhScriptNameTemplate: string, + insertSlot?: boolean, +): WalletTemplateScenarioBytecode | ['slot'] => { + if (insertSlot) return ['slot']; + + if (isUnlockableUtxo(input) && isStandardUnlockableUtxo(input)) { + // If the input is a contract unlocker, we need to generate the locking bytecode params for the source outputs + if (isContractUnlocker(input.unlocker)) { + const lockScriptName = getLockScriptName(input.unlocker.contract); + const lockingBytecodeParams = generateLockingScriptParams(input.unlocker.contract, input, lockScriptName); + return lockingBytecodeParams; + } + + // For a P2PKH unlocker, the sourceOutputs "locking bytecode params" are the same as the unlocking bytecode params + return generateUnlockingScriptParams(input, libauthInput, p2pkhScriptNameTemplate, inputIndex); + } + + // 'slot' means that we are currently evaluating this specific input, + // {} means that it is the same script type, but not being evaluated + return {}; +}; + const generateTemplateScenarioTransactionOutputLockingBytecode = ( csOutput: Output, - contract: Contract, + libauthOutput: LibauthOutput, + contract: Contract | undefined, + lockingBytecodeParamsMapping: Record, ): string | {} => { + // If lockingBytecodeParams is known from the mapping, return it + const lockingBytecode = binToHex(libauthOutput.lockingBytecode); + const lockingBytecodeParams = lockingBytecodeParamsMapping[lockingBytecode]; + if (lockingBytecodeParams) return lockingBytecodeParams; + if (csOutput.to instanceof Uint8Array) return binToHex(csOutput.to); - if ([contract.address, contract.tokenAddress].includes(csOutput.to)) return {}; + if (contract && [contract.address, contract.tokenAddress].includes(csOutput.to)) return {}; return binToHex(addressToLockScript(csOutput.to)); }; diff --git a/packages/cashscript/src/libauth-template/utils.ts b/packages/cashscript/src/libauth-template/utils.ts index f4e3b02c..2f2cd52e 100644 --- a/packages/cashscript/src/libauth-template/utils.ts +++ b/packages/cashscript/src/libauth-template/utils.ts @@ -1,11 +1,13 @@ import { AbiFunction, AbiInput, Artifact, bytecodeToScript, formatBitAuthScript } from '@cashscript/utils'; -import { HashType, LibauthTokenDetails, SignatureAlgorithm, TokenDetails } from '../interfaces.js'; -import { hexToBin, binToHex, isHex, decodeCashAddress, type WalletTemplateScenarioBytecode, Input, assertSuccess, decodeAuthenticationInstructions, AuthenticationInstructionPush } from '@bitauth/libauth'; +import { HashType, LibauthTokenDetails, SignatureAlgorithm, TokenDetails, VmTarget } from '../interfaces.js'; +import { hexToBin, binToHex, isHex, decodeCashAddress, Input, assertSuccess, decodeAuthenticationInstructions, AuthenticationInstructionPush } from '@bitauth/libauth'; import { EncodedFunctionArgument } from '../Argument.js'; import { zip } from '../utils.js'; import SignatureTemplate from '../SignatureTemplate.js'; import { Contract } from '../Contract.js'; +export const DEFAULT_VM_TARGET = VmTarget.BCH_2026_05; + export const getLockScriptName = (contract: Contract): string => { const result = decodeCashAddress(contract.address); if (typeof result === 'string') throw new Error(result); @@ -109,10 +111,6 @@ interface LibauthTemplateTokenDetails { }; } -export const lockingBytecodeIsSetToSlot = (lockingBytecode?: WalletTemplateScenarioBytecode | ['slot']): boolean => { - return Array.isArray(lockingBytecode) && lockingBytecode.length === 1 && lockingBytecode[0] === 'slot'; -}; - export const getSignatureAndPubkeyFromP2PKHInput = ( libauthInput: Input, ): { signature: Uint8Array; publicKey: Uint8Array } => { diff --git a/packages/cashscript/src/network/MockNetworkProvider.ts b/packages/cashscript/src/network/MockNetworkProvider.ts index 2af9b763..3b8f5c5a 100644 --- a/packages/cashscript/src/network/MockNetworkProvider.ts +++ b/packages/cashscript/src/network/MockNetworkProvider.ts @@ -3,6 +3,7 @@ import { sha256 } from '@cashscript/utils'; import { Utxo, Network, VmTarget } from '../interfaces.js'; import NetworkProvider from './NetworkProvider.js'; import { addressToLockScript, libauthTokenDetailsToCashScriptTokenDetails } from '../utils.js'; +import { DEFAULT_VM_TARGET } from '../libauth-template/utils.js'; export interface MockNetworkProviderOptions { updateUtxoSet: boolean; @@ -20,7 +21,7 @@ export default class MockNetworkProvider implements NetworkProvider { constructor(options?: Partial) { this.options = { updateUtxoSet: true, ...options }; - this.vmTarget = this.options.vmTarget ?? VmTarget.BCH_2025_05; + this.vmTarget = this.options.vmTarget ?? DEFAULT_VM_TARGET; } async getUtxos(address: string): Promise { diff --git a/packages/cashscript/test/debugging.test.ts b/packages/cashscript/test/debugging.test.ts index 1342341a..54c1730d 100644 --- a/packages/cashscript/test/debugging.test.ts +++ b/packages/cashscript/test/debugging.test.ts @@ -1,4 +1,5 @@ import { Contract, FailedTransactionError, MockNetworkProvider, SignatureAlgorithm, SignatureTemplate, TransactionBuilder, VmTarget } from '../src/index.js'; +import { DEFAULT_VM_TARGET } from '../src/libauth-template/utils.js'; import { aliceAddress, alicePriv, alicePub, bobPriv, bobPub } from './fixture/vars.js'; import { randomUtxo } from '../src/utils.js'; import { AuthenticationErrorCommon, binToHex, hexToBin } from '@bitauth/libauth'; @@ -11,16 +12,23 @@ import { artifactTestSingleFunction, artifactTestMultilineRequires, artifactTestZeroHandling, + artifactTestRequireInsideLoop, + artifactTestLogInsideLoop, } from './fixture/debugging/debugging_contracts.js'; import { sha256 } from '@cashscript/utils'; describe('Debugging tests', () => { describe('console.log statements', () => { const provider = new MockNetworkProvider(); + const contractTestLogs = new Contract(artifactTestLogs, [alicePub], { provider }); const contractUtxo = randomUtxo(); provider.addUtxo(contractTestLogs.address, contractUtxo); + const contractTestLogInsideLoop = new Contract(artifactTestLogInsideLoop, [], { provider }); + const contractTestLogInsideLoopUtxo = randomUtxo(); + provider.addUtxo(contractTestLogInsideLoop.address, contractTestLogInsideLoopUtxo); + it('should log correct values', async () => { const transaction = new TransactionBuilder({ provider }) .addInput(contractUtxo, contractTestLogs.unlock.transfer(new SignatureTemplate(alicePriv), 1000n)) @@ -153,6 +161,38 @@ describe('Debugging tests', () => { }); it.todo('intermediate results that is more complex than the test above'); + + it('should log inside a loop', async () => { + const transaction = new TransactionBuilder({ provider }) + .addInput(contractUtxo, contractTestLogInsideLoop.unlock.test_log_inside_loop()) + .addOutput({ to: contractTestLogInsideLoop.address, amount: 10000n }); + + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 0$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 1$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 2$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 3$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 4$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 5$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 6$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 7$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 8$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:6 i: 9$')); + }); + + it('should log inside a complex nested loop', async () => { + const transaction = new TransactionBuilder({ provider }) + .addInput(contractTestLogInsideLoopUtxo, contractTestLogInsideLoop.unlock.test_log_inside_loop_complex()) + .addOutput({ to: contractTestLogInsideLoop.address, amount: 10000n }); + + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:28 inner loop i: 0 j: 0 k: 0 l: 5 m: 10$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:28 inner loop i: 0 j: 1 k: 1 l: 5 m: 10$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:32 outer loop i: 0$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:28 inner loop i: 1 j: 0 k: 1 l: 5 m: 10$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:28 inner loop i: 1 j: 1 k: 2 l: 5 m: 10$')); + expect(transaction).toLog(new RegExp('^\\[Input #0] Test.cash:32 outer loop i: 1$')); + }); + + it.todo('should log intermediate results that get optimised out inside a loop'); }); describe('require statements', () => { @@ -165,6 +205,10 @@ describe('Debugging tests', () => { const contractTestMultiLineRequiresUtxo = randomUtxo(); provider.addUtxo(contractTestMultiLineRequires.address, contractTestMultiLineRequiresUtxo); + const contractTestRequireInsideLoop = new Contract(artifactTestRequireInsideLoop, [], { provider }); + const contractTestRequireInsideLoopUtxo = randomUtxo(); + provider.addUtxo(contractTestRequireInsideLoop.address, contractTestRequireInsideLoopUtxo); + // test_require it('should fail with error message when require statement fails in a multi-function contract', async () => { const transaction = new TransactionBuilder({ provider }) @@ -448,6 +492,17 @@ describe('Debugging tests', () => { ]) );`); }); + + it('should fail a require statement inside a loop', async () => { + const transaction = new TransactionBuilder({ provider }) + .addInput(contractTestRequireInsideLoopUtxo, contractTestRequireInsideLoop.unlock.test_require_inside_loop()) + .addOutput({ to: contractTestRequireInsideLoop.address, amount: 10000n }); + + expect(transaction).toFailRequireWith('Test.cash:7 Require statement failed at input 0 in contract Test.cash at line 7 with the following message: i should be less than 6.'); + expect(transaction).toFailRequireWith('Failing statement: require(i < 6, \'i should be less than 6\')'); + }); + + it.todo('should fail correct require statement inside nested loops'); }); describe('Non-require error messages', () => { @@ -668,7 +723,7 @@ describe('Debugging tests', () => { .addInput(contractUtxo, contractTestLogs.unlock.transfer(new SignatureTemplate(alicePriv), 1000n)) .addOutput({ to: contractTestLogs.address, amount: 10000n }); - expect(transaction.getLibauthTemplate().supported[0]).toBe(vmTarget ?? 'BCH_2025_05'); + expect(transaction.getLibauthTemplate().supported[0]).toBe(vmTarget ?? DEFAULT_VM_TARGET); const expectedLog = new RegExp(`^\\[Input #0] Test.cash:10 0x[0-9a-f]{130} 0x${binToHex(alicePub)} 1000 0xbeef 1 test true$`); expect(transaction).toLog(expectedLog); diff --git a/packages/cashscript/test/fixture/Bar.artifact.ts b/packages/cashscript/test/fixture/Bar.artifact.ts index 407ef1cf..5992352c 100644 --- a/packages/cashscript/test/fixture/Bar.artifact.ts +++ b/packages/cashscript/test/fixture/Bar.artifact.ts @@ -64,7 +64,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:54.204Z', + updatedAt: '2026-01-20T10:49:39.179Z', } as const; diff --git a/packages/cashscript/test/fixture/Bar.json b/packages/cashscript/test/fixture/Bar.json index 2e899afc..fb0c1d01 100644 --- a/packages/cashscript/test/fixture/Bar.json +++ b/packages/cashscript/test/fixture/Bar.json @@ -64,7 +64,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:53.940Z" -} + "updatedAt": "2026-01-20T10:49:38.918Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/Foo.artifact.ts b/packages/cashscript/test/fixture/Foo.artifact.ts index 94635a15..438e89fe 100644 --- a/packages/cashscript/test/fixture/Foo.artifact.ts +++ b/packages/cashscript/test/fixture/Foo.artifact.ts @@ -48,7 +48,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:54.732Z', + updatedAt: '2026-01-20T10:49:39.679Z', } as const; diff --git a/packages/cashscript/test/fixture/Foo.json b/packages/cashscript/test/fixture/Foo.json index 0333d286..a8bfa189 100644 --- a/packages/cashscript/test/fixture/Foo.json +++ b/packages/cashscript/test/fixture/Foo.json @@ -48,7 +48,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:54.487Z" -} + "updatedAt": "2026-01-20T10:49:39.429Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/SiblingIntrospection.artifact.ts b/packages/cashscript/test/fixture/SiblingIntrospection.artifact.ts index ee356881..abf6b58a 100644 --- a/packages/cashscript/test/fixture/SiblingIntrospection.artifact.ts +++ b/packages/cashscript/test/fixture/SiblingIntrospection.artifact.ts @@ -62,7 +62,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T16:07:30.092Z', + updatedAt: '2026-01-20T10:49:38.649Z', } as const; diff --git a/packages/cashscript/test/fixture/SiblingIntrospection.json b/packages/cashscript/test/fixture/SiblingIntrospection.json index 08d2104e..c02d75a9 100644 --- a/packages/cashscript/test/fixture/SiblingIntrospection.json +++ b/packages/cashscript/test/fixture/SiblingIntrospection.json @@ -62,7 +62,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T16:07:29.693Z" -} + "updatedAt": "2026-01-20T10:49:38.293Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/announcement.artifact.ts b/packages/cashscript/test/fixture/announcement.artifact.ts index 86e132bd..ad253276 100644 --- a/packages/cashscript/test/fixture/announcement.artifact.ts +++ b/packages/cashscript/test/fixture/announcement.artifact.ts @@ -34,7 +34,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T14:40:53.438Z', + updatedAt: '2026-01-20T10:49:37.942Z', } as const; diff --git a/packages/cashscript/test/fixture/announcement.json b/packages/cashscript/test/fixture/announcement.json index 5a9a2d17..76a03fd9 100644 --- a/packages/cashscript/test/fixture/announcement.json +++ b/packages/cashscript/test/fixture/announcement.json @@ -34,7 +34,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-05-11T10:02:25.092Z" -} + "updatedAt": "2026-01-20T10:49:37.662Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/bigint.artifact.ts b/packages/cashscript/test/fixture/bigint.artifact.ts index 214d68a9..ccd0f9eb 100644 --- a/packages/cashscript/test/fixture/bigint.artifact.ts +++ b/packages/cashscript/test/fixture/bigint.artifact.ts @@ -35,7 +35,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:52.713Z', + updatedAt: '2026-01-20T10:49:37.394Z', } as const; diff --git a/packages/cashscript/test/fixture/bigint.json b/packages/cashscript/test/fixture/bigint.json index 904d7499..52febb8f 100644 --- a/packages/cashscript/test/fixture/bigint.json +++ b/packages/cashscript/test/fixture/bigint.json @@ -35,7 +35,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:52.485Z" -} + "updatedAt": "2026-01-20T10:49:37.159Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/bounded_bytes.artifact.ts b/packages/cashscript/test/fixture/bounded_bytes.artifact.ts index 811d4fd7..e26896b1 100644 --- a/packages/cashscript/test/fixture/bounded_bytes.artifact.ts +++ b/packages/cashscript/test/fixture/bounded_bytes.artifact.ts @@ -17,10 +17,10 @@ export default { }, ], bytecode: 'OP_SWAP OP_4 OP_NUM2BIN OP_EQUAL', - source: 'contract BoundedBytes() {\n function spend(bytes4 b, int i) {\n require(b == bytes4(i));\n }\n}\n', + source: 'contract BoundedBytes() {\n function spend(bytes4 b, int i) {\n require(b == toPaddedBytes(i, 4));\n }\n}\n', debug: { bytecode: '7c548087', - sourceMap: '3:28:3:29;:21::30:1;;:8::32', + sourceMap: '3:35:3:36;:38::39;:21::40:1;:8::42', logs: [], requires: [ { @@ -31,7 +31,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:56.281Z', + updatedAt: '2026-01-20T10:49:41.226Z', } as const; diff --git a/packages/cashscript/test/fixture/bounded_bytes.cash b/packages/cashscript/test/fixture/bounded_bytes.cash index 7076f51e..2fc2e8b8 100644 --- a/packages/cashscript/test/fixture/bounded_bytes.cash +++ b/packages/cashscript/test/fixture/bounded_bytes.cash @@ -1,5 +1,5 @@ contract BoundedBytes() { function spend(bytes4 b, int i) { - require(b == bytes4(i)); + require(b == toPaddedBytes(i, 4)); } } diff --git a/packages/cashscript/test/fixture/bounded_bytes.json b/packages/cashscript/test/fixture/bounded_bytes.json index 5b6a8a36..0346a087 100644 --- a/packages/cashscript/test/fixture/bounded_bytes.json +++ b/packages/cashscript/test/fixture/bounded_bytes.json @@ -17,10 +17,10 @@ } ], "bytecode": "OP_SWAP OP_4 OP_NUM2BIN OP_EQUAL", - "source": "contract BoundedBytes() {\n function spend(bytes4 b, int i) {\n require(b == bytes4(i));\n }\n}\n", + "source": "contract BoundedBytes() {\n function spend(bytes4 b, int i) {\n require(b == toPaddedBytes(i, 4));\n }\n}\n", "debug": { "bytecode": "7c548087", - "sourceMap": "3:28:3:29;:21::30:1;;:8::32", + "sourceMap": "3:35:3:36;:38::39;:21::40:1;:8::42", "logs": [], "requires": [ { @@ -31,7 +31,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:56.024Z" -} + "updatedAt": "2026-01-20T10:49:40.986Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/debugging/debugging_contracts.ts b/packages/cashscript/test/fixture/debugging/debugging_contracts.ts index 34aba269..d9709cc8 100644 --- a/packages/cashscript/test/fixture/debugging/debugging_contracts.ts +++ b/packages/cashscript/test/fixture/debugging/debugging_contracts.ts @@ -94,6 +94,18 @@ contract Test() { } `; +const CONTRACT_TEST_REQUIRE_INSIDE_LOOP = ` +contract Test() { + function test_require_inside_loop() { + int i = 0; + do { + i = i + 1; + require(i < 6, 'i should be less than 6'); + } while (i < 10); + } +} +`; + const CONTRACT_TEST_REQUIRE_SINGLE_FUNCTION = ` contract Test() { function test_require_single_function() { @@ -255,6 +267,47 @@ contract Test(pubkey owner) { } `; +const CONTRACT_TEST_LOG_INSIDE_LOOP = ` +contract Test() { + function test_log_inside_loop() { + int i = 0; + do { + console.log('i:', i); + i = i + 1; + } while (i < 10); + + require(i == 10); + } + + function test_log_inside_loop_complex() { + int i = 0; + + int l = 5; + require(l < 10); + + do { + int j = 0; + + int m = 10; + require(m < 20); + + do { + int k = i + j; + require(k < 100); + console.log('inner loop', 'i:', i, 'j:', j, 'k:', k, 'l:', l, 'm:', m); + j = j + 1; + } while (j < 2); + + console.log('outer loop', 'i:', i); + + i = i + 1; + } while (i < 2); + + require(i == 2); + } +} +`; + const CONTRACT_TEST_CONSECUTIVE_LOGS = ` contract Test(pubkey owner) { function transfer(sig ownerSig, int num) { @@ -321,3 +374,5 @@ export const artifactTestLogs = compileString(CONTRACT_TEST_LOGS); export const artifactTestConsecutiveLogs = compileString(CONTRACT_TEST_CONSECUTIVE_LOGS); export const artifactTestMultipleLogs = compileString(CONTRACT_TEST_MULTIPLE_LOGS); export const artifactTestMultipleConstructorParameters = compileString(CONTRACT_TEST_MULTIPLE_CONSTRUCTOR_PARAMETERS); +export const artifactTestRequireInsideLoop = compileString(CONTRACT_TEST_REQUIRE_INSIDE_LOOP); +export const artifactTestLogInsideLoop = compileString(CONTRACT_TEST_LOG_INSIDE_LOOP); diff --git a/packages/cashscript/test/fixture/hodl_vault.artifact.ts b/packages/cashscript/test/fixture/hodl_vault.artifact.ts index 92ed0243..e6471e12 100644 --- a/packages/cashscript/test/fixture/hodl_vault.artifact.ts +++ b/packages/cashscript/test/fixture/hodl_vault.artifact.ts @@ -68,7 +68,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:55.227Z', + updatedAt: '2026-01-20T10:49:40.224Z', } as const; diff --git a/packages/cashscript/test/fixture/hodl_vault.json b/packages/cashscript/test/fixture/hodl_vault.json index ac7eebbc..c9915d96 100644 --- a/packages/cashscript/test/fixture/hodl_vault.json +++ b/packages/cashscript/test/fixture/hodl_vault.json @@ -68,7 +68,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:54.980Z" -} + "updatedAt": "2026-01-20T10:49:39.944Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/libauth-template/fixtures.ts b/packages/cashscript/test/fixture/libauth-template/fixtures.ts index d0a7857f..07c1afd3 100644 --- a/packages/cashscript/test/fixture/libauth-template/fixtures.ts +++ b/packages/cashscript/test/fixture/libauth-template/fixtures.ts @@ -33,7 +33,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -165,7 +165,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -301,7 +301,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -435,7 +435,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -716,7 +716,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -838,7 +838,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -1139,7 +1139,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -1316,7 +1316,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { diff --git a/packages/cashscript/test/fixture/libauth-template/multi-contract-fixtures.ts b/packages/cashscript/test/fixture/libauth-template/multi-contract-fixtures.ts index e22dfaf9..45107437 100644 --- a/packages/cashscript/test/fixture/libauth-template/multi-contract-fixtures.ts +++ b/packages/cashscript/test/fixture/libauth-template/multi-contract-fixtures.ts @@ -63,7 +63,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -2084,7 +2084,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -2203,7 +2203,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -2531,7 +2531,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { @@ -3366,7 +3366,7 @@ export const fixtures: Fixture[] = [ 'description': 'Imported from cashscript', 'name': 'CashScript Generated Debugging Template', 'supported': [ - 'BCH_2025_05', + 'BCH_2026_05', ], 'version': 0, 'entities': { diff --git a/packages/cashscript/test/fixture/mecenas.artifact.ts b/packages/cashscript/test/fixture/mecenas.artifact.ts index 5d72fe62..485a866e 100644 --- a/packages/cashscript/test/fixture/mecenas.artifact.ts +++ b/packages/cashscript/test/fixture/mecenas.artifact.ts @@ -72,7 +72,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:58.336Z', + updatedAt: '2026-01-20T10:49:43.526Z', } as const; diff --git a/packages/cashscript/test/fixture/mecenas.json b/packages/cashscript/test/fixture/mecenas.json index 0e86e989..5d77dd7c 100644 --- a/packages/cashscript/test/fixture/mecenas.json +++ b/packages/cashscript/test/fixture/mecenas.json @@ -72,7 +72,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:58.078Z" -} + "updatedAt": "2026-01-20T10:49:43.215Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/p2palindrome.artifact.ts b/packages/cashscript/test/fixture/p2palindrome.artifact.ts index 67e321b2..e7614394 100644 --- a/packages/cashscript/test/fixture/p2palindrome.artifact.ts +++ b/packages/cashscript/test/fixture/p2palindrome.artifact.ts @@ -27,7 +27,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:55.718Z', + updatedAt: '2026-01-20T10:49:40.761Z', } as const; diff --git a/packages/cashscript/test/fixture/p2palindrome.json b/packages/cashscript/test/fixture/p2palindrome.json index 87fb9103..b855e272 100644 --- a/packages/cashscript/test/fixture/p2palindrome.json +++ b/packages/cashscript/test/fixture/p2palindrome.json @@ -27,7 +27,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:55.464Z" -} + "updatedAt": "2026-01-20T10:49:40.443Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/p2pkh.artifact.ts b/packages/cashscript/test/fixture/p2pkh.artifact.ts index 8b197a2a..d2d42781 100644 --- a/packages/cashscript/test/fixture/p2pkh.artifact.ts +++ b/packages/cashscript/test/fixture/p2pkh.artifact.ts @@ -40,7 +40,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:57.831Z', + updatedAt: '2026-01-20T10:49:42.707Z', } as const; diff --git a/packages/cashscript/test/fixture/p2pkh.json b/packages/cashscript/test/fixture/p2pkh.json index 0d52d36c..ec8a11e9 100644 --- a/packages/cashscript/test/fixture/p2pkh.json +++ b/packages/cashscript/test/fixture/p2pkh.json @@ -40,7 +40,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:57.597Z" -} + "updatedAt": "2026-01-20T10:49:42.466Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/token_category_comparison.artifact.ts b/packages/cashscript/test/fixture/token_category_comparison.artifact.ts index 8809e2c8..8c3817f7 100644 --- a/packages/cashscript/test/fixture/token_category_comparison.artifact.ts +++ b/packages/cashscript/test/fixture/token_category_comparison.artifact.ts @@ -22,7 +22,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:57.354Z', + updatedAt: '2026-01-20T10:49:42.200Z', } as const; diff --git a/packages/cashscript/test/fixture/token_category_comparison.json b/packages/cashscript/test/fixture/token_category_comparison.json index d5c0d54e..ecf91c55 100644 --- a/packages/cashscript/test/fixture/token_category_comparison.json +++ b/packages/cashscript/test/fixture/token_category_comparison.json @@ -22,7 +22,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:57.130Z" -} + "updatedAt": "2026-01-20T10:49:41.977Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/transfer_with_timeout.artifact.ts b/packages/cashscript/test/fixture/transfer_with_timeout.artifact.ts index b42aa6d6..bcdbb6b3 100644 --- a/packages/cashscript/test/fixture/transfer_with_timeout.artifact.ts +++ b/packages/cashscript/test/fixture/transfer_with_timeout.artifact.ts @@ -57,7 +57,7 @@ export default { }, compiler: { name: 'cashc', - version: '0.11.0', + version: '0.13.0-next.2', }, - updatedAt: '2025-06-16T15:05:56.888Z', + updatedAt: '2026-01-20T10:49:41.722Z', } as const; diff --git a/packages/cashscript/test/fixture/transfer_with_timeout.json b/packages/cashscript/test/fixture/transfer_with_timeout.json index 78311a54..fb51d827 100644 --- a/packages/cashscript/test/fixture/transfer_with_timeout.json +++ b/packages/cashscript/test/fixture/transfer_with_timeout.json @@ -57,7 +57,7 @@ }, "compiler": { "name": "cashc", - "version": "0.11.0" + "version": "0.13.0-next.2" }, - "updatedAt": "2025-06-16T15:05:56.646Z" -} + "updatedAt": "2026-01-20T10:49:41.492Z" +} \ No newline at end of file diff --git a/packages/cashscript/test/fixture/walletconnect/fixtures.ts b/packages/cashscript/test/fixture/walletconnect/fixtures.ts index 91813a55..e188bfd8 100644 --- a/packages/cashscript/test/fixture/walletconnect/fixtures.ts +++ b/packages/cashscript/test/fixture/walletconnect/fixtures.ts @@ -91,7 +91,7 @@ export const generateWcTransactionObjectFixture = { }, 'compiler': { 'name': 'cashc', - 'version': '0.11.0', + 'version': expect.any(String), }, 'updatedAt': expect.any(String), }, @@ -107,4 +107,4 @@ export const generateWcTransactionObjectFixture = { }, ], } -; \ No newline at end of file + ; diff --git a/packages/utils/package.json b/packages/utils/package.json index 16534132..e70804d4 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@cashscript/utils", - "version": "0.12.1", + "version": "0.13.0-next.3", "description": "CashScript utilities and types", "keywords": [ "bitcoin cash", diff --git a/packages/utils/src/cashproof-optimisations.ts b/packages/utils/src/cashproof-optimisations.ts index 508101b9..59f64d04 100644 --- a/packages/utils/src/cashproof-optimisations.ts +++ b/packages/utils/src/cashproof-optimisations.ts @@ -125,4 +125,12 @@ OP_2 OP_PICK OP_SWAP OP_2 OP_PICK OP_NIP <=> OP_DROP OP_2DUP; # .slice(0, x) optimisation & .slice(x, y.length) optimisation OP_0 OP_SPLIT OP_NIP <=> ; OP_SIZE OP_SPLIT OP_DROP <=> ; + +# These are new optimisations that we cannot prove since CashProof doesn't work any more +# ////////////////////////////////////////////////////////////////////////////////////// + +OP_LESSTHAN OP_NOT <=> OP_GREATERTHANOREQUAL; +OP_GREATERTHAN OP_NOT <=> OP_LESSTHANOREQUAL; +OP_LESSTHANOREQUAL OP_NOT <=> OP_GREATERTHAN; +OP_GREATERTHANOREQUAL OP_NOT <=> OP_LESSTHAN; `; diff --git a/packages/utils/src/optimisations.ts b/packages/utils/src/optimisations.ts index 6477a794..651a682e 100644 --- a/packages/utils/src/optimisations.ts +++ b/packages/utils/src/optimisations.ts @@ -137,6 +137,18 @@ const unprovableOptimisations = [ // CashProof can't prove bitwise operators ['OP_DUP OP_AND', ''], ['OP_DUP OP_OR', ''], + + // These are new optimisations that we cannot prove since CashProof doesn't work any more + // ////////////////////////////////////////////////////////////////////////////////////// + + // TODO: Enable this optimisation when we overhaul the type system + // (right now bool(4) == true => false, but !!bool(4) == true => true) so can't replace OP_NOT OP_NOT with '' + // ['OP_NOT OP_NOT', ''] + + ['OP_LESSTHAN OP_NOT', 'OP_GREATERTHANOREQUAL'], + ['OP_GREATERTHAN OP_NOT', 'OP_LESSTHANOREQUAL'], + ['OP_LESSTHANOREQUAL OP_NOT', 'OP_GREATERTHAN'], + ['OP_GREATERTHANOREQUAL OP_NOT', 'OP_LESSTHAN'], ] as [string, string][]; // Note: we moved these optimisations into a single file, but kept the exact same order as before, diff --git a/packages/utils/src/script.ts b/packages/utils/src/script.ts index 9519dedc..854b5864 100644 --- a/packages/utils/src/script.ts +++ b/packages/utils/src/script.ts @@ -1,18 +1,19 @@ import { - OpcodesBch2023, encodeDataPush, hexToBin, disassembleBytecodeBch, flattenBinArray, encodeAuthenticationInstructions, decodeAuthenticationInstructions, + OpcodesBch, + AuthenticationInstruction, } from '@bitauth/libauth'; import OptimisationsEquivFile from './cashproof-optimisations.js'; import { optimisationReplacements } from './optimisations.js'; import { FullLocationData, PositionHint, SingleLocationData } from './types.js'; import { LogEntry, RequireStatement } from './artifact.js'; -export const Op = OpcodesBch2023; +export const Op = OpcodesBch; export type Op = number; export type OpOrData = Op | Uint8Array; export type Script = OpOrData[]; @@ -66,8 +67,10 @@ export function asmToBytecode(asm: string): Uint8Array { // Convert the ASM tokens to AuthenticationInstructions const instructions = asm.split(' ').map((token) => { + // Even though the OpcodesBch type allows for { [key: number]: string }, we know that the keys are always the opcodes + // so we can safely cast to the AuthenticationInstruction type if (token.startsWith('OP_')) { - return { opcode: Op[token as keyof typeof Op] }; + return { opcode: Op[token as keyof typeof Op] } as AuthenticationInstruction; } const data = token.replace(/<|>/g, '').replace(/^0x/, ''); diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index a4d6f030..fbf51d9f 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -155,10 +155,9 @@ export function implicitlyCastable(actual?: Type, expected?: Type): boolean { return actual === expected; } -export function resultingType( - left?: Type, - right?: Type, -): Type | undefined { +function resultingTypeForArrayElements(left: Type | undefined, right: Type | undefined): Type | undefined { + if (!left || !right) return undefined; + if (implicitlyCastable(left, right)) return right; if (implicitlyCastable(right, left)) return left; if (left instanceof BytesType && right instanceof BytesType) { @@ -171,7 +170,7 @@ export function arrayType(types: Type[]): Type | undefined { if (types.length === 0) return undefined; let resType: Type | undefined = types[0]; types.forEach((t) => { - resType = resultingType(resType, t) as Type; + resType = resultingTypeForArrayElements(resType, t) as Type; }); return resType; } diff --git a/packages/utils/test/manual-optimisation-proofs.test.ts b/packages/utils/test/manual-optimisation-proofs.test.ts new file mode 100644 index 00000000..d2a50d13 --- /dev/null +++ b/packages/utils/test/manual-optimisation-proofs.test.ts @@ -0,0 +1,57 @@ +describe('Manual Optimisation Proofs', () => { + it.todo('Properly implement automated tests'); + // <1> <2> OP_GREATERTHAN OP_NOT + // <1> <2> OP_LESSTHANOREQUAL + // OP_EQUALVERIFY + + // <2> <1> OP_GREATERTHAN OP_NOT + // <2> <1> OP_LESSTHANOREQUAL + // OP_EQUALVERIFY + + // <1> <1> OP_GREATERTHAN OP_NOT + // <1> <1> OP_LESSTHANOREQUAL + // OP_EQUALVERIFY + + + + + // <1> <2> OP_LESSTHAN OP_NOT + // <1> <2> OP_GREATERTHANOREQUAL + // OP_EQUALVERIFY + + // <2> <1> OP_LESSTHAN OP_NOT + // <2> <1> OP_GREATERTHANOREQUAL + // OP_EQUALVERIFY + + // <1> <1> OP_LESSTHAN OP_NOT + // <1> <1> OP_GREATERTHANOREQUAL + // OP_EQUALVERIFY + + + + // <1> <2> OP_LESSTHANOREQUAL OP_NOT + // <1> <2> OP_GREATERTHAN + // OP_EQUALVERIFY + + // <2> <1> OP_LESSTHANOREQUAL OP_NOT + // <2> <1> OP_GREATERTHAN + // OP_EQUALVERIFY + + // <1> <1> OP_LESSTHANOREQUAL OP_NOT + // <1> <1> OP_GREATERTHAN + // OP_EQUALVERIFY + + + + // <1> <2> OP_GREATERTHANOREQUAL OP_NOT + // <1> <2> OP_LESSTHAN + // OP_EQUALVERIFY + + // <2> <1> OP_GREATERTHANOREQUAL OP_NOT + // <2> <1> OP_LESSTHAN + // OP_EQUALVERIFY + + // <1> <1> OP_GREATERTHANOREQUAL OP_NOT + // <1> <1> OP_LESSTHAN + // OP_EQUALVERIFY +}); diff --git a/website/docs/basics/getting-started.md b/website/docs/basics/getting-started.md index 0adc2e2e..83d34a71 100644 --- a/website/docs/basics/getting-started.md +++ b/website/docs/basics/getting-started.md @@ -52,7 +52,7 @@ We can start from a basic `TransferWithTimeout` smart contract, a simple contrac Open your code editor to start writing your first CashScript smart contract. Then create a new file `TransferWithTimeout.cash` and copy over the smart contracts code from below. ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract TransferWithTimeout(pubkey sender, pubkey recipient, int timeout) { // Allow the recipient to claim their received money @@ -119,7 +119,6 @@ For a code example of how to generate key-pairs with Libauth, see the [CashScrip With the instantiated contract, we can now get the contract address and get the contract balance and UTXOs in the following way: - ```javascript import { ElectrumNetworkProvider, Contract } from 'cashscript'; import artifact from './TransferWithTimeout.json' with { type: 'json' }; diff --git a/website/docs/compiler/grammar.md b/website/docs/compiler/grammar.md index 6f6c0601..bc917637 100644 --- a/website/docs/compiler/grammar.md +++ b/website/docs/compiler/grammar.md @@ -58,6 +58,7 @@ statement | timeOpStatement | requireStatement | ifStatement + | loopStatement | consoleStatement ; @@ -85,6 +86,14 @@ ifStatement : 'if' '(' expression ')' ifBlock=block ('else' elseBlock=block)? ; +loopStatement + : doWhileStatement + ; + +doWhileStatement + : 'do' block 'while' '(' expression ')' ';' + ; + consoleStatement : 'console.log' consoleParameterList ';' ; @@ -121,10 +130,10 @@ expression | expression op=('.reverse()' | '.length') # UnaryOp | left=expression op='.split' '(' right=expression ')' # BinaryOp | element=expression '.slice' '(' start=expression ',' end=expression ')' # Slice - | op=('!' | '-') expression # UnaryOp + | op=('!' | '-' | '~') expression # UnaryOp | left=expression op=('*' | '/' | '%') right=expression # BinaryOp | left=expression op=('+' | '-') right=expression # BinaryOp - // | expression ('>>' | '<<') expression --- OP_LSHIFT & RSHIFT are disabled in BCH Script + | left=expression op=('>>' | '<<') right=expression # BinaryOp | left=expression op=('<' | '<=' | '>' | '>=') right=expression # BinaryOp | left=expression op=('==' | '!=') right=expression # BinaryOp | left=expression op='&' right=expression # BinaryOp diff --git a/website/docs/compiler/script-limits.md b/website/docs/compiler/script-limits.md index 3f0f747d..7deffd55 100644 --- a/website/docs/compiler/script-limits.md +++ b/website/docs/compiler/script-limits.md @@ -11,23 +11,20 @@ Some of the limits below are hard BCH consensus rules, others are standardness r ## Contract-related limits -### Maximum contract size +### Maximum contract size (P2SH) -The Bitcoin Cash limits contract bytecode to **1,650 bytes** in the standardness rules. Transactions with contract bytecode won't be relayed by most nodes. +The limit on Bitcoin Cash for contract bytecode for P2SH outputs is **10,000 bytes** by the BCH consensus rules. Technically this limit is the 'maximum unlocking bytecode length' because for P2SH outputs the full script is provided in the **unlocking bytecode**. -While typical contracts stay well below this, complex contracts with extensive logic might need adjustments to fit within this constraint. +### Maximum contract size (P2S) -#### Modular contract design +The limit on Bitcoin Cash for contract bytecode for P2S outputs is **201 bytes** by the BCH consensus rules. Technically this limit is the 'maximum locking bytecode length' because for P2S outputs the script is provided directly in the **locking bytecode**. -To keep contracts within size limits, consider modular design. Splitting contract logic into smaller, independent components allows each function to be deployed separately, reducing transaction size. See [Contract Optimization](/docs/guides/optimization) for more details. ### NFT commitment length limit -NFT commitments can store up to 40 bytes of data as local state. If more data is needed, you can hash the full state and store only the hash in the commitment data. Later, when required, the full state must be provided and validated against the stored hash. +NFT commitments can store up to **128 bytes** of data as local state. This 128-bytes limit on commitment length is of practical importance for contract authors, as workarounds are needed to keep more data in local state. -:::caution -The 40-bytes limit on commitment length is of great practical importance for contract authors. Workarounds are needed to keep more bytes of local state in smart contracts. -::: +If your local state grows larger than the allowed maximum, one option is to hash the full state and store only the hash in the commitment data. Later, when using the local state, the full state must be provided and validated against the stored state hash. ### Operation cost limit @@ -47,7 +44,7 @@ function maxOperationCost(unlockingBytecodeLength) { - Signature operation count (SigChecks): Limits the number of signature verifications (`OP_CHECKSIG`, `OP_CHECKDATASIG`) per transaction to ensure efficient validation. - Hashing limit: Limits the number of hashing operations (`OP_SHA256`, `OP_HASH160`) allowed per transaction to prevent excessive resource usage. -- Stack element byte length: Each stack element has a maximum length of 10,000 bytes, affecting Pay-to-Script-Hash (P2SH) contracts. +- Stack element byte length: stack elements have a maximum length of 10,000 bytes. ## General transaction limits @@ -74,22 +71,12 @@ function calculateDust(outputSize: number): number { } ``` -Before CashTokens `546` bytes was often used as good default value, however with tokenData outputs have become larger in size. -For ease of development, it is standard practice to use 1,000 satoshis as dust to outputs. +Before CashTokens `546` sats was often used as dust default value, however with tokenData outputs have become larger in size, which affects the dust value calculation. +For ease of development, it is standard practice to use `1,000` satoshis as dust to outputs. :::note -The standard practice of 1,000 satoshis as dust amount for outputs is only considering `P2PH`, `P2SH` and `P2PK` output types. -For `P2MS` (raw multisig) a higher dust limits may be required, you can [find more info here][info-dust-limit] -::: - -### Output Standardness - -Bitcoin Cash only allows a few types of `lockingBytecode` scripts for outputs in the normal network relay rules. These are called 'standard outputs', contrasted to 'non-standard outputs' which cause the transaction not to relay on the network. - -There's 4 types of standard output types: `P2PKH`, `P2SH` (which includes `P2SH20` & `P2SH32`), `P2MS` and `OP_RETURN` data-outputs. For more details see the [standard outputs documentation][standard-outputs-docs]. - -:::caution -The `lockingBytecode` standardness rules can be important for smart contract developers, and is why CashScript has helpers like `LockingBytecodeP2PKH`, `LockingBytecodeP2SH32` and `LockingBytecodeNullData`. +The standard practice of 1,000 satoshis as dust amount for outputs is for the `P2PKH`, `P2SH20` and `P2SH32` output types. +For custom locking bytecode outputs a higher dust limits may be required, you can [find more info here][info-dust-limit]. ::: ### Minimum Relay Fee @@ -100,15 +87,15 @@ The Bitcoin Cash protocol does not strictly enforce minimum fees for transaction | Limit type | Constraint | |------------|-------------| -| Max contract size | 1,650 bytes (standardness) | -| NFT commitment length | 40 bytes (consensus) | +| Max contract size | 10,000 bytes (consensus) | +| NFT commitment length | 128 bytes (consensus) | | Operation cost limit | Based on script length (consensus) | | Max stack element size | 10,000 bytes (consensus) | | Max transaction size | 100,000 bytes for standardness (1MB for consensus) | -| Max OP_RETURN data size | 220 bytes data payload (standardness) | +| Output locking bytecode size | 201 bytes (standardness) | +| Max OP_RETURN data size | 220 bytes data payload (standardness) | | Dust threshold | based on output size (standardness) - commonly 1,000 sats is used as dust | | Minimum relay fee | 1sat/byte (standardness) | -| Output Standardness | `P2PKH`, `P2SH` (incl. `P2SH20` & `P2SH32`), `P2MS` and `OP_RETURN` data-outputs| For further details on transaction validation and standardness rules, see the [documentation on BCH transaction validation][standardness-docs]. diff --git a/website/docs/guides/cashtokens.md b/website/docs/guides/cashtokens.md index 9164d3b5..bda86712 100644 --- a/website/docs/guides/cashtokens.md +++ b/website/docs/guides/cashtokens.md @@ -38,7 +38,7 @@ The maximum size for a fungible token `amount` is the max signed 64-bit integer ### Non-Fungible Tokens -The `nft` info on a UTXO will only be present if the UTXO contains an NFT. The `nft` object has 2 properties: the `capability` and the `commitment`. The `commitment` is the data field for the NFT which can is allowed to be up to 40 bytes. +The `nft` info on a UTXO will only be present if the UTXO contains an NFT. The `nft` object has 2 properties: the `capability` and the `commitment`. The `commitment` is the data field for the NFT which can is allowed to be up to 128 bytes. Capability `none` then refers to an immutable NFT where the commitment cannot be changed. The `mutable` capability means the `commitment` field can change over time, usually to contain smart contract state. Lastly the `minting` capability means that the NFT can create new NFTs from the same `category`. diff --git a/website/docs/guides/covenants.md b/website/docs/guides/covenants.md index acbbc122..27b6dcc2 100644 --- a/website/docs/guides/covenants.md +++ b/website/docs/guides/covenants.md @@ -143,7 +143,11 @@ Smart contracts which persist for multiple transactions might want to keep data Covenants can also use 'simulated state', where state is kept in the contract script and the contract enforces a new P2SH locking bytecode of the contract with a different state update. This method causes the contract address to change with each state update. ::: -### Keeping local State in NFTs +### Keeping local state in NFTs + +When we want to share local state between multiple transactions or contracts, we can use the NFT commitment field in an NFT. This state is accessible in any transaction that includes the NFT. + +#### Example: Streaming Mecenas To demonstrate the concept of 'local state' we consider the Mecenas contract again, and focus on a drawback of this contract: you have to claim the funds at exactly the right moment or you're leaving money on the table. Every time you claim money from the contract, the `this.age` counter is reset, so the next claim is possible 30 days after the previous claim. So if we wait a few days to claim, **these days are basically wasted**. @@ -194,7 +198,7 @@ contract StreamingMecenas( require(tx.outputs[1].lockingBytecode == tx.inputs[0].lockingBytecode); // Update the block height of the previous pledge, kept in the NFT commitment - bytes blockHeightNewPledge = bytes8(tx.locktime); + bytes blockHeightNewPledge = toPaddedBytes(tx.locktime, 8); require(tx.outputs[1].nftCommitment == blockHeightNewPledge); } } @@ -212,6 +216,21 @@ Instead of having a pledge per 30 day period, we define a pledge per block. At a We use `tx.locktime` to introspect the value of the timelock, and to write the value to the contract local state: the NFT commitment field. ::: +#### Integer padding for local state + +Padding an integer to a fixed-size byte-length is a very important when storing local state in an nftCommitment. We can use the `toPaddedBytes(int, length)` function to pad the integer to the desired length. When casting a script number to bytes, developers need to consider what the preferable fixed-size length is for each individual case depending on the integer range. Below we add a table with info on the maximum integer size for common cases: + +| Integer Type | Max integer value | Max Byte Size in Script Number Format | +| -------------- | -----------------------------------| ---------------------------------------| +| Satoshis | 2.1 quadrillion (21,000,000 BCH) | 7 bytes | +| CashTokens | 9.2 quintillion (`2^63 - 1`) | 8 bytes for max supply token | +| Locktime | 4 bytes uInt (`2^32 - 1`) | 5 bytes | +| SequenceNumber | 4 bytes uInt (`2^32 - 1`) | 5 bytes | + +:::info +VM numbers follow Script Number format (A.K.A. CSCriptNum), to convert VM number to bytes or the reverse, it's recommended to use helper functions for these conversions from libraries like Libauth. +::: + ### Issuing NFTs as receipts A covenant that manages funds (BCH + fungible tokens of a certain category) which are pooled together from different people often wants to enable its participants to also exit the covenants with their funds. It would be incredibly hard continuously updating a data structure to keep track of which address contributed how much in the local state of the contract. A much better solution is to issue receipts each time funds are added to the pool! This way the contract does not have a 'global view' of who owns what at any time, but it can validate the receipts when invoking a withdrawal. @@ -251,12 +270,12 @@ contract PooledFunds( if (amountTokensAdded > 0) { // Require 1000 sats to pay for future withdrawal fee require(amountSatsAdded == 1000); - receiptCommitment = 0x01 + bytes8(amountTokensAdded); + receiptCommitment = 0x01 + toPaddedBytes(amountTokensAdded, 8); } else { // Place a minimum on the amount of funds that can be added // Implicitly requires tx.outputs[0].value > tx.inputs[0].value require(amountSatsAdded > 10000); - receiptCommitment = 0x00 + bytes8(amountSatsAdded); + receiptCommitment = 0x00 + toPaddedBytes(amountSatsAdded, 8); } // Require there to be at most three outputs so no additional NFTs can be minted diff --git a/website/docs/language/contracts.md b/website/docs/language/contracts.md index 8ee365ff..6c8175a8 100644 --- a/website/docs/language/contracts.md +++ b/website/docs/language/contracts.md @@ -13,7 +13,7 @@ Contract authors should be careful when allowing a range of versions to check th #### Example ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; pragma cashscript >= 0.7.0 < 0.9.3; ``` @@ -22,7 +22,7 @@ A CashScript constructor works slightly differently than what you might be used #### Example ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract HTLC(pubkey sender, pubkey recipient, int expiration, bytes32 hash) { ... @@ -46,7 +46,7 @@ The main construct in a CashScript contract is the function. A contract can cont #### Example ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract TransferWithTimeout(pubkey sender, pubkey recipient, int timeout) { function transfer(sig recipientSig) { @@ -89,7 +89,7 @@ The error message in a `require` statement is only available in debug evaluation #### Example ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract P2PKH(bytes20 pkh) { function spend(pubkey pk, sig s) { @@ -122,8 +122,8 @@ hashedValue = sha256(hashedValue); myString = 'Cash'; ``` -### Control structures -The only control structures in CashScript are `if...else` statements. This is due to limitations in the underlying Bitcoin Script which prevents loops, recursion, and `return` statements. If-else statements follow usual semantics known from languages like C or JavaScript. +### If statements +If and if-else statements follow usual semantics known from languages like C or JavaScript. If the condition within the `if` statement evaluates to `true`, the block of code within the `if` statement is executed. If the condition evaluates to `false`, the block of code within the optional `else` statement is executed. :::note There is no implicit type conversion from non-boolean to boolean types. So `if (1) { ... }` is not valid CashScript and should instead be written as `if (bool(1)) { ... }` @@ -131,7 +131,7 @@ There is no implicit type conversion from non-boolean to boolean types. So `if ( #### Example ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract OneOfTwo(bytes20 pkh1, bytes32 hash1, bytes20 pkh2, bytes32 hash2) { function spend(pubkey pk, sig s, bytes message) { @@ -149,6 +149,31 @@ contract OneOfTwo(bytes20 pkh1, bytes32 hash1, bytes20 pkh2, bytes32 hash2) { } ``` +### Loops (beta) + +Currently, CashScript only supports `do {} while ()` loops in the 0.13.0-next.0 pre-release. More advanced loop constructs will be added in the full 0.13.0 release. Keep in mind that in a `do {} while ()` loop, the condition is checked *after* the block of code within the loop is executed. This means that the block of code within the loop will be executed at least once, even if the condition is initially `false`. + +:::caution +Loops in CashScript are currently in beta and may not fully behave as expected with debugging and console.log statements. The syntax for loops may change in the future. +::: + +#### Example +```solidity +pragma cashscript ^0.13.0; + +contract NoTokensAllowed() { + function spend() { + int inputIndex = 0; + + // Loop over all inputs (variable length), and make sure that none of them contain tokens + do { + require(tx.inputs[inputIndex].tokenCategory == 0x); + inputIndex = inputIndex + 1; + } while (inputIndex < tx.inputs.length); + } +} +``` + ### console.log() The `console.log` statement can be used to log values during debug evaluation of a transaction. Any variables or primitive values (such as ints, strings, bytes, etc) can be logged. You can read more about debugging in the [debugging guide](/docs/guides/debugging). @@ -158,7 +183,7 @@ Logging is only available in debug evaluation of a transaction, but has no impac #### Example ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract P2PKH(bytes20 pkh) { function spend(pubkey pk, sig s) { diff --git a/website/docs/language/examples.md b/website/docs/language/examples.md index 76431b21..9e16a639 100644 --- a/website/docs/language/examples.md +++ b/website/docs/language/examples.md @@ -12,7 +12,7 @@ This smart contract works by connecting with a price oracle. This price oracle i This involves some degree of trust in the price oracle, but since the oracle produces price data for everyone to use, their incentive to attack *your* smart contract is minimised. To improve this situation, you can also choose to connect with multiple oracle providers so you do not have to trust a single party. ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; // A minimum block is provided to ensure that oracle price entries from before // this block are disregarded. i.e. when the BCH price was $1000 in the past, @@ -53,7 +53,7 @@ The contract works by checking that a UTXO is at least 30 days old, after which Due to the nature of covenants, we have to be very specific about the outputs (amounts and destinations) of the transaction. This also means that we have to account for the special case where the remaining contract balance is lower than the `pledge` amount, meaning no remainder should be sent back. Finally, we have to account for a small fee that has to be taken from the contract's balance to pay the miners. ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract Mecenas(bytes20 recipient, bytes20 funder, int pledge, int period) { function receive() { @@ -95,7 +95,7 @@ AMM DEX contract based on [the Cauldron DEX contract][Cauldron-Whitepaper], you The CashScript contract code has the big advantage of abstracting away any stack management, having variable names, explicit types and a logical order of operations (compared to the 'reverse Polish notation' of raw script). ```solidity -pragma cashscript ^0.12.0; +pragma cashscript ^0.13.0; contract DexContract(bytes20 poolOwnerPkh) { function swap() { diff --git a/website/docs/language/functions.md b/website/docs/language/functions.md index 2cec0839..f407017a 100644 --- a/website/docs/language/functions.md +++ b/website/docs/language/functions.md @@ -113,4 +113,19 @@ bool checkDataSig(datasig s, bytes msg, pubkey pk) Checks that sig `s` is a valid signature for message `msg` and matches with public key `pk`. +## Other functions + +### toPaddedBytes() +```solidity +bytes toPaddedBytes(int value, int length) +``` + +Pads the integer `value` with zeros to the specified `length`. This is most useful when storing integer values in local state (see [local state guide][local-state-guide]). + +:::tip +Using `bytes20 placeholderPkh = toPaddedBytes(0, 20)` will generate a 20 byte zero-array at runtime, whereas +`bytes20 placeholderPkh = 0x0000000000000000000000000000000000000000` will actually take 20 bytes of space in your contract. +::: + [bip146]: https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki +[local-state-guide]: /docs/guides/covenants#keeping-local-state-in-nfts diff --git a/website/docs/language/types.md b/website/docs/language/types.md index e22590e4..662da733 100644 --- a/website/docs/language/types.md +++ b/website/docs/language/types.md @@ -26,8 +26,9 @@ Operators: - Comparisons: `<=`, `<`, `==`, `!=`, `>=`, `>` (all evaluate to `bool`) - Arithmetic operators: `+`, `-`, unary `-`, `*`, `/`, `%` (modulo). +- Arithmetic shift operators: `<<`, `>>` (left and right shift) -Note the lack of the `**` (exponentiation) operator as well as any shifting operators. +Note the lack of the `**` (exponentiation). #### Number Formatting @@ -69,7 +70,7 @@ Members: - `reverse()`: Reverses the string. :::caution -The script will fail if `split()`or `slice()` is called with an index that is out of bounds. +The script will fail if `split()` or `slice()` is called with an index that is out of bounds. ::: ## Bytes @@ -83,8 +84,9 @@ Operators: - `&` (bitwise AND) - `|` (bitwise OR) - `^` (bitwise XOR) - -Note the lack of the bitshift operators (`<<` and `>>`) as well as bitwise INVERT (`~`). +- `<<` (bitwise left shift) +- `>>` (bitwise right shift) +- `~` (bitwise inversion) Members: @@ -165,7 +167,7 @@ Type casting can be done both explicitly and implicitly depending on the type. ` ```solidity pubkey pk = pubkey(0x0000); bytes editedPk = bytes(pk) + 0x1234; -bytes4 zeroBytes = bytes4(0); // 0x00000000 +bool b = bool(5); // true ``` ### Casting Table @@ -177,53 +179,37 @@ See the following table for information on which types can be cast to other whic | int | | bytes, bool | | bool | | int | | string | | bytes | -| bytes | | sig, pubkey, int | +| bytes | | sig, datasig, pubkey, int | | pubkey | bytes | bytes | | sig | bytes | bytes | | datasig | bytes | bytes | -:::caution -Casting from `int` to `bool` does not currently change the value of the integer. This can have unexpected consequences in boolean comparisons. +### Semantic Bytes Casting +When casting unbounded `bytes` types to bounded `bytes` types (such as `bytes20` or `bytes32`), this is a purely semantic cast. The bytes are not padded with zeros, and no checks are performed to ensure the cast bytes are of the correct length. This is why this cast is marked with the `unsafe_` prefix. This can be helpful in certain cases, such as `LockingBytecode`, which expects a specific length input. + +#### Example ```solidity -if (bool(7)) { ...} // This works as expected -if (bool(7) == true) { ... } // This does not work as expected +bytes pkh = tx.inputs[0].nftCommitment; // (type = bytes, content = 20 bytes) +// Typecast the variable to be able to use it for 'new LockingBytecodeP2PKH()' +bytes20 bytes20Pkh = unsafe_bytes20(pkh); // (type = bytes20, content = 20 bytes) +bytes25 lockingBytecode = new LockingBytecodeP2PKH(bytes20Pkh); ``` -::: - -### Int to Byte Casting - -When casting integer types to bytes of a certain size, the integer value is padded with zeros, e.g. `bytes4(0) == 0x00000000`. It is also possible to pad with a variable number of zeros by passing in a `size` parameter, which indicates the size of the output, e.g. `bytes(0, 4 - 2) == 0x0000`. +### Other Semantic Casting +When casting a `bytes` to an `int` or when casting an `int` to a `bool`, opcodes are added to the script to perform a conversion between the two types. If you are an advanced user and want to perform these casts without the added opcodes, you can use the `unsafe_` prefix. -:::tip -Using `bytes20 placeholderPkh= bytes20(0)` will generate a 20 byte zero-array programmatically, whereas -`bytes20 placeholderPkh= 0x0000000000000000000000000000000000000000` will actually take 20 bytes of space in your contract. -::: - -Casting an integer to a fixed-size byte-length can be a very important when storing local state in an nftCommitment. When casting a script number to bytes, developers need to consider what the preferable fixed-size length is for each individual case depending on the integer range. Below we add a table with info on the maximum integer size for common cases: - -| Integer Type | Max integer value | Max Byte Size in Script Number Format | -| -------------- | -----------------------------------| ---------------------------------------| -| Satoshis | 2.1 quadrillion (21,000,000 BCH) | 7 bytes | -| CashTokens | 9.2 quintillion (`2^63 - 1`) | 8 bytes for max supply token | -| Locktime | 4 bytes uInt (`2^32 - 1`) | 5 bytes | -| SequenceNumber | 4 bytes uInt (`2^32 - 1`) | 5 bytes | - -:::info -VM numbers follow Script Number format (A.K.A. CSCriptNum), to convert VM number to bytes or the reverse, it's recommended to use helper functions for these conversions from libraries like Libauth. -::: +#### Example +```solidity +bytes bytesValue = 0x123456000000; // not a valid minimally encoded integer -### Semantic Byte Casting +int(bytesValue); // (type = int, content = 0x123456) +unsafe_int(bytesValue); // (type = int, content = 0x123456000000) -When casting unbounded `bytes` types to bounded `bytes` types (such as `bytes20` or `bytes32`), this is a purely semantic cast. The bytes are not padded with zeros, and no checks are performed to ensure the cast bytes are of the correct length. This can be helpful in certain cases, such as `LockingBytecode`, which expects a specific length input. +int intValue = 25; -#### Example -```solidity -bytes pkh = tx.inputs[0].nftCommitment; // (type = bytes, content = 20 bytes) -// Typecast the variable to be able to use it for 'new LockingBytecodeP2PKH()' -bytes20 bytes20Pkh = bytes20(pkh); // (type = bytes20, content = 20 bytes) -bytes25 lockingBytecode = new LockingBytecodeP2PKH(bytes20Pkh); +bool(intValue); // (type = bool, content = true / 0x01) +unsafe_bool(intValue); // (type = bool, content = 25 / 0x19) ``` ## Operators @@ -239,14 +225,16 @@ An overview of all supported operators and their precedence is included below. N | 6 | Member access | `.` | | 7 | Unary minus | `-` | | 7 | Logical NOT | `!` | +| 7 | Bitwise inversion | `~` | | 8 | Multiplication, division and modulo | `*`, `/`, `%` | | 9 | Addition and subtraction | `+`, `-` | | 9 | String / bytes concatenation | `+` | -| 10 | Numeric comparison | `<`, `>`, `<=`, `>=` | -| 11 | Equality and inequality | `==`, `!=` | -| 12 | Bitwise AND | `&` | -| 13 | Bitwise XOR | `^` | -| 14 | Bitwise OR | \| | -| 15 | Logical AND | `&&` | -| 16 | Logical OR | \|\| | -| 17 | Assignment | `=` | +| 10 | Bitwise / Arithmetic shift | `<<`, `>>` | +| 11 | Numeric comparison | `<`, `>`, `<=`, `>=` | +| 12 | Equality and inequality | `==`, `!=` | +| 13 | Bitwise AND | `&` | +| 14 | Bitwise XOR | `^` | +| 15 | Bitwise OR | `\|` | +| 16 | Logical AND | `&&` | +| 17 | Logical OR | `\|\|` | +| 18 | Assignment | `=` | diff --git a/website/docs/releases/migration-notes.md b/website/docs/releases/migration-notes.md index 2501e253..8dfce84f 100644 --- a/website/docs/releases/migration-notes.md +++ b/website/docs/releases/migration-notes.md @@ -2,6 +2,56 @@ title: Migration Notes --- +## v0.12 to v0.13 + +### cashc compiler + +#### bounded bytes casting + +To indicate that `bytes4(bytes)` casting is purely semantic (and does not offer any type safety), we have renamed it to `unsafe_bytes4(bytes)`. We have also disallowed `bytes4(int)` casting (see section *int to padded bytes casting*). + +```solidity +bytes x = 0x12345678; + +// before +bytes4(x); // => 0x12345678 (correct semantic cast) +bytes5(x); // => 0x12345678 (incorrect semantic cast) + +// after +// marked as unsafe to indicate that this is a purely semantic cast +unsafe_bytes4(x); // => 0x12345678 (correct semantic cast) +unsafe_bytes5(x); // => 0x12345678 (incorrect semantic cast) +``` + +#### int to padded bytes casting + +In the past, `bytes4(int)` or `bytes(int, 4)` would perform a `NUM2BIN` operation, padding the value to 4 bytes, while `bytes4(bytes)` was a purely semantic type cast. This caused confusion, so instead you can now use the `toPaddedBytes(int, length)` function to perform the same padding (`NUM2BIN`) operation. + +```solidity +// before +bytes4(5); // => 0x05000000 +bytes(5, 4); // => 0x05000000 + +// after +toPaddedBytes(5, 4); // => 0x05000000 +``` + +#### bool casting + +The `bool()` casting function now correctly changes the value of the argument to `true` for non-zero values and `false` for zero values, instead of only semantically treating the value as a boolean. This worked correctly when using the boolean directly inside `require` or `if` statements, but not when using it in a comparison. + +```solidity +// before +require(bool(5)); // => true +require(bool(5) == true); // => false || compiles to 0x05 0x01 OP_NUMEQUALVERIFY + +// after +require(bool(5)); // => still true +require(bool(5) == true); // => true || compiles to 0x05 OP_0NOTEQUAL 0x01 OP_NUMEQUALVERIFY +``` + +If you want to keep the old behaviour (without added opcodes), you can use the `unsafe_bool()` casting function instead. + ## v0.11 to v0.12 There are several breaking changes to the SDK in this release. diff --git a/website/docs/releases/release-notes.md b/website/docs/releases/release-notes.md index 26bd0930..6d72b611 100644 --- a/website/docs/releases/release-notes.md +++ b/website/docs/releases/release-notes.md @@ -2,6 +2,32 @@ title: Release Notes --- +## v0.13.0-next.3 + +This release contains several breaking changes, please refer to the [migration notes](/docs/releases/migration-notes) for more information. + +#### cashc compiler +- :sparkles: Add support for `do {} while ()` loops. +- :sparkles: Add support for bitwise and arithmetic shift operators (`<<`, `>>`) and bitwise inversion (`~`). +- :sparkles: Add `unsafe_bool()` and `unsafe_int()` casting for semantic-only casts. +- :bug: **BREAKING**: Fix issue where `bool()` casting did not change the value of the argument. +- :boom: **BREAKING**: Rename `bytes4(int)` and `bytes(int, 4)` to `toPaddedBytes(int, 4)`. +- :boom: **BREAKING**: Rename `bytes4(bytes)` to `unsafe_bytes4(bytes)`. +- :racehorse: Add optimisations for negated number comparisons. + +#### CashScript SDK + +- :sparkles: Add support for `do {} while ()` loops in debug tooling. +- :hammer_and_wrench: Update default VM target to `BCH_2026_05`. +- :hammer_and_wrench: Improve package size by tidying up dependencies. + +#### Testing Suite + +- :hammer_and_wrench: Add README.md to help guide users on how to use the testing suite. +- :hammer_and_wrench: Compile all contracts in the `contracts/` directory and save the artifacts in the `artifacts/` directory. +- :hammer_and_wrench: Compile TS artifacts as well as JSON artifacts. +- :hammer_and_wrench: Add key management utilities for testing. + ## v0.12.1 #### CashScript SDK @@ -9,6 +35,8 @@ title: Release Notes ## v0.12.0 +This release contains several breaking changes, please refer to the [migration notes](/docs/releases/migration-notes) for more information. + #### CashScript SDK - :sparkles: Add `getVmResourceUsage` method to `TransactionBuilder`. - :sparkles: Add `maximumFeeSatsPerByte` and `allowImplicitFungibleTokenBurn` options to `TransactionBuilder` constructor. diff --git a/website/docs/sdk/examples.md b/website/docs/sdk/examples.md index ffb13050..54c26031 100644 --- a/website/docs/sdk/examples.md +++ b/website/docs/sdk/examples.md @@ -14,7 +14,8 @@ We will break up the development of the smart contract application in 4 manageab ### Creating the keypairs -To put the `HodlVault.cash` contract to use in a TypeScript application, we have to use the CashScript SDK in combination with a BCH library such as [Libauth][libauth], [Mainnetjs][mainnetjs] or [BCHJS][bchjs]. These libraries are used to generate public/private keys for the contract participants. +To put the `HodlVault.cash` contract to use in a TypeScript application, we have to use the CashScript SDK in combination with a BCH library such as [Libauth][libauth] or [Mainnetjs][mainnetjs]. These libraries are used to generate public/private keys for the contract participants. + In this example we'll use [Libauth][libauth] to generate the keys `alicePriv`, `alicePub`, `oracle` & `oraclePub`. Then we can use these keys to create the smart contract. :::caution @@ -57,11 +58,11 @@ export const oracleAddress = encodeCashAddress('bchtest', 'p2pkhWithTokens', ora ### Generating a Contract -For the networkprovider, we'll use the `ElectrumNetworkProvider` from the SDK and for `Simple Transaction Builder` for this example. Once you have a smart contract address you can send funds to it. To spend the Bitcoin cash locked in the contract you will have to satisfy the spending conditions on the contract. +For development purposes, we'll use the `MockNetworkProvider` so you can simulate transactions in a 'mock' network environment. To do proper testing, you also need to add "mock" UTXOs to the `MockNetworkProvider`. ```ts title="hodl_vault.ts" import { stringify } from '@bitauth/libauth'; -import { Contract, SignatureTemplate, ElectrumNetworkProvider } from 'cashscript'; +import { Contract, SignatureTemplate, MockNetworkProvider, randomUtxo } from 'cashscript'; import { compileFile } from 'cashc'; import { URL } from 'url'; @@ -74,14 +75,17 @@ import { // Compile the HodlVault contract to an artifact object const artifact = compileFile(new URL('hodl_vault.cash', import.meta.url)); -// Initialise a network provider for network operations on CHIPNET -const provider = new ElectrumNetworkProvider('chipnet'); +// Initialise a network provider for network operations on MockNet +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters const parameters = [alicePub, oraclePub, 100000n, 30000n]; const contract = new Contract(artifact, parameters, { provider }); +// Add a mock UTXO to the network provider +provider.addUtxo(contract.address, randomUtxo()); + // Get contract balance & output address + balance console.log('contract address:', contract.address); console.log('contract balance:', await contract.getBalance()); @@ -121,7 +125,7 @@ Finally, we can put all of this together to create a working smart contract appl ```ts title="hodl_vault.ts" import { stringify } from '@bitauth/libauth'; -import { Contract, SignatureTemplate, ElectrumNetworkProvider } from 'cashscript'; +import { Contract, SignatureTemplate, MockNetworkProvider } from 'cashscript'; import { compileFile } from 'cashc'; import { URL } from 'url'; @@ -136,14 +140,17 @@ import { // Compile the HodlVault contract to an artifact object const artifact = compileFile(new URL('hodl_vault.cash', import.meta.url)); -// Initialise a network provider for network operations on CHIPNET -const provider = new ElectrumNetworkProvider('chipnet'); +// Initialise a network provider for network operations on MockNet +const provider = new MockNetworkProvider(); // Instantiate a new contract using the compiled artifact and network provider // AND providing the constructor parameters const parameters = [alicePub, oraclePub, 100000n, 30000n]; const contract = new Contract(artifact, parameters, { provider }); +// Add a mock UTXO to the network provider +provider.addUtxo(contract.address, randomUtxo()); + // Fetch contract utxos const contractUtxos = await contract.getUtxos(); @@ -177,7 +184,6 @@ const transferDetails = await new TransactionBuilder({ provider }) console.log(transferDetails); ``` -[bchjs]: https://bchjs.fullstack.cash/ [mainnetjs]: https://mainnet.cash/ [libauth]: https://libauth.org/ [github-examples]: https://github.com/CashScript/cashscript/tree/master/examples diff --git a/website/docs/sdk/transaction-builder.md b/website/docs/sdk/transaction-builder.md index 3ac07fb4..1d450867 100644 --- a/website/docs/sdk/transaction-builder.md +++ b/website/docs/sdk/transaction-builder.md @@ -114,7 +114,7 @@ transactionBuilder.addOutput(output: Output): this transactionBuilder.addOutputs(outputs: Output[]): this ``` -Adds a single output or a list of outputs to the transaction. +Adds a single output or a list of outputs to the transaction. The `to` field in an output can be a string representing a cash address, or a `Uint8Array` representing a locking bytecode. For `P2PKH`, `P2SH20` and `P2SH32` outputs, it is easiest to use the cash address string. For `P2S` outputs, you need to use the locking bytecode. ```ts interface Output { diff --git a/yarn.lock b/yarn.lock index eb49e31e..89b6a3d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2010,11 +2010,6 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== -"@types/pako@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/pako/-/pako-2.0.3.tgz#b6993334f3af27c158f3fe0dfeeba987c578afb1" - integrity sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q== - "@types/semver@^7.5.8": version "7.5.8" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" @@ -4566,6 +4561,11 @@ fdir@^6.5.0: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== +fflate@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" + integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== + figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" @@ -7185,11 +7185,6 @@ p-waterfall@^1.0.0: dependencies: p-reduce "^1.0.0" -pako@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" - integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== - parallel-transform@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" @@ -9075,11 +9070,6 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-join@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-5.0.0.tgz#c2f1e5cbd95fa91082a93b58a1f42fecb4bdbcf1" - integrity sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA== - use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"