From 6ab12fbb7b5d2149e1b02c2febab343fbdc2c786 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Fri, 26 Jun 2026 12:43:42 +0200 Subject: [PATCH 1/4] Add minimal user-defined functions implementation Co-authored-by: lightswarm124 Co-authored-by: Mathieu Geukens - Add top-level user-defined function syntax - Functions can return a single value or nothing - Add import syntax - Imports are resolved and flattened into a single AST before compiler traversals - Used functions are defined at the top of a contract, their function bodies are compiled with a separate GenerateTargetTraversal + optimisations - Update builtin function compilation to self-document their bytecode - Update docs & release notes This version does NOT YET support: - Multiple return values / tuples - Proper SDK debugging integration - Safety checks - Nested / multiple returns in a function - Advanced optimisations - Global constants - Cross-file pragma resolutions --- .cspell.json | 1 + packages/cashc/src/Errors.ts | 53 +- packages/cashc/src/artifact/Artifact.ts | 1 + packages/cashc/src/ast/AST.ts | 52 +- packages/cashc/src/ast/AstBuilder.ts | 74 +- packages/cashc/src/ast/AstTraversal.ts | 20 +- packages/cashc/src/ast/AstVisitor.ts | 6 + packages/cashc/src/ast/Globals.ts | 99 +- packages/cashc/src/ast/SymbolTable.ts | 21 +- packages/cashc/src/compiler.ts | 53 +- packages/cashc/src/dependency-resolution.ts | 55 + .../src/generation/GenerateTargetTraversal.ts | 73 +- packages/cashc/src/generation/utils.ts | 22 +- packages/cashc/src/grammar/CashScript.g4 | 31 +- packages/cashc/src/grammar/CashScript.interp | 21 +- packages/cashc/src/grammar/CashScript.tokens | 150 +- .../cashc/src/grammar/CashScriptLexer.interp | 17 +- .../cashc/src/grammar/CashScriptLexer.tokens | 150 +- packages/cashc/src/grammar/CashScriptLexer.ts | 678 +++---- .../cashc/src/grammar/CashScriptParser.ts | 1737 ++++++++++------- .../cashc/src/grammar/CashScriptVisitor.ts | 41 +- packages/cashc/src/parser.ts | 30 + .../src/print/OutputSourceCodeTraversal.ts | 29 + .../semantic/EnsureFinalRequireTraversal.ts | 59 +- .../semantic/InjectLocktimeGuardTraversal.ts | 86 +- .../src/semantic/SymbolTableTraversal.ts | 45 +- .../cashc/src/semantic/TypeCheckTraversal.ts | 53 +- packages/cashc/test/ast/AST.test.ts | 2 +- packages/cashc/test/ast/Location.test.ts | 7 +- packages/cashc/test/ast/fixtures.ts | 15 + .../void_function_as_value.cash | 10 + .../conditional_return.cash | 12 + .../global_function_missing_return.cash | 10 + .../ParseError/import_after_contract.cash | 7 + .../ParseError/import_after_function.cash | 11 + .../duplicate_global_function.cash | 13 + .../return_in_contract_function.cash | 5 + .../ReturnTypeError/wrong_return_type.cash | 9 + .../nonvoid_function_call.cash | 0 .../unused_global_function_local.cash | 10 + .../unused_global_function_parameter.cash | 9 + packages/cashc/test/generation/fixtures.ts | 138 ++ .../cashc/test/import-fixtures/cycle_a.cash | 5 + .../cashc/test/import-fixtures/cycle_b.cash | 5 + .../test/import-fixtures/cycle_main.cash | 7 + .../cashc/test/import-fixtures/diamond.cash | 8 + .../duplicate_import_helper.cash | 3 + .../duplicate_import_main.cash | 11 + packages/cashc/test/import-fixtures/leaf.cash | 3 + packages/cashc/test/import-fixtures/main.cash | 7 + packages/cashc/test/import-fixtures/math.cash | 7 + packages/cashc/test/import-fixtures/mid1.cash | 4 + packages/cashc/test/import-fixtures/mid2.cash | 4 + packages/cashc/test/imports.test.ts | 46 + .../InjectLocktimeGuardTraversal.test.ts | 99 + .../global_function_in_control_flow.cash | 17 + .../global_function_multi_param.cash | 9 + .../global_function_nested.cash | 13 + .../global_function_simple.cash | 9 + .../global_function_void.cash | 10 + packages/utils/src/types.ts | 8 + website/docs/compiler/compiler.md | 8 + website/docs/compiler/grammar.md | 31 +- website/docs/language/contracts.md | 72 +- website/docs/releases/release-notes.md | 8 + 65 files changed, 2972 insertions(+), 1337 deletions(-) create mode 100644 packages/cashc/src/dependency-resolution.ts create mode 100644 packages/cashc/src/parser.ts create mode 100644 packages/cashc/test/compiler/AssignTypeError/void_function_as_value.cash create mode 100644 packages/cashc/test/compiler/MisplacedReturnError/conditional_return.cash create mode 100644 packages/cashc/test/compiler/MissingReturnError/global_function_missing_return.cash create mode 100644 packages/cashc/test/compiler/ParseError/import_after_contract.cash create mode 100644 packages/cashc/test/compiler/ParseError/import_after_function.cash create mode 100644 packages/cashc/test/compiler/RedefinitionError/duplicate_global_function.cash create mode 100644 packages/cashc/test/compiler/ReturnTypeError/return_in_contract_function.cash create mode 100644 packages/cashc/test/compiler/ReturnTypeError/wrong_return_type.cash rename packages/cashc/test/compiler/{ParseError => UnusedFunctionReturnError}/nonvoid_function_call.cash (100%) create mode 100644 packages/cashc/test/compiler/UnusedVariableError/unused_global_function_local.cash create mode 100644 packages/cashc/test/compiler/UnusedVariableError/unused_global_function_parameter.cash create mode 100644 packages/cashc/test/import-fixtures/cycle_a.cash create mode 100644 packages/cashc/test/import-fixtures/cycle_b.cash create mode 100644 packages/cashc/test/import-fixtures/cycle_main.cash create mode 100644 packages/cashc/test/import-fixtures/diamond.cash create mode 100644 packages/cashc/test/import-fixtures/duplicate_import_helper.cash create mode 100644 packages/cashc/test/import-fixtures/duplicate_import_main.cash create mode 100644 packages/cashc/test/import-fixtures/leaf.cash create mode 100644 packages/cashc/test/import-fixtures/main.cash create mode 100644 packages/cashc/test/import-fixtures/math.cash create mode 100644 packages/cashc/test/import-fixtures/mid1.cash create mode 100644 packages/cashc/test/import-fixtures/mid2.cash create mode 100644 packages/cashc/test/imports.test.ts create mode 100644 packages/cashc/test/valid-contract-files/global_function_in_control_flow.cash create mode 100644 packages/cashc/test/valid-contract-files/global_function_multi_param.cash create mode 100644 packages/cashc/test/valid-contract-files/global_function_nested.cash create mode 100644 packages/cashc/test/valid-contract-files/global_function_simple.cash create mode 100644 packages/cashc/test/valid-contract-files/global_function_void.cash diff --git a/.cspell.json b/.cspell.json index 948da88f..56f78ca2 100644 --- a/.cspell.json +++ b/.cspell.json @@ -108,6 +108,7 @@ "lshift", "LSHIFTNUM", "LSHIFTBIN", + "math", "mecenas", "meep", "minimaldata", diff --git a/packages/cashc/src/Errors.ts b/packages/cashc/src/Errors.ts index 511d7521..de4c866e 100644 --- a/packages/cashc/src/Errors.ts +++ b/packages/cashc/src/Errors.ts @@ -1,6 +1,7 @@ import { Type, PrimitiveType } from '@cashscript/utils'; import { IdentifierNode, + ImportNode, FunctionDefinitionNode, VariableDefinitionNode, ParameterNode, @@ -69,7 +70,7 @@ export class InvalidSymbolTypeError extends CashScriptError { public node: IdentifierNode, public expected: SymbolType, ) { - super(node, `Found symbol ${node.name} with type ${node.definition?.symbolType} where type ${expected} was expected`); + super(node, `Found symbol ${node.name} with type ${node.symbol?.symbolType} where type ${expected} was expected`); } } @@ -83,6 +84,22 @@ export class FunctionRedefinitionError extends RedefinitionError { } } +export class MissingContractError extends Error { + constructor() { + super('Source file does not contain a contract definition'); + this.name = this.constructor.name; + } +} + +export class ImportResolutionError extends CashScriptError { + constructor( + public node: ImportNode, + message: string, + ) { + super(node, message); + } +} + export class VariableRedefinitionError extends RedefinitionError { constructor( public node: VariableDefinitionNode | ParameterNode, @@ -123,6 +140,30 @@ export class FinalRequireStatementError extends CashScriptError { } } +export class UnusedFunctionReturnError extends CashScriptError { + constructor( + public node: FunctionCallNode, + ) { + super(node, `Return value of ${node.identifier.name} must be used; only void functions may be called as a statement`); + } +} + +export class MissingReturnError extends CashScriptError { + constructor( + public node: Node, + ) { + super(node, 'A value-returning function must end with a return statement'); + } +} + +export class MisplacedReturnError extends CashScriptError { + constructor( + public node: StatementNode, + ) { + super(node, 'A return statement is only allowed as the final statement of a function body'); + } +} + export class TypeError extends CashScriptError { constructor( node: Node, @@ -134,6 +175,16 @@ export class TypeError extends CashScriptError { } } +export class ReturnTypeError extends TypeError { + constructor( + node: Node, + actual?: Type, + expected?: Type, + ) { + super(node, actual, expected, `Cannot return type '${actual}' from a function with return type '${expected}'`); + } +} + export class InvalidParameterTypeError extends TypeError { constructor( node: FunctionCallNode | RequireNode | InstantiationNode, diff --git a/packages/cashc/src/artifact/Artifact.ts b/packages/cashc/src/artifact/Artifact.ts index ff09b9f3..159aa0ef 100644 --- a/packages/cashc/src/artifact/Artifact.ts +++ b/packages/cashc/src/artifact/Artifact.ts @@ -13,6 +13,7 @@ export function generateArtifact( fingerprint: string, ): Artifact { const { contract } = ast; + if (!contract) throw new Error('Internal error: cannot generate an artifact for a source file with no contract'); const constructorInputs = contract.parameters .map((parameter) => ({ name: parameter.name, type: parameter.type.toString() })); diff --git a/packages/cashc/src/ast/AST.ts b/packages/cashc/src/ast/AST.ts index 3b4a869a..8d097023 100644 --- a/packages/cashc/src/ast/AST.ts +++ b/packages/cashc/src/ast/AST.ts @@ -21,9 +21,19 @@ export interface Typed { type: Type; } +export enum FunctionKind { + CONTRACT = 'contract', + GLOBAL = 'global', +} + export class SourceFileNode extends Node { + // The source file's scope: the table of global functions (each symbol carries its VM function-table id). + symbolTable?: SymbolTable; + constructor( - public contract: ContractNode, + public contract?: ContractNode, + public functions: FunctionDefinitionNode[] = [], + public imports: ImportNode[] = [], ) { super(); } @@ -33,6 +43,18 @@ export class SourceFileNode extends Node { } } +export class ImportNode extends Node { + constructor( + public path: string, + ) { + super(); + } + + accept(visitor: AstVisitor): T { + return visitor.visitImport(this); + } +} + export class ContractNode extends Node implements Named { symbolTable?: SymbolTable; @@ -54,9 +76,11 @@ export class FunctionDefinitionNode extends Node implements Named { opRolls: Map = new Map(); constructor( + public kind: FunctionKind, public name: string, public parameters: ParameterNode[], public body: BlockNode, + public returnType?: Type, ) { super(); } @@ -168,6 +192,30 @@ export class ConsoleStatementNode extends NonControlStatementNode { } } +export class FunctionCallStatementNode extends NonControlStatementNode { + constructor( + public functionCall: FunctionCallNode, + ) { + super(); + } + + accept(visitor: AstVisitor): T { + return visitor.visitFunctionCallStatement(this); + } +} + +export class ReturnNode extends NonControlStatementNode { + constructor( + public expression: ExpressionNode, + ) { + super(); + } + + accept(visitor: AstVisitor): T { + return visitor.visitReturn(this); + } +} + export class BranchNode extends ControlStatementNode { constructor( public condition: ExpressionNode, @@ -362,7 +410,7 @@ export class ArrayNode extends ExpressionNode { } export class IdentifierNode extends ExpressionNode implements Named { - definition?: Symbol; + symbol?: Symbol; constructor( public name: string, diff --git a/packages/cashc/src/ast/AstBuilder.ts b/packages/cashc/src/ast/AstBuilder.ts index fc671b03..c2bdd0e3 100644 --- a/packages/cashc/src/ast/AstBuilder.ts +++ b/packages/cashc/src/ast/AstBuilder.ts @@ -1,14 +1,16 @@ import { ParseTree, ParseTreeVisitor } from 'antlr4'; import { hexToBin } from '@bitauth/libauth'; -import { parseType } from '@cashscript/utils'; +import { parseType, Type } from '@cashscript/utils'; import semver from 'semver'; import { Node, SourceFileNode, + ImportNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, + FunctionKind, AssignNode, IdentifierNode, BranchNode, @@ -28,11 +30,13 @@ import { ArrayNode, TupleIndexOpNode, RequireNode, + ReturnNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, ConsoleParameterNode, + FunctionCallStatementNode, SliceNode, DoWhileNode, WhileNode, @@ -40,8 +44,12 @@ import { } from './AST.js'; import { UnaryOperator, BinaryOperator, NullaryOperator } from './Operator.js'; import type { + ImportDirectiveContext, ContractDefinitionContext, - FunctionDefinitionContext, + ContractFunctionDefinitionContext, + GlobalFunctionDefinitionContext, + ReturnStatementContext, + FunctionCallStatementContext, VariableDefinitionContext, TupleAssignmentContext, ParameterContext, @@ -110,12 +118,34 @@ export default class AstBuilder this.processPragma(pragma); }); - const contract = this.visit(ctx.contractDefinition()) as ContractNode; - const sourceFileNode = new SourceFileNode(contract); + const imports = ctx.importDirective_list().map((directive) => this.visit(directive) as ImportNode); + + const functions: FunctionDefinitionNode[] = []; + let contract: ContractNode | undefined; + + ctx.topLevelDefinition_list().forEach((def) => { + if (def.globalFunctionDefinition()) { + functions.push(this.visit(def.globalFunctionDefinition()) as FunctionDefinitionNode); + } else if (def.contractDefinition()) { + if (contract) { + throw new ParseError('A source file may define at most one contract', Location.fromCtx(def.contractDefinition())); + } + contract = this.visit(def.contractDefinition()) as ContractNode; + } + }); + + const sourceFileNode = new SourceFileNode(contract, functions, imports); sourceFileNode.location = Location.fromCtx(ctx); return sourceFileNode; } + visitImportDirective(ctx: ImportDirectiveContext): ImportNode { + const raw = ctx.StringLiteral().getText(); + const importNode = new ImportNode(raw.substring(1, raw.length - 1)); + importNode.location = Location.fromCtx(ctx); + return importNode; + } + processPragma(ctx: PragmaDirectiveContext): void { const pragmaName = getPragmaName(ctx.pragmaName().getText()); if (pragmaName !== PragmaName.CASHSCRIPT) throw new Error(); // Shouldn't happen @@ -135,17 +165,31 @@ export default class AstBuilder visitContractDefinition(ctx: ContractDefinitionContext): ContractNode { const name = ctx.Identifier().getText(); const parameters = ctx.parameterList().parameter_list().map((p) => this.visit(p) as ParameterNode); - const functions = ctx.functionDefinition_list().map((f) => this.visit(f) as FunctionDefinitionNode); + const functions = ctx.contractFunctionDefinition_list() + .map((f) => this.visit(f) as FunctionDefinitionNode); const contract = new ContractNode(name, parameters, functions); contract.location = Location.fromCtx(ctx); return contract; } - visitFunctionDefinition(ctx: FunctionDefinitionContext): FunctionDefinitionNode { + visitContractFunctionDefinition(ctx: ContractFunctionDefinitionContext): FunctionDefinitionNode { + return this.buildFunctionDefinition(ctx, FunctionKind.CONTRACT); + } + + visitGlobalFunctionDefinition(ctx: GlobalFunctionDefinitionContext): FunctionDefinitionNode { + const returnType = ctx.typeName() ? parseType(ctx.typeName().getText()) : undefined; + return this.buildFunctionDefinition(ctx, FunctionKind.GLOBAL, returnType); + } + + private buildFunctionDefinition( + ctx: ContractFunctionDefinitionContext | GlobalFunctionDefinitionContext, + kind: FunctionKind, + returnType?: Type, + ): FunctionDefinitionNode { const name = ctx.Identifier().getText(); const parameters = ctx.parameterList().parameter_list().map((p) => this.visit(p) as ParameterNode); - const body = this.visit(ctx.functionBody()); - const functionDefinition = new FunctionDefinitionNode(name, parameters, body); + const body = this.visit(ctx.functionBody()) as BlockNode; + const functionDefinition = new FunctionDefinitionNode(kind, name, parameters, body, returnType); functionDefinition.location = Location.fromCtx(ctx); return functionDefinition; } @@ -260,6 +304,20 @@ export default class AstBuilder return require; } + visitReturnStatement(ctx: ReturnStatementContext): ReturnNode { + const expression = this.visit(ctx.expression()); + const returnNode = new ReturnNode(expression); + returnNode.location = Location.fromCtx(ctx); + return returnNode; + } + + visitFunctionCallStatement(ctx: FunctionCallStatementContext): FunctionCallStatementNode { + const functionCall = this.visit(ctx.functionCall()) as FunctionCallNode; + const node = new FunctionCallStatementNode(functionCall); + node.location = Location.fromCtx(ctx); + return node; + } + visitIfStatement(ctx: IfStatementContext): BranchNode { const condition = this.visit(ctx.expression()); const ifBlock = this.visit(ctx._ifBlock) as StatementNode; diff --git a/packages/cashc/src/ast/AstTraversal.ts b/packages/cashc/src/ast/AstTraversal.ts index ba73d204..bd428132 100644 --- a/packages/cashc/src/ast/AstTraversal.ts +++ b/packages/cashc/src/ast/AstTraversal.ts @@ -1,6 +1,7 @@ import { Node, SourceFileNode, + ImportNode, ContractNode, ParameterNode, VariableDefinitionNode, @@ -22,11 +23,13 @@ import { ArrayNode, TupleIndexOpNode, RequireNode, + ReturnNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, ConsoleParameterNode, + FunctionCallStatementNode, SliceNode, DoWhileNode, WhileNode, @@ -36,7 +39,12 @@ import AstVisitor from './AstVisitor.js'; export default class AstTraversal extends AstVisitor { visitSourceFile(node: SourceFileNode): Node { - node.contract = this.visit(node.contract) as ContractNode; + node.functions = this.visitList(node.functions) as FunctionDefinitionNode[]; + node.contract = this.visitOptional(node.contract) as ContractNode | undefined; + return node; + } + + visitImport(node: ImportNode): Node { return node; } @@ -82,11 +90,21 @@ export default class AstTraversal extends AstVisitor { return node; } + visitReturn(node: ReturnNode): Node { + node.expression = this.visit(node.expression); + return node; + } + visitConsoleStatement(node: ConsoleStatementNode): Node { node.parameters = this.visitList(node.parameters) as ConsoleParameterNode[]; return node; } + visitFunctionCallStatement(node: FunctionCallStatementNode): Node { + node.functionCall = this.visit(node.functionCall) as FunctionCallNode; + return node; + } + visitBranch(node: BranchNode): Node { node.condition = this.visit(node.condition); node.ifBlock = this.visit(node.ifBlock) as StatementNode; diff --git a/packages/cashc/src/ast/AstVisitor.ts b/packages/cashc/src/ast/AstVisitor.ts index 1c131bf3..3b72d57f 100644 --- a/packages/cashc/src/ast/AstVisitor.ts +++ b/packages/cashc/src/ast/AstVisitor.ts @@ -1,6 +1,7 @@ import { Node, SourceFileNode, + ImportNode, ContractNode, ParameterNode, VariableDefinitionNode, @@ -21,10 +22,12 @@ import { ArrayNode, TupleIndexOpNode, RequireNode, + ReturnNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, + FunctionCallStatementNode, SliceNode, DoWhileNode, WhileNode, @@ -33,6 +36,7 @@ import { export default abstract class AstVisitor { abstract visitSourceFile(node: SourceFileNode): T; + abstract visitImport(node: ImportNode): T; abstract visitContract(node: ContractNode): T; abstract visitFunctionDefinition(node: FunctionDefinitionNode): T; abstract visitParameter(node: ParameterNode): T; @@ -41,7 +45,9 @@ export default abstract class AstVisitor { abstract visitAssign(node: AssignNode): T; abstract visitTimeOp(node: TimeOpNode): T; abstract visitRequire(node: RequireNode): T; + abstract visitReturn(node: ReturnNode): T; abstract visitConsoleStatement(node: ConsoleStatementNode): T; + abstract visitFunctionCallStatement(node: FunctionCallStatementNode): T; abstract visitBranch(node: BranchNode): T; abstract visitDoWhile(node: DoWhileNode): T; abstract visitWhile(node: WhileNode): T; diff --git a/packages/cashc/src/ast/Globals.ts b/packages/cashc/src/ast/Globals.ts index cc1273d7..878475c6 100644 --- a/packages/cashc/src/ast/Globals.ts +++ b/packages/cashc/src/ast/Globals.ts @@ -1,4 +1,4 @@ -import { PrimitiveType, ArrayType, BytesType } from '@cashscript/utils'; +import { PrimitiveType, ArrayType, BytesType, Op } from '@cashscript/utils'; import { SymbolTable, Symbol } from './SymbolTable.js'; export const NumberUnit: { [index: string]: number } = { @@ -63,47 +63,88 @@ GLOBAL_SYMBOL_TABLE.set( ); // Global functions + +// abs(int) -> int +GLOBAL_SYMBOL_TABLE.set( + Symbol.builtinFunction(GlobalFunction.ABS, PrimitiveType.INT, [PrimitiveType.INT], [Op.OP_ABS]), +); + +// min(int, int) -> int GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.ABS, PrimitiveType.INT, [PrimitiveType.INT]), + Symbol.builtinFunction(GlobalFunction.MIN, PrimitiveType.INT, [PrimitiveType.INT, PrimitiveType.INT], [Op.OP_MIN]), ); + +// max(int, int) -> int GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.MIN, PrimitiveType.INT, [PrimitiveType.INT, PrimitiveType.INT]), + Symbol.builtinFunction(GlobalFunction.MAX, PrimitiveType.INT, [PrimitiveType.INT, PrimitiveType.INT], [Op.OP_MAX]), ); + +// within(int, int, int) -> bool GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.MAX, PrimitiveType.INT, [PrimitiveType.INT, PrimitiveType.INT]), + Symbol.builtinFunction( + GlobalFunction.WITHIN, PrimitiveType.BOOL, + [PrimitiveType.INT, PrimitiveType.INT, PrimitiveType.INT], + [Op.OP_WITHIN], + ), ); -GLOBAL_SYMBOL_TABLE.set(Symbol.function( - GlobalFunction.WITHIN, PrimitiveType.BOOL, - [PrimitiveType.INT, PrimitiveType.INT, PrimitiveType.INT], -)); + +// ripemd160(any) -> bytes20 GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.RIPEMD160, new BytesType(20), [PrimitiveType.ANY]), + Symbol.builtinFunction(GlobalFunction.RIPEMD160, new BytesType(20), [PrimitiveType.ANY], [Op.OP_RIPEMD160]), ); + +// sha1(any) -> bytes20 GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.SHA1, new BytesType(20), [PrimitiveType.ANY]), + Symbol.builtinFunction(GlobalFunction.SHA1, new BytesType(20), [PrimitiveType.ANY], [Op.OP_SHA1]), ); + +// sha256(any) -> bytes32 GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.SHA256, new BytesType(32), [PrimitiveType.ANY]), + Symbol.builtinFunction(GlobalFunction.SHA256, new BytesType(32), [PrimitiveType.ANY], [Op.OP_SHA256]), ); + +// hash160(any) -> bytes20 GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.HASH160, new BytesType(20), [PrimitiveType.ANY]), + Symbol.builtinFunction(GlobalFunction.HASH160, new BytesType(20), [PrimitiveType.ANY], [Op.OP_HASH160]), ); + +// hash256(any) -> bytes32 +GLOBAL_SYMBOL_TABLE.set( + Symbol.builtinFunction(GlobalFunction.HASH256, new BytesType(32), [PrimitiveType.ANY], [Op.OP_HASH256]), +); + +// checkSig(sig, pubkey) -> bool +GLOBAL_SYMBOL_TABLE.set( + Symbol.builtinFunction( + GlobalFunction.CHECKSIG, PrimitiveType.BOOL, + [PrimitiveType.SIG, PrimitiveType.PUBKEY], + [Op.OP_CHECKSIG], + ), +); + +// checkMultiSig(sig[], pubkey[]) -> bool +GLOBAL_SYMBOL_TABLE.set( + Symbol.builtinFunction( + GlobalFunction.CHECKMULTISIG, PrimitiveType.BOOL, + [new ArrayType(PrimitiveType.SIG), new ArrayType(PrimitiveType.PUBKEY)], + [Op.OP_CHECKMULTISIG], + ), +); + +// checkDataSig(datasig, bytes, pubkey) -> bool +GLOBAL_SYMBOL_TABLE.set( + Symbol.builtinFunction( + GlobalFunction.CHECKDATASIG, PrimitiveType.BOOL, + [PrimitiveType.DATASIG, new BytesType(), PrimitiveType.PUBKEY], + [Op.OP_CHECKDATASIG], + ), +); + +// toPaddedBytes(int, int) -> bytes GLOBAL_SYMBOL_TABLE.set( - Symbol.function(GlobalFunction.HASH256, new BytesType(32), [PrimitiveType.ANY]), + Symbol.builtinFunction( + GlobalFunction.TO_PADDED_BYTES, new BytesType(), + [PrimitiveType.INT, PrimitiveType.INT], + [Op.OP_NUM2BIN], + ), ); -GLOBAL_SYMBOL_TABLE.set(Symbol.function( - GlobalFunction.CHECKSIG, PrimitiveType.BOOL, - [PrimitiveType.SIG, PrimitiveType.PUBKEY], -)); -GLOBAL_SYMBOL_TABLE.set(Symbol.function( - GlobalFunction.CHECKMULTISIG, PrimitiveType.BOOL, - [new ArrayType(PrimitiveType.SIG), new ArrayType(PrimitiveType.PUBKEY)], -)); -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/SymbolTable.ts b/packages/cashc/src/ast/SymbolTable.ts index fcfada94..852be038 100644 --- a/packages/cashc/src/ast/SymbolTable.ts +++ b/packages/cashc/src/ast/SymbolTable.ts @@ -1,20 +1,24 @@ -import { Type } from '@cashscript/utils'; +import { Type, PrimitiveType, Script, Op, encodeInt } from '@cashscript/utils'; import { VariableDefinitionNode, ParameterNode, + FunctionDefinitionNode, IdentifierNode, Node, } from './AST.js'; export class Symbol { references: IdentifierNode[] = []; + private constructor( public name: string, public type: Type, public symbolType: SymbolType, public definition?: Node, public parameters?: Type[], - ) {} + public bytecode?: Script, + public functionId?: number, + ) { } static variable(node: VariableDefinitionNode | ParameterNode): Symbol { return new Symbol(node.name, node.type, SymbolType.VARIABLE, node); @@ -24,8 +28,15 @@ export class Symbol { return new Symbol(name, type, SymbolType.VARIABLE); } - static function(name: string, type: Type, parameters: Type[]): Symbol { - return new Symbol(name, type, SymbolType.FUNCTION, undefined, parameters); + static builtinFunction(name: string, returnType: Type, parameters: Type[], bytecode: Script): Symbol { + return new Symbol(name, returnType, SymbolType.FUNCTION, undefined, parameters, bytecode); + } + + static userFunction(node: FunctionDefinitionNode, functionId: number): Symbol { + const parameterTypes = node.parameters.map((parameter) => parameter.type); + const returnType = node.returnType ?? PrimitiveType.VOID; + const bytecode = [encodeInt(BigInt(functionId)), Op.OP_INVOKE]; + return new Symbol(node.name, returnType, SymbolType.FUNCTION, node, parameterTypes, bytecode, functionId); } static class(name: string, type: Type, parameters: Type[]): Symbol { @@ -52,7 +63,7 @@ export class SymbolTable { constructor( public parent?: SymbolTable, - ) {} + ) { } set(symbol: Symbol): void { this.symbols.set(symbol.name, symbol); diff --git a/packages/cashc/src/compiler.ts b/packages/cashc/src/compiler.ts index 46c24927..44963727 100644 --- a/packages/cashc/src/compiler.ts +++ b/packages/cashc/src/compiler.ts @@ -1,4 +1,3 @@ -import { CharStream, CommonTokenStream } from 'antlr4'; import { binToHex } from '@bitauth/libauth'; import { Artifact, @@ -13,13 +12,15 @@ import { sourceMapToLocationData, } from '@cashscript/utils'; import fs, { PathLike } from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; import { generateArtifact } from './artifact/Artifact.js'; import { Ast } from './ast/AST.js'; -import AstBuilder from './ast/AstBuilder.js'; -import { ThrowingErrorListener, CashScriptErrorListener, ForwardingErrorListener } from './ast/error-listeners.js'; +import { CashScriptErrorListener } from './ast/error-listeners.js'; +import { MissingContractError } from './Errors.js'; +import { parseCode } from './parser.js'; +import { resolveDependencies } from './dependency-resolution.js'; import GenerateTargetTraversal from './generation/GenerateTargetTraversal.js'; -import CashScriptLexer from './grammar/CashScriptLexer.js'; -import CashScriptParser from './grammar/CashScriptParser.js'; import SymbolTableTraversal from './semantic/SymbolTableTraversal.js'; import TypeCheckTraversal from './semantic/TypeCheckTraversal.js'; import EnsureFinalRequireTraversal from './semantic/EnsureFinalRequireTraversal.js'; @@ -32,6 +33,7 @@ export const DEFAULT_COMPILER_OPTIONS: CompilerOptions = { export interface CompileOptions extends CompilerOptions { errorListener?: CashScriptErrorListener; + basePath?: string; } /** @@ -43,12 +45,17 @@ export interface CompileOptions extends CompilerOptions { * @throws If the source code contains a syntax, semantic, or type error. */ export function compileString(code: string, compilerOptions: CompileOptions = {}): Artifact { - const { errorListener, ...artifactCompilerOptions } = compilerOptions; + const { errorListener, basePath, ...artifactCompilerOptions } = compilerOptions; const mergedCompilerOptions = { ...DEFAULT_COMPILER_OPTIONS, ...artifactCompilerOptions }; // Lexing + parsing let ast = parseCode(code, errorListener); + ast = resolveDependencies(ast, { basePath, errorListener }) as Ast; + if (!ast.contract) throw new MissingContractError(); + + const constructorParamLength = ast.contract.parameters.length; + // Semantic analysis ast = ast.accept(new SymbolTableTraversal()) as Ast; ast = ast.accept(new TypeCheckTraversal()) as Ast; @@ -61,8 +68,6 @@ export function compileString(code: string, compilerOptions: CompileOptions = {} const traversal = new GenerateTargetTraversal(mergedCompilerOptions); ast = ast.accept(traversal) as Ast; - const constructorParamLength = ast.contract.parameters.length; - // Bytecode optimisation const optimisedBytecodeOld = optimiseBytecodeOld(traversal.output); const optimisationResult = optimiseBytecode( @@ -104,32 +109,8 @@ export function compileString(code: string, compilerOptions: CompileOptions = {} * @throws If the file cannot be read, or if the source contains a compilation error. */ export function compileFile(codeFile: PathLike, compilerOptions: CompileOptions = {}): Artifact { - const code = fs.readFileSync(codeFile, { encoding: 'utf-8' }); - return compileString(code, compilerOptions); -} - -export function parseCode( - code: string, - errorListener: CashScriptErrorListener = ThrowingErrorListener.INSTANCE, -): Ast { - const syntaxErrorListener = new ForwardingErrorListener(errorListener); - - // Lexing (throwing on errors) - const inputStream = new CharStream(code); - const lexer = new CashScriptLexer(inputStream); - lexer.removeErrorListeners(); - lexer.addErrorListener(syntaxErrorListener); - const tokenStream = new CommonTokenStream(lexer); - - // Parsing (throwing on errors) - const parser = new CashScriptParser(tokenStream); - parser.removeErrorListeners(); - parser.addErrorListener(syntaxErrorListener); - const parseTree = parser.sourceFile(); - syntaxErrorListener.throwFirstError(); - - // AST building - const ast = new AstBuilder(parseTree).build() as Ast; - - return ast; + const filePath = codeFile instanceof URL ? fileURLToPath(codeFile) : codeFile.toString(); + const code = fs.readFileSync(filePath, { encoding: 'utf-8' }); + const basePath = compilerOptions.basePath ?? path.dirname(filePath); + return compileString(code, { ...compilerOptions, basePath }); } diff --git a/packages/cashc/src/dependency-resolution.ts b/packages/cashc/src/dependency-resolution.ts new file mode 100644 index 00000000..c182d509 --- /dev/null +++ b/packages/cashc/src/dependency-resolution.ts @@ -0,0 +1,55 @@ +import fs from 'fs'; +import path from 'path'; +import { SourceFileNode, FunctionDefinitionNode, ImportNode } from './ast/AST.js'; +import type { CompileOptions } from './compiler.js'; +import { ImportResolutionError } from './Errors.js'; +import { parseCode } from './parser.js'; + +export function resolveDependencies(ast: SourceFileNode, options: CompileOptions): SourceFileNode { + if (ast.imports.length === 0) return ast; + + const importedFunctions = collectImports(ast.imports, options.basePath, options); + ast.functions = [...importedFunctions, ...ast.functions]; + ast.imports = []; + + return ast; +} + +// Depth-first walk of the import graph, returning every global function it reaches. `visitedPaths` is +// internal bookkeeping that de-duplicates files by absolute path — collapsing diamonds (a file reached +// through two paths is read once) and guaranteeing termination for mutual or cyclic imports — so this +// function stays pure with respect to its arguments. +function collectImports( + imports: ImportNode[], + fileDir: string | undefined, + options: CompileOptions, +): FunctionDefinitionNode[] { + const visitedPaths = new Set(); + + const collect = (currentImports: ImportNode[], currentDir: string | undefined): FunctionDefinitionNode[] => + currentImports.flatMap((importNode) => { + if (currentDir === undefined) { + throw new ImportResolutionError(importNode, 'Cannot resolve imports without a base path (compile from a file)'); + } + + const absolutePath = path.resolve(currentDir, importNode.path); + if (visitedPaths.has(absolutePath)) return []; + visitedPaths.add(absolutePath); + + const importedAst = parseCode(readImportedFile(importNode, absolutePath), options.errorListener); + return [...collect(importedAst.imports, path.dirname(absolutePath)), ...importedAst.functions]; + }); + + return collect(imports, fileDir); +} + +function readImportedFile(importNode: ImportNode, absolutePath: string): string { + try { + return fs.readFileSync(absolutePath, { encoding: 'utf-8' }); + } catch { + throw new ImportResolutionError( + importNode, + `Could not read imported file '${importNode.path}' (resolved to ${absolutePath})`, + ); + } +} diff --git a/packages/cashc/src/generation/GenerateTargetTraversal.ts b/packages/cashc/src/generation/GenerateTargetTraversal.ts index ef0a0096..286168c0 100644 --- a/packages/cashc/src/generation/GenerateTargetTraversal.ts +++ b/packages/cashc/src/generation/GenerateTargetTraversal.ts @@ -9,6 +9,8 @@ import { PrimitiveType, Script, scriptToAsm, + scriptToBytecode, + optimiseBytecode, generateSourceMap, FullLocationData, LogEntry, @@ -26,6 +28,7 @@ import { ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, + FunctionKind, AssignNode, IdentifierNode, BranchNode, @@ -60,14 +63,13 @@ import { BinaryOperator } from '../ast/Operator.js'; import { compileBinaryOp, compileCast, - compileGlobalFunction, compileNullaryOp, compileTimeOp, compileUnaryOp, } from './utils.js'; import { isNumericType } from '../utils.js'; -export default class GenerateTargetTraversalWithLocation extends AstTraversal { +export default class GenerateTargetTraversal extends AstTraversal { private locationData: FullLocationData = []; // detailed location data needed for sourcemap creation sourceMap: string; output: Script = []; @@ -133,7 +135,10 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { } visitSourceFile(node: SourceFileNode): Node { - node.contract = this.visit(node.contract) as ContractNode; + this.defineGlobalFunctions(node); + + // The contract is guaranteed to exist here (compileString throws MissingContractError otherwise). + node.contract = this.visit(node.contract!) as ContractNode; // Minimally encode output by going Script -> ASM -> Script this.output = asmToScript(scriptToAsm(this.output)); @@ -143,6 +148,51 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { return node; } + private defineGlobalFunctions(node: SourceFileNode): void { + node.functions.forEach((func) => { + const { functionId } = node.symbolTable!.getFromThis(func.name)!; + const bodyBytecode = this.compileGlobalFunctionBody(func); + + const locationData = { location: func.location, positionHint: PositionHint.START }; + this.emit(bodyBytecode, locationData); // + this.emit(encodeInt(BigInt(functionId!)), locationData); // + this.emit(Op.OP_DEFINE, { ...locationData, positionHint: PositionHint.END }); + }); + } + + private compileGlobalFunctionBody(node: FunctionDefinitionNode): Uint8Array { + const bodyTraversal = new GenerateTargetTraversal(this.compilerOptions); + bodyTraversal.currentFunction = node; + bodyTraversal.constructorParameterCount = 0; + + // Seed the stack with parameters in reverse order so the last parameter is on top (simila to how builtin functions work) + for (let i = node.parameters.length - 1; i >= 0; i -= 1) { + bodyTraversal.visit(node.parameters[i]); + } + + bodyTraversal.visit(node.body); + bodyTraversal.cleanGlobalFunctionStack(node); + + const optimised = optimiseBytecode( + bodyTraversal.output, + bodyTraversal.locationData, + bodyTraversal.consoleLogs, + bodyTraversal.requires, + bodyTraversal.sourceTags, + 0, + ); + + return scriptToBytecode(optimised.script); + } + + cleanGlobalFunctionStack(node: FunctionDefinitionNode): void { + if (node.returnType === undefined) { + this.removeScopedVariables(0, node.body); // void: drop the entire frame + } else { + this.cleanStack(node.body); // value: OP_NIP everything below the return value on top + } + } + visitContract(node: ContractNode): Node { node.parameters = this.visitList(node.parameters) as ParameterNode[]; @@ -196,6 +246,10 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { } visitFunctionDefinition(node: FunctionDefinitionNode): Node { + if (node.kind !== FunctionKind.CONTRACT) { + throw new Error('Internal error: global functions are compiled via defineGlobalFunctions'); + } + this.currentFunction = node; node.parameters = this.visitList(node.parameters) as ParameterNode[]; @@ -402,7 +456,7 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { const data = node.parameters.map((parameter: ConsoleParameterNode) => { if (parameter instanceof IdentifierNode) { - const symbol = parameter.definition!; + const symbol = parameter.symbol!; // If the variable is not on the stack, then we add the final stack usage to the console log const stackIndex = this.getStackIndex(parameter.name, true); @@ -587,14 +641,11 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { return this.visitMultiSig(node); } + const symbol = node.identifier.symbol!; node.parameters = this.visitList(node.parameters); - - this.emit( - compileGlobalFunction(node.identifier.name as GlobalFunction), - { location: node.location, positionHint: PositionHint.END }, - ); + this.emit(symbol.bytecode!, { location: node.location, positionHint: PositionHint.END }); this.popFromStack(node.parameters.length); - this.pushToStack('(value)'); + if (symbol.type !== PrimitiveType.VOID) this.pushToStack('(value)'); return node; } @@ -774,7 +825,7 @@ export default class GenerateTargetTraversalWithLocation extends AstTraversal { // If the final use is inside an if-statement, we still OP_PICK it // We do this so that there's no difference in stack depths between execution paths if (this.isOpRoll(node)) { - const symbol = node.definition!; + const symbol = node.symbol!; this.finalStackUsage[node.name] = { type: symbol.type.toString(), stackIndex, diff --git a/packages/cashc/src/generation/utils.ts b/packages/cashc/src/generation/utils.ts index fa017aac..b6bac219 100644 --- a/packages/cashc/src/generation/utils.ts +++ b/packages/cashc/src/generation/utils.ts @@ -7,7 +7,7 @@ import { Type, } from '@cashscript/utils'; import { UnaryOperator, BinaryOperator, NullaryOperator } from '../ast/Operator.js'; -import { GlobalFunction, TimeOp } from '../ast/Globals.js'; +import { TimeOp } from '../ast/Globals.js'; export function compileTimeOp(op: TimeOp): Script { const mapping = { @@ -36,26 +36,6 @@ export function compileCast(from: Type, to: Type, isUnsafe: boolean): Script { return []; } -export function compileGlobalFunction(fn: GlobalFunction): Script { - const mapping = { - [GlobalFunction.ABS]: [Op.OP_ABS], - [GlobalFunction.CHECKDATASIG]: [Op.OP_CHECKDATASIG], - [GlobalFunction.CHECKMULTISIG]: [Op.OP_CHECKMULTISIG], - [GlobalFunction.CHECKSIG]: [Op.OP_CHECKSIG], - [GlobalFunction.MAX]: [Op.OP_MAX], - [GlobalFunction.MIN]: [Op.OP_MIN], - [GlobalFunction.RIPEMD160]: [Op.OP_RIPEMD160], - [GlobalFunction.SHA1]: [Op.OP_SHA1], - [GlobalFunction.SHA256]: [Op.OP_SHA256], - [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]; -} - export function compileBinaryOp(op: BinaryOperator, numeric: boolean = false): Script { const mapping: { [key in BinaryOperator]: Script } = { [BinaryOperator.MUL]: [Op.OP_MUL], diff --git a/packages/cashc/src/grammar/CashScript.g4 b/packages/cashc/src/grammar/CashScript.g4 index e4ad1d4b..c221b077 100644 --- a/packages/cashc/src/grammar/CashScript.g4 +++ b/packages/cashc/src/grammar/CashScript.g4 @@ -1,7 +1,7 @@ grammar CashScript; sourceFile - : pragmaDirective* contractDefinition EOF + : pragmaDirective* importDirective* topLevelDefinition* EOF ; pragmaDirective @@ -24,11 +24,24 @@ versionOperator : '^' | '~' | '>=' | '>' | '<' | '<=' | '=' ; +importDirective + : 'import' StringLiteral ';' + ; + +topLevelDefinition + : globalFunctionDefinition + | contractDefinition + ; + +globalFunctionDefinition + : 'function' Identifier parameterList ('returns' '(' typeName ')')? functionBody + ; + contractDefinition - : 'contract' Identifier parameterList '{' functionDefinition* '}' + : 'contract' Identifier parameterList '{' contractFunctionDefinition* '}' ; -functionDefinition +contractFunctionDefinition : 'function' Identifier parameterList functionBody ; @@ -60,7 +73,17 @@ nonControlStatement | assignStatement | timeOpStatement | requireStatement + | functionCallStatement | consoleStatement + | returnStatement + ; + +functionCallStatement + : functionCall + ; + +returnStatement + : 'return' expression ; controlStatement @@ -134,7 +157,7 @@ consoleParameterList ; functionCall - : Identifier expressionList // Only built-in functions are accepted + : Identifier expressionList // Built-in global functions and user-defined global functions ; expressionList diff --git a/packages/cashc/src/grammar/CashScript.interp b/packages/cashc/src/grammar/CashScript.interp index 7368b9dd..30fbbbcd 100644 --- a/packages/cashc/src/grammar/CashScript.interp +++ b/packages/cashc/src/grammar/CashScript.interp @@ -10,13 +10,16 @@ null '<' '<=' '=' +'import' +'function' +'returns' +'(' +')' 'contract' '{' '}' -'function' -'(' ',' -')' +'return' '+=' '-=' '++' @@ -145,6 +148,9 @@ null null null null +null +null +null VersionLiteral BooleanLiteral NumberUnit @@ -173,14 +179,19 @@ pragmaName pragmaValue versionConstraint versionOperator +importDirective +topLevelDefinition +globalFunctionDefinition contractDefinition -functionDefinition +contractFunctionDefinition functionBody parameterList parameter block statement nonControlStatement +functionCallStatement +returnStatement controlStatement variableDefinition tupleAssignment @@ -208,4 +219,4 @@ typeCast atn: -[4, 1, 81, 433, 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, 1, 0, 5, 0, 78, 8, 0, 10, 0, 12, 0, 81, 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, 95, 8, 3, 1, 4, 3, 4, 98, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 109, 8, 6, 10, 6, 12, 6, 112, 9, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 5, 8, 123, 8, 8, 10, 8, 12, 8, 126, 9, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 134, 8, 9, 10, 9, 12, 9, 137, 9, 9, 1, 9, 3, 9, 140, 8, 9, 3, 9, 142, 8, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 5, 11, 151, 8, 11, 10, 11, 12, 11, 154, 9, 11, 1, 11, 1, 11, 3, 11, 158, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 164, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 172, 8, 13, 1, 14, 1, 14, 3, 14, 176, 8, 14, 1, 15, 1, 15, 5, 15, 180, 8, 15, 10, 15, 12, 15, 183, 9, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 202, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 211, 8, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 3, 19, 220, 8, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 234, 8, 21, 1, 22, 1, 22, 1, 22, 3, 22, 239, 8, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 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, 25, 1, 25, 1, 25, 1, 26, 1, 26, 3, 26, 267, 8, 26, 1, 27, 1, 27, 1, 28, 1, 28, 3, 28, 273, 8, 28, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 279, 8, 29, 10, 29, 12, 29, 282, 9, 29, 1, 29, 3, 29, 285, 8, 29, 3, 29, 287, 8, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 298, 8, 31, 10, 31, 12, 31, 301, 9, 31, 1, 31, 3, 31, 304, 8, 31, 3, 31, 306, 8, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 319, 8, 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, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 345, 8, 32, 10, 32, 12, 32, 348, 9, 32, 1, 32, 3, 32, 351, 8, 32, 3, 32, 353, 8, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 359, 8, 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, 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, 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, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 411, 8, 32, 10, 32, 12, 32, 414, 9, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 423, 8, 34, 1, 35, 1, 35, 3, 35, 427, 8, 35, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 0, 1, 64, 38, 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, 64, 66, 68, 70, 72, 74, 0, 14, 1, 0, 4, 10, 2, 0, 10, 10, 18, 19, 1, 0, 20, 21, 1, 0, 33, 37, 2, 0, 33, 37, 39, 42, 2, 0, 5, 5, 47, 48, 1, 0, 49, 51, 2, 0, 48, 48, 52, 52, 1, 0, 53, 54, 1, 0, 6, 9, 1, 0, 55, 56, 1, 0, 43, 44, 1, 0, 68, 70, 2, 0, 68, 69, 76, 76, 459, 0, 79, 1, 0, 0, 0, 2, 85, 1, 0, 0, 0, 4, 90, 1, 0, 0, 0, 6, 92, 1, 0, 0, 0, 8, 97, 1, 0, 0, 0, 10, 101, 1, 0, 0, 0, 12, 103, 1, 0, 0, 0, 14, 115, 1, 0, 0, 0, 16, 120, 1, 0, 0, 0, 18, 129, 1, 0, 0, 0, 20, 145, 1, 0, 0, 0, 22, 157, 1, 0, 0, 0, 24, 163, 1, 0, 0, 0, 26, 171, 1, 0, 0, 0, 28, 175, 1, 0, 0, 0, 30, 177, 1, 0, 0, 0, 32, 188, 1, 0, 0, 0, 34, 201, 1, 0, 0, 0, 36, 203, 1, 0, 0, 0, 38, 214, 1, 0, 0, 0, 40, 223, 1, 0, 0, 0, 42, 226, 1, 0, 0, 0, 44, 238, 1, 0, 0, 0, 46, 240, 1, 0, 0, 0, 48, 248, 1, 0, 0, 0, 50, 254, 1, 0, 0, 0, 52, 266, 1, 0, 0, 0, 54, 268, 1, 0, 0, 0, 56, 272, 1, 0, 0, 0, 58, 274, 1, 0, 0, 0, 60, 290, 1, 0, 0, 0, 62, 293, 1, 0, 0, 0, 64, 358, 1, 0, 0, 0, 66, 415, 1, 0, 0, 0, 68, 422, 1, 0, 0, 0, 70, 424, 1, 0, 0, 0, 72, 428, 1, 0, 0, 0, 74, 430, 1, 0, 0, 0, 76, 78, 3, 2, 1, 0, 77, 76, 1, 0, 0, 0, 78, 81, 1, 0, 0, 0, 79, 77, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 82, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 82, 83, 3, 12, 6, 0, 83, 84, 5, 0, 0, 1, 84, 1, 1, 0, 0, 0, 85, 86, 5, 1, 0, 0, 86, 87, 3, 4, 2, 0, 87, 88, 3, 6, 3, 0, 88, 89, 5, 2, 0, 0, 89, 3, 1, 0, 0, 0, 90, 91, 5, 3, 0, 0, 91, 5, 1, 0, 0, 0, 92, 94, 3, 8, 4, 0, 93, 95, 3, 8, 4, 0, 94, 93, 1, 0, 0, 0, 94, 95, 1, 0, 0, 0, 95, 7, 1, 0, 0, 0, 96, 98, 3, 10, 5, 0, 97, 96, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 99, 1, 0, 0, 0, 99, 100, 5, 62, 0, 0, 100, 9, 1, 0, 0, 0, 101, 102, 7, 0, 0, 0, 102, 11, 1, 0, 0, 0, 103, 104, 5, 11, 0, 0, 104, 105, 5, 78, 0, 0, 105, 106, 3, 18, 9, 0, 106, 110, 5, 12, 0, 0, 107, 109, 3, 14, 7, 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, 13, 1, 0, 0, 0, 115, 116, 5, 14, 0, 0, 116, 117, 5, 78, 0, 0, 117, 118, 3, 18, 9, 0, 118, 119, 3, 16, 8, 0, 119, 15, 1, 0, 0, 0, 120, 124, 5, 12, 0, 0, 121, 123, 3, 24, 12, 0, 122, 121, 1, 0, 0, 0, 123, 126, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 124, 125, 1, 0, 0, 0, 125, 127, 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, 127, 128, 5, 13, 0, 0, 128, 17, 1, 0, 0, 0, 129, 141, 5, 15, 0, 0, 130, 135, 3, 20, 10, 0, 131, 132, 5, 16, 0, 0, 132, 134, 3, 20, 10, 0, 133, 131, 1, 0, 0, 0, 134, 137, 1, 0, 0, 0, 135, 133, 1, 0, 0, 0, 135, 136, 1, 0, 0, 0, 136, 139, 1, 0, 0, 0, 137, 135, 1, 0, 0, 0, 138, 140, 5, 16, 0, 0, 139, 138, 1, 0, 0, 0, 139, 140, 1, 0, 0, 0, 140, 142, 1, 0, 0, 0, 141, 130, 1, 0, 0, 0, 141, 142, 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 144, 5, 17, 0, 0, 144, 19, 1, 0, 0, 0, 145, 146, 3, 72, 36, 0, 146, 147, 5, 78, 0, 0, 147, 21, 1, 0, 0, 0, 148, 152, 5, 12, 0, 0, 149, 151, 3, 24, 12, 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, 158, 5, 13, 0, 0, 156, 158, 3, 24, 12, 0, 157, 148, 1, 0, 0, 0, 157, 156, 1, 0, 0, 0, 158, 23, 1, 0, 0, 0, 159, 164, 3, 28, 14, 0, 160, 161, 3, 26, 13, 0, 161, 162, 5, 2, 0, 0, 162, 164, 1, 0, 0, 0, 163, 159, 1, 0, 0, 0, 163, 160, 1, 0, 0, 0, 164, 25, 1, 0, 0, 0, 165, 172, 3, 30, 15, 0, 166, 172, 3, 32, 16, 0, 167, 172, 3, 34, 17, 0, 168, 172, 3, 36, 18, 0, 169, 172, 3, 38, 19, 0, 170, 172, 3, 40, 20, 0, 171, 165, 1, 0, 0, 0, 171, 166, 1, 0, 0, 0, 171, 167, 1, 0, 0, 0, 171, 168, 1, 0, 0, 0, 171, 169, 1, 0, 0, 0, 171, 170, 1, 0, 0, 0, 172, 27, 1, 0, 0, 0, 173, 176, 3, 42, 21, 0, 174, 176, 3, 44, 22, 0, 175, 173, 1, 0, 0, 0, 175, 174, 1, 0, 0, 0, 176, 29, 1, 0, 0, 0, 177, 181, 3, 72, 36, 0, 178, 180, 3, 66, 33, 0, 179, 178, 1, 0, 0, 0, 180, 183, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 184, 1, 0, 0, 0, 183, 181, 1, 0, 0, 0, 184, 185, 5, 78, 0, 0, 185, 186, 5, 10, 0, 0, 186, 187, 3, 64, 32, 0, 187, 31, 1, 0, 0, 0, 188, 189, 3, 72, 36, 0, 189, 190, 5, 78, 0, 0, 190, 191, 5, 16, 0, 0, 191, 192, 3, 72, 36, 0, 192, 193, 5, 78, 0, 0, 193, 194, 5, 10, 0, 0, 194, 195, 3, 64, 32, 0, 195, 33, 1, 0, 0, 0, 196, 197, 5, 78, 0, 0, 197, 198, 7, 1, 0, 0, 198, 202, 3, 64, 32, 0, 199, 200, 5, 78, 0, 0, 200, 202, 7, 2, 0, 0, 201, 196, 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 202, 35, 1, 0, 0, 0, 203, 204, 5, 22, 0, 0, 204, 205, 5, 15, 0, 0, 205, 206, 5, 75, 0, 0, 206, 207, 5, 6, 0, 0, 207, 210, 3, 64, 32, 0, 208, 209, 5, 16, 0, 0, 209, 211, 3, 54, 27, 0, 210, 208, 1, 0, 0, 0, 210, 211, 1, 0, 0, 0, 211, 212, 1, 0, 0, 0, 212, 213, 5, 17, 0, 0, 213, 37, 1, 0, 0, 0, 214, 215, 5, 22, 0, 0, 215, 216, 5, 15, 0, 0, 216, 219, 3, 64, 32, 0, 217, 218, 5, 16, 0, 0, 218, 220, 3, 54, 27, 0, 219, 217, 1, 0, 0, 0, 219, 220, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221, 222, 5, 17, 0, 0, 222, 39, 1, 0, 0, 0, 223, 224, 5, 23, 0, 0, 224, 225, 3, 58, 29, 0, 225, 41, 1, 0, 0, 0, 226, 227, 5, 24, 0, 0, 227, 228, 5, 15, 0, 0, 228, 229, 3, 64, 32, 0, 229, 230, 5, 17, 0, 0, 230, 233, 3, 22, 11, 0, 231, 232, 5, 25, 0, 0, 232, 234, 3, 22, 11, 0, 233, 231, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 43, 1, 0, 0, 0, 235, 239, 3, 46, 23, 0, 236, 239, 3, 48, 24, 0, 237, 239, 3, 50, 25, 0, 238, 235, 1, 0, 0, 0, 238, 236, 1, 0, 0, 0, 238, 237, 1, 0, 0, 0, 239, 45, 1, 0, 0, 0, 240, 241, 5, 26, 0, 0, 241, 242, 3, 22, 11, 0, 242, 243, 5, 27, 0, 0, 243, 244, 5, 15, 0, 0, 244, 245, 3, 64, 32, 0, 245, 246, 5, 17, 0, 0, 246, 247, 5, 2, 0, 0, 247, 47, 1, 0, 0, 0, 248, 249, 5, 27, 0, 0, 249, 250, 5, 15, 0, 0, 250, 251, 3, 64, 32, 0, 251, 252, 5, 17, 0, 0, 252, 253, 3, 22, 11, 0, 253, 49, 1, 0, 0, 0, 254, 255, 5, 28, 0, 0, 255, 256, 5, 15, 0, 0, 256, 257, 3, 52, 26, 0, 257, 258, 5, 2, 0, 0, 258, 259, 3, 64, 32, 0, 259, 260, 5, 2, 0, 0, 260, 261, 3, 34, 17, 0, 261, 262, 5, 17, 0, 0, 262, 263, 3, 22, 11, 0, 263, 51, 1, 0, 0, 0, 264, 267, 3, 30, 15, 0, 265, 267, 3, 34, 17, 0, 266, 264, 1, 0, 0, 0, 266, 265, 1, 0, 0, 0, 267, 53, 1, 0, 0, 0, 268, 269, 5, 72, 0, 0, 269, 55, 1, 0, 0, 0, 270, 273, 5, 78, 0, 0, 271, 273, 3, 68, 34, 0, 272, 270, 1, 0, 0, 0, 272, 271, 1, 0, 0, 0, 273, 57, 1, 0, 0, 0, 274, 286, 5, 15, 0, 0, 275, 280, 3, 56, 28, 0, 276, 277, 5, 16, 0, 0, 277, 279, 3, 56, 28, 0, 278, 276, 1, 0, 0, 0, 279, 282, 1, 0, 0, 0, 280, 278, 1, 0, 0, 0, 280, 281, 1, 0, 0, 0, 281, 284, 1, 0, 0, 0, 282, 280, 1, 0, 0, 0, 283, 285, 5, 16, 0, 0, 284, 283, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 1, 0, 0, 0, 286, 275, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 289, 5, 17, 0, 0, 289, 59, 1, 0, 0, 0, 290, 291, 5, 78, 0, 0, 291, 292, 3, 62, 31, 0, 292, 61, 1, 0, 0, 0, 293, 305, 5, 15, 0, 0, 294, 299, 3, 64, 32, 0, 295, 296, 5, 16, 0, 0, 296, 298, 3, 64, 32, 0, 297, 295, 1, 0, 0, 0, 298, 301, 1, 0, 0, 0, 299, 297, 1, 0, 0, 0, 299, 300, 1, 0, 0, 0, 300, 303, 1, 0, 0, 0, 301, 299, 1, 0, 0, 0, 302, 304, 5, 16, 0, 0, 303, 302, 1, 0, 0, 0, 303, 304, 1, 0, 0, 0, 304, 306, 1, 0, 0, 0, 305, 294, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 308, 5, 17, 0, 0, 308, 63, 1, 0, 0, 0, 309, 310, 6, 32, -1, 0, 310, 311, 5, 15, 0, 0, 311, 312, 3, 64, 32, 0, 312, 313, 5, 17, 0, 0, 313, 359, 1, 0, 0, 0, 314, 315, 3, 74, 37, 0, 315, 316, 5, 15, 0, 0, 316, 318, 3, 64, 32, 0, 317, 319, 5, 16, 0, 0, 318, 317, 1, 0, 0, 0, 318, 319, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 321, 5, 17, 0, 0, 321, 359, 1, 0, 0, 0, 322, 359, 3, 60, 30, 0, 323, 324, 5, 29, 0, 0, 324, 325, 5, 78, 0, 0, 325, 359, 3, 62, 31, 0, 326, 327, 5, 32, 0, 0, 327, 328, 5, 30, 0, 0, 328, 329, 3, 64, 32, 0, 329, 330, 5, 31, 0, 0, 330, 331, 7, 3, 0, 0, 331, 359, 1, 0, 0, 0, 332, 333, 5, 38, 0, 0, 333, 334, 5, 30, 0, 0, 334, 335, 3, 64, 32, 0, 335, 336, 5, 31, 0, 0, 336, 337, 7, 4, 0, 0, 337, 359, 1, 0, 0, 0, 338, 339, 7, 5, 0, 0, 339, 359, 3, 64, 32, 15, 340, 352, 5, 30, 0, 0, 341, 346, 3, 64, 32, 0, 342, 343, 5, 16, 0, 0, 343, 345, 3, 64, 32, 0, 344, 342, 1, 0, 0, 0, 345, 348, 1, 0, 0, 0, 346, 344, 1, 0, 0, 0, 346, 347, 1, 0, 0, 0, 347, 350, 1, 0, 0, 0, 348, 346, 1, 0, 0, 0, 349, 351, 5, 16, 0, 0, 350, 349, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 351, 353, 1, 0, 0, 0, 352, 341, 1, 0, 0, 0, 352, 353, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 359, 5, 31, 0, 0, 355, 359, 5, 77, 0, 0, 356, 359, 5, 78, 0, 0, 357, 359, 3, 68, 34, 0, 358, 309, 1, 0, 0, 0, 358, 314, 1, 0, 0, 0, 358, 322, 1, 0, 0, 0, 358, 323, 1, 0, 0, 0, 358, 326, 1, 0, 0, 0, 358, 332, 1, 0, 0, 0, 358, 338, 1, 0, 0, 0, 358, 340, 1, 0, 0, 0, 358, 355, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 358, 357, 1, 0, 0, 0, 359, 412, 1, 0, 0, 0, 360, 361, 10, 14, 0, 0, 361, 362, 7, 6, 0, 0, 362, 411, 3, 64, 32, 15, 363, 364, 10, 13, 0, 0, 364, 365, 7, 7, 0, 0, 365, 411, 3, 64, 32, 14, 366, 367, 10, 12, 0, 0, 367, 368, 7, 8, 0, 0, 368, 411, 3, 64, 32, 13, 369, 370, 10, 11, 0, 0, 370, 371, 7, 9, 0, 0, 371, 411, 3, 64, 32, 12, 372, 373, 10, 10, 0, 0, 373, 374, 7, 10, 0, 0, 374, 411, 3, 64, 32, 11, 375, 376, 10, 9, 0, 0, 376, 377, 5, 57, 0, 0, 377, 411, 3, 64, 32, 10, 378, 379, 10, 8, 0, 0, 379, 380, 5, 4, 0, 0, 380, 411, 3, 64, 32, 9, 381, 382, 10, 7, 0, 0, 382, 383, 5, 58, 0, 0, 383, 411, 3, 64, 32, 8, 384, 385, 10, 6, 0, 0, 385, 386, 5, 59, 0, 0, 386, 411, 3, 64, 32, 7, 387, 388, 10, 5, 0, 0, 388, 389, 5, 60, 0, 0, 389, 411, 3, 64, 32, 6, 390, 391, 10, 21, 0, 0, 391, 392, 5, 30, 0, 0, 392, 393, 5, 65, 0, 0, 393, 411, 5, 31, 0, 0, 394, 395, 10, 18, 0, 0, 395, 411, 7, 11, 0, 0, 396, 397, 10, 17, 0, 0, 397, 398, 5, 45, 0, 0, 398, 399, 5, 15, 0, 0, 399, 400, 3, 64, 32, 0, 400, 401, 5, 17, 0, 0, 401, 411, 1, 0, 0, 0, 402, 403, 10, 16, 0, 0, 403, 404, 5, 46, 0, 0, 404, 405, 5, 15, 0, 0, 405, 406, 3, 64, 32, 0, 406, 407, 5, 16, 0, 0, 407, 408, 3, 64, 32, 0, 408, 409, 5, 17, 0, 0, 409, 411, 1, 0, 0, 0, 410, 360, 1, 0, 0, 0, 410, 363, 1, 0, 0, 0, 410, 366, 1, 0, 0, 0, 410, 369, 1, 0, 0, 0, 410, 372, 1, 0, 0, 0, 410, 375, 1, 0, 0, 0, 410, 378, 1, 0, 0, 0, 410, 381, 1, 0, 0, 0, 410, 384, 1, 0, 0, 0, 410, 387, 1, 0, 0, 0, 410, 390, 1, 0, 0, 0, 410, 394, 1, 0, 0, 0, 410, 396, 1, 0, 0, 0, 410, 402, 1, 0, 0, 0, 411, 414, 1, 0, 0, 0, 412, 410, 1, 0, 0, 0, 412, 413, 1, 0, 0, 0, 413, 65, 1, 0, 0, 0, 414, 412, 1, 0, 0, 0, 415, 416, 5, 61, 0, 0, 416, 67, 1, 0, 0, 0, 417, 423, 5, 63, 0, 0, 418, 423, 3, 70, 35, 0, 419, 423, 5, 72, 0, 0, 420, 423, 5, 73, 0, 0, 421, 423, 5, 74, 0, 0, 422, 417, 1, 0, 0, 0, 422, 418, 1, 0, 0, 0, 422, 419, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 422, 421, 1, 0, 0, 0, 423, 69, 1, 0, 0, 0, 424, 426, 5, 65, 0, 0, 425, 427, 5, 64, 0, 0, 426, 425, 1, 0, 0, 0, 426, 427, 1, 0, 0, 0, 427, 71, 1, 0, 0, 0, 428, 429, 7, 12, 0, 0, 429, 73, 1, 0, 0, 0, 430, 431, 7, 13, 0, 0, 431, 75, 1, 0, 0, 0, 36, 79, 94, 97, 110, 124, 135, 139, 141, 152, 157, 163, 171, 175, 181, 201, 210, 219, 233, 238, 266, 272, 280, 284, 286, 299, 303, 305, 318, 346, 350, 352, 358, 410, 412, 422, 426] \ No newline at end of file +[4, 1, 84, 481, 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, 1, 0, 5, 0, 88, 8, 0, 10, 0, 12, 0, 91, 9, 0, 1, 0, 5, 0, 94, 8, 0, 10, 0, 12, 0, 97, 9, 0, 1, 0, 5, 0, 100, 8, 0, 10, 0, 12, 0, 103, 9, 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, 116, 8, 3, 1, 4, 3, 4, 119, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 3, 7, 131, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 141, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 150, 8, 9, 10, 9, 12, 9, 153, 9, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 5, 11, 164, 8, 11, 10, 11, 12, 11, 167, 9, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 5, 12, 175, 8, 12, 10, 12, 12, 12, 178, 9, 12, 1, 12, 3, 12, 181, 8, 12, 3, 12, 183, 8, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 5, 14, 192, 8, 14, 10, 14, 12, 14, 195, 9, 14, 1, 14, 1, 14, 3, 14, 199, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 205, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 215, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 3, 19, 224, 8, 19, 1, 20, 1, 20, 5, 20, 228, 8, 20, 10, 20, 12, 20, 231, 9, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 3, 22, 250, 8, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 259, 8, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 268, 8, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 282, 8, 26, 1, 27, 1, 27, 1, 27, 3, 27, 287, 8, 27, 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, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 3, 31, 315, 8, 31, 1, 32, 1, 32, 1, 33, 1, 33, 3, 33, 321, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 5, 34, 327, 8, 34, 10, 34, 12, 34, 330, 9, 34, 1, 34, 3, 34, 333, 8, 34, 3, 34, 335, 8, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 346, 8, 36, 10, 36, 12, 36, 349, 9, 36, 1, 36, 3, 36, 352, 8, 36, 3, 36, 354, 8, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 367, 8, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 393, 8, 37, 10, 37, 12, 37, 396, 9, 37, 1, 37, 3, 37, 399, 8, 37, 3, 37, 401, 8, 37, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 407, 8, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 459, 8, 37, 10, 37, 12, 37, 462, 9, 37, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 471, 8, 39, 1, 40, 1, 40, 3, 40, 475, 8, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 0, 1, 74, 43, 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, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 0, 14, 1, 0, 4, 10, 2, 0, 10, 10, 21, 22, 1, 0, 23, 24, 1, 0, 36, 40, 2, 0, 36, 40, 42, 45, 2, 0, 5, 5, 50, 51, 1, 0, 52, 54, 2, 0, 51, 51, 55, 55, 1, 0, 56, 57, 1, 0, 6, 9, 1, 0, 58, 59, 1, 0, 46, 47, 1, 0, 71, 73, 2, 0, 71, 72, 79, 79, 508, 0, 89, 1, 0, 0, 0, 2, 106, 1, 0, 0, 0, 4, 111, 1, 0, 0, 0, 6, 113, 1, 0, 0, 0, 8, 118, 1, 0, 0, 0, 10, 122, 1, 0, 0, 0, 12, 124, 1, 0, 0, 0, 14, 130, 1, 0, 0, 0, 16, 132, 1, 0, 0, 0, 18, 144, 1, 0, 0, 0, 20, 156, 1, 0, 0, 0, 22, 161, 1, 0, 0, 0, 24, 170, 1, 0, 0, 0, 26, 186, 1, 0, 0, 0, 28, 198, 1, 0, 0, 0, 30, 204, 1, 0, 0, 0, 32, 214, 1, 0, 0, 0, 34, 216, 1, 0, 0, 0, 36, 218, 1, 0, 0, 0, 38, 223, 1, 0, 0, 0, 40, 225, 1, 0, 0, 0, 42, 236, 1, 0, 0, 0, 44, 249, 1, 0, 0, 0, 46, 251, 1, 0, 0, 0, 48, 262, 1, 0, 0, 0, 50, 271, 1, 0, 0, 0, 52, 274, 1, 0, 0, 0, 54, 286, 1, 0, 0, 0, 56, 288, 1, 0, 0, 0, 58, 296, 1, 0, 0, 0, 60, 302, 1, 0, 0, 0, 62, 314, 1, 0, 0, 0, 64, 316, 1, 0, 0, 0, 66, 320, 1, 0, 0, 0, 68, 322, 1, 0, 0, 0, 70, 338, 1, 0, 0, 0, 72, 341, 1, 0, 0, 0, 74, 406, 1, 0, 0, 0, 76, 463, 1, 0, 0, 0, 78, 470, 1, 0, 0, 0, 80, 472, 1, 0, 0, 0, 82, 476, 1, 0, 0, 0, 84, 478, 1, 0, 0, 0, 86, 88, 3, 2, 1, 0, 87, 86, 1, 0, 0, 0, 88, 91, 1, 0, 0, 0, 89, 87, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 95, 1, 0, 0, 0, 91, 89, 1, 0, 0, 0, 92, 94, 3, 12, 6, 0, 93, 92, 1, 0, 0, 0, 94, 97, 1, 0, 0, 0, 95, 93, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 101, 1, 0, 0, 0, 97, 95, 1, 0, 0, 0, 98, 100, 3, 14, 7, 0, 99, 98, 1, 0, 0, 0, 100, 103, 1, 0, 0, 0, 101, 99, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 104, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 104, 105, 5, 0, 0, 1, 105, 1, 1, 0, 0, 0, 106, 107, 5, 1, 0, 0, 107, 108, 3, 4, 2, 0, 108, 109, 3, 6, 3, 0, 109, 110, 5, 2, 0, 0, 110, 3, 1, 0, 0, 0, 111, 112, 5, 3, 0, 0, 112, 5, 1, 0, 0, 0, 113, 115, 3, 8, 4, 0, 114, 116, 3, 8, 4, 0, 115, 114, 1, 0, 0, 0, 115, 116, 1, 0, 0, 0, 116, 7, 1, 0, 0, 0, 117, 119, 3, 10, 5, 0, 118, 117, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 120, 121, 5, 65, 0, 0, 121, 9, 1, 0, 0, 0, 122, 123, 7, 0, 0, 0, 123, 11, 1, 0, 0, 0, 124, 125, 5, 11, 0, 0, 125, 126, 5, 75, 0, 0, 126, 127, 5, 2, 0, 0, 127, 13, 1, 0, 0, 0, 128, 131, 3, 16, 8, 0, 129, 131, 3, 18, 9, 0, 130, 128, 1, 0, 0, 0, 130, 129, 1, 0, 0, 0, 131, 15, 1, 0, 0, 0, 132, 133, 5, 12, 0, 0, 133, 134, 5, 81, 0, 0, 134, 140, 3, 24, 12, 0, 135, 136, 5, 13, 0, 0, 136, 137, 5, 14, 0, 0, 137, 138, 3, 82, 41, 0, 138, 139, 5, 15, 0, 0, 139, 141, 1, 0, 0, 0, 140, 135, 1, 0, 0, 0, 140, 141, 1, 0, 0, 0, 141, 142, 1, 0, 0, 0, 142, 143, 3, 22, 11, 0, 143, 17, 1, 0, 0, 0, 144, 145, 5, 16, 0, 0, 145, 146, 5, 81, 0, 0, 146, 147, 3, 24, 12, 0, 147, 151, 5, 17, 0, 0, 148, 150, 3, 20, 10, 0, 149, 148, 1, 0, 0, 0, 150, 153, 1, 0, 0, 0, 151, 149, 1, 0, 0, 0, 151, 152, 1, 0, 0, 0, 152, 154, 1, 0, 0, 0, 153, 151, 1, 0, 0, 0, 154, 155, 5, 18, 0, 0, 155, 19, 1, 0, 0, 0, 156, 157, 5, 12, 0, 0, 157, 158, 5, 81, 0, 0, 158, 159, 3, 24, 12, 0, 159, 160, 3, 22, 11, 0, 160, 21, 1, 0, 0, 0, 161, 165, 5, 17, 0, 0, 162, 164, 3, 30, 15, 0, 163, 162, 1, 0, 0, 0, 164, 167, 1, 0, 0, 0, 165, 163, 1, 0, 0, 0, 165, 166, 1, 0, 0, 0, 166, 168, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 168, 169, 5, 18, 0, 0, 169, 23, 1, 0, 0, 0, 170, 182, 5, 14, 0, 0, 171, 176, 3, 26, 13, 0, 172, 173, 5, 19, 0, 0, 173, 175, 3, 26, 13, 0, 174, 172, 1, 0, 0, 0, 175, 178, 1, 0, 0, 0, 176, 174, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 180, 1, 0, 0, 0, 178, 176, 1, 0, 0, 0, 179, 181, 5, 19, 0, 0, 180, 179, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 183, 1, 0, 0, 0, 182, 171, 1, 0, 0, 0, 182, 183, 1, 0, 0, 0, 183, 184, 1, 0, 0, 0, 184, 185, 5, 15, 0, 0, 185, 25, 1, 0, 0, 0, 186, 187, 3, 82, 41, 0, 187, 188, 5, 81, 0, 0, 188, 27, 1, 0, 0, 0, 189, 193, 5, 17, 0, 0, 190, 192, 3, 30, 15, 0, 191, 190, 1, 0, 0, 0, 192, 195, 1, 0, 0, 0, 193, 191, 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, 194, 196, 1, 0, 0, 0, 195, 193, 1, 0, 0, 0, 196, 199, 5, 18, 0, 0, 197, 199, 3, 30, 15, 0, 198, 189, 1, 0, 0, 0, 198, 197, 1, 0, 0, 0, 199, 29, 1, 0, 0, 0, 200, 205, 3, 38, 19, 0, 201, 202, 3, 32, 16, 0, 202, 203, 5, 2, 0, 0, 203, 205, 1, 0, 0, 0, 204, 200, 1, 0, 0, 0, 204, 201, 1, 0, 0, 0, 205, 31, 1, 0, 0, 0, 206, 215, 3, 40, 20, 0, 207, 215, 3, 42, 21, 0, 208, 215, 3, 44, 22, 0, 209, 215, 3, 46, 23, 0, 210, 215, 3, 48, 24, 0, 211, 215, 3, 34, 17, 0, 212, 215, 3, 50, 25, 0, 213, 215, 3, 36, 18, 0, 214, 206, 1, 0, 0, 0, 214, 207, 1, 0, 0, 0, 214, 208, 1, 0, 0, 0, 214, 209, 1, 0, 0, 0, 214, 210, 1, 0, 0, 0, 214, 211, 1, 0, 0, 0, 214, 212, 1, 0, 0, 0, 214, 213, 1, 0, 0, 0, 215, 33, 1, 0, 0, 0, 216, 217, 3, 70, 35, 0, 217, 35, 1, 0, 0, 0, 218, 219, 5, 20, 0, 0, 219, 220, 3, 74, 37, 0, 220, 37, 1, 0, 0, 0, 221, 224, 3, 52, 26, 0, 222, 224, 3, 54, 27, 0, 223, 221, 1, 0, 0, 0, 223, 222, 1, 0, 0, 0, 224, 39, 1, 0, 0, 0, 225, 229, 3, 82, 41, 0, 226, 228, 3, 76, 38, 0, 227, 226, 1, 0, 0, 0, 228, 231, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 230, 232, 1, 0, 0, 0, 231, 229, 1, 0, 0, 0, 232, 233, 5, 81, 0, 0, 233, 234, 5, 10, 0, 0, 234, 235, 3, 74, 37, 0, 235, 41, 1, 0, 0, 0, 236, 237, 3, 82, 41, 0, 237, 238, 5, 81, 0, 0, 238, 239, 5, 19, 0, 0, 239, 240, 3, 82, 41, 0, 240, 241, 5, 81, 0, 0, 241, 242, 5, 10, 0, 0, 242, 243, 3, 74, 37, 0, 243, 43, 1, 0, 0, 0, 244, 245, 5, 81, 0, 0, 245, 246, 7, 1, 0, 0, 246, 250, 3, 74, 37, 0, 247, 248, 5, 81, 0, 0, 248, 250, 7, 2, 0, 0, 249, 244, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 250, 45, 1, 0, 0, 0, 251, 252, 5, 25, 0, 0, 252, 253, 5, 14, 0, 0, 253, 254, 5, 78, 0, 0, 254, 255, 5, 6, 0, 0, 255, 258, 3, 74, 37, 0, 256, 257, 5, 19, 0, 0, 257, 259, 3, 64, 32, 0, 258, 256, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 260, 1, 0, 0, 0, 260, 261, 5, 15, 0, 0, 261, 47, 1, 0, 0, 0, 262, 263, 5, 25, 0, 0, 263, 264, 5, 14, 0, 0, 264, 267, 3, 74, 37, 0, 265, 266, 5, 19, 0, 0, 266, 268, 3, 64, 32, 0, 267, 265, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 270, 5, 15, 0, 0, 270, 49, 1, 0, 0, 0, 271, 272, 5, 26, 0, 0, 272, 273, 3, 68, 34, 0, 273, 51, 1, 0, 0, 0, 274, 275, 5, 27, 0, 0, 275, 276, 5, 14, 0, 0, 276, 277, 3, 74, 37, 0, 277, 278, 5, 15, 0, 0, 278, 281, 3, 28, 14, 0, 279, 280, 5, 28, 0, 0, 280, 282, 3, 28, 14, 0, 281, 279, 1, 0, 0, 0, 281, 282, 1, 0, 0, 0, 282, 53, 1, 0, 0, 0, 283, 287, 3, 56, 28, 0, 284, 287, 3, 58, 29, 0, 285, 287, 3, 60, 30, 0, 286, 283, 1, 0, 0, 0, 286, 284, 1, 0, 0, 0, 286, 285, 1, 0, 0, 0, 287, 55, 1, 0, 0, 0, 288, 289, 5, 29, 0, 0, 289, 290, 3, 28, 14, 0, 290, 291, 5, 30, 0, 0, 291, 292, 5, 14, 0, 0, 292, 293, 3, 74, 37, 0, 293, 294, 5, 15, 0, 0, 294, 295, 5, 2, 0, 0, 295, 57, 1, 0, 0, 0, 296, 297, 5, 30, 0, 0, 297, 298, 5, 14, 0, 0, 298, 299, 3, 74, 37, 0, 299, 300, 5, 15, 0, 0, 300, 301, 3, 28, 14, 0, 301, 59, 1, 0, 0, 0, 302, 303, 5, 31, 0, 0, 303, 304, 5, 14, 0, 0, 304, 305, 3, 62, 31, 0, 305, 306, 5, 2, 0, 0, 306, 307, 3, 74, 37, 0, 307, 308, 5, 2, 0, 0, 308, 309, 3, 44, 22, 0, 309, 310, 5, 15, 0, 0, 310, 311, 3, 28, 14, 0, 311, 61, 1, 0, 0, 0, 312, 315, 3, 40, 20, 0, 313, 315, 3, 44, 22, 0, 314, 312, 1, 0, 0, 0, 314, 313, 1, 0, 0, 0, 315, 63, 1, 0, 0, 0, 316, 317, 5, 75, 0, 0, 317, 65, 1, 0, 0, 0, 318, 321, 5, 81, 0, 0, 319, 321, 3, 78, 39, 0, 320, 318, 1, 0, 0, 0, 320, 319, 1, 0, 0, 0, 321, 67, 1, 0, 0, 0, 322, 334, 5, 14, 0, 0, 323, 328, 3, 66, 33, 0, 324, 325, 5, 19, 0, 0, 325, 327, 3, 66, 33, 0, 326, 324, 1, 0, 0, 0, 327, 330, 1, 0, 0, 0, 328, 326, 1, 0, 0, 0, 328, 329, 1, 0, 0, 0, 329, 332, 1, 0, 0, 0, 330, 328, 1, 0, 0, 0, 331, 333, 5, 19, 0, 0, 332, 331, 1, 0, 0, 0, 332, 333, 1, 0, 0, 0, 333, 335, 1, 0, 0, 0, 334, 323, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 336, 1, 0, 0, 0, 336, 337, 5, 15, 0, 0, 337, 69, 1, 0, 0, 0, 338, 339, 5, 81, 0, 0, 339, 340, 3, 72, 36, 0, 340, 71, 1, 0, 0, 0, 341, 353, 5, 14, 0, 0, 342, 347, 3, 74, 37, 0, 343, 344, 5, 19, 0, 0, 344, 346, 3, 74, 37, 0, 345, 343, 1, 0, 0, 0, 346, 349, 1, 0, 0, 0, 347, 345, 1, 0, 0, 0, 347, 348, 1, 0, 0, 0, 348, 351, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 350, 352, 5, 19, 0, 0, 351, 350, 1, 0, 0, 0, 351, 352, 1, 0, 0, 0, 352, 354, 1, 0, 0, 0, 353, 342, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 355, 1, 0, 0, 0, 355, 356, 5, 15, 0, 0, 356, 73, 1, 0, 0, 0, 357, 358, 6, 37, -1, 0, 358, 359, 5, 14, 0, 0, 359, 360, 3, 74, 37, 0, 360, 361, 5, 15, 0, 0, 361, 407, 1, 0, 0, 0, 362, 363, 3, 84, 42, 0, 363, 364, 5, 14, 0, 0, 364, 366, 3, 74, 37, 0, 365, 367, 5, 19, 0, 0, 366, 365, 1, 0, 0, 0, 366, 367, 1, 0, 0, 0, 367, 368, 1, 0, 0, 0, 368, 369, 5, 15, 0, 0, 369, 407, 1, 0, 0, 0, 370, 407, 3, 70, 35, 0, 371, 372, 5, 32, 0, 0, 372, 373, 5, 81, 0, 0, 373, 407, 3, 72, 36, 0, 374, 375, 5, 35, 0, 0, 375, 376, 5, 33, 0, 0, 376, 377, 3, 74, 37, 0, 377, 378, 5, 34, 0, 0, 378, 379, 7, 3, 0, 0, 379, 407, 1, 0, 0, 0, 380, 381, 5, 41, 0, 0, 381, 382, 5, 33, 0, 0, 382, 383, 3, 74, 37, 0, 383, 384, 5, 34, 0, 0, 384, 385, 7, 4, 0, 0, 385, 407, 1, 0, 0, 0, 386, 387, 7, 5, 0, 0, 387, 407, 3, 74, 37, 15, 388, 400, 5, 33, 0, 0, 389, 394, 3, 74, 37, 0, 390, 391, 5, 19, 0, 0, 391, 393, 3, 74, 37, 0, 392, 390, 1, 0, 0, 0, 393, 396, 1, 0, 0, 0, 394, 392, 1, 0, 0, 0, 394, 395, 1, 0, 0, 0, 395, 398, 1, 0, 0, 0, 396, 394, 1, 0, 0, 0, 397, 399, 5, 19, 0, 0, 398, 397, 1, 0, 0, 0, 398, 399, 1, 0, 0, 0, 399, 401, 1, 0, 0, 0, 400, 389, 1, 0, 0, 0, 400, 401, 1, 0, 0, 0, 401, 402, 1, 0, 0, 0, 402, 407, 5, 34, 0, 0, 403, 407, 5, 80, 0, 0, 404, 407, 5, 81, 0, 0, 405, 407, 3, 78, 39, 0, 406, 357, 1, 0, 0, 0, 406, 362, 1, 0, 0, 0, 406, 370, 1, 0, 0, 0, 406, 371, 1, 0, 0, 0, 406, 374, 1, 0, 0, 0, 406, 380, 1, 0, 0, 0, 406, 386, 1, 0, 0, 0, 406, 388, 1, 0, 0, 0, 406, 403, 1, 0, 0, 0, 406, 404, 1, 0, 0, 0, 406, 405, 1, 0, 0, 0, 407, 460, 1, 0, 0, 0, 408, 409, 10, 14, 0, 0, 409, 410, 7, 6, 0, 0, 410, 459, 3, 74, 37, 15, 411, 412, 10, 13, 0, 0, 412, 413, 7, 7, 0, 0, 413, 459, 3, 74, 37, 14, 414, 415, 10, 12, 0, 0, 415, 416, 7, 8, 0, 0, 416, 459, 3, 74, 37, 13, 417, 418, 10, 11, 0, 0, 418, 419, 7, 9, 0, 0, 419, 459, 3, 74, 37, 12, 420, 421, 10, 10, 0, 0, 421, 422, 7, 10, 0, 0, 422, 459, 3, 74, 37, 11, 423, 424, 10, 9, 0, 0, 424, 425, 5, 60, 0, 0, 425, 459, 3, 74, 37, 10, 426, 427, 10, 8, 0, 0, 427, 428, 5, 4, 0, 0, 428, 459, 3, 74, 37, 9, 429, 430, 10, 7, 0, 0, 430, 431, 5, 61, 0, 0, 431, 459, 3, 74, 37, 8, 432, 433, 10, 6, 0, 0, 433, 434, 5, 62, 0, 0, 434, 459, 3, 74, 37, 7, 435, 436, 10, 5, 0, 0, 436, 437, 5, 63, 0, 0, 437, 459, 3, 74, 37, 6, 438, 439, 10, 21, 0, 0, 439, 440, 5, 33, 0, 0, 440, 441, 5, 68, 0, 0, 441, 459, 5, 34, 0, 0, 442, 443, 10, 18, 0, 0, 443, 459, 7, 11, 0, 0, 444, 445, 10, 17, 0, 0, 445, 446, 5, 48, 0, 0, 446, 447, 5, 14, 0, 0, 447, 448, 3, 74, 37, 0, 448, 449, 5, 15, 0, 0, 449, 459, 1, 0, 0, 0, 450, 451, 10, 16, 0, 0, 451, 452, 5, 49, 0, 0, 452, 453, 5, 14, 0, 0, 453, 454, 3, 74, 37, 0, 454, 455, 5, 19, 0, 0, 455, 456, 3, 74, 37, 0, 456, 457, 5, 15, 0, 0, 457, 459, 1, 0, 0, 0, 458, 408, 1, 0, 0, 0, 458, 411, 1, 0, 0, 0, 458, 414, 1, 0, 0, 0, 458, 417, 1, 0, 0, 0, 458, 420, 1, 0, 0, 0, 458, 423, 1, 0, 0, 0, 458, 426, 1, 0, 0, 0, 458, 429, 1, 0, 0, 0, 458, 432, 1, 0, 0, 0, 458, 435, 1, 0, 0, 0, 458, 438, 1, 0, 0, 0, 458, 442, 1, 0, 0, 0, 458, 444, 1, 0, 0, 0, 458, 450, 1, 0, 0, 0, 459, 462, 1, 0, 0, 0, 460, 458, 1, 0, 0, 0, 460, 461, 1, 0, 0, 0, 461, 75, 1, 0, 0, 0, 462, 460, 1, 0, 0, 0, 463, 464, 5, 64, 0, 0, 464, 77, 1, 0, 0, 0, 465, 471, 5, 66, 0, 0, 466, 471, 3, 80, 40, 0, 467, 471, 5, 75, 0, 0, 468, 471, 5, 76, 0, 0, 469, 471, 5, 77, 0, 0, 470, 465, 1, 0, 0, 0, 470, 466, 1, 0, 0, 0, 470, 467, 1, 0, 0, 0, 470, 468, 1, 0, 0, 0, 470, 469, 1, 0, 0, 0, 471, 79, 1, 0, 0, 0, 472, 474, 5, 68, 0, 0, 473, 475, 5, 67, 0, 0, 474, 473, 1, 0, 0, 0, 474, 475, 1, 0, 0, 0, 475, 81, 1, 0, 0, 0, 476, 477, 7, 12, 0, 0, 477, 83, 1, 0, 0, 0, 478, 479, 7, 13, 0, 0, 479, 85, 1, 0, 0, 0, 40, 89, 95, 101, 115, 118, 130, 140, 151, 165, 176, 180, 182, 193, 198, 204, 214, 223, 229, 249, 258, 267, 281, 286, 314, 320, 328, 332, 334, 347, 351, 353, 366, 394, 398, 400, 406, 458, 460, 470, 474] \ No newline at end of file diff --git a/packages/cashc/src/grammar/CashScript.tokens b/packages/cashc/src/grammar/CashScript.tokens index b9cfb61b..16dc361d 100644 --- a/packages/cashc/src/grammar/CashScript.tokens +++ b/packages/cashc/src/grammar/CashScript.tokens @@ -59,26 +59,29 @@ T__57=58 T__58=59 T__59=60 T__60=61 -VersionLiteral=62 -BooleanLiteral=63 -NumberUnit=64 -NumberLiteral=65 -NumberPart=66 -ExponentPart=67 -PrimitiveType=68 -UnboundedBytes=69 -BoundedBytes=70 -Bound=71 -StringLiteral=72 -DateLiteral=73 -HexLiteral=74 -TxVar=75 -UnsafeCast=76 -NullaryOp=77 -Identifier=78 -WHITESPACE=79 -COMMENT=80 -LINE_COMMENT=81 +T__61=62 +T__62=63 +T__63=64 +VersionLiteral=65 +BooleanLiteral=66 +NumberUnit=67 +NumberLiteral=68 +NumberPart=69 +ExponentPart=70 +PrimitiveType=71 +UnboundedBytes=72 +BoundedBytes=73 +Bound=74 +StringLiteral=75 +DateLiteral=76 +HexLiteral=77 +TxVar=78 +UnsafeCast=79 +NullaryOp=80 +Identifier=81 +WHITESPACE=82 +COMMENT=83 +LINE_COMMENT=84 'pragma'=1 ';'=2 'cashscript'=3 @@ -89,55 +92,58 @@ LINE_COMMENT=81 '<'=8 '<='=9 '='=10 -'contract'=11 -'{'=12 -'}'=13 -'function'=14 -'('=15 -','=16 -')'=17 -'+='=18 -'-='=19 -'++'=20 -'--'=21 -'require'=22 -'console.log'=23 -'if'=24 -'else'=25 -'do'=26 -'while'=27 -'for'=28 -'new'=29 -'['=30 -']'=31 -'tx.outputs'=32 -'.value'=33 -'.lockingBytecode'=34 -'.tokenCategory'=35 -'.nftCommitment'=36 -'.tokenAmount'=37 -'tx.inputs'=38 -'.outpointTransactionHash'=39 -'.outpointIndex'=40 -'.unlockingBytecode'=41 -'.sequenceNumber'=42 -'.reverse()'=43 -'.length'=44 -'.split'=45 -'.slice'=46 -'!'=47 -'-'=48 -'*'=49 -'/'=50 -'%'=51 -'+'=52 -'>>'=53 -'<<'=54 -'=='=55 -'!='=56 -'&'=57 -'|'=58 -'&&'=59 -'||'=60 -'constant'=61 -'bytes'=69 +'import'=11 +'function'=12 +'returns'=13 +'('=14 +')'=15 +'contract'=16 +'{'=17 +'}'=18 +','=19 +'return'=20 +'+='=21 +'-='=22 +'++'=23 +'--'=24 +'require'=25 +'console.log'=26 +'if'=27 +'else'=28 +'do'=29 +'while'=30 +'for'=31 +'new'=32 +'['=33 +']'=34 +'tx.outputs'=35 +'.value'=36 +'.lockingBytecode'=37 +'.tokenCategory'=38 +'.nftCommitment'=39 +'.tokenAmount'=40 +'tx.inputs'=41 +'.outpointTransactionHash'=42 +'.outpointIndex'=43 +'.unlockingBytecode'=44 +'.sequenceNumber'=45 +'.reverse()'=46 +'.length'=47 +'.split'=48 +'.slice'=49 +'!'=50 +'-'=51 +'*'=52 +'/'=53 +'%'=54 +'+'=55 +'>>'=56 +'<<'=57 +'=='=58 +'!='=59 +'&'=60 +'|'=61 +'&&'=62 +'||'=63 +'constant'=64 +'bytes'=72 diff --git a/packages/cashc/src/grammar/CashScriptLexer.interp b/packages/cashc/src/grammar/CashScriptLexer.interp index e2bb72fc..d394bd0e 100644 --- a/packages/cashc/src/grammar/CashScriptLexer.interp +++ b/packages/cashc/src/grammar/CashScriptLexer.interp @@ -10,13 +10,16 @@ null '<' '<=' '=' +'import' +'function' +'returns' +'(' +')' 'contract' '{' '}' -'function' -'(' ',' -')' +'return' '+=' '-=' '++' @@ -145,6 +148,9 @@ null null null null +null +null +null VersionLiteral BooleanLiteral NumberUnit @@ -228,6 +234,9 @@ T__57 T__58 T__59 T__60 +T__61 +T__62 +T__63 VersionLiteral BooleanLiteral NumberUnit @@ -257,4 +266,4 @@ mode names: DEFAULT_MODE atn: -[4, 0, 81, 938, 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, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 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, 18, 1, 18, 1, 18, 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, 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, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 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, 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, 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, 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, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 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, 39, 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, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 4, 61, 529, 8, 61, 11, 61, 12, 61, 530, 1, 61, 1, 61, 4, 61, 535, 8, 61, 11, 61, 12, 61, 536, 1, 61, 1, 61, 4, 61, 541, 8, 61, 11, 61, 12, 61, 542, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 554, 8, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 613, 8, 63, 1, 64, 3, 64, 616, 8, 64, 1, 64, 1, 64, 3, 64, 620, 8, 64, 1, 65, 4, 65, 623, 8, 65, 11, 65, 12, 65, 624, 1, 65, 1, 65, 4, 65, 629, 8, 65, 11, 65, 12, 65, 630, 5, 65, 633, 8, 65, 10, 65, 12, 65, 636, 9, 65, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 670, 8, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 3, 69, 689, 8, 69, 1, 70, 1, 70, 5, 70, 693, 8, 70, 10, 70, 12, 70, 696, 9, 70, 1, 71, 1, 71, 1, 71, 1, 71, 5, 71, 702, 8, 71, 10, 71, 12, 71, 705, 9, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 5, 71, 712, 8, 71, 10, 71, 12, 71, 715, 9, 71, 1, 71, 3, 71, 718, 8, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 5, 73, 732, 8, 73, 10, 73, 12, 73, 735, 9, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 752, 8, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 3, 75, 789, 8, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 3, 75, 802, 8, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 3, 76, 898, 8, 76, 1, 77, 1, 77, 5, 77, 902, 8, 77, 10, 77, 12, 77, 905, 9, 77, 1, 78, 4, 78, 908, 8, 78, 11, 78, 12, 78, 909, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 5, 79, 918, 8, 79, 10, 79, 12, 79, 921, 9, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 5, 80, 932, 8, 80, 10, 80, 12, 80, 935, 9, 80, 1, 80, 1, 80, 3, 703, 713, 919, 0, 81, 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, 153, 77, 155, 78, 157, 79, 159, 80, 161, 81, 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, 982, 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, 0, 153, 1, 0, 0, 0, 0, 155, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 159, 1, 0, 0, 0, 0, 161, 1, 0, 0, 0, 1, 163, 1, 0, 0, 0, 3, 170, 1, 0, 0, 0, 5, 172, 1, 0, 0, 0, 7, 183, 1, 0, 0, 0, 9, 185, 1, 0, 0, 0, 11, 187, 1, 0, 0, 0, 13, 190, 1, 0, 0, 0, 15, 192, 1, 0, 0, 0, 17, 194, 1, 0, 0, 0, 19, 197, 1, 0, 0, 0, 21, 199, 1, 0, 0, 0, 23, 208, 1, 0, 0, 0, 25, 210, 1, 0, 0, 0, 27, 212, 1, 0, 0, 0, 29, 221, 1, 0, 0, 0, 31, 223, 1, 0, 0, 0, 33, 225, 1, 0, 0, 0, 35, 227, 1, 0, 0, 0, 37, 230, 1, 0, 0, 0, 39, 233, 1, 0, 0, 0, 41, 236, 1, 0, 0, 0, 43, 239, 1, 0, 0, 0, 45, 247, 1, 0, 0, 0, 47, 259, 1, 0, 0, 0, 49, 262, 1, 0, 0, 0, 51, 267, 1, 0, 0, 0, 53, 270, 1, 0, 0, 0, 55, 276, 1, 0, 0, 0, 57, 280, 1, 0, 0, 0, 59, 284, 1, 0, 0, 0, 61, 286, 1, 0, 0, 0, 63, 288, 1, 0, 0, 0, 65, 299, 1, 0, 0, 0, 67, 306, 1, 0, 0, 0, 69, 323, 1, 0, 0, 0, 71, 338, 1, 0, 0, 0, 73, 353, 1, 0, 0, 0, 75, 366, 1, 0, 0, 0, 77, 376, 1, 0, 0, 0, 79, 401, 1, 0, 0, 0, 81, 416, 1, 0, 0, 0, 83, 435, 1, 0, 0, 0, 85, 451, 1, 0, 0, 0, 87, 462, 1, 0, 0, 0, 89, 470, 1, 0, 0, 0, 91, 477, 1, 0, 0, 0, 93, 484, 1, 0, 0, 0, 95, 486, 1, 0, 0, 0, 97, 488, 1, 0, 0, 0, 99, 490, 1, 0, 0, 0, 101, 492, 1, 0, 0, 0, 103, 494, 1, 0, 0, 0, 105, 496, 1, 0, 0, 0, 107, 499, 1, 0, 0, 0, 109, 502, 1, 0, 0, 0, 111, 505, 1, 0, 0, 0, 113, 508, 1, 0, 0, 0, 115, 510, 1, 0, 0, 0, 117, 512, 1, 0, 0, 0, 119, 515, 1, 0, 0, 0, 121, 518, 1, 0, 0, 0, 123, 528, 1, 0, 0, 0, 125, 553, 1, 0, 0, 0, 127, 612, 1, 0, 0, 0, 129, 615, 1, 0, 0, 0, 131, 622, 1, 0, 0, 0, 133, 637, 1, 0, 0, 0, 135, 669, 1, 0, 0, 0, 137, 671, 1, 0, 0, 0, 139, 688, 1, 0, 0, 0, 141, 690, 1, 0, 0, 0, 143, 717, 1, 0, 0, 0, 145, 719, 1, 0, 0, 0, 147, 728, 1, 0, 0, 0, 149, 751, 1, 0, 0, 0, 151, 801, 1, 0, 0, 0, 153, 897, 1, 0, 0, 0, 155, 899, 1, 0, 0, 0, 157, 907, 1, 0, 0, 0, 159, 913, 1, 0, 0, 0, 161, 927, 1, 0, 0, 0, 163, 164, 5, 112, 0, 0, 164, 165, 5, 114, 0, 0, 165, 166, 5, 97, 0, 0, 166, 167, 5, 103, 0, 0, 167, 168, 5, 109, 0, 0, 168, 169, 5, 97, 0, 0, 169, 2, 1, 0, 0, 0, 170, 171, 5, 59, 0, 0, 171, 4, 1, 0, 0, 0, 172, 173, 5, 99, 0, 0, 173, 174, 5, 97, 0, 0, 174, 175, 5, 115, 0, 0, 175, 176, 5, 104, 0, 0, 176, 177, 5, 115, 0, 0, 177, 178, 5, 99, 0, 0, 178, 179, 5, 114, 0, 0, 179, 180, 5, 105, 0, 0, 180, 181, 5, 112, 0, 0, 181, 182, 5, 116, 0, 0, 182, 6, 1, 0, 0, 0, 183, 184, 5, 94, 0, 0, 184, 8, 1, 0, 0, 0, 185, 186, 5, 126, 0, 0, 186, 10, 1, 0, 0, 0, 187, 188, 5, 62, 0, 0, 188, 189, 5, 61, 0, 0, 189, 12, 1, 0, 0, 0, 190, 191, 5, 62, 0, 0, 191, 14, 1, 0, 0, 0, 192, 193, 5, 60, 0, 0, 193, 16, 1, 0, 0, 0, 194, 195, 5, 60, 0, 0, 195, 196, 5, 61, 0, 0, 196, 18, 1, 0, 0, 0, 197, 198, 5, 61, 0, 0, 198, 20, 1, 0, 0, 0, 199, 200, 5, 99, 0, 0, 200, 201, 5, 111, 0, 0, 201, 202, 5, 110, 0, 0, 202, 203, 5, 116, 0, 0, 203, 204, 5, 114, 0, 0, 204, 205, 5, 97, 0, 0, 205, 206, 5, 99, 0, 0, 206, 207, 5, 116, 0, 0, 207, 22, 1, 0, 0, 0, 208, 209, 5, 123, 0, 0, 209, 24, 1, 0, 0, 0, 210, 211, 5, 125, 0, 0, 211, 26, 1, 0, 0, 0, 212, 213, 5, 102, 0, 0, 213, 214, 5, 117, 0, 0, 214, 215, 5, 110, 0, 0, 215, 216, 5, 99, 0, 0, 216, 217, 5, 116, 0, 0, 217, 218, 5, 105, 0, 0, 218, 219, 5, 111, 0, 0, 219, 220, 5, 110, 0, 0, 220, 28, 1, 0, 0, 0, 221, 222, 5, 40, 0, 0, 222, 30, 1, 0, 0, 0, 223, 224, 5, 44, 0, 0, 224, 32, 1, 0, 0, 0, 225, 226, 5, 41, 0, 0, 226, 34, 1, 0, 0, 0, 227, 228, 5, 43, 0, 0, 228, 229, 5, 61, 0, 0, 229, 36, 1, 0, 0, 0, 230, 231, 5, 45, 0, 0, 231, 232, 5, 61, 0, 0, 232, 38, 1, 0, 0, 0, 233, 234, 5, 43, 0, 0, 234, 235, 5, 43, 0, 0, 235, 40, 1, 0, 0, 0, 236, 237, 5, 45, 0, 0, 237, 238, 5, 45, 0, 0, 238, 42, 1, 0, 0, 0, 239, 240, 5, 114, 0, 0, 240, 241, 5, 101, 0, 0, 241, 242, 5, 113, 0, 0, 242, 243, 5, 117, 0, 0, 243, 244, 5, 105, 0, 0, 244, 245, 5, 114, 0, 0, 245, 246, 5, 101, 0, 0, 246, 44, 1, 0, 0, 0, 247, 248, 5, 99, 0, 0, 248, 249, 5, 111, 0, 0, 249, 250, 5, 110, 0, 0, 250, 251, 5, 115, 0, 0, 251, 252, 5, 111, 0, 0, 252, 253, 5, 108, 0, 0, 253, 254, 5, 101, 0, 0, 254, 255, 5, 46, 0, 0, 255, 256, 5, 108, 0, 0, 256, 257, 5, 111, 0, 0, 257, 258, 5, 103, 0, 0, 258, 46, 1, 0, 0, 0, 259, 260, 5, 105, 0, 0, 260, 261, 5, 102, 0, 0, 261, 48, 1, 0, 0, 0, 262, 263, 5, 101, 0, 0, 263, 264, 5, 108, 0, 0, 264, 265, 5, 115, 0, 0, 265, 266, 5, 101, 0, 0, 266, 50, 1, 0, 0, 0, 267, 268, 5, 100, 0, 0, 268, 269, 5, 111, 0, 0, 269, 52, 1, 0, 0, 0, 270, 271, 5, 119, 0, 0, 271, 272, 5, 104, 0, 0, 272, 273, 5, 105, 0, 0, 273, 274, 5, 108, 0, 0, 274, 275, 5, 101, 0, 0, 275, 54, 1, 0, 0, 0, 276, 277, 5, 102, 0, 0, 277, 278, 5, 111, 0, 0, 278, 279, 5, 114, 0, 0, 279, 56, 1, 0, 0, 0, 280, 281, 5, 110, 0, 0, 281, 282, 5, 101, 0, 0, 282, 283, 5, 119, 0, 0, 283, 58, 1, 0, 0, 0, 284, 285, 5, 91, 0, 0, 285, 60, 1, 0, 0, 0, 286, 287, 5, 93, 0, 0, 287, 62, 1, 0, 0, 0, 288, 289, 5, 116, 0, 0, 289, 290, 5, 120, 0, 0, 290, 291, 5, 46, 0, 0, 291, 292, 5, 111, 0, 0, 292, 293, 5, 117, 0, 0, 293, 294, 5, 116, 0, 0, 294, 295, 5, 112, 0, 0, 295, 296, 5, 117, 0, 0, 296, 297, 5, 116, 0, 0, 297, 298, 5, 115, 0, 0, 298, 64, 1, 0, 0, 0, 299, 300, 5, 46, 0, 0, 300, 301, 5, 118, 0, 0, 301, 302, 5, 97, 0, 0, 302, 303, 5, 108, 0, 0, 303, 304, 5, 117, 0, 0, 304, 305, 5, 101, 0, 0, 305, 66, 1, 0, 0, 0, 306, 307, 5, 46, 0, 0, 307, 308, 5, 108, 0, 0, 308, 309, 5, 111, 0, 0, 309, 310, 5, 99, 0, 0, 310, 311, 5, 107, 0, 0, 311, 312, 5, 105, 0, 0, 312, 313, 5, 110, 0, 0, 313, 314, 5, 103, 0, 0, 314, 315, 5, 66, 0, 0, 315, 316, 5, 121, 0, 0, 316, 317, 5, 116, 0, 0, 317, 318, 5, 101, 0, 0, 318, 319, 5, 99, 0, 0, 319, 320, 5, 111, 0, 0, 320, 321, 5, 100, 0, 0, 321, 322, 5, 101, 0, 0, 322, 68, 1, 0, 0, 0, 323, 324, 5, 46, 0, 0, 324, 325, 5, 116, 0, 0, 325, 326, 5, 111, 0, 0, 326, 327, 5, 107, 0, 0, 327, 328, 5, 101, 0, 0, 328, 329, 5, 110, 0, 0, 329, 330, 5, 67, 0, 0, 330, 331, 5, 97, 0, 0, 331, 332, 5, 116, 0, 0, 332, 333, 5, 101, 0, 0, 333, 334, 5, 103, 0, 0, 334, 335, 5, 111, 0, 0, 335, 336, 5, 114, 0, 0, 336, 337, 5, 121, 0, 0, 337, 70, 1, 0, 0, 0, 338, 339, 5, 46, 0, 0, 339, 340, 5, 110, 0, 0, 340, 341, 5, 102, 0, 0, 341, 342, 5, 116, 0, 0, 342, 343, 5, 67, 0, 0, 343, 344, 5, 111, 0, 0, 344, 345, 5, 109, 0, 0, 345, 346, 5, 109, 0, 0, 346, 347, 5, 105, 0, 0, 347, 348, 5, 116, 0, 0, 348, 349, 5, 109, 0, 0, 349, 350, 5, 101, 0, 0, 350, 351, 5, 110, 0, 0, 351, 352, 5, 116, 0, 0, 352, 72, 1, 0, 0, 0, 353, 354, 5, 46, 0, 0, 354, 355, 5, 116, 0, 0, 355, 356, 5, 111, 0, 0, 356, 357, 5, 107, 0, 0, 357, 358, 5, 101, 0, 0, 358, 359, 5, 110, 0, 0, 359, 360, 5, 65, 0, 0, 360, 361, 5, 109, 0, 0, 361, 362, 5, 111, 0, 0, 362, 363, 5, 117, 0, 0, 363, 364, 5, 110, 0, 0, 364, 365, 5, 116, 0, 0, 365, 74, 1, 0, 0, 0, 366, 367, 5, 116, 0, 0, 367, 368, 5, 120, 0, 0, 368, 369, 5, 46, 0, 0, 369, 370, 5, 105, 0, 0, 370, 371, 5, 110, 0, 0, 371, 372, 5, 112, 0, 0, 372, 373, 5, 117, 0, 0, 373, 374, 5, 116, 0, 0, 374, 375, 5, 115, 0, 0, 375, 76, 1, 0, 0, 0, 376, 377, 5, 46, 0, 0, 377, 378, 5, 111, 0, 0, 378, 379, 5, 117, 0, 0, 379, 380, 5, 116, 0, 0, 380, 381, 5, 112, 0, 0, 381, 382, 5, 111, 0, 0, 382, 383, 5, 105, 0, 0, 383, 384, 5, 110, 0, 0, 384, 385, 5, 116, 0, 0, 385, 386, 5, 84, 0, 0, 386, 387, 5, 114, 0, 0, 387, 388, 5, 97, 0, 0, 388, 389, 5, 110, 0, 0, 389, 390, 5, 115, 0, 0, 390, 391, 5, 97, 0, 0, 391, 392, 5, 99, 0, 0, 392, 393, 5, 116, 0, 0, 393, 394, 5, 105, 0, 0, 394, 395, 5, 111, 0, 0, 395, 396, 5, 110, 0, 0, 396, 397, 5, 72, 0, 0, 397, 398, 5, 97, 0, 0, 398, 399, 5, 115, 0, 0, 399, 400, 5, 104, 0, 0, 400, 78, 1, 0, 0, 0, 401, 402, 5, 46, 0, 0, 402, 403, 5, 111, 0, 0, 403, 404, 5, 117, 0, 0, 404, 405, 5, 116, 0, 0, 405, 406, 5, 112, 0, 0, 406, 407, 5, 111, 0, 0, 407, 408, 5, 105, 0, 0, 408, 409, 5, 110, 0, 0, 409, 410, 5, 116, 0, 0, 410, 411, 5, 73, 0, 0, 411, 412, 5, 110, 0, 0, 412, 413, 5, 100, 0, 0, 413, 414, 5, 101, 0, 0, 414, 415, 5, 120, 0, 0, 415, 80, 1, 0, 0, 0, 416, 417, 5, 46, 0, 0, 417, 418, 5, 117, 0, 0, 418, 419, 5, 110, 0, 0, 419, 420, 5, 108, 0, 0, 420, 421, 5, 111, 0, 0, 421, 422, 5, 99, 0, 0, 422, 423, 5, 107, 0, 0, 423, 424, 5, 105, 0, 0, 424, 425, 5, 110, 0, 0, 425, 426, 5, 103, 0, 0, 426, 427, 5, 66, 0, 0, 427, 428, 5, 121, 0, 0, 428, 429, 5, 116, 0, 0, 429, 430, 5, 101, 0, 0, 430, 431, 5, 99, 0, 0, 431, 432, 5, 111, 0, 0, 432, 433, 5, 100, 0, 0, 433, 434, 5, 101, 0, 0, 434, 82, 1, 0, 0, 0, 435, 436, 5, 46, 0, 0, 436, 437, 5, 115, 0, 0, 437, 438, 5, 101, 0, 0, 438, 439, 5, 113, 0, 0, 439, 440, 5, 117, 0, 0, 440, 441, 5, 101, 0, 0, 441, 442, 5, 110, 0, 0, 442, 443, 5, 99, 0, 0, 443, 444, 5, 101, 0, 0, 444, 445, 5, 78, 0, 0, 445, 446, 5, 117, 0, 0, 446, 447, 5, 109, 0, 0, 447, 448, 5, 98, 0, 0, 448, 449, 5, 101, 0, 0, 449, 450, 5, 114, 0, 0, 450, 84, 1, 0, 0, 0, 451, 452, 5, 46, 0, 0, 452, 453, 5, 114, 0, 0, 453, 454, 5, 101, 0, 0, 454, 455, 5, 118, 0, 0, 455, 456, 5, 101, 0, 0, 456, 457, 5, 114, 0, 0, 457, 458, 5, 115, 0, 0, 458, 459, 5, 101, 0, 0, 459, 460, 5, 40, 0, 0, 460, 461, 5, 41, 0, 0, 461, 86, 1, 0, 0, 0, 462, 463, 5, 46, 0, 0, 463, 464, 5, 108, 0, 0, 464, 465, 5, 101, 0, 0, 465, 466, 5, 110, 0, 0, 466, 467, 5, 103, 0, 0, 467, 468, 5, 116, 0, 0, 468, 469, 5, 104, 0, 0, 469, 88, 1, 0, 0, 0, 470, 471, 5, 46, 0, 0, 471, 472, 5, 115, 0, 0, 472, 473, 5, 112, 0, 0, 473, 474, 5, 108, 0, 0, 474, 475, 5, 105, 0, 0, 475, 476, 5, 116, 0, 0, 476, 90, 1, 0, 0, 0, 477, 478, 5, 46, 0, 0, 478, 479, 5, 115, 0, 0, 479, 480, 5, 108, 0, 0, 480, 481, 5, 105, 0, 0, 481, 482, 5, 99, 0, 0, 482, 483, 5, 101, 0, 0, 483, 92, 1, 0, 0, 0, 484, 485, 5, 33, 0, 0, 485, 94, 1, 0, 0, 0, 486, 487, 5, 45, 0, 0, 487, 96, 1, 0, 0, 0, 488, 489, 5, 42, 0, 0, 489, 98, 1, 0, 0, 0, 490, 491, 5, 47, 0, 0, 491, 100, 1, 0, 0, 0, 492, 493, 5, 37, 0, 0, 493, 102, 1, 0, 0, 0, 494, 495, 5, 43, 0, 0, 495, 104, 1, 0, 0, 0, 496, 497, 5, 62, 0, 0, 497, 498, 5, 62, 0, 0, 498, 106, 1, 0, 0, 0, 499, 500, 5, 60, 0, 0, 500, 501, 5, 60, 0, 0, 501, 108, 1, 0, 0, 0, 502, 503, 5, 61, 0, 0, 503, 504, 5, 61, 0, 0, 504, 110, 1, 0, 0, 0, 505, 506, 5, 33, 0, 0, 506, 507, 5, 61, 0, 0, 507, 112, 1, 0, 0, 0, 508, 509, 5, 38, 0, 0, 509, 114, 1, 0, 0, 0, 510, 511, 5, 124, 0, 0, 511, 116, 1, 0, 0, 0, 512, 513, 5, 38, 0, 0, 513, 514, 5, 38, 0, 0, 514, 118, 1, 0, 0, 0, 515, 516, 5, 124, 0, 0, 516, 517, 5, 124, 0, 0, 517, 120, 1, 0, 0, 0, 518, 519, 5, 99, 0, 0, 519, 520, 5, 111, 0, 0, 520, 521, 5, 110, 0, 0, 521, 522, 5, 115, 0, 0, 522, 523, 5, 116, 0, 0, 523, 524, 5, 97, 0, 0, 524, 525, 5, 110, 0, 0, 525, 526, 5, 116, 0, 0, 526, 122, 1, 0, 0, 0, 527, 529, 7, 0, 0, 0, 528, 527, 1, 0, 0, 0, 529, 530, 1, 0, 0, 0, 530, 528, 1, 0, 0, 0, 530, 531, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 534, 5, 46, 0, 0, 533, 535, 7, 0, 0, 0, 534, 533, 1, 0, 0, 0, 535, 536, 1, 0, 0, 0, 536, 534, 1, 0, 0, 0, 536, 537, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 540, 5, 46, 0, 0, 539, 541, 7, 0, 0, 0, 540, 539, 1, 0, 0, 0, 541, 542, 1, 0, 0, 0, 542, 540, 1, 0, 0, 0, 542, 543, 1, 0, 0, 0, 543, 124, 1, 0, 0, 0, 544, 545, 5, 116, 0, 0, 545, 546, 5, 114, 0, 0, 546, 547, 5, 117, 0, 0, 547, 554, 5, 101, 0, 0, 548, 549, 5, 102, 0, 0, 549, 550, 5, 97, 0, 0, 550, 551, 5, 108, 0, 0, 551, 552, 5, 115, 0, 0, 552, 554, 5, 101, 0, 0, 553, 544, 1, 0, 0, 0, 553, 548, 1, 0, 0, 0, 554, 126, 1, 0, 0, 0, 555, 556, 5, 115, 0, 0, 556, 557, 5, 97, 0, 0, 557, 558, 5, 116, 0, 0, 558, 559, 5, 111, 0, 0, 559, 560, 5, 115, 0, 0, 560, 561, 5, 104, 0, 0, 561, 562, 5, 105, 0, 0, 562, 613, 5, 115, 0, 0, 563, 564, 5, 115, 0, 0, 564, 565, 5, 97, 0, 0, 565, 566, 5, 116, 0, 0, 566, 613, 5, 115, 0, 0, 567, 568, 5, 102, 0, 0, 568, 569, 5, 105, 0, 0, 569, 570, 5, 110, 0, 0, 570, 571, 5, 110, 0, 0, 571, 572, 5, 101, 0, 0, 572, 613, 5, 121, 0, 0, 573, 574, 5, 98, 0, 0, 574, 575, 5, 105, 0, 0, 575, 576, 5, 116, 0, 0, 576, 613, 5, 115, 0, 0, 577, 578, 5, 98, 0, 0, 578, 579, 5, 105, 0, 0, 579, 580, 5, 116, 0, 0, 580, 581, 5, 99, 0, 0, 581, 582, 5, 111, 0, 0, 582, 583, 5, 105, 0, 0, 583, 613, 5, 110, 0, 0, 584, 585, 5, 115, 0, 0, 585, 586, 5, 101, 0, 0, 586, 587, 5, 99, 0, 0, 587, 588, 5, 111, 0, 0, 588, 589, 5, 110, 0, 0, 589, 590, 5, 100, 0, 0, 590, 613, 5, 115, 0, 0, 591, 592, 5, 109, 0, 0, 592, 593, 5, 105, 0, 0, 593, 594, 5, 110, 0, 0, 594, 595, 5, 117, 0, 0, 595, 596, 5, 116, 0, 0, 596, 597, 5, 101, 0, 0, 597, 613, 5, 115, 0, 0, 598, 599, 5, 104, 0, 0, 599, 600, 5, 111, 0, 0, 600, 601, 5, 117, 0, 0, 601, 602, 5, 114, 0, 0, 602, 613, 5, 115, 0, 0, 603, 604, 5, 100, 0, 0, 604, 605, 5, 97, 0, 0, 605, 606, 5, 121, 0, 0, 606, 613, 5, 115, 0, 0, 607, 608, 5, 119, 0, 0, 608, 609, 5, 101, 0, 0, 609, 610, 5, 101, 0, 0, 610, 611, 5, 107, 0, 0, 611, 613, 5, 115, 0, 0, 612, 555, 1, 0, 0, 0, 612, 563, 1, 0, 0, 0, 612, 567, 1, 0, 0, 0, 612, 573, 1, 0, 0, 0, 612, 577, 1, 0, 0, 0, 612, 584, 1, 0, 0, 0, 612, 591, 1, 0, 0, 0, 612, 598, 1, 0, 0, 0, 612, 603, 1, 0, 0, 0, 612, 607, 1, 0, 0, 0, 613, 128, 1, 0, 0, 0, 614, 616, 5, 45, 0, 0, 615, 614, 1, 0, 0, 0, 615, 616, 1, 0, 0, 0, 616, 617, 1, 0, 0, 0, 617, 619, 3, 131, 65, 0, 618, 620, 3, 133, 66, 0, 619, 618, 1, 0, 0, 0, 619, 620, 1, 0, 0, 0, 620, 130, 1, 0, 0, 0, 621, 623, 7, 0, 0, 0, 622, 621, 1, 0, 0, 0, 623, 624, 1, 0, 0, 0, 624, 622, 1, 0, 0, 0, 624, 625, 1, 0, 0, 0, 625, 634, 1, 0, 0, 0, 626, 628, 5, 95, 0, 0, 627, 629, 7, 0, 0, 0, 628, 627, 1, 0, 0, 0, 629, 630, 1, 0, 0, 0, 630, 628, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 633, 1, 0, 0, 0, 632, 626, 1, 0, 0, 0, 633, 636, 1, 0, 0, 0, 634, 632, 1, 0, 0, 0, 634, 635, 1, 0, 0, 0, 635, 132, 1, 0, 0, 0, 636, 634, 1, 0, 0, 0, 637, 638, 7, 1, 0, 0, 638, 639, 3, 131, 65, 0, 639, 134, 1, 0, 0, 0, 640, 641, 5, 105, 0, 0, 641, 642, 5, 110, 0, 0, 642, 670, 5, 116, 0, 0, 643, 644, 5, 98, 0, 0, 644, 645, 5, 111, 0, 0, 645, 646, 5, 111, 0, 0, 646, 670, 5, 108, 0, 0, 647, 648, 5, 115, 0, 0, 648, 649, 5, 116, 0, 0, 649, 650, 5, 114, 0, 0, 650, 651, 5, 105, 0, 0, 651, 652, 5, 110, 0, 0, 652, 670, 5, 103, 0, 0, 653, 654, 5, 112, 0, 0, 654, 655, 5, 117, 0, 0, 655, 656, 5, 98, 0, 0, 656, 657, 5, 107, 0, 0, 657, 658, 5, 101, 0, 0, 658, 670, 5, 121, 0, 0, 659, 660, 5, 115, 0, 0, 660, 661, 5, 105, 0, 0, 661, 670, 5, 103, 0, 0, 662, 663, 5, 100, 0, 0, 663, 664, 5, 97, 0, 0, 664, 665, 5, 116, 0, 0, 665, 666, 5, 97, 0, 0, 666, 667, 5, 115, 0, 0, 667, 668, 5, 105, 0, 0, 668, 670, 5, 103, 0, 0, 669, 640, 1, 0, 0, 0, 669, 643, 1, 0, 0, 0, 669, 647, 1, 0, 0, 0, 669, 653, 1, 0, 0, 0, 669, 659, 1, 0, 0, 0, 669, 662, 1, 0, 0, 0, 670, 136, 1, 0, 0, 0, 671, 672, 5, 98, 0, 0, 672, 673, 5, 121, 0, 0, 673, 674, 5, 116, 0, 0, 674, 675, 5, 101, 0, 0, 675, 676, 5, 115, 0, 0, 676, 138, 1, 0, 0, 0, 677, 678, 5, 98, 0, 0, 678, 679, 5, 121, 0, 0, 679, 680, 5, 116, 0, 0, 680, 681, 5, 101, 0, 0, 681, 682, 5, 115, 0, 0, 682, 683, 1, 0, 0, 0, 683, 689, 3, 141, 70, 0, 684, 685, 5, 98, 0, 0, 685, 686, 5, 121, 0, 0, 686, 687, 5, 116, 0, 0, 687, 689, 5, 101, 0, 0, 688, 677, 1, 0, 0, 0, 688, 684, 1, 0, 0, 0, 689, 140, 1, 0, 0, 0, 690, 694, 7, 2, 0, 0, 691, 693, 7, 0, 0, 0, 692, 691, 1, 0, 0, 0, 693, 696, 1, 0, 0, 0, 694, 692, 1, 0, 0, 0, 694, 695, 1, 0, 0, 0, 695, 142, 1, 0, 0, 0, 696, 694, 1, 0, 0, 0, 697, 703, 5, 34, 0, 0, 698, 699, 5, 92, 0, 0, 699, 702, 5, 34, 0, 0, 700, 702, 8, 3, 0, 0, 701, 698, 1, 0, 0, 0, 701, 700, 1, 0, 0, 0, 702, 705, 1, 0, 0, 0, 703, 704, 1, 0, 0, 0, 703, 701, 1, 0, 0, 0, 704, 706, 1, 0, 0, 0, 705, 703, 1, 0, 0, 0, 706, 718, 5, 34, 0, 0, 707, 713, 5, 39, 0, 0, 708, 709, 5, 92, 0, 0, 709, 712, 5, 39, 0, 0, 710, 712, 8, 4, 0, 0, 711, 708, 1, 0, 0, 0, 711, 710, 1, 0, 0, 0, 712, 715, 1, 0, 0, 0, 713, 714, 1, 0, 0, 0, 713, 711, 1, 0, 0, 0, 714, 716, 1, 0, 0, 0, 715, 713, 1, 0, 0, 0, 716, 718, 5, 39, 0, 0, 717, 697, 1, 0, 0, 0, 717, 707, 1, 0, 0, 0, 718, 144, 1, 0, 0, 0, 719, 720, 5, 100, 0, 0, 720, 721, 5, 97, 0, 0, 721, 722, 5, 116, 0, 0, 722, 723, 5, 101, 0, 0, 723, 724, 5, 40, 0, 0, 724, 725, 1, 0, 0, 0, 725, 726, 3, 143, 71, 0, 726, 727, 5, 41, 0, 0, 727, 146, 1, 0, 0, 0, 728, 729, 5, 48, 0, 0, 729, 733, 7, 5, 0, 0, 730, 732, 7, 6, 0, 0, 731, 730, 1, 0, 0, 0, 732, 735, 1, 0, 0, 0, 733, 731, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 148, 1, 0, 0, 0, 735, 733, 1, 0, 0, 0, 736, 737, 5, 116, 0, 0, 737, 738, 5, 104, 0, 0, 738, 739, 5, 105, 0, 0, 739, 740, 5, 115, 0, 0, 740, 741, 5, 46, 0, 0, 741, 742, 5, 97, 0, 0, 742, 743, 5, 103, 0, 0, 743, 752, 5, 101, 0, 0, 744, 745, 5, 116, 0, 0, 745, 746, 5, 120, 0, 0, 746, 747, 5, 46, 0, 0, 747, 748, 5, 116, 0, 0, 748, 749, 5, 105, 0, 0, 749, 750, 5, 109, 0, 0, 750, 752, 5, 101, 0, 0, 751, 736, 1, 0, 0, 0, 751, 744, 1, 0, 0, 0, 752, 150, 1, 0, 0, 0, 753, 754, 5, 117, 0, 0, 754, 755, 5, 110, 0, 0, 755, 756, 5, 115, 0, 0, 756, 757, 5, 97, 0, 0, 757, 758, 5, 102, 0, 0, 758, 759, 5, 101, 0, 0, 759, 760, 5, 95, 0, 0, 760, 761, 5, 105, 0, 0, 761, 762, 5, 110, 0, 0, 762, 802, 5, 116, 0, 0, 763, 764, 5, 117, 0, 0, 764, 765, 5, 110, 0, 0, 765, 766, 5, 115, 0, 0, 766, 767, 5, 97, 0, 0, 767, 768, 5, 102, 0, 0, 768, 769, 5, 101, 0, 0, 769, 770, 5, 95, 0, 0, 770, 771, 5, 98, 0, 0, 771, 772, 5, 111, 0, 0, 772, 773, 5, 111, 0, 0, 773, 802, 5, 108, 0, 0, 774, 775, 5, 117, 0, 0, 775, 776, 5, 110, 0, 0, 776, 777, 5, 115, 0, 0, 777, 778, 5, 97, 0, 0, 778, 779, 5, 102, 0, 0, 779, 780, 5, 101, 0, 0, 780, 781, 5, 95, 0, 0, 781, 782, 5, 98, 0, 0, 782, 783, 5, 121, 0, 0, 783, 784, 5, 116, 0, 0, 784, 785, 5, 101, 0, 0, 785, 786, 5, 115, 0, 0, 786, 788, 1, 0, 0, 0, 787, 789, 3, 141, 70, 0, 788, 787, 1, 0, 0, 0, 788, 789, 1, 0, 0, 0, 789, 802, 1, 0, 0, 0, 790, 791, 5, 117, 0, 0, 791, 792, 5, 110, 0, 0, 792, 793, 5, 115, 0, 0, 793, 794, 5, 97, 0, 0, 794, 795, 5, 102, 0, 0, 795, 796, 5, 101, 0, 0, 796, 797, 5, 95, 0, 0, 797, 798, 5, 98, 0, 0, 798, 799, 5, 121, 0, 0, 799, 800, 5, 116, 0, 0, 800, 802, 5, 101, 0, 0, 801, 753, 1, 0, 0, 0, 801, 763, 1, 0, 0, 0, 801, 774, 1, 0, 0, 0, 801, 790, 1, 0, 0, 0, 802, 152, 1, 0, 0, 0, 803, 804, 5, 116, 0, 0, 804, 805, 5, 104, 0, 0, 805, 806, 5, 105, 0, 0, 806, 807, 5, 115, 0, 0, 807, 808, 5, 46, 0, 0, 808, 809, 5, 97, 0, 0, 809, 810, 5, 99, 0, 0, 810, 811, 5, 116, 0, 0, 811, 812, 5, 105, 0, 0, 812, 813, 5, 118, 0, 0, 813, 814, 5, 101, 0, 0, 814, 815, 5, 73, 0, 0, 815, 816, 5, 110, 0, 0, 816, 817, 5, 112, 0, 0, 817, 818, 5, 117, 0, 0, 818, 819, 5, 116, 0, 0, 819, 820, 5, 73, 0, 0, 820, 821, 5, 110, 0, 0, 821, 822, 5, 100, 0, 0, 822, 823, 5, 101, 0, 0, 823, 898, 5, 120, 0, 0, 824, 825, 5, 116, 0, 0, 825, 826, 5, 104, 0, 0, 826, 827, 5, 105, 0, 0, 827, 828, 5, 115, 0, 0, 828, 829, 5, 46, 0, 0, 829, 830, 5, 97, 0, 0, 830, 831, 5, 99, 0, 0, 831, 832, 5, 116, 0, 0, 832, 833, 5, 105, 0, 0, 833, 834, 5, 118, 0, 0, 834, 835, 5, 101, 0, 0, 835, 836, 5, 66, 0, 0, 836, 837, 5, 121, 0, 0, 837, 838, 5, 116, 0, 0, 838, 839, 5, 101, 0, 0, 839, 840, 5, 99, 0, 0, 840, 841, 5, 111, 0, 0, 841, 842, 5, 100, 0, 0, 842, 898, 5, 101, 0, 0, 843, 844, 5, 116, 0, 0, 844, 845, 5, 120, 0, 0, 845, 846, 5, 46, 0, 0, 846, 847, 5, 105, 0, 0, 847, 848, 5, 110, 0, 0, 848, 849, 5, 112, 0, 0, 849, 850, 5, 117, 0, 0, 850, 851, 5, 116, 0, 0, 851, 852, 5, 115, 0, 0, 852, 853, 5, 46, 0, 0, 853, 854, 5, 108, 0, 0, 854, 855, 5, 101, 0, 0, 855, 856, 5, 110, 0, 0, 856, 857, 5, 103, 0, 0, 857, 858, 5, 116, 0, 0, 858, 898, 5, 104, 0, 0, 859, 860, 5, 116, 0, 0, 860, 861, 5, 120, 0, 0, 861, 862, 5, 46, 0, 0, 862, 863, 5, 111, 0, 0, 863, 864, 5, 117, 0, 0, 864, 865, 5, 116, 0, 0, 865, 866, 5, 112, 0, 0, 866, 867, 5, 117, 0, 0, 867, 868, 5, 116, 0, 0, 868, 869, 5, 115, 0, 0, 869, 870, 5, 46, 0, 0, 870, 871, 5, 108, 0, 0, 871, 872, 5, 101, 0, 0, 872, 873, 5, 110, 0, 0, 873, 874, 5, 103, 0, 0, 874, 875, 5, 116, 0, 0, 875, 898, 5, 104, 0, 0, 876, 877, 5, 116, 0, 0, 877, 878, 5, 120, 0, 0, 878, 879, 5, 46, 0, 0, 879, 880, 5, 118, 0, 0, 880, 881, 5, 101, 0, 0, 881, 882, 5, 114, 0, 0, 882, 883, 5, 115, 0, 0, 883, 884, 5, 105, 0, 0, 884, 885, 5, 111, 0, 0, 885, 898, 5, 110, 0, 0, 886, 887, 5, 116, 0, 0, 887, 888, 5, 120, 0, 0, 888, 889, 5, 46, 0, 0, 889, 890, 5, 108, 0, 0, 890, 891, 5, 111, 0, 0, 891, 892, 5, 99, 0, 0, 892, 893, 5, 107, 0, 0, 893, 894, 5, 116, 0, 0, 894, 895, 5, 105, 0, 0, 895, 896, 5, 109, 0, 0, 896, 898, 5, 101, 0, 0, 897, 803, 1, 0, 0, 0, 897, 824, 1, 0, 0, 0, 897, 843, 1, 0, 0, 0, 897, 859, 1, 0, 0, 0, 897, 876, 1, 0, 0, 0, 897, 886, 1, 0, 0, 0, 898, 154, 1, 0, 0, 0, 899, 903, 7, 7, 0, 0, 900, 902, 7, 8, 0, 0, 901, 900, 1, 0, 0, 0, 902, 905, 1, 0, 0, 0, 903, 901, 1, 0, 0, 0, 903, 904, 1, 0, 0, 0, 904, 156, 1, 0, 0, 0, 905, 903, 1, 0, 0, 0, 906, 908, 7, 9, 0, 0, 907, 906, 1, 0, 0, 0, 908, 909, 1, 0, 0, 0, 909, 907, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 911, 1, 0, 0, 0, 911, 912, 6, 78, 0, 0, 912, 158, 1, 0, 0, 0, 913, 914, 5, 47, 0, 0, 914, 915, 5, 42, 0, 0, 915, 919, 1, 0, 0, 0, 916, 918, 9, 0, 0, 0, 917, 916, 1, 0, 0, 0, 918, 921, 1, 0, 0, 0, 919, 920, 1, 0, 0, 0, 919, 917, 1, 0, 0, 0, 920, 922, 1, 0, 0, 0, 921, 919, 1, 0, 0, 0, 922, 923, 5, 42, 0, 0, 923, 924, 5, 47, 0, 0, 924, 925, 1, 0, 0, 0, 925, 926, 6, 79, 1, 0, 926, 160, 1, 0, 0, 0, 927, 928, 5, 47, 0, 0, 928, 929, 5, 47, 0, 0, 929, 933, 1, 0, 0, 0, 930, 932, 8, 10, 0, 0, 931, 930, 1, 0, 0, 0, 932, 935, 1, 0, 0, 0, 933, 931, 1, 0, 0, 0, 933, 934, 1, 0, 0, 0, 934, 936, 1, 0, 0, 0, 935, 933, 1, 0, 0, 0, 936, 937, 6, 80, 1, 0, 937, 162, 1, 0, 0, 0, 28, 0, 530, 536, 542, 553, 612, 615, 619, 624, 630, 634, 669, 688, 694, 701, 703, 711, 713, 717, 733, 751, 788, 801, 897, 903, 909, 919, 933, 2, 6, 0, 0, 0, 1, 0] \ No newline at end of file +[4, 0, 84, 966, 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, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 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, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 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, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 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, 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, 36, 1, 37, 1, 37, 1, 37, 1, 37, 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, 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, 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, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 4, 64, 557, 8, 64, 11, 64, 12, 64, 558, 1, 64, 1, 64, 4, 64, 563, 8, 64, 11, 64, 12, 64, 564, 1, 64, 1, 64, 4, 64, 569, 8, 64, 11, 64, 12, 64, 570, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 582, 8, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 641, 8, 66, 1, 67, 3, 67, 644, 8, 67, 1, 67, 1, 67, 3, 67, 648, 8, 67, 1, 68, 4, 68, 651, 8, 68, 11, 68, 12, 68, 652, 1, 68, 1, 68, 4, 68, 657, 8, 68, 11, 68, 12, 68, 658, 5, 68, 661, 8, 68, 10, 68, 12, 68, 664, 9, 68, 1, 69, 1, 69, 1, 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, 3, 70, 698, 8, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 3, 72, 717, 8, 72, 1, 73, 1, 73, 5, 73, 721, 8, 73, 10, 73, 12, 73, 724, 9, 73, 1, 74, 1, 74, 1, 74, 1, 74, 5, 74, 730, 8, 74, 10, 74, 12, 74, 733, 9, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 5, 74, 740, 8, 74, 10, 74, 12, 74, 743, 9, 74, 1, 74, 3, 74, 746, 8, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 5, 76, 760, 8, 76, 10, 76, 12, 76, 763, 9, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 3, 77, 780, 8, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 3, 78, 817, 8, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 3, 78, 830, 8, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 3, 79, 926, 8, 79, 1, 80, 1, 80, 5, 80, 930, 8, 80, 10, 80, 12, 80, 933, 9, 80, 1, 81, 4, 81, 936, 8, 81, 11, 81, 12, 81, 937, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 5, 82, 946, 8, 82, 10, 82, 12, 82, 949, 9, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 5, 83, 960, 8, 83, 10, 83, 12, 83, 963, 9, 83, 1, 83, 1, 83, 3, 731, 741, 947, 0, 84, 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, 153, 77, 155, 78, 157, 79, 159, 80, 161, 81, 163, 82, 165, 83, 167, 84, 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, 1010, 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, 0, 153, 1, 0, 0, 0, 0, 155, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 159, 1, 0, 0, 0, 0, 161, 1, 0, 0, 0, 0, 163, 1, 0, 0, 0, 0, 165, 1, 0, 0, 0, 0, 167, 1, 0, 0, 0, 1, 169, 1, 0, 0, 0, 3, 176, 1, 0, 0, 0, 5, 178, 1, 0, 0, 0, 7, 189, 1, 0, 0, 0, 9, 191, 1, 0, 0, 0, 11, 193, 1, 0, 0, 0, 13, 196, 1, 0, 0, 0, 15, 198, 1, 0, 0, 0, 17, 200, 1, 0, 0, 0, 19, 203, 1, 0, 0, 0, 21, 205, 1, 0, 0, 0, 23, 212, 1, 0, 0, 0, 25, 221, 1, 0, 0, 0, 27, 229, 1, 0, 0, 0, 29, 231, 1, 0, 0, 0, 31, 233, 1, 0, 0, 0, 33, 242, 1, 0, 0, 0, 35, 244, 1, 0, 0, 0, 37, 246, 1, 0, 0, 0, 39, 248, 1, 0, 0, 0, 41, 255, 1, 0, 0, 0, 43, 258, 1, 0, 0, 0, 45, 261, 1, 0, 0, 0, 47, 264, 1, 0, 0, 0, 49, 267, 1, 0, 0, 0, 51, 275, 1, 0, 0, 0, 53, 287, 1, 0, 0, 0, 55, 290, 1, 0, 0, 0, 57, 295, 1, 0, 0, 0, 59, 298, 1, 0, 0, 0, 61, 304, 1, 0, 0, 0, 63, 308, 1, 0, 0, 0, 65, 312, 1, 0, 0, 0, 67, 314, 1, 0, 0, 0, 69, 316, 1, 0, 0, 0, 71, 327, 1, 0, 0, 0, 73, 334, 1, 0, 0, 0, 75, 351, 1, 0, 0, 0, 77, 366, 1, 0, 0, 0, 79, 381, 1, 0, 0, 0, 81, 394, 1, 0, 0, 0, 83, 404, 1, 0, 0, 0, 85, 429, 1, 0, 0, 0, 87, 444, 1, 0, 0, 0, 89, 463, 1, 0, 0, 0, 91, 479, 1, 0, 0, 0, 93, 490, 1, 0, 0, 0, 95, 498, 1, 0, 0, 0, 97, 505, 1, 0, 0, 0, 99, 512, 1, 0, 0, 0, 101, 514, 1, 0, 0, 0, 103, 516, 1, 0, 0, 0, 105, 518, 1, 0, 0, 0, 107, 520, 1, 0, 0, 0, 109, 522, 1, 0, 0, 0, 111, 524, 1, 0, 0, 0, 113, 527, 1, 0, 0, 0, 115, 530, 1, 0, 0, 0, 117, 533, 1, 0, 0, 0, 119, 536, 1, 0, 0, 0, 121, 538, 1, 0, 0, 0, 123, 540, 1, 0, 0, 0, 125, 543, 1, 0, 0, 0, 127, 546, 1, 0, 0, 0, 129, 556, 1, 0, 0, 0, 131, 581, 1, 0, 0, 0, 133, 640, 1, 0, 0, 0, 135, 643, 1, 0, 0, 0, 137, 650, 1, 0, 0, 0, 139, 665, 1, 0, 0, 0, 141, 697, 1, 0, 0, 0, 143, 699, 1, 0, 0, 0, 145, 716, 1, 0, 0, 0, 147, 718, 1, 0, 0, 0, 149, 745, 1, 0, 0, 0, 151, 747, 1, 0, 0, 0, 153, 756, 1, 0, 0, 0, 155, 779, 1, 0, 0, 0, 157, 829, 1, 0, 0, 0, 159, 925, 1, 0, 0, 0, 161, 927, 1, 0, 0, 0, 163, 935, 1, 0, 0, 0, 165, 941, 1, 0, 0, 0, 167, 955, 1, 0, 0, 0, 169, 170, 5, 112, 0, 0, 170, 171, 5, 114, 0, 0, 171, 172, 5, 97, 0, 0, 172, 173, 5, 103, 0, 0, 173, 174, 5, 109, 0, 0, 174, 175, 5, 97, 0, 0, 175, 2, 1, 0, 0, 0, 176, 177, 5, 59, 0, 0, 177, 4, 1, 0, 0, 0, 178, 179, 5, 99, 0, 0, 179, 180, 5, 97, 0, 0, 180, 181, 5, 115, 0, 0, 181, 182, 5, 104, 0, 0, 182, 183, 5, 115, 0, 0, 183, 184, 5, 99, 0, 0, 184, 185, 5, 114, 0, 0, 185, 186, 5, 105, 0, 0, 186, 187, 5, 112, 0, 0, 187, 188, 5, 116, 0, 0, 188, 6, 1, 0, 0, 0, 189, 190, 5, 94, 0, 0, 190, 8, 1, 0, 0, 0, 191, 192, 5, 126, 0, 0, 192, 10, 1, 0, 0, 0, 193, 194, 5, 62, 0, 0, 194, 195, 5, 61, 0, 0, 195, 12, 1, 0, 0, 0, 196, 197, 5, 62, 0, 0, 197, 14, 1, 0, 0, 0, 198, 199, 5, 60, 0, 0, 199, 16, 1, 0, 0, 0, 200, 201, 5, 60, 0, 0, 201, 202, 5, 61, 0, 0, 202, 18, 1, 0, 0, 0, 203, 204, 5, 61, 0, 0, 204, 20, 1, 0, 0, 0, 205, 206, 5, 105, 0, 0, 206, 207, 5, 109, 0, 0, 207, 208, 5, 112, 0, 0, 208, 209, 5, 111, 0, 0, 209, 210, 5, 114, 0, 0, 210, 211, 5, 116, 0, 0, 211, 22, 1, 0, 0, 0, 212, 213, 5, 102, 0, 0, 213, 214, 5, 117, 0, 0, 214, 215, 5, 110, 0, 0, 215, 216, 5, 99, 0, 0, 216, 217, 5, 116, 0, 0, 217, 218, 5, 105, 0, 0, 218, 219, 5, 111, 0, 0, 219, 220, 5, 110, 0, 0, 220, 24, 1, 0, 0, 0, 221, 222, 5, 114, 0, 0, 222, 223, 5, 101, 0, 0, 223, 224, 5, 116, 0, 0, 224, 225, 5, 117, 0, 0, 225, 226, 5, 114, 0, 0, 226, 227, 5, 110, 0, 0, 227, 228, 5, 115, 0, 0, 228, 26, 1, 0, 0, 0, 229, 230, 5, 40, 0, 0, 230, 28, 1, 0, 0, 0, 231, 232, 5, 41, 0, 0, 232, 30, 1, 0, 0, 0, 233, 234, 5, 99, 0, 0, 234, 235, 5, 111, 0, 0, 235, 236, 5, 110, 0, 0, 236, 237, 5, 116, 0, 0, 237, 238, 5, 114, 0, 0, 238, 239, 5, 97, 0, 0, 239, 240, 5, 99, 0, 0, 240, 241, 5, 116, 0, 0, 241, 32, 1, 0, 0, 0, 242, 243, 5, 123, 0, 0, 243, 34, 1, 0, 0, 0, 244, 245, 5, 125, 0, 0, 245, 36, 1, 0, 0, 0, 246, 247, 5, 44, 0, 0, 247, 38, 1, 0, 0, 0, 248, 249, 5, 114, 0, 0, 249, 250, 5, 101, 0, 0, 250, 251, 5, 116, 0, 0, 251, 252, 5, 117, 0, 0, 252, 253, 5, 114, 0, 0, 253, 254, 5, 110, 0, 0, 254, 40, 1, 0, 0, 0, 255, 256, 5, 43, 0, 0, 256, 257, 5, 61, 0, 0, 257, 42, 1, 0, 0, 0, 258, 259, 5, 45, 0, 0, 259, 260, 5, 61, 0, 0, 260, 44, 1, 0, 0, 0, 261, 262, 5, 43, 0, 0, 262, 263, 5, 43, 0, 0, 263, 46, 1, 0, 0, 0, 264, 265, 5, 45, 0, 0, 265, 266, 5, 45, 0, 0, 266, 48, 1, 0, 0, 0, 267, 268, 5, 114, 0, 0, 268, 269, 5, 101, 0, 0, 269, 270, 5, 113, 0, 0, 270, 271, 5, 117, 0, 0, 271, 272, 5, 105, 0, 0, 272, 273, 5, 114, 0, 0, 273, 274, 5, 101, 0, 0, 274, 50, 1, 0, 0, 0, 275, 276, 5, 99, 0, 0, 276, 277, 5, 111, 0, 0, 277, 278, 5, 110, 0, 0, 278, 279, 5, 115, 0, 0, 279, 280, 5, 111, 0, 0, 280, 281, 5, 108, 0, 0, 281, 282, 5, 101, 0, 0, 282, 283, 5, 46, 0, 0, 283, 284, 5, 108, 0, 0, 284, 285, 5, 111, 0, 0, 285, 286, 5, 103, 0, 0, 286, 52, 1, 0, 0, 0, 287, 288, 5, 105, 0, 0, 288, 289, 5, 102, 0, 0, 289, 54, 1, 0, 0, 0, 290, 291, 5, 101, 0, 0, 291, 292, 5, 108, 0, 0, 292, 293, 5, 115, 0, 0, 293, 294, 5, 101, 0, 0, 294, 56, 1, 0, 0, 0, 295, 296, 5, 100, 0, 0, 296, 297, 5, 111, 0, 0, 297, 58, 1, 0, 0, 0, 298, 299, 5, 119, 0, 0, 299, 300, 5, 104, 0, 0, 300, 301, 5, 105, 0, 0, 301, 302, 5, 108, 0, 0, 302, 303, 5, 101, 0, 0, 303, 60, 1, 0, 0, 0, 304, 305, 5, 102, 0, 0, 305, 306, 5, 111, 0, 0, 306, 307, 5, 114, 0, 0, 307, 62, 1, 0, 0, 0, 308, 309, 5, 110, 0, 0, 309, 310, 5, 101, 0, 0, 310, 311, 5, 119, 0, 0, 311, 64, 1, 0, 0, 0, 312, 313, 5, 91, 0, 0, 313, 66, 1, 0, 0, 0, 314, 315, 5, 93, 0, 0, 315, 68, 1, 0, 0, 0, 316, 317, 5, 116, 0, 0, 317, 318, 5, 120, 0, 0, 318, 319, 5, 46, 0, 0, 319, 320, 5, 111, 0, 0, 320, 321, 5, 117, 0, 0, 321, 322, 5, 116, 0, 0, 322, 323, 5, 112, 0, 0, 323, 324, 5, 117, 0, 0, 324, 325, 5, 116, 0, 0, 325, 326, 5, 115, 0, 0, 326, 70, 1, 0, 0, 0, 327, 328, 5, 46, 0, 0, 328, 329, 5, 118, 0, 0, 329, 330, 5, 97, 0, 0, 330, 331, 5, 108, 0, 0, 331, 332, 5, 117, 0, 0, 332, 333, 5, 101, 0, 0, 333, 72, 1, 0, 0, 0, 334, 335, 5, 46, 0, 0, 335, 336, 5, 108, 0, 0, 336, 337, 5, 111, 0, 0, 337, 338, 5, 99, 0, 0, 338, 339, 5, 107, 0, 0, 339, 340, 5, 105, 0, 0, 340, 341, 5, 110, 0, 0, 341, 342, 5, 103, 0, 0, 342, 343, 5, 66, 0, 0, 343, 344, 5, 121, 0, 0, 344, 345, 5, 116, 0, 0, 345, 346, 5, 101, 0, 0, 346, 347, 5, 99, 0, 0, 347, 348, 5, 111, 0, 0, 348, 349, 5, 100, 0, 0, 349, 350, 5, 101, 0, 0, 350, 74, 1, 0, 0, 0, 351, 352, 5, 46, 0, 0, 352, 353, 5, 116, 0, 0, 353, 354, 5, 111, 0, 0, 354, 355, 5, 107, 0, 0, 355, 356, 5, 101, 0, 0, 356, 357, 5, 110, 0, 0, 357, 358, 5, 67, 0, 0, 358, 359, 5, 97, 0, 0, 359, 360, 5, 116, 0, 0, 360, 361, 5, 101, 0, 0, 361, 362, 5, 103, 0, 0, 362, 363, 5, 111, 0, 0, 363, 364, 5, 114, 0, 0, 364, 365, 5, 121, 0, 0, 365, 76, 1, 0, 0, 0, 366, 367, 5, 46, 0, 0, 367, 368, 5, 110, 0, 0, 368, 369, 5, 102, 0, 0, 369, 370, 5, 116, 0, 0, 370, 371, 5, 67, 0, 0, 371, 372, 5, 111, 0, 0, 372, 373, 5, 109, 0, 0, 373, 374, 5, 109, 0, 0, 374, 375, 5, 105, 0, 0, 375, 376, 5, 116, 0, 0, 376, 377, 5, 109, 0, 0, 377, 378, 5, 101, 0, 0, 378, 379, 5, 110, 0, 0, 379, 380, 5, 116, 0, 0, 380, 78, 1, 0, 0, 0, 381, 382, 5, 46, 0, 0, 382, 383, 5, 116, 0, 0, 383, 384, 5, 111, 0, 0, 384, 385, 5, 107, 0, 0, 385, 386, 5, 101, 0, 0, 386, 387, 5, 110, 0, 0, 387, 388, 5, 65, 0, 0, 388, 389, 5, 109, 0, 0, 389, 390, 5, 111, 0, 0, 390, 391, 5, 117, 0, 0, 391, 392, 5, 110, 0, 0, 392, 393, 5, 116, 0, 0, 393, 80, 1, 0, 0, 0, 394, 395, 5, 116, 0, 0, 395, 396, 5, 120, 0, 0, 396, 397, 5, 46, 0, 0, 397, 398, 5, 105, 0, 0, 398, 399, 5, 110, 0, 0, 399, 400, 5, 112, 0, 0, 400, 401, 5, 117, 0, 0, 401, 402, 5, 116, 0, 0, 402, 403, 5, 115, 0, 0, 403, 82, 1, 0, 0, 0, 404, 405, 5, 46, 0, 0, 405, 406, 5, 111, 0, 0, 406, 407, 5, 117, 0, 0, 407, 408, 5, 116, 0, 0, 408, 409, 5, 112, 0, 0, 409, 410, 5, 111, 0, 0, 410, 411, 5, 105, 0, 0, 411, 412, 5, 110, 0, 0, 412, 413, 5, 116, 0, 0, 413, 414, 5, 84, 0, 0, 414, 415, 5, 114, 0, 0, 415, 416, 5, 97, 0, 0, 416, 417, 5, 110, 0, 0, 417, 418, 5, 115, 0, 0, 418, 419, 5, 97, 0, 0, 419, 420, 5, 99, 0, 0, 420, 421, 5, 116, 0, 0, 421, 422, 5, 105, 0, 0, 422, 423, 5, 111, 0, 0, 423, 424, 5, 110, 0, 0, 424, 425, 5, 72, 0, 0, 425, 426, 5, 97, 0, 0, 426, 427, 5, 115, 0, 0, 427, 428, 5, 104, 0, 0, 428, 84, 1, 0, 0, 0, 429, 430, 5, 46, 0, 0, 430, 431, 5, 111, 0, 0, 431, 432, 5, 117, 0, 0, 432, 433, 5, 116, 0, 0, 433, 434, 5, 112, 0, 0, 434, 435, 5, 111, 0, 0, 435, 436, 5, 105, 0, 0, 436, 437, 5, 110, 0, 0, 437, 438, 5, 116, 0, 0, 438, 439, 5, 73, 0, 0, 439, 440, 5, 110, 0, 0, 440, 441, 5, 100, 0, 0, 441, 442, 5, 101, 0, 0, 442, 443, 5, 120, 0, 0, 443, 86, 1, 0, 0, 0, 444, 445, 5, 46, 0, 0, 445, 446, 5, 117, 0, 0, 446, 447, 5, 110, 0, 0, 447, 448, 5, 108, 0, 0, 448, 449, 5, 111, 0, 0, 449, 450, 5, 99, 0, 0, 450, 451, 5, 107, 0, 0, 451, 452, 5, 105, 0, 0, 452, 453, 5, 110, 0, 0, 453, 454, 5, 103, 0, 0, 454, 455, 5, 66, 0, 0, 455, 456, 5, 121, 0, 0, 456, 457, 5, 116, 0, 0, 457, 458, 5, 101, 0, 0, 458, 459, 5, 99, 0, 0, 459, 460, 5, 111, 0, 0, 460, 461, 5, 100, 0, 0, 461, 462, 5, 101, 0, 0, 462, 88, 1, 0, 0, 0, 463, 464, 5, 46, 0, 0, 464, 465, 5, 115, 0, 0, 465, 466, 5, 101, 0, 0, 466, 467, 5, 113, 0, 0, 467, 468, 5, 117, 0, 0, 468, 469, 5, 101, 0, 0, 469, 470, 5, 110, 0, 0, 470, 471, 5, 99, 0, 0, 471, 472, 5, 101, 0, 0, 472, 473, 5, 78, 0, 0, 473, 474, 5, 117, 0, 0, 474, 475, 5, 109, 0, 0, 475, 476, 5, 98, 0, 0, 476, 477, 5, 101, 0, 0, 477, 478, 5, 114, 0, 0, 478, 90, 1, 0, 0, 0, 479, 480, 5, 46, 0, 0, 480, 481, 5, 114, 0, 0, 481, 482, 5, 101, 0, 0, 482, 483, 5, 118, 0, 0, 483, 484, 5, 101, 0, 0, 484, 485, 5, 114, 0, 0, 485, 486, 5, 115, 0, 0, 486, 487, 5, 101, 0, 0, 487, 488, 5, 40, 0, 0, 488, 489, 5, 41, 0, 0, 489, 92, 1, 0, 0, 0, 490, 491, 5, 46, 0, 0, 491, 492, 5, 108, 0, 0, 492, 493, 5, 101, 0, 0, 493, 494, 5, 110, 0, 0, 494, 495, 5, 103, 0, 0, 495, 496, 5, 116, 0, 0, 496, 497, 5, 104, 0, 0, 497, 94, 1, 0, 0, 0, 498, 499, 5, 46, 0, 0, 499, 500, 5, 115, 0, 0, 500, 501, 5, 112, 0, 0, 501, 502, 5, 108, 0, 0, 502, 503, 5, 105, 0, 0, 503, 504, 5, 116, 0, 0, 504, 96, 1, 0, 0, 0, 505, 506, 5, 46, 0, 0, 506, 507, 5, 115, 0, 0, 507, 508, 5, 108, 0, 0, 508, 509, 5, 105, 0, 0, 509, 510, 5, 99, 0, 0, 510, 511, 5, 101, 0, 0, 511, 98, 1, 0, 0, 0, 512, 513, 5, 33, 0, 0, 513, 100, 1, 0, 0, 0, 514, 515, 5, 45, 0, 0, 515, 102, 1, 0, 0, 0, 516, 517, 5, 42, 0, 0, 517, 104, 1, 0, 0, 0, 518, 519, 5, 47, 0, 0, 519, 106, 1, 0, 0, 0, 520, 521, 5, 37, 0, 0, 521, 108, 1, 0, 0, 0, 522, 523, 5, 43, 0, 0, 523, 110, 1, 0, 0, 0, 524, 525, 5, 62, 0, 0, 525, 526, 5, 62, 0, 0, 526, 112, 1, 0, 0, 0, 527, 528, 5, 60, 0, 0, 528, 529, 5, 60, 0, 0, 529, 114, 1, 0, 0, 0, 530, 531, 5, 61, 0, 0, 531, 532, 5, 61, 0, 0, 532, 116, 1, 0, 0, 0, 533, 534, 5, 33, 0, 0, 534, 535, 5, 61, 0, 0, 535, 118, 1, 0, 0, 0, 536, 537, 5, 38, 0, 0, 537, 120, 1, 0, 0, 0, 538, 539, 5, 124, 0, 0, 539, 122, 1, 0, 0, 0, 540, 541, 5, 38, 0, 0, 541, 542, 5, 38, 0, 0, 542, 124, 1, 0, 0, 0, 543, 544, 5, 124, 0, 0, 544, 545, 5, 124, 0, 0, 545, 126, 1, 0, 0, 0, 546, 547, 5, 99, 0, 0, 547, 548, 5, 111, 0, 0, 548, 549, 5, 110, 0, 0, 549, 550, 5, 115, 0, 0, 550, 551, 5, 116, 0, 0, 551, 552, 5, 97, 0, 0, 552, 553, 5, 110, 0, 0, 553, 554, 5, 116, 0, 0, 554, 128, 1, 0, 0, 0, 555, 557, 7, 0, 0, 0, 556, 555, 1, 0, 0, 0, 557, 558, 1, 0, 0, 0, 558, 556, 1, 0, 0, 0, 558, 559, 1, 0, 0, 0, 559, 560, 1, 0, 0, 0, 560, 562, 5, 46, 0, 0, 561, 563, 7, 0, 0, 0, 562, 561, 1, 0, 0, 0, 563, 564, 1, 0, 0, 0, 564, 562, 1, 0, 0, 0, 564, 565, 1, 0, 0, 0, 565, 566, 1, 0, 0, 0, 566, 568, 5, 46, 0, 0, 567, 569, 7, 0, 0, 0, 568, 567, 1, 0, 0, 0, 569, 570, 1, 0, 0, 0, 570, 568, 1, 0, 0, 0, 570, 571, 1, 0, 0, 0, 571, 130, 1, 0, 0, 0, 572, 573, 5, 116, 0, 0, 573, 574, 5, 114, 0, 0, 574, 575, 5, 117, 0, 0, 575, 582, 5, 101, 0, 0, 576, 577, 5, 102, 0, 0, 577, 578, 5, 97, 0, 0, 578, 579, 5, 108, 0, 0, 579, 580, 5, 115, 0, 0, 580, 582, 5, 101, 0, 0, 581, 572, 1, 0, 0, 0, 581, 576, 1, 0, 0, 0, 582, 132, 1, 0, 0, 0, 583, 584, 5, 115, 0, 0, 584, 585, 5, 97, 0, 0, 585, 586, 5, 116, 0, 0, 586, 587, 5, 111, 0, 0, 587, 588, 5, 115, 0, 0, 588, 589, 5, 104, 0, 0, 589, 590, 5, 105, 0, 0, 590, 641, 5, 115, 0, 0, 591, 592, 5, 115, 0, 0, 592, 593, 5, 97, 0, 0, 593, 594, 5, 116, 0, 0, 594, 641, 5, 115, 0, 0, 595, 596, 5, 102, 0, 0, 596, 597, 5, 105, 0, 0, 597, 598, 5, 110, 0, 0, 598, 599, 5, 110, 0, 0, 599, 600, 5, 101, 0, 0, 600, 641, 5, 121, 0, 0, 601, 602, 5, 98, 0, 0, 602, 603, 5, 105, 0, 0, 603, 604, 5, 116, 0, 0, 604, 641, 5, 115, 0, 0, 605, 606, 5, 98, 0, 0, 606, 607, 5, 105, 0, 0, 607, 608, 5, 116, 0, 0, 608, 609, 5, 99, 0, 0, 609, 610, 5, 111, 0, 0, 610, 611, 5, 105, 0, 0, 611, 641, 5, 110, 0, 0, 612, 613, 5, 115, 0, 0, 613, 614, 5, 101, 0, 0, 614, 615, 5, 99, 0, 0, 615, 616, 5, 111, 0, 0, 616, 617, 5, 110, 0, 0, 617, 618, 5, 100, 0, 0, 618, 641, 5, 115, 0, 0, 619, 620, 5, 109, 0, 0, 620, 621, 5, 105, 0, 0, 621, 622, 5, 110, 0, 0, 622, 623, 5, 117, 0, 0, 623, 624, 5, 116, 0, 0, 624, 625, 5, 101, 0, 0, 625, 641, 5, 115, 0, 0, 626, 627, 5, 104, 0, 0, 627, 628, 5, 111, 0, 0, 628, 629, 5, 117, 0, 0, 629, 630, 5, 114, 0, 0, 630, 641, 5, 115, 0, 0, 631, 632, 5, 100, 0, 0, 632, 633, 5, 97, 0, 0, 633, 634, 5, 121, 0, 0, 634, 641, 5, 115, 0, 0, 635, 636, 5, 119, 0, 0, 636, 637, 5, 101, 0, 0, 637, 638, 5, 101, 0, 0, 638, 639, 5, 107, 0, 0, 639, 641, 5, 115, 0, 0, 640, 583, 1, 0, 0, 0, 640, 591, 1, 0, 0, 0, 640, 595, 1, 0, 0, 0, 640, 601, 1, 0, 0, 0, 640, 605, 1, 0, 0, 0, 640, 612, 1, 0, 0, 0, 640, 619, 1, 0, 0, 0, 640, 626, 1, 0, 0, 0, 640, 631, 1, 0, 0, 0, 640, 635, 1, 0, 0, 0, 641, 134, 1, 0, 0, 0, 642, 644, 5, 45, 0, 0, 643, 642, 1, 0, 0, 0, 643, 644, 1, 0, 0, 0, 644, 645, 1, 0, 0, 0, 645, 647, 3, 137, 68, 0, 646, 648, 3, 139, 69, 0, 647, 646, 1, 0, 0, 0, 647, 648, 1, 0, 0, 0, 648, 136, 1, 0, 0, 0, 649, 651, 7, 0, 0, 0, 650, 649, 1, 0, 0, 0, 651, 652, 1, 0, 0, 0, 652, 650, 1, 0, 0, 0, 652, 653, 1, 0, 0, 0, 653, 662, 1, 0, 0, 0, 654, 656, 5, 95, 0, 0, 655, 657, 7, 0, 0, 0, 656, 655, 1, 0, 0, 0, 657, 658, 1, 0, 0, 0, 658, 656, 1, 0, 0, 0, 658, 659, 1, 0, 0, 0, 659, 661, 1, 0, 0, 0, 660, 654, 1, 0, 0, 0, 661, 664, 1, 0, 0, 0, 662, 660, 1, 0, 0, 0, 662, 663, 1, 0, 0, 0, 663, 138, 1, 0, 0, 0, 664, 662, 1, 0, 0, 0, 665, 666, 7, 1, 0, 0, 666, 667, 3, 137, 68, 0, 667, 140, 1, 0, 0, 0, 668, 669, 5, 105, 0, 0, 669, 670, 5, 110, 0, 0, 670, 698, 5, 116, 0, 0, 671, 672, 5, 98, 0, 0, 672, 673, 5, 111, 0, 0, 673, 674, 5, 111, 0, 0, 674, 698, 5, 108, 0, 0, 675, 676, 5, 115, 0, 0, 676, 677, 5, 116, 0, 0, 677, 678, 5, 114, 0, 0, 678, 679, 5, 105, 0, 0, 679, 680, 5, 110, 0, 0, 680, 698, 5, 103, 0, 0, 681, 682, 5, 112, 0, 0, 682, 683, 5, 117, 0, 0, 683, 684, 5, 98, 0, 0, 684, 685, 5, 107, 0, 0, 685, 686, 5, 101, 0, 0, 686, 698, 5, 121, 0, 0, 687, 688, 5, 115, 0, 0, 688, 689, 5, 105, 0, 0, 689, 698, 5, 103, 0, 0, 690, 691, 5, 100, 0, 0, 691, 692, 5, 97, 0, 0, 692, 693, 5, 116, 0, 0, 693, 694, 5, 97, 0, 0, 694, 695, 5, 115, 0, 0, 695, 696, 5, 105, 0, 0, 696, 698, 5, 103, 0, 0, 697, 668, 1, 0, 0, 0, 697, 671, 1, 0, 0, 0, 697, 675, 1, 0, 0, 0, 697, 681, 1, 0, 0, 0, 697, 687, 1, 0, 0, 0, 697, 690, 1, 0, 0, 0, 698, 142, 1, 0, 0, 0, 699, 700, 5, 98, 0, 0, 700, 701, 5, 121, 0, 0, 701, 702, 5, 116, 0, 0, 702, 703, 5, 101, 0, 0, 703, 704, 5, 115, 0, 0, 704, 144, 1, 0, 0, 0, 705, 706, 5, 98, 0, 0, 706, 707, 5, 121, 0, 0, 707, 708, 5, 116, 0, 0, 708, 709, 5, 101, 0, 0, 709, 710, 5, 115, 0, 0, 710, 711, 1, 0, 0, 0, 711, 717, 3, 147, 73, 0, 712, 713, 5, 98, 0, 0, 713, 714, 5, 121, 0, 0, 714, 715, 5, 116, 0, 0, 715, 717, 5, 101, 0, 0, 716, 705, 1, 0, 0, 0, 716, 712, 1, 0, 0, 0, 717, 146, 1, 0, 0, 0, 718, 722, 7, 2, 0, 0, 719, 721, 7, 0, 0, 0, 720, 719, 1, 0, 0, 0, 721, 724, 1, 0, 0, 0, 722, 720, 1, 0, 0, 0, 722, 723, 1, 0, 0, 0, 723, 148, 1, 0, 0, 0, 724, 722, 1, 0, 0, 0, 725, 731, 5, 34, 0, 0, 726, 727, 5, 92, 0, 0, 727, 730, 5, 34, 0, 0, 728, 730, 8, 3, 0, 0, 729, 726, 1, 0, 0, 0, 729, 728, 1, 0, 0, 0, 730, 733, 1, 0, 0, 0, 731, 732, 1, 0, 0, 0, 731, 729, 1, 0, 0, 0, 732, 734, 1, 0, 0, 0, 733, 731, 1, 0, 0, 0, 734, 746, 5, 34, 0, 0, 735, 741, 5, 39, 0, 0, 736, 737, 5, 92, 0, 0, 737, 740, 5, 39, 0, 0, 738, 740, 8, 4, 0, 0, 739, 736, 1, 0, 0, 0, 739, 738, 1, 0, 0, 0, 740, 743, 1, 0, 0, 0, 741, 742, 1, 0, 0, 0, 741, 739, 1, 0, 0, 0, 742, 744, 1, 0, 0, 0, 743, 741, 1, 0, 0, 0, 744, 746, 5, 39, 0, 0, 745, 725, 1, 0, 0, 0, 745, 735, 1, 0, 0, 0, 746, 150, 1, 0, 0, 0, 747, 748, 5, 100, 0, 0, 748, 749, 5, 97, 0, 0, 749, 750, 5, 116, 0, 0, 750, 751, 5, 101, 0, 0, 751, 752, 5, 40, 0, 0, 752, 753, 1, 0, 0, 0, 753, 754, 3, 149, 74, 0, 754, 755, 5, 41, 0, 0, 755, 152, 1, 0, 0, 0, 756, 757, 5, 48, 0, 0, 757, 761, 7, 5, 0, 0, 758, 760, 7, 6, 0, 0, 759, 758, 1, 0, 0, 0, 760, 763, 1, 0, 0, 0, 761, 759, 1, 0, 0, 0, 761, 762, 1, 0, 0, 0, 762, 154, 1, 0, 0, 0, 763, 761, 1, 0, 0, 0, 764, 765, 5, 116, 0, 0, 765, 766, 5, 104, 0, 0, 766, 767, 5, 105, 0, 0, 767, 768, 5, 115, 0, 0, 768, 769, 5, 46, 0, 0, 769, 770, 5, 97, 0, 0, 770, 771, 5, 103, 0, 0, 771, 780, 5, 101, 0, 0, 772, 773, 5, 116, 0, 0, 773, 774, 5, 120, 0, 0, 774, 775, 5, 46, 0, 0, 775, 776, 5, 116, 0, 0, 776, 777, 5, 105, 0, 0, 777, 778, 5, 109, 0, 0, 778, 780, 5, 101, 0, 0, 779, 764, 1, 0, 0, 0, 779, 772, 1, 0, 0, 0, 780, 156, 1, 0, 0, 0, 781, 782, 5, 117, 0, 0, 782, 783, 5, 110, 0, 0, 783, 784, 5, 115, 0, 0, 784, 785, 5, 97, 0, 0, 785, 786, 5, 102, 0, 0, 786, 787, 5, 101, 0, 0, 787, 788, 5, 95, 0, 0, 788, 789, 5, 105, 0, 0, 789, 790, 5, 110, 0, 0, 790, 830, 5, 116, 0, 0, 791, 792, 5, 117, 0, 0, 792, 793, 5, 110, 0, 0, 793, 794, 5, 115, 0, 0, 794, 795, 5, 97, 0, 0, 795, 796, 5, 102, 0, 0, 796, 797, 5, 101, 0, 0, 797, 798, 5, 95, 0, 0, 798, 799, 5, 98, 0, 0, 799, 800, 5, 111, 0, 0, 800, 801, 5, 111, 0, 0, 801, 830, 5, 108, 0, 0, 802, 803, 5, 117, 0, 0, 803, 804, 5, 110, 0, 0, 804, 805, 5, 115, 0, 0, 805, 806, 5, 97, 0, 0, 806, 807, 5, 102, 0, 0, 807, 808, 5, 101, 0, 0, 808, 809, 5, 95, 0, 0, 809, 810, 5, 98, 0, 0, 810, 811, 5, 121, 0, 0, 811, 812, 5, 116, 0, 0, 812, 813, 5, 101, 0, 0, 813, 814, 5, 115, 0, 0, 814, 816, 1, 0, 0, 0, 815, 817, 3, 147, 73, 0, 816, 815, 1, 0, 0, 0, 816, 817, 1, 0, 0, 0, 817, 830, 1, 0, 0, 0, 818, 819, 5, 117, 0, 0, 819, 820, 5, 110, 0, 0, 820, 821, 5, 115, 0, 0, 821, 822, 5, 97, 0, 0, 822, 823, 5, 102, 0, 0, 823, 824, 5, 101, 0, 0, 824, 825, 5, 95, 0, 0, 825, 826, 5, 98, 0, 0, 826, 827, 5, 121, 0, 0, 827, 828, 5, 116, 0, 0, 828, 830, 5, 101, 0, 0, 829, 781, 1, 0, 0, 0, 829, 791, 1, 0, 0, 0, 829, 802, 1, 0, 0, 0, 829, 818, 1, 0, 0, 0, 830, 158, 1, 0, 0, 0, 831, 832, 5, 116, 0, 0, 832, 833, 5, 104, 0, 0, 833, 834, 5, 105, 0, 0, 834, 835, 5, 115, 0, 0, 835, 836, 5, 46, 0, 0, 836, 837, 5, 97, 0, 0, 837, 838, 5, 99, 0, 0, 838, 839, 5, 116, 0, 0, 839, 840, 5, 105, 0, 0, 840, 841, 5, 118, 0, 0, 841, 842, 5, 101, 0, 0, 842, 843, 5, 73, 0, 0, 843, 844, 5, 110, 0, 0, 844, 845, 5, 112, 0, 0, 845, 846, 5, 117, 0, 0, 846, 847, 5, 116, 0, 0, 847, 848, 5, 73, 0, 0, 848, 849, 5, 110, 0, 0, 849, 850, 5, 100, 0, 0, 850, 851, 5, 101, 0, 0, 851, 926, 5, 120, 0, 0, 852, 853, 5, 116, 0, 0, 853, 854, 5, 104, 0, 0, 854, 855, 5, 105, 0, 0, 855, 856, 5, 115, 0, 0, 856, 857, 5, 46, 0, 0, 857, 858, 5, 97, 0, 0, 858, 859, 5, 99, 0, 0, 859, 860, 5, 116, 0, 0, 860, 861, 5, 105, 0, 0, 861, 862, 5, 118, 0, 0, 862, 863, 5, 101, 0, 0, 863, 864, 5, 66, 0, 0, 864, 865, 5, 121, 0, 0, 865, 866, 5, 116, 0, 0, 866, 867, 5, 101, 0, 0, 867, 868, 5, 99, 0, 0, 868, 869, 5, 111, 0, 0, 869, 870, 5, 100, 0, 0, 870, 926, 5, 101, 0, 0, 871, 872, 5, 116, 0, 0, 872, 873, 5, 120, 0, 0, 873, 874, 5, 46, 0, 0, 874, 875, 5, 105, 0, 0, 875, 876, 5, 110, 0, 0, 876, 877, 5, 112, 0, 0, 877, 878, 5, 117, 0, 0, 878, 879, 5, 116, 0, 0, 879, 880, 5, 115, 0, 0, 880, 881, 5, 46, 0, 0, 881, 882, 5, 108, 0, 0, 882, 883, 5, 101, 0, 0, 883, 884, 5, 110, 0, 0, 884, 885, 5, 103, 0, 0, 885, 886, 5, 116, 0, 0, 886, 926, 5, 104, 0, 0, 887, 888, 5, 116, 0, 0, 888, 889, 5, 120, 0, 0, 889, 890, 5, 46, 0, 0, 890, 891, 5, 111, 0, 0, 891, 892, 5, 117, 0, 0, 892, 893, 5, 116, 0, 0, 893, 894, 5, 112, 0, 0, 894, 895, 5, 117, 0, 0, 895, 896, 5, 116, 0, 0, 896, 897, 5, 115, 0, 0, 897, 898, 5, 46, 0, 0, 898, 899, 5, 108, 0, 0, 899, 900, 5, 101, 0, 0, 900, 901, 5, 110, 0, 0, 901, 902, 5, 103, 0, 0, 902, 903, 5, 116, 0, 0, 903, 926, 5, 104, 0, 0, 904, 905, 5, 116, 0, 0, 905, 906, 5, 120, 0, 0, 906, 907, 5, 46, 0, 0, 907, 908, 5, 118, 0, 0, 908, 909, 5, 101, 0, 0, 909, 910, 5, 114, 0, 0, 910, 911, 5, 115, 0, 0, 911, 912, 5, 105, 0, 0, 912, 913, 5, 111, 0, 0, 913, 926, 5, 110, 0, 0, 914, 915, 5, 116, 0, 0, 915, 916, 5, 120, 0, 0, 916, 917, 5, 46, 0, 0, 917, 918, 5, 108, 0, 0, 918, 919, 5, 111, 0, 0, 919, 920, 5, 99, 0, 0, 920, 921, 5, 107, 0, 0, 921, 922, 5, 116, 0, 0, 922, 923, 5, 105, 0, 0, 923, 924, 5, 109, 0, 0, 924, 926, 5, 101, 0, 0, 925, 831, 1, 0, 0, 0, 925, 852, 1, 0, 0, 0, 925, 871, 1, 0, 0, 0, 925, 887, 1, 0, 0, 0, 925, 904, 1, 0, 0, 0, 925, 914, 1, 0, 0, 0, 926, 160, 1, 0, 0, 0, 927, 931, 7, 7, 0, 0, 928, 930, 7, 8, 0, 0, 929, 928, 1, 0, 0, 0, 930, 933, 1, 0, 0, 0, 931, 929, 1, 0, 0, 0, 931, 932, 1, 0, 0, 0, 932, 162, 1, 0, 0, 0, 933, 931, 1, 0, 0, 0, 934, 936, 7, 9, 0, 0, 935, 934, 1, 0, 0, 0, 936, 937, 1, 0, 0, 0, 937, 935, 1, 0, 0, 0, 937, 938, 1, 0, 0, 0, 938, 939, 1, 0, 0, 0, 939, 940, 6, 81, 0, 0, 940, 164, 1, 0, 0, 0, 941, 942, 5, 47, 0, 0, 942, 943, 5, 42, 0, 0, 943, 947, 1, 0, 0, 0, 944, 946, 9, 0, 0, 0, 945, 944, 1, 0, 0, 0, 946, 949, 1, 0, 0, 0, 947, 948, 1, 0, 0, 0, 947, 945, 1, 0, 0, 0, 948, 950, 1, 0, 0, 0, 949, 947, 1, 0, 0, 0, 950, 951, 5, 42, 0, 0, 951, 952, 5, 47, 0, 0, 952, 953, 1, 0, 0, 0, 953, 954, 6, 82, 1, 0, 954, 166, 1, 0, 0, 0, 955, 956, 5, 47, 0, 0, 956, 957, 5, 47, 0, 0, 957, 961, 1, 0, 0, 0, 958, 960, 8, 10, 0, 0, 959, 958, 1, 0, 0, 0, 960, 963, 1, 0, 0, 0, 961, 959, 1, 0, 0, 0, 961, 962, 1, 0, 0, 0, 962, 964, 1, 0, 0, 0, 963, 961, 1, 0, 0, 0, 964, 965, 6, 83, 1, 0, 965, 168, 1, 0, 0, 0, 28, 0, 558, 564, 570, 581, 640, 643, 647, 652, 658, 662, 697, 716, 722, 729, 731, 739, 741, 745, 761, 779, 816, 829, 925, 931, 937, 947, 961, 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 b9cfb61b..16dc361d 100644 --- a/packages/cashc/src/grammar/CashScriptLexer.tokens +++ b/packages/cashc/src/grammar/CashScriptLexer.tokens @@ -59,26 +59,29 @@ T__57=58 T__58=59 T__59=60 T__60=61 -VersionLiteral=62 -BooleanLiteral=63 -NumberUnit=64 -NumberLiteral=65 -NumberPart=66 -ExponentPart=67 -PrimitiveType=68 -UnboundedBytes=69 -BoundedBytes=70 -Bound=71 -StringLiteral=72 -DateLiteral=73 -HexLiteral=74 -TxVar=75 -UnsafeCast=76 -NullaryOp=77 -Identifier=78 -WHITESPACE=79 -COMMENT=80 -LINE_COMMENT=81 +T__61=62 +T__62=63 +T__63=64 +VersionLiteral=65 +BooleanLiteral=66 +NumberUnit=67 +NumberLiteral=68 +NumberPart=69 +ExponentPart=70 +PrimitiveType=71 +UnboundedBytes=72 +BoundedBytes=73 +Bound=74 +StringLiteral=75 +DateLiteral=76 +HexLiteral=77 +TxVar=78 +UnsafeCast=79 +NullaryOp=80 +Identifier=81 +WHITESPACE=82 +COMMENT=83 +LINE_COMMENT=84 'pragma'=1 ';'=2 'cashscript'=3 @@ -89,55 +92,58 @@ LINE_COMMENT=81 '<'=8 '<='=9 '='=10 -'contract'=11 -'{'=12 -'}'=13 -'function'=14 -'('=15 -','=16 -')'=17 -'+='=18 -'-='=19 -'++'=20 -'--'=21 -'require'=22 -'console.log'=23 -'if'=24 -'else'=25 -'do'=26 -'while'=27 -'for'=28 -'new'=29 -'['=30 -']'=31 -'tx.outputs'=32 -'.value'=33 -'.lockingBytecode'=34 -'.tokenCategory'=35 -'.nftCommitment'=36 -'.tokenAmount'=37 -'tx.inputs'=38 -'.outpointTransactionHash'=39 -'.outpointIndex'=40 -'.unlockingBytecode'=41 -'.sequenceNumber'=42 -'.reverse()'=43 -'.length'=44 -'.split'=45 -'.slice'=46 -'!'=47 -'-'=48 -'*'=49 -'/'=50 -'%'=51 -'+'=52 -'>>'=53 -'<<'=54 -'=='=55 -'!='=56 -'&'=57 -'|'=58 -'&&'=59 -'||'=60 -'constant'=61 -'bytes'=69 +'import'=11 +'function'=12 +'returns'=13 +'('=14 +')'=15 +'contract'=16 +'{'=17 +'}'=18 +','=19 +'return'=20 +'+='=21 +'-='=22 +'++'=23 +'--'=24 +'require'=25 +'console.log'=26 +'if'=27 +'else'=28 +'do'=29 +'while'=30 +'for'=31 +'new'=32 +'['=33 +']'=34 +'tx.outputs'=35 +'.value'=36 +'.lockingBytecode'=37 +'.tokenCategory'=38 +'.nftCommitment'=39 +'.tokenAmount'=40 +'tx.inputs'=41 +'.outpointTransactionHash'=42 +'.outpointIndex'=43 +'.unlockingBytecode'=44 +'.sequenceNumber'=45 +'.reverse()'=46 +'.length'=47 +'.split'=48 +'.slice'=49 +'!'=50 +'-'=51 +'*'=52 +'/'=53 +'%'=54 +'+'=55 +'>>'=56 +'<<'=57 +'=='=58 +'!='=59 +'&'=60 +'|'=61 +'&&'=62 +'||'=63 +'constant'=64 +'bytes'=72 diff --git a/packages/cashc/src/grammar/CashScriptLexer.ts b/packages/cashc/src/grammar/CashScriptLexer.ts index c67a03b5..0300faed 100644 --- a/packages/cashc/src/grammar/CashScriptLexer.ts +++ b/packages/cashc/src/grammar/CashScriptLexer.ts @@ -73,26 +73,29 @@ export default class CashScriptLexer extends Lexer { public static readonly T__58 = 59; public static readonly T__59 = 60; public static readonly T__60 = 61; - public static readonly VersionLiteral = 62; - public static readonly BooleanLiteral = 63; - public static readonly NumberUnit = 64; - public static readonly NumberLiteral = 65; - public static readonly NumberPart = 66; - public static readonly ExponentPart = 67; - public static readonly PrimitiveType = 68; - public static readonly UnboundedBytes = 69; - public static readonly BoundedBytes = 70; - public static readonly Bound = 71; - public static readonly StringLiteral = 72; - public static readonly DateLiteral = 73; - public static readonly HexLiteral = 74; - public static readonly TxVar = 75; - public static readonly UnsafeCast = 76; - public static readonly NullaryOp = 77; - public static readonly Identifier = 78; - public static readonly WHITESPACE = 79; - public static readonly COMMENT = 80; - public static readonly LINE_COMMENT = 81; + public static readonly T__61 = 62; + public static readonly T__62 = 63; + public static readonly T__63 = 64; + public static readonly VersionLiteral = 65; + public static readonly BooleanLiteral = 66; + public static readonly NumberUnit = 67; + public static readonly NumberLiteral = 68; + public static readonly NumberPart = 69; + public static readonly ExponentPart = 70; + public static readonly PrimitiveType = 71; + public static readonly UnboundedBytes = 72; + public static readonly BoundedBytes = 73; + public static readonly Bound = 74; + public static readonly StringLiteral = 75; + public static readonly DateLiteral = 76; + public static readonly HexLiteral = 77; + public static readonly TxVar = 78; + public static readonly UnsafeCast = 79; + public static readonly NullaryOp = 80; + public static readonly Identifier = 81; + public static readonly WHITESPACE = 82; + public static readonly COMMENT = 83; + public static readonly LINE_COMMENT = 84; public static readonly EOF = Token.EOF; public static readonly channelNames: string[] = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN" ]; @@ -101,13 +104,16 @@ export default class CashScriptLexer extends Lexer { "'^'", "'~'", "'>='", "'>'", "'<'", "'<='", - "'='", "'contract'", - "'{'", "'}'", + "'='", "'import'", "'function'", - "'('", "','", - "')'", "'+='", - "'-='", "'++'", - "'--'", "'require'", + "'returns'", + "'('", "')'", + "'contract'", + "'{'", "'}'", + "','", "'return'", + "'+='", "'-='", + "'++'", "'--'", + "'require'", "'console.log'", "'if'", "'else'", "'do'", "'while'", @@ -171,7 +177,8 @@ export default class CashScriptLexer extends Lexer { null, null, null, null, null, null, - "VersionLiteral", + null, null, + null, "VersionLiteral", "BooleanLiteral", "NumberUnit", "NumberLiteral", @@ -199,11 +206,11 @@ export default class CashScriptLexer extends Lexer { "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", "T__58", "T__59", "T__60", "VersionLiteral", "BooleanLiteral", - "NumberUnit", "NumberLiteral", "NumberPart", "ExponentPart", "PrimitiveType", - "UnboundedBytes", "BoundedBytes", "Bound", "StringLiteral", "DateLiteral", - "HexLiteral", "TxVar", "UnsafeCast", "NullaryOp", "Identifier", "WHITESPACE", - "COMMENT", "LINE_COMMENT", + "T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "VersionLiteral", + "BooleanLiteral", "NumberUnit", "NumberLiteral", "NumberPart", "ExponentPart", + "PrimitiveType", "UnboundedBytes", "BoundedBytes", "Bound", "StringLiteral", + "DateLiteral", "HexLiteral", "TxVar", "UnsafeCast", "NullaryOp", "Identifier", + "WHITESPACE", "COMMENT", "LINE_COMMENT", ]; @@ -224,7 +231,7 @@ export default class CashScriptLexer extends Lexer { public get modeNames(): string[] { return CashScriptLexer.modeNames; } - public static readonly _serializedATN: number[] = [4,0,81,938,6,-1,2,0, + public static readonly _serializedATN: number[] = [4,0,84,966,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, @@ -235,304 +242,313 @@ 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,2,75,7,75,2,76,7,76,2,77,7,77,2,78,7,78,2,79,7,79,2,80,7,80,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,18,1,18,1,18,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,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,24,1,24,1,24,1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,26, - 1,26,1,26,1,26,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,29,1,29,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,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,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,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,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38, - 1,38,1,38,1,38,1,38,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,39,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,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1, - 40,1,40,1,40,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41, - 1,41,1,41,1,41,1,41,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1, - 42,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44,1,44,1,44,1,44, - 1,44,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,46,1,46,1,47,1,47,1,48,1,48,1, - 49,1,49,1,50,1,50,1,51,1,51,1,52,1,52,1,52,1,53,1,53,1,53,1,54,1,54,1,54, - 1,55,1,55,1,55,1,56,1,56,1,57,1,57,1,58,1,58,1,58,1,59,1,59,1,59,1,60,1, - 60,1,60,1,60,1,60,1,60,1,60,1,60,1,60,1,61,4,61,529,8,61,11,61,12,61,530, - 1,61,1,61,4,61,535,8,61,11,61,12,61,536,1,61,1,61,4,61,541,8,61,11,61,12, - 61,542,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,1,62,3,62,554,8,62,1,63, - 1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1, - 63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63, - 1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1, - 63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,3,63,613, - 8,63,1,64,3,64,616,8,64,1,64,1,64,3,64,620,8,64,1,65,4,65,623,8,65,11,65, - 12,65,624,1,65,1,65,4,65,629,8,65,11,65,12,65,630,5,65,633,8,65,10,65,12, - 65,636,9,65,1,66,1,66,1,66,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67, - 1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1,67,1, - 67,1,67,1,67,1,67,1,67,1,67,3,67,670,8,67,1,68,1,68,1,68,1,68,1,68,1,68, - 1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,1,69,3,69,689,8,69,1, - 70,1,70,5,70,693,8,70,10,70,12,70,696,9,70,1,71,1,71,1,71,1,71,5,71,702, - 8,71,10,71,12,71,705,9,71,1,71,1,71,1,71,1,71,1,71,5,71,712,8,71,10,71, - 12,71,715,9,71,1,71,3,71,718,8,71,1,72,1,72,1,72,1,72,1,72,1,72,1,72,1, - 72,1,72,1,73,1,73,1,73,5,73,732,8,73,10,73,12,73,735,9,73,1,74,1,74,1,74, - 1,74,1,74,1,74,1,74,1,74,1,74,1,74,1,74,1,74,1,74,1,74,1,74,3,74,752,8, - 74,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75, - 1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1, - 75,1,75,1,75,1,75,1,75,1,75,1,75,3,75,789,8,75,1,75,1,75,1,75,1,75,1,75, - 1,75,1,75,1,75,1,75,1,75,1,75,3,75,802,8,75,1,76,1,76,1,76,1,76,1,76,1, - 76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76, - 1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1, - 76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76, - 1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1, - 76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76, - 1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1,76,1, - 76,1,76,3,76,898,8,76,1,77,1,77,5,77,902,8,77,10,77,12,77,905,9,77,1,78, - 4,78,908,8,78,11,78,12,78,909,1,78,1,78,1,79,1,79,1,79,1,79,5,79,918,8, - 79,10,79,12,79,921,9,79,1,79,1,79,1,79,1,79,1,79,1,80,1,80,1,80,1,80,5, - 80,932,8,80,10,80,12,80,935,9,80,1,80,1,80,3,703,713,919,0,81,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,153,77,155,78,157,79,159,80,161,81,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,982,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,0,153,1,0, - 0,0,0,155,1,0,0,0,0,157,1,0,0,0,0,159,1,0,0,0,0,161,1,0,0,0,1,163,1,0,0, - 0,3,170,1,0,0,0,5,172,1,0,0,0,7,183,1,0,0,0,9,185,1,0,0,0,11,187,1,0,0, - 0,13,190,1,0,0,0,15,192,1,0,0,0,17,194,1,0,0,0,19,197,1,0,0,0,21,199,1, - 0,0,0,23,208,1,0,0,0,25,210,1,0,0,0,27,212,1,0,0,0,29,221,1,0,0,0,31,223, - 1,0,0,0,33,225,1,0,0,0,35,227,1,0,0,0,37,230,1,0,0,0,39,233,1,0,0,0,41, - 236,1,0,0,0,43,239,1,0,0,0,45,247,1,0,0,0,47,259,1,0,0,0,49,262,1,0,0,0, - 51,267,1,0,0,0,53,270,1,0,0,0,55,276,1,0,0,0,57,280,1,0,0,0,59,284,1,0, - 0,0,61,286,1,0,0,0,63,288,1,0,0,0,65,299,1,0,0,0,67,306,1,0,0,0,69,323, - 1,0,0,0,71,338,1,0,0,0,73,353,1,0,0,0,75,366,1,0,0,0,77,376,1,0,0,0,79, - 401,1,0,0,0,81,416,1,0,0,0,83,435,1,0,0,0,85,451,1,0,0,0,87,462,1,0,0,0, - 89,470,1,0,0,0,91,477,1,0,0,0,93,484,1,0,0,0,95,486,1,0,0,0,97,488,1,0, - 0,0,99,490,1,0,0,0,101,492,1,0,0,0,103,494,1,0,0,0,105,496,1,0,0,0,107, - 499,1,0,0,0,109,502,1,0,0,0,111,505,1,0,0,0,113,508,1,0,0,0,115,510,1,0, - 0,0,117,512,1,0,0,0,119,515,1,0,0,0,121,518,1,0,0,0,123,528,1,0,0,0,125, - 553,1,0,0,0,127,612,1,0,0,0,129,615,1,0,0,0,131,622,1,0,0,0,133,637,1,0, - 0,0,135,669,1,0,0,0,137,671,1,0,0,0,139,688,1,0,0,0,141,690,1,0,0,0,143, - 717,1,0,0,0,145,719,1,0,0,0,147,728,1,0,0,0,149,751,1,0,0,0,151,801,1,0, - 0,0,153,897,1,0,0,0,155,899,1,0,0,0,157,907,1,0,0,0,159,913,1,0,0,0,161, - 927,1,0,0,0,163,164,5,112,0,0,164,165,5,114,0,0,165,166,5,97,0,0,166,167, - 5,103,0,0,167,168,5,109,0,0,168,169,5,97,0,0,169,2,1,0,0,0,170,171,5,59, - 0,0,171,4,1,0,0,0,172,173,5,99,0,0,173,174,5,97,0,0,174,175,5,115,0,0,175, - 176,5,104,0,0,176,177,5,115,0,0,177,178,5,99,0,0,178,179,5,114,0,0,179, - 180,5,105,0,0,180,181,5,112,0,0,181,182,5,116,0,0,182,6,1,0,0,0,183,184, - 5,94,0,0,184,8,1,0,0,0,185,186,5,126,0,0,186,10,1,0,0,0,187,188,5,62,0, - 0,188,189,5,61,0,0,189,12,1,0,0,0,190,191,5,62,0,0,191,14,1,0,0,0,192,193, - 5,60,0,0,193,16,1,0,0,0,194,195,5,60,0,0,195,196,5,61,0,0,196,18,1,0,0, - 0,197,198,5,61,0,0,198,20,1,0,0,0,199,200,5,99,0,0,200,201,5,111,0,0,201, - 202,5,110,0,0,202,203,5,116,0,0,203,204,5,114,0,0,204,205,5,97,0,0,205, - 206,5,99,0,0,206,207,5,116,0,0,207,22,1,0,0,0,208,209,5,123,0,0,209,24, - 1,0,0,0,210,211,5,125,0,0,211,26,1,0,0,0,212,213,5,102,0,0,213,214,5,117, - 0,0,214,215,5,110,0,0,215,216,5,99,0,0,216,217,5,116,0,0,217,218,5,105, - 0,0,218,219,5,111,0,0,219,220,5,110,0,0,220,28,1,0,0,0,221,222,5,40,0,0, - 222,30,1,0,0,0,223,224,5,44,0,0,224,32,1,0,0,0,225,226,5,41,0,0,226,34, - 1,0,0,0,227,228,5,43,0,0,228,229,5,61,0,0,229,36,1,0,0,0,230,231,5,45,0, - 0,231,232,5,61,0,0,232,38,1,0,0,0,233,234,5,43,0,0,234,235,5,43,0,0,235, - 40,1,0,0,0,236,237,5,45,0,0,237,238,5,45,0,0,238,42,1,0,0,0,239,240,5,114, - 0,0,240,241,5,101,0,0,241,242,5,113,0,0,242,243,5,117,0,0,243,244,5,105, - 0,0,244,245,5,114,0,0,245,246,5,101,0,0,246,44,1,0,0,0,247,248,5,99,0,0, - 248,249,5,111,0,0,249,250,5,110,0,0,250,251,5,115,0,0,251,252,5,111,0,0, - 252,253,5,108,0,0,253,254,5,101,0,0,254,255,5,46,0,0,255,256,5,108,0,0, - 256,257,5,111,0,0,257,258,5,103,0,0,258,46,1,0,0,0,259,260,5,105,0,0,260, - 261,5,102,0,0,261,48,1,0,0,0,262,263,5,101,0,0,263,264,5,108,0,0,264,265, - 5,115,0,0,265,266,5,101,0,0,266,50,1,0,0,0,267,268,5,100,0,0,268,269,5, - 111,0,0,269,52,1,0,0,0,270,271,5,119,0,0,271,272,5,104,0,0,272,273,5,105, - 0,0,273,274,5,108,0,0,274,275,5,101,0,0,275,54,1,0,0,0,276,277,5,102,0, - 0,277,278,5,111,0,0,278,279,5,114,0,0,279,56,1,0,0,0,280,281,5,110,0,0, - 281,282,5,101,0,0,282,283,5,119,0,0,283,58,1,0,0,0,284,285,5,91,0,0,285, - 60,1,0,0,0,286,287,5,93,0,0,287,62,1,0,0,0,288,289,5,116,0,0,289,290,5, - 120,0,0,290,291,5,46,0,0,291,292,5,111,0,0,292,293,5,117,0,0,293,294,5, - 116,0,0,294,295,5,112,0,0,295,296,5,117,0,0,296,297,5,116,0,0,297,298,5, - 115,0,0,298,64,1,0,0,0,299,300,5,46,0,0,300,301,5,118,0,0,301,302,5,97, - 0,0,302,303,5,108,0,0,303,304,5,117,0,0,304,305,5,101,0,0,305,66,1,0,0, - 0,306,307,5,46,0,0,307,308,5,108,0,0,308,309,5,111,0,0,309,310,5,99,0,0, - 310,311,5,107,0,0,311,312,5,105,0,0,312,313,5,110,0,0,313,314,5,103,0,0, - 314,315,5,66,0,0,315,316,5,121,0,0,316,317,5,116,0,0,317,318,5,101,0,0, - 318,319,5,99,0,0,319,320,5,111,0,0,320,321,5,100,0,0,321,322,5,101,0,0, - 322,68,1,0,0,0,323,324,5,46,0,0,324,325,5,116,0,0,325,326,5,111,0,0,326, - 327,5,107,0,0,327,328,5,101,0,0,328,329,5,110,0,0,329,330,5,67,0,0,330, - 331,5,97,0,0,331,332,5,116,0,0,332,333,5,101,0,0,333,334,5,103,0,0,334, - 335,5,111,0,0,335,336,5,114,0,0,336,337,5,121,0,0,337,70,1,0,0,0,338,339, - 5,46,0,0,339,340,5,110,0,0,340,341,5,102,0,0,341,342,5,116,0,0,342,343, - 5,67,0,0,343,344,5,111,0,0,344,345,5,109,0,0,345,346,5,109,0,0,346,347, - 5,105,0,0,347,348,5,116,0,0,348,349,5,109,0,0,349,350,5,101,0,0,350,351, - 5,110,0,0,351,352,5,116,0,0,352,72,1,0,0,0,353,354,5,46,0,0,354,355,5,116, - 0,0,355,356,5,111,0,0,356,357,5,107,0,0,357,358,5,101,0,0,358,359,5,110, - 0,0,359,360,5,65,0,0,360,361,5,109,0,0,361,362,5,111,0,0,362,363,5,117, - 0,0,363,364,5,110,0,0,364,365,5,116,0,0,365,74,1,0,0,0,366,367,5,116,0, - 0,367,368,5,120,0,0,368,369,5,46,0,0,369,370,5,105,0,0,370,371,5,110,0, - 0,371,372,5,112,0,0,372,373,5,117,0,0,373,374,5,116,0,0,374,375,5,115,0, - 0,375,76,1,0,0,0,376,377,5,46,0,0,377,378,5,111,0,0,378,379,5,117,0,0,379, - 380,5,116,0,0,380,381,5,112,0,0,381,382,5,111,0,0,382,383,5,105,0,0,383, - 384,5,110,0,0,384,385,5,116,0,0,385,386,5,84,0,0,386,387,5,114,0,0,387, - 388,5,97,0,0,388,389,5,110,0,0,389,390,5,115,0,0,390,391,5,97,0,0,391,392, - 5,99,0,0,392,393,5,116,0,0,393,394,5,105,0,0,394,395,5,111,0,0,395,396, - 5,110,0,0,396,397,5,72,0,0,397,398,5,97,0,0,398,399,5,115,0,0,399,400,5, - 104,0,0,400,78,1,0,0,0,401,402,5,46,0,0,402,403,5,111,0,0,403,404,5,117, - 0,0,404,405,5,116,0,0,405,406,5,112,0,0,406,407,5,111,0,0,407,408,5,105, - 0,0,408,409,5,110,0,0,409,410,5,116,0,0,410,411,5,73,0,0,411,412,5,110, - 0,0,412,413,5,100,0,0,413,414,5,101,0,0,414,415,5,120,0,0,415,80,1,0,0, - 0,416,417,5,46,0,0,417,418,5,117,0,0,418,419,5,110,0,0,419,420,5,108,0, - 0,420,421,5,111,0,0,421,422,5,99,0,0,422,423,5,107,0,0,423,424,5,105,0, - 0,424,425,5,110,0,0,425,426,5,103,0,0,426,427,5,66,0,0,427,428,5,121,0, - 0,428,429,5,116,0,0,429,430,5,101,0,0,430,431,5,99,0,0,431,432,5,111,0, - 0,432,433,5,100,0,0,433,434,5,101,0,0,434,82,1,0,0,0,435,436,5,46,0,0,436, - 437,5,115,0,0,437,438,5,101,0,0,438,439,5,113,0,0,439,440,5,117,0,0,440, - 441,5,101,0,0,441,442,5,110,0,0,442,443,5,99,0,0,443,444,5,101,0,0,444, - 445,5,78,0,0,445,446,5,117,0,0,446,447,5,109,0,0,447,448,5,98,0,0,448,449, - 5,101,0,0,449,450,5,114,0,0,450,84,1,0,0,0,451,452,5,46,0,0,452,453,5,114, - 0,0,453,454,5,101,0,0,454,455,5,118,0,0,455,456,5,101,0,0,456,457,5,114, - 0,0,457,458,5,115,0,0,458,459,5,101,0,0,459,460,5,40,0,0,460,461,5,41,0, - 0,461,86,1,0,0,0,462,463,5,46,0,0,463,464,5,108,0,0,464,465,5,101,0,0,465, - 466,5,110,0,0,466,467,5,103,0,0,467,468,5,116,0,0,468,469,5,104,0,0,469, - 88,1,0,0,0,470,471,5,46,0,0,471,472,5,115,0,0,472,473,5,112,0,0,473,474, - 5,108,0,0,474,475,5,105,0,0,475,476,5,116,0,0,476,90,1,0,0,0,477,478,5, - 46,0,0,478,479,5,115,0,0,479,480,5,108,0,0,480,481,5,105,0,0,481,482,5, - 99,0,0,482,483,5,101,0,0,483,92,1,0,0,0,484,485,5,33,0,0,485,94,1,0,0,0, - 486,487,5,45,0,0,487,96,1,0,0,0,488,489,5,42,0,0,489,98,1,0,0,0,490,491, - 5,47,0,0,491,100,1,0,0,0,492,493,5,37,0,0,493,102,1,0,0,0,494,495,5,43, - 0,0,495,104,1,0,0,0,496,497,5,62,0,0,497,498,5,62,0,0,498,106,1,0,0,0,499, - 500,5,60,0,0,500,501,5,60,0,0,501,108,1,0,0,0,502,503,5,61,0,0,503,504, - 5,61,0,0,504,110,1,0,0,0,505,506,5,33,0,0,506,507,5,61,0,0,507,112,1,0, - 0,0,508,509,5,38,0,0,509,114,1,0,0,0,510,511,5,124,0,0,511,116,1,0,0,0, - 512,513,5,38,0,0,513,514,5,38,0,0,514,118,1,0,0,0,515,516,5,124,0,0,516, - 517,5,124,0,0,517,120,1,0,0,0,518,519,5,99,0,0,519,520,5,111,0,0,520,521, - 5,110,0,0,521,522,5,115,0,0,522,523,5,116,0,0,523,524,5,97,0,0,524,525, - 5,110,0,0,525,526,5,116,0,0,526,122,1,0,0,0,527,529,7,0,0,0,528,527,1,0, - 0,0,529,530,1,0,0,0,530,528,1,0,0,0,530,531,1,0,0,0,531,532,1,0,0,0,532, - 534,5,46,0,0,533,535,7,0,0,0,534,533,1,0,0,0,535,536,1,0,0,0,536,534,1, - 0,0,0,536,537,1,0,0,0,537,538,1,0,0,0,538,540,5,46,0,0,539,541,7,0,0,0, - 540,539,1,0,0,0,541,542,1,0,0,0,542,540,1,0,0,0,542,543,1,0,0,0,543,124, - 1,0,0,0,544,545,5,116,0,0,545,546,5,114,0,0,546,547,5,117,0,0,547,554,5, - 101,0,0,548,549,5,102,0,0,549,550,5,97,0,0,550,551,5,108,0,0,551,552,5, - 115,0,0,552,554,5,101,0,0,553,544,1,0,0,0,553,548,1,0,0,0,554,126,1,0,0, - 0,555,556,5,115,0,0,556,557,5,97,0,0,557,558,5,116,0,0,558,559,5,111,0, - 0,559,560,5,115,0,0,560,561,5,104,0,0,561,562,5,105,0,0,562,613,5,115,0, - 0,563,564,5,115,0,0,564,565,5,97,0,0,565,566,5,116,0,0,566,613,5,115,0, - 0,567,568,5,102,0,0,568,569,5,105,0,0,569,570,5,110,0,0,570,571,5,110,0, - 0,571,572,5,101,0,0,572,613,5,121,0,0,573,574,5,98,0,0,574,575,5,105,0, - 0,575,576,5,116,0,0,576,613,5,115,0,0,577,578,5,98,0,0,578,579,5,105,0, - 0,579,580,5,116,0,0,580,581,5,99,0,0,581,582,5,111,0,0,582,583,5,105,0, - 0,583,613,5,110,0,0,584,585,5,115,0,0,585,586,5,101,0,0,586,587,5,99,0, - 0,587,588,5,111,0,0,588,589,5,110,0,0,589,590,5,100,0,0,590,613,5,115,0, - 0,591,592,5,109,0,0,592,593,5,105,0,0,593,594,5,110,0,0,594,595,5,117,0, - 0,595,596,5,116,0,0,596,597,5,101,0,0,597,613,5,115,0,0,598,599,5,104,0, - 0,599,600,5,111,0,0,600,601,5,117,0,0,601,602,5,114,0,0,602,613,5,115,0, - 0,603,604,5,100,0,0,604,605,5,97,0,0,605,606,5,121,0,0,606,613,5,115,0, - 0,607,608,5,119,0,0,608,609,5,101,0,0,609,610,5,101,0,0,610,611,5,107,0, - 0,611,613,5,115,0,0,612,555,1,0,0,0,612,563,1,0,0,0,612,567,1,0,0,0,612, - 573,1,0,0,0,612,577,1,0,0,0,612,584,1,0,0,0,612,591,1,0,0,0,612,598,1,0, - 0,0,612,603,1,0,0,0,612,607,1,0,0,0,613,128,1,0,0,0,614,616,5,45,0,0,615, - 614,1,0,0,0,615,616,1,0,0,0,616,617,1,0,0,0,617,619,3,131,65,0,618,620, - 3,133,66,0,619,618,1,0,0,0,619,620,1,0,0,0,620,130,1,0,0,0,621,623,7,0, - 0,0,622,621,1,0,0,0,623,624,1,0,0,0,624,622,1,0,0,0,624,625,1,0,0,0,625, - 634,1,0,0,0,626,628,5,95,0,0,627,629,7,0,0,0,628,627,1,0,0,0,629,630,1, - 0,0,0,630,628,1,0,0,0,630,631,1,0,0,0,631,633,1,0,0,0,632,626,1,0,0,0,633, - 636,1,0,0,0,634,632,1,0,0,0,634,635,1,0,0,0,635,132,1,0,0,0,636,634,1,0, - 0,0,637,638,7,1,0,0,638,639,3,131,65,0,639,134,1,0,0,0,640,641,5,105,0, - 0,641,642,5,110,0,0,642,670,5,116,0,0,643,644,5,98,0,0,644,645,5,111,0, - 0,645,646,5,111,0,0,646,670,5,108,0,0,647,648,5,115,0,0,648,649,5,116,0, - 0,649,650,5,114,0,0,650,651,5,105,0,0,651,652,5,110,0,0,652,670,5,103,0, - 0,653,654,5,112,0,0,654,655,5,117,0,0,655,656,5,98,0,0,656,657,5,107,0, - 0,657,658,5,101,0,0,658,670,5,121,0,0,659,660,5,115,0,0,660,661,5,105,0, - 0,661,670,5,103,0,0,662,663,5,100,0,0,663,664,5,97,0,0,664,665,5,116,0, - 0,665,666,5,97,0,0,666,667,5,115,0,0,667,668,5,105,0,0,668,670,5,103,0, - 0,669,640,1,0,0,0,669,643,1,0,0,0,669,647,1,0,0,0,669,653,1,0,0,0,669,659, - 1,0,0,0,669,662,1,0,0,0,670,136,1,0,0,0,671,672,5,98,0,0,672,673,5,121, - 0,0,673,674,5,116,0,0,674,675,5,101,0,0,675,676,5,115,0,0,676,138,1,0,0, - 0,677,678,5,98,0,0,678,679,5,121,0,0,679,680,5,116,0,0,680,681,5,101,0, - 0,681,682,5,115,0,0,682,683,1,0,0,0,683,689,3,141,70,0,684,685,5,98,0,0, - 685,686,5,121,0,0,686,687,5,116,0,0,687,689,5,101,0,0,688,677,1,0,0,0,688, - 684,1,0,0,0,689,140,1,0,0,0,690,694,7,2,0,0,691,693,7,0,0,0,692,691,1,0, - 0,0,693,696,1,0,0,0,694,692,1,0,0,0,694,695,1,0,0,0,695,142,1,0,0,0,696, - 694,1,0,0,0,697,703,5,34,0,0,698,699,5,92,0,0,699,702,5,34,0,0,700,702, - 8,3,0,0,701,698,1,0,0,0,701,700,1,0,0,0,702,705,1,0,0,0,703,704,1,0,0,0, - 703,701,1,0,0,0,704,706,1,0,0,0,705,703,1,0,0,0,706,718,5,34,0,0,707,713, - 5,39,0,0,708,709,5,92,0,0,709,712,5,39,0,0,710,712,8,4,0,0,711,708,1,0, - 0,0,711,710,1,0,0,0,712,715,1,0,0,0,713,714,1,0,0,0,713,711,1,0,0,0,714, - 716,1,0,0,0,715,713,1,0,0,0,716,718,5,39,0,0,717,697,1,0,0,0,717,707,1, - 0,0,0,718,144,1,0,0,0,719,720,5,100,0,0,720,721,5,97,0,0,721,722,5,116, - 0,0,722,723,5,101,0,0,723,724,5,40,0,0,724,725,1,0,0,0,725,726,3,143,71, - 0,726,727,5,41,0,0,727,146,1,0,0,0,728,729,5,48,0,0,729,733,7,5,0,0,730, - 732,7,6,0,0,731,730,1,0,0,0,732,735,1,0,0,0,733,731,1,0,0,0,733,734,1,0, - 0,0,734,148,1,0,0,0,735,733,1,0,0,0,736,737,5,116,0,0,737,738,5,104,0,0, - 738,739,5,105,0,0,739,740,5,115,0,0,740,741,5,46,0,0,741,742,5,97,0,0,742, - 743,5,103,0,0,743,752,5,101,0,0,744,745,5,116,0,0,745,746,5,120,0,0,746, - 747,5,46,0,0,747,748,5,116,0,0,748,749,5,105,0,0,749,750,5,109,0,0,750, - 752,5,101,0,0,751,736,1,0,0,0,751,744,1,0,0,0,752,150,1,0,0,0,753,754,5, - 117,0,0,754,755,5,110,0,0,755,756,5,115,0,0,756,757,5,97,0,0,757,758,5, - 102,0,0,758,759,5,101,0,0,759,760,5,95,0,0,760,761,5,105,0,0,761,762,5, - 110,0,0,762,802,5,116,0,0,763,764,5,117,0,0,764,765,5,110,0,0,765,766,5, - 115,0,0,766,767,5,97,0,0,767,768,5,102,0,0,768,769,5,101,0,0,769,770,5, - 95,0,0,770,771,5,98,0,0,771,772,5,111,0,0,772,773,5,111,0,0,773,802,5,108, - 0,0,774,775,5,117,0,0,775,776,5,110,0,0,776,777,5,115,0,0,777,778,5,97, - 0,0,778,779,5,102,0,0,779,780,5,101,0,0,780,781,5,95,0,0,781,782,5,98,0, - 0,782,783,5,121,0,0,783,784,5,116,0,0,784,785,5,101,0,0,785,786,5,115,0, - 0,786,788,1,0,0,0,787,789,3,141,70,0,788,787,1,0,0,0,788,789,1,0,0,0,789, - 802,1,0,0,0,790,791,5,117,0,0,791,792,5,110,0,0,792,793,5,115,0,0,793,794, - 5,97,0,0,794,795,5,102,0,0,795,796,5,101,0,0,796,797,5,95,0,0,797,798,5, - 98,0,0,798,799,5,121,0,0,799,800,5,116,0,0,800,802,5,101,0,0,801,753,1, - 0,0,0,801,763,1,0,0,0,801,774,1,0,0,0,801,790,1,0,0,0,802,152,1,0,0,0,803, - 804,5,116,0,0,804,805,5,104,0,0,805,806,5,105,0,0,806,807,5,115,0,0,807, - 808,5,46,0,0,808,809,5,97,0,0,809,810,5,99,0,0,810,811,5,116,0,0,811,812, - 5,105,0,0,812,813,5,118,0,0,813,814,5,101,0,0,814,815,5,73,0,0,815,816, - 5,110,0,0,816,817,5,112,0,0,817,818,5,117,0,0,818,819,5,116,0,0,819,820, - 5,73,0,0,820,821,5,110,0,0,821,822,5,100,0,0,822,823,5,101,0,0,823,898, - 5,120,0,0,824,825,5,116,0,0,825,826,5,104,0,0,826,827,5,105,0,0,827,828, - 5,115,0,0,828,829,5,46,0,0,829,830,5,97,0,0,830,831,5,99,0,0,831,832,5, - 116,0,0,832,833,5,105,0,0,833,834,5,118,0,0,834,835,5,101,0,0,835,836,5, - 66,0,0,836,837,5,121,0,0,837,838,5,116,0,0,838,839,5,101,0,0,839,840,5, - 99,0,0,840,841,5,111,0,0,841,842,5,100,0,0,842,898,5,101,0,0,843,844,5, - 116,0,0,844,845,5,120,0,0,845,846,5,46,0,0,846,847,5,105,0,0,847,848,5, - 110,0,0,848,849,5,112,0,0,849,850,5,117,0,0,850,851,5,116,0,0,851,852,5, - 115,0,0,852,853,5,46,0,0,853,854,5,108,0,0,854,855,5,101,0,0,855,856,5, - 110,0,0,856,857,5,103,0,0,857,858,5,116,0,0,858,898,5,104,0,0,859,860,5, - 116,0,0,860,861,5,120,0,0,861,862,5,46,0,0,862,863,5,111,0,0,863,864,5, - 117,0,0,864,865,5,116,0,0,865,866,5,112,0,0,866,867,5,117,0,0,867,868,5, - 116,0,0,868,869,5,115,0,0,869,870,5,46,0,0,870,871,5,108,0,0,871,872,5, - 101,0,0,872,873,5,110,0,0,873,874,5,103,0,0,874,875,5,116,0,0,875,898,5, - 104,0,0,876,877,5,116,0,0,877,878,5,120,0,0,878,879,5,46,0,0,879,880,5, - 118,0,0,880,881,5,101,0,0,881,882,5,114,0,0,882,883,5,115,0,0,883,884,5, - 105,0,0,884,885,5,111,0,0,885,898,5,110,0,0,886,887,5,116,0,0,887,888,5, - 120,0,0,888,889,5,46,0,0,889,890,5,108,0,0,890,891,5,111,0,0,891,892,5, - 99,0,0,892,893,5,107,0,0,893,894,5,116,0,0,894,895,5,105,0,0,895,896,5, - 109,0,0,896,898,5,101,0,0,897,803,1,0,0,0,897,824,1,0,0,0,897,843,1,0,0, - 0,897,859,1,0,0,0,897,876,1,0,0,0,897,886,1,0,0,0,898,154,1,0,0,0,899,903, - 7,7,0,0,900,902,7,8,0,0,901,900,1,0,0,0,902,905,1,0,0,0,903,901,1,0,0,0, - 903,904,1,0,0,0,904,156,1,0,0,0,905,903,1,0,0,0,906,908,7,9,0,0,907,906, - 1,0,0,0,908,909,1,0,0,0,909,907,1,0,0,0,909,910,1,0,0,0,910,911,1,0,0,0, - 911,912,6,78,0,0,912,158,1,0,0,0,913,914,5,47,0,0,914,915,5,42,0,0,915, - 919,1,0,0,0,916,918,9,0,0,0,917,916,1,0,0,0,918,921,1,0,0,0,919,920,1,0, - 0,0,919,917,1,0,0,0,920,922,1,0,0,0,921,919,1,0,0,0,922,923,5,42,0,0,923, - 924,5,47,0,0,924,925,1,0,0,0,925,926,6,79,1,0,926,160,1,0,0,0,927,928,5, - 47,0,0,928,929,5,47,0,0,929,933,1,0,0,0,930,932,8,10,0,0,931,930,1,0,0, - 0,932,935,1,0,0,0,933,931,1,0,0,0,933,934,1,0,0,0,934,936,1,0,0,0,935,933, - 1,0,0,0,936,937,6,80,1,0,937,162,1,0,0,0,28,0,530,536,542,553,612,615,619, - 624,630,634,669,688,694,701,703,711,713,717,733,751,788,801,897,903,909, - 919,933,2,6,0,0,0,1,0]; + 74,2,75,7,75,2,76,7,76,2,77,7,77,2,78,7,78,2,79,7,79,2,80,7,80,2,81,7,81, + 2,82,7,82,2,83,7,83,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,11,1,11,1,11,1, + 11,1,11,1,11,1,11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,13, + 1,13,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,15,1,15,1,15,1,15,1,16,1,16,1, + 17,1,17,1,18,1,18,1,19,1,19,1,19,1,19,1,19,1,19,1,19,1,20,1,20,1,20,1,21, + 1,21,1,21,1,22,1,22,1,22,1,23,1,23,1,23,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,25,1,25,1,25,1,25,1,25,1,26, + 1,26,1,26,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,29,1,29,1,29,1,29,1, + 29,1,29,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31,1,32,1,32,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,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,36,1,37,1,37,1,37,1,37,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,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,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,40,1,40,1,40, + 1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1, + 41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1,42, + 1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,43,1,43,1,43,1, + 43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43, + 1,43,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1, + 44,1,44,1,44,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,46, + 1,46,1,46,1,46,1,46,1,46,1,46,1,46,1,47,1,47,1,47,1,47,1,47,1,47,1,47,1, + 48,1,48,1,48,1,48,1,48,1,48,1,48,1,49,1,49,1,50,1,50,1,51,1,51,1,52,1,52, + 1,53,1,53,1,54,1,54,1,55,1,55,1,55,1,56,1,56,1,56,1,57,1,57,1,57,1,58,1, + 58,1,58,1,59,1,59,1,60,1,60,1,61,1,61,1,61,1,62,1,62,1,62,1,63,1,63,1,63, + 1,63,1,63,1,63,1,63,1,63,1,63,1,64,4,64,557,8,64,11,64,12,64,558,1,64,1, + 64,4,64,563,8,64,11,64,12,64,564,1,64,1,64,4,64,569,8,64,11,64,12,64,570, + 1,65,1,65,1,65,1,65,1,65,1,65,1,65,1,65,1,65,3,65,582,8,65,1,66,1,66,1, + 66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66, + 1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1, + 66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66, + 1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,1,66,3,66,641,8,66,1, + 67,3,67,644,8,67,1,67,1,67,3,67,648,8,67,1,68,4,68,651,8,68,11,68,12,68, + 652,1,68,1,68,4,68,657,8,68,11,68,12,68,658,5,68,661,8,68,10,68,12,68,664, + 9,68,1,69,1,69,1,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,3,70,698,8,70,1,71,1,71,1,71,1,71,1,71,1,71,1,72,1, + 72,1,72,1,72,1,72,1,72,1,72,1,72,1,72,1,72,1,72,3,72,717,8,72,1,73,1,73, + 5,73,721,8,73,10,73,12,73,724,9,73,1,74,1,74,1,74,1,74,5,74,730,8,74,10, + 74,12,74,733,9,74,1,74,1,74,1,74,1,74,1,74,5,74,740,8,74,10,74,12,74,743, + 9,74,1,74,3,74,746,8,74,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1,75,1, + 76,1,76,1,76,5,76,760,8,76,10,76,12,76,763,9,76,1,77,1,77,1,77,1,77,1,77, + 1,77,1,77,1,77,1,77,1,77,1,77,1,77,1,77,1,77,1,77,3,77,780,8,77,1,78,1, + 78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78, + 1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78,1, + 78,1,78,1,78,1,78,1,78,3,78,817,8,78,1,78,1,78,1,78,1,78,1,78,1,78,1,78, + 1,78,1,78,1,78,1,78,3,78,830,8,78,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1, + 79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79, + 1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1, + 79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79, + 1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1, + 79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79, + 1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,3, + 79,926,8,79,1,80,1,80,5,80,930,8,80,10,80,12,80,933,9,80,1,81,4,81,936, + 8,81,11,81,12,81,937,1,81,1,81,1,82,1,82,1,82,1,82,5,82,946,8,82,10,82, + 12,82,949,9,82,1,82,1,82,1,82,1,82,1,82,1,83,1,83,1,83,1,83,5,83,960,8, + 83,10,83,12,83,963,9,83,1,83,1,83,3,731,741,947,0,84,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,153,77,155,78,157,79,159,80,161,81,163,82,165,83,167,84,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,1010, + 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,0,153,1,0,0,0,0,155,1,0,0,0,0,157,1,0,0,0,0,159,1,0,0,0,0,161,1,0,0, + 0,0,163,1,0,0,0,0,165,1,0,0,0,0,167,1,0,0,0,1,169,1,0,0,0,3,176,1,0,0,0, + 5,178,1,0,0,0,7,189,1,0,0,0,9,191,1,0,0,0,11,193,1,0,0,0,13,196,1,0,0,0, + 15,198,1,0,0,0,17,200,1,0,0,0,19,203,1,0,0,0,21,205,1,0,0,0,23,212,1,0, + 0,0,25,221,1,0,0,0,27,229,1,0,0,0,29,231,1,0,0,0,31,233,1,0,0,0,33,242, + 1,0,0,0,35,244,1,0,0,0,37,246,1,0,0,0,39,248,1,0,0,0,41,255,1,0,0,0,43, + 258,1,0,0,0,45,261,1,0,0,0,47,264,1,0,0,0,49,267,1,0,0,0,51,275,1,0,0,0, + 53,287,1,0,0,0,55,290,1,0,0,0,57,295,1,0,0,0,59,298,1,0,0,0,61,304,1,0, + 0,0,63,308,1,0,0,0,65,312,1,0,0,0,67,314,1,0,0,0,69,316,1,0,0,0,71,327, + 1,0,0,0,73,334,1,0,0,0,75,351,1,0,0,0,77,366,1,0,0,0,79,381,1,0,0,0,81, + 394,1,0,0,0,83,404,1,0,0,0,85,429,1,0,0,0,87,444,1,0,0,0,89,463,1,0,0,0, + 91,479,1,0,0,0,93,490,1,0,0,0,95,498,1,0,0,0,97,505,1,0,0,0,99,512,1,0, + 0,0,101,514,1,0,0,0,103,516,1,0,0,0,105,518,1,0,0,0,107,520,1,0,0,0,109, + 522,1,0,0,0,111,524,1,0,0,0,113,527,1,0,0,0,115,530,1,0,0,0,117,533,1,0, + 0,0,119,536,1,0,0,0,121,538,1,0,0,0,123,540,1,0,0,0,125,543,1,0,0,0,127, + 546,1,0,0,0,129,556,1,0,0,0,131,581,1,0,0,0,133,640,1,0,0,0,135,643,1,0, + 0,0,137,650,1,0,0,0,139,665,1,0,0,0,141,697,1,0,0,0,143,699,1,0,0,0,145, + 716,1,0,0,0,147,718,1,0,0,0,149,745,1,0,0,0,151,747,1,0,0,0,153,756,1,0, + 0,0,155,779,1,0,0,0,157,829,1,0,0,0,159,925,1,0,0,0,161,927,1,0,0,0,163, + 935,1,0,0,0,165,941,1,0,0,0,167,955,1,0,0,0,169,170,5,112,0,0,170,171,5, + 114,0,0,171,172,5,97,0,0,172,173,5,103,0,0,173,174,5,109,0,0,174,175,5, + 97,0,0,175,2,1,0,0,0,176,177,5,59,0,0,177,4,1,0,0,0,178,179,5,99,0,0,179, + 180,5,97,0,0,180,181,5,115,0,0,181,182,5,104,0,0,182,183,5,115,0,0,183, + 184,5,99,0,0,184,185,5,114,0,0,185,186,5,105,0,0,186,187,5,112,0,0,187, + 188,5,116,0,0,188,6,1,0,0,0,189,190,5,94,0,0,190,8,1,0,0,0,191,192,5,126, + 0,0,192,10,1,0,0,0,193,194,5,62,0,0,194,195,5,61,0,0,195,12,1,0,0,0,196, + 197,5,62,0,0,197,14,1,0,0,0,198,199,5,60,0,0,199,16,1,0,0,0,200,201,5,60, + 0,0,201,202,5,61,0,0,202,18,1,0,0,0,203,204,5,61,0,0,204,20,1,0,0,0,205, + 206,5,105,0,0,206,207,5,109,0,0,207,208,5,112,0,0,208,209,5,111,0,0,209, + 210,5,114,0,0,210,211,5,116,0,0,211,22,1,0,0,0,212,213,5,102,0,0,213,214, + 5,117,0,0,214,215,5,110,0,0,215,216,5,99,0,0,216,217,5,116,0,0,217,218, + 5,105,0,0,218,219,5,111,0,0,219,220,5,110,0,0,220,24,1,0,0,0,221,222,5, + 114,0,0,222,223,5,101,0,0,223,224,5,116,0,0,224,225,5,117,0,0,225,226,5, + 114,0,0,226,227,5,110,0,0,227,228,5,115,0,0,228,26,1,0,0,0,229,230,5,40, + 0,0,230,28,1,0,0,0,231,232,5,41,0,0,232,30,1,0,0,0,233,234,5,99,0,0,234, + 235,5,111,0,0,235,236,5,110,0,0,236,237,5,116,0,0,237,238,5,114,0,0,238, + 239,5,97,0,0,239,240,5,99,0,0,240,241,5,116,0,0,241,32,1,0,0,0,242,243, + 5,123,0,0,243,34,1,0,0,0,244,245,5,125,0,0,245,36,1,0,0,0,246,247,5,44, + 0,0,247,38,1,0,0,0,248,249,5,114,0,0,249,250,5,101,0,0,250,251,5,116,0, + 0,251,252,5,117,0,0,252,253,5,114,0,0,253,254,5,110,0,0,254,40,1,0,0,0, + 255,256,5,43,0,0,256,257,5,61,0,0,257,42,1,0,0,0,258,259,5,45,0,0,259,260, + 5,61,0,0,260,44,1,0,0,0,261,262,5,43,0,0,262,263,5,43,0,0,263,46,1,0,0, + 0,264,265,5,45,0,0,265,266,5,45,0,0,266,48,1,0,0,0,267,268,5,114,0,0,268, + 269,5,101,0,0,269,270,5,113,0,0,270,271,5,117,0,0,271,272,5,105,0,0,272, + 273,5,114,0,0,273,274,5,101,0,0,274,50,1,0,0,0,275,276,5,99,0,0,276,277, + 5,111,0,0,277,278,5,110,0,0,278,279,5,115,0,0,279,280,5,111,0,0,280,281, + 5,108,0,0,281,282,5,101,0,0,282,283,5,46,0,0,283,284,5,108,0,0,284,285, + 5,111,0,0,285,286,5,103,0,0,286,52,1,0,0,0,287,288,5,105,0,0,288,289,5, + 102,0,0,289,54,1,0,0,0,290,291,5,101,0,0,291,292,5,108,0,0,292,293,5,115, + 0,0,293,294,5,101,0,0,294,56,1,0,0,0,295,296,5,100,0,0,296,297,5,111,0, + 0,297,58,1,0,0,0,298,299,5,119,0,0,299,300,5,104,0,0,300,301,5,105,0,0, + 301,302,5,108,0,0,302,303,5,101,0,0,303,60,1,0,0,0,304,305,5,102,0,0,305, + 306,5,111,0,0,306,307,5,114,0,0,307,62,1,0,0,0,308,309,5,110,0,0,309,310, + 5,101,0,0,310,311,5,119,0,0,311,64,1,0,0,0,312,313,5,91,0,0,313,66,1,0, + 0,0,314,315,5,93,0,0,315,68,1,0,0,0,316,317,5,116,0,0,317,318,5,120,0,0, + 318,319,5,46,0,0,319,320,5,111,0,0,320,321,5,117,0,0,321,322,5,116,0,0, + 322,323,5,112,0,0,323,324,5,117,0,0,324,325,5,116,0,0,325,326,5,115,0,0, + 326,70,1,0,0,0,327,328,5,46,0,0,328,329,5,118,0,0,329,330,5,97,0,0,330, + 331,5,108,0,0,331,332,5,117,0,0,332,333,5,101,0,0,333,72,1,0,0,0,334,335, + 5,46,0,0,335,336,5,108,0,0,336,337,5,111,0,0,337,338,5,99,0,0,338,339,5, + 107,0,0,339,340,5,105,0,0,340,341,5,110,0,0,341,342,5,103,0,0,342,343,5, + 66,0,0,343,344,5,121,0,0,344,345,5,116,0,0,345,346,5,101,0,0,346,347,5, + 99,0,0,347,348,5,111,0,0,348,349,5,100,0,0,349,350,5,101,0,0,350,74,1,0, + 0,0,351,352,5,46,0,0,352,353,5,116,0,0,353,354,5,111,0,0,354,355,5,107, + 0,0,355,356,5,101,0,0,356,357,5,110,0,0,357,358,5,67,0,0,358,359,5,97,0, + 0,359,360,5,116,0,0,360,361,5,101,0,0,361,362,5,103,0,0,362,363,5,111,0, + 0,363,364,5,114,0,0,364,365,5,121,0,0,365,76,1,0,0,0,366,367,5,46,0,0,367, + 368,5,110,0,0,368,369,5,102,0,0,369,370,5,116,0,0,370,371,5,67,0,0,371, + 372,5,111,0,0,372,373,5,109,0,0,373,374,5,109,0,0,374,375,5,105,0,0,375, + 376,5,116,0,0,376,377,5,109,0,0,377,378,5,101,0,0,378,379,5,110,0,0,379, + 380,5,116,0,0,380,78,1,0,0,0,381,382,5,46,0,0,382,383,5,116,0,0,383,384, + 5,111,0,0,384,385,5,107,0,0,385,386,5,101,0,0,386,387,5,110,0,0,387,388, + 5,65,0,0,388,389,5,109,0,0,389,390,5,111,0,0,390,391,5,117,0,0,391,392, + 5,110,0,0,392,393,5,116,0,0,393,80,1,0,0,0,394,395,5,116,0,0,395,396,5, + 120,0,0,396,397,5,46,0,0,397,398,5,105,0,0,398,399,5,110,0,0,399,400,5, + 112,0,0,400,401,5,117,0,0,401,402,5,116,0,0,402,403,5,115,0,0,403,82,1, + 0,0,0,404,405,5,46,0,0,405,406,5,111,0,0,406,407,5,117,0,0,407,408,5,116, + 0,0,408,409,5,112,0,0,409,410,5,111,0,0,410,411,5,105,0,0,411,412,5,110, + 0,0,412,413,5,116,0,0,413,414,5,84,0,0,414,415,5,114,0,0,415,416,5,97,0, + 0,416,417,5,110,0,0,417,418,5,115,0,0,418,419,5,97,0,0,419,420,5,99,0,0, + 420,421,5,116,0,0,421,422,5,105,0,0,422,423,5,111,0,0,423,424,5,110,0,0, + 424,425,5,72,0,0,425,426,5,97,0,0,426,427,5,115,0,0,427,428,5,104,0,0,428, + 84,1,0,0,0,429,430,5,46,0,0,430,431,5,111,0,0,431,432,5,117,0,0,432,433, + 5,116,0,0,433,434,5,112,0,0,434,435,5,111,0,0,435,436,5,105,0,0,436,437, + 5,110,0,0,437,438,5,116,0,0,438,439,5,73,0,0,439,440,5,110,0,0,440,441, + 5,100,0,0,441,442,5,101,0,0,442,443,5,120,0,0,443,86,1,0,0,0,444,445,5, + 46,0,0,445,446,5,117,0,0,446,447,5,110,0,0,447,448,5,108,0,0,448,449,5, + 111,0,0,449,450,5,99,0,0,450,451,5,107,0,0,451,452,5,105,0,0,452,453,5, + 110,0,0,453,454,5,103,0,0,454,455,5,66,0,0,455,456,5,121,0,0,456,457,5, + 116,0,0,457,458,5,101,0,0,458,459,5,99,0,0,459,460,5,111,0,0,460,461,5, + 100,0,0,461,462,5,101,0,0,462,88,1,0,0,0,463,464,5,46,0,0,464,465,5,115, + 0,0,465,466,5,101,0,0,466,467,5,113,0,0,467,468,5,117,0,0,468,469,5,101, + 0,0,469,470,5,110,0,0,470,471,5,99,0,0,471,472,5,101,0,0,472,473,5,78,0, + 0,473,474,5,117,0,0,474,475,5,109,0,0,475,476,5,98,0,0,476,477,5,101,0, + 0,477,478,5,114,0,0,478,90,1,0,0,0,479,480,5,46,0,0,480,481,5,114,0,0,481, + 482,5,101,0,0,482,483,5,118,0,0,483,484,5,101,0,0,484,485,5,114,0,0,485, + 486,5,115,0,0,486,487,5,101,0,0,487,488,5,40,0,0,488,489,5,41,0,0,489,92, + 1,0,0,0,490,491,5,46,0,0,491,492,5,108,0,0,492,493,5,101,0,0,493,494,5, + 110,0,0,494,495,5,103,0,0,495,496,5,116,0,0,496,497,5,104,0,0,497,94,1, + 0,0,0,498,499,5,46,0,0,499,500,5,115,0,0,500,501,5,112,0,0,501,502,5,108, + 0,0,502,503,5,105,0,0,503,504,5,116,0,0,504,96,1,0,0,0,505,506,5,46,0,0, + 506,507,5,115,0,0,507,508,5,108,0,0,508,509,5,105,0,0,509,510,5,99,0,0, + 510,511,5,101,0,0,511,98,1,0,0,0,512,513,5,33,0,0,513,100,1,0,0,0,514,515, + 5,45,0,0,515,102,1,0,0,0,516,517,5,42,0,0,517,104,1,0,0,0,518,519,5,47, + 0,0,519,106,1,0,0,0,520,521,5,37,0,0,521,108,1,0,0,0,522,523,5,43,0,0,523, + 110,1,0,0,0,524,525,5,62,0,0,525,526,5,62,0,0,526,112,1,0,0,0,527,528,5, + 60,0,0,528,529,5,60,0,0,529,114,1,0,0,0,530,531,5,61,0,0,531,532,5,61,0, + 0,532,116,1,0,0,0,533,534,5,33,0,0,534,535,5,61,0,0,535,118,1,0,0,0,536, + 537,5,38,0,0,537,120,1,0,0,0,538,539,5,124,0,0,539,122,1,0,0,0,540,541, + 5,38,0,0,541,542,5,38,0,0,542,124,1,0,0,0,543,544,5,124,0,0,544,545,5,124, + 0,0,545,126,1,0,0,0,546,547,5,99,0,0,547,548,5,111,0,0,548,549,5,110,0, + 0,549,550,5,115,0,0,550,551,5,116,0,0,551,552,5,97,0,0,552,553,5,110,0, + 0,553,554,5,116,0,0,554,128,1,0,0,0,555,557,7,0,0,0,556,555,1,0,0,0,557, + 558,1,0,0,0,558,556,1,0,0,0,558,559,1,0,0,0,559,560,1,0,0,0,560,562,5,46, + 0,0,561,563,7,0,0,0,562,561,1,0,0,0,563,564,1,0,0,0,564,562,1,0,0,0,564, + 565,1,0,0,0,565,566,1,0,0,0,566,568,5,46,0,0,567,569,7,0,0,0,568,567,1, + 0,0,0,569,570,1,0,0,0,570,568,1,0,0,0,570,571,1,0,0,0,571,130,1,0,0,0,572, + 573,5,116,0,0,573,574,5,114,0,0,574,575,5,117,0,0,575,582,5,101,0,0,576, + 577,5,102,0,0,577,578,5,97,0,0,578,579,5,108,0,0,579,580,5,115,0,0,580, + 582,5,101,0,0,581,572,1,0,0,0,581,576,1,0,0,0,582,132,1,0,0,0,583,584,5, + 115,0,0,584,585,5,97,0,0,585,586,5,116,0,0,586,587,5,111,0,0,587,588,5, + 115,0,0,588,589,5,104,0,0,589,590,5,105,0,0,590,641,5,115,0,0,591,592,5, + 115,0,0,592,593,5,97,0,0,593,594,5,116,0,0,594,641,5,115,0,0,595,596,5, + 102,0,0,596,597,5,105,0,0,597,598,5,110,0,0,598,599,5,110,0,0,599,600,5, + 101,0,0,600,641,5,121,0,0,601,602,5,98,0,0,602,603,5,105,0,0,603,604,5, + 116,0,0,604,641,5,115,0,0,605,606,5,98,0,0,606,607,5,105,0,0,607,608,5, + 116,0,0,608,609,5,99,0,0,609,610,5,111,0,0,610,611,5,105,0,0,611,641,5, + 110,0,0,612,613,5,115,0,0,613,614,5,101,0,0,614,615,5,99,0,0,615,616,5, + 111,0,0,616,617,5,110,0,0,617,618,5,100,0,0,618,641,5,115,0,0,619,620,5, + 109,0,0,620,621,5,105,0,0,621,622,5,110,0,0,622,623,5,117,0,0,623,624,5, + 116,0,0,624,625,5,101,0,0,625,641,5,115,0,0,626,627,5,104,0,0,627,628,5, + 111,0,0,628,629,5,117,0,0,629,630,5,114,0,0,630,641,5,115,0,0,631,632,5, + 100,0,0,632,633,5,97,0,0,633,634,5,121,0,0,634,641,5,115,0,0,635,636,5, + 119,0,0,636,637,5,101,0,0,637,638,5,101,0,0,638,639,5,107,0,0,639,641,5, + 115,0,0,640,583,1,0,0,0,640,591,1,0,0,0,640,595,1,0,0,0,640,601,1,0,0,0, + 640,605,1,0,0,0,640,612,1,0,0,0,640,619,1,0,0,0,640,626,1,0,0,0,640,631, + 1,0,0,0,640,635,1,0,0,0,641,134,1,0,0,0,642,644,5,45,0,0,643,642,1,0,0, + 0,643,644,1,0,0,0,644,645,1,0,0,0,645,647,3,137,68,0,646,648,3,139,69,0, + 647,646,1,0,0,0,647,648,1,0,0,0,648,136,1,0,0,0,649,651,7,0,0,0,650,649, + 1,0,0,0,651,652,1,0,0,0,652,650,1,0,0,0,652,653,1,0,0,0,653,662,1,0,0,0, + 654,656,5,95,0,0,655,657,7,0,0,0,656,655,1,0,0,0,657,658,1,0,0,0,658,656, + 1,0,0,0,658,659,1,0,0,0,659,661,1,0,0,0,660,654,1,0,0,0,661,664,1,0,0,0, + 662,660,1,0,0,0,662,663,1,0,0,0,663,138,1,0,0,0,664,662,1,0,0,0,665,666, + 7,1,0,0,666,667,3,137,68,0,667,140,1,0,0,0,668,669,5,105,0,0,669,670,5, + 110,0,0,670,698,5,116,0,0,671,672,5,98,0,0,672,673,5,111,0,0,673,674,5, + 111,0,0,674,698,5,108,0,0,675,676,5,115,0,0,676,677,5,116,0,0,677,678,5, + 114,0,0,678,679,5,105,0,0,679,680,5,110,0,0,680,698,5,103,0,0,681,682,5, + 112,0,0,682,683,5,117,0,0,683,684,5,98,0,0,684,685,5,107,0,0,685,686,5, + 101,0,0,686,698,5,121,0,0,687,688,5,115,0,0,688,689,5,105,0,0,689,698,5, + 103,0,0,690,691,5,100,0,0,691,692,5,97,0,0,692,693,5,116,0,0,693,694,5, + 97,0,0,694,695,5,115,0,0,695,696,5,105,0,0,696,698,5,103,0,0,697,668,1, + 0,0,0,697,671,1,0,0,0,697,675,1,0,0,0,697,681,1,0,0,0,697,687,1,0,0,0,697, + 690,1,0,0,0,698,142,1,0,0,0,699,700,5,98,0,0,700,701,5,121,0,0,701,702, + 5,116,0,0,702,703,5,101,0,0,703,704,5,115,0,0,704,144,1,0,0,0,705,706,5, + 98,0,0,706,707,5,121,0,0,707,708,5,116,0,0,708,709,5,101,0,0,709,710,5, + 115,0,0,710,711,1,0,0,0,711,717,3,147,73,0,712,713,5,98,0,0,713,714,5,121, + 0,0,714,715,5,116,0,0,715,717,5,101,0,0,716,705,1,0,0,0,716,712,1,0,0,0, + 717,146,1,0,0,0,718,722,7,2,0,0,719,721,7,0,0,0,720,719,1,0,0,0,721,724, + 1,0,0,0,722,720,1,0,0,0,722,723,1,0,0,0,723,148,1,0,0,0,724,722,1,0,0,0, + 725,731,5,34,0,0,726,727,5,92,0,0,727,730,5,34,0,0,728,730,8,3,0,0,729, + 726,1,0,0,0,729,728,1,0,0,0,730,733,1,0,0,0,731,732,1,0,0,0,731,729,1,0, + 0,0,732,734,1,0,0,0,733,731,1,0,0,0,734,746,5,34,0,0,735,741,5,39,0,0,736, + 737,5,92,0,0,737,740,5,39,0,0,738,740,8,4,0,0,739,736,1,0,0,0,739,738,1, + 0,0,0,740,743,1,0,0,0,741,742,1,0,0,0,741,739,1,0,0,0,742,744,1,0,0,0,743, + 741,1,0,0,0,744,746,5,39,0,0,745,725,1,0,0,0,745,735,1,0,0,0,746,150,1, + 0,0,0,747,748,5,100,0,0,748,749,5,97,0,0,749,750,5,116,0,0,750,751,5,101, + 0,0,751,752,5,40,0,0,752,753,1,0,0,0,753,754,3,149,74,0,754,755,5,41,0, + 0,755,152,1,0,0,0,756,757,5,48,0,0,757,761,7,5,0,0,758,760,7,6,0,0,759, + 758,1,0,0,0,760,763,1,0,0,0,761,759,1,0,0,0,761,762,1,0,0,0,762,154,1,0, + 0,0,763,761,1,0,0,0,764,765,5,116,0,0,765,766,5,104,0,0,766,767,5,105,0, + 0,767,768,5,115,0,0,768,769,5,46,0,0,769,770,5,97,0,0,770,771,5,103,0,0, + 771,780,5,101,0,0,772,773,5,116,0,0,773,774,5,120,0,0,774,775,5,46,0,0, + 775,776,5,116,0,0,776,777,5,105,0,0,777,778,5,109,0,0,778,780,5,101,0,0, + 779,764,1,0,0,0,779,772,1,0,0,0,780,156,1,0,0,0,781,782,5,117,0,0,782,783, + 5,110,0,0,783,784,5,115,0,0,784,785,5,97,0,0,785,786,5,102,0,0,786,787, + 5,101,0,0,787,788,5,95,0,0,788,789,5,105,0,0,789,790,5,110,0,0,790,830, + 5,116,0,0,791,792,5,117,0,0,792,793,5,110,0,0,793,794,5,115,0,0,794,795, + 5,97,0,0,795,796,5,102,0,0,796,797,5,101,0,0,797,798,5,95,0,0,798,799,5, + 98,0,0,799,800,5,111,0,0,800,801,5,111,0,0,801,830,5,108,0,0,802,803,5, + 117,0,0,803,804,5,110,0,0,804,805,5,115,0,0,805,806,5,97,0,0,806,807,5, + 102,0,0,807,808,5,101,0,0,808,809,5,95,0,0,809,810,5,98,0,0,810,811,5,121, + 0,0,811,812,5,116,0,0,812,813,5,101,0,0,813,814,5,115,0,0,814,816,1,0,0, + 0,815,817,3,147,73,0,816,815,1,0,0,0,816,817,1,0,0,0,817,830,1,0,0,0,818, + 819,5,117,0,0,819,820,5,110,0,0,820,821,5,115,0,0,821,822,5,97,0,0,822, + 823,5,102,0,0,823,824,5,101,0,0,824,825,5,95,0,0,825,826,5,98,0,0,826,827, + 5,121,0,0,827,828,5,116,0,0,828,830,5,101,0,0,829,781,1,0,0,0,829,791,1, + 0,0,0,829,802,1,0,0,0,829,818,1,0,0,0,830,158,1,0,0,0,831,832,5,116,0,0, + 832,833,5,104,0,0,833,834,5,105,0,0,834,835,5,115,0,0,835,836,5,46,0,0, + 836,837,5,97,0,0,837,838,5,99,0,0,838,839,5,116,0,0,839,840,5,105,0,0,840, + 841,5,118,0,0,841,842,5,101,0,0,842,843,5,73,0,0,843,844,5,110,0,0,844, + 845,5,112,0,0,845,846,5,117,0,0,846,847,5,116,0,0,847,848,5,73,0,0,848, + 849,5,110,0,0,849,850,5,100,0,0,850,851,5,101,0,0,851,926,5,120,0,0,852, + 853,5,116,0,0,853,854,5,104,0,0,854,855,5,105,0,0,855,856,5,115,0,0,856, + 857,5,46,0,0,857,858,5,97,0,0,858,859,5,99,0,0,859,860,5,116,0,0,860,861, + 5,105,0,0,861,862,5,118,0,0,862,863,5,101,0,0,863,864,5,66,0,0,864,865, + 5,121,0,0,865,866,5,116,0,0,866,867,5,101,0,0,867,868,5,99,0,0,868,869, + 5,111,0,0,869,870,5,100,0,0,870,926,5,101,0,0,871,872,5,116,0,0,872,873, + 5,120,0,0,873,874,5,46,0,0,874,875,5,105,0,0,875,876,5,110,0,0,876,877, + 5,112,0,0,877,878,5,117,0,0,878,879,5,116,0,0,879,880,5,115,0,0,880,881, + 5,46,0,0,881,882,5,108,0,0,882,883,5,101,0,0,883,884,5,110,0,0,884,885, + 5,103,0,0,885,886,5,116,0,0,886,926,5,104,0,0,887,888,5,116,0,0,888,889, + 5,120,0,0,889,890,5,46,0,0,890,891,5,111,0,0,891,892,5,117,0,0,892,893, + 5,116,0,0,893,894,5,112,0,0,894,895,5,117,0,0,895,896,5,116,0,0,896,897, + 5,115,0,0,897,898,5,46,0,0,898,899,5,108,0,0,899,900,5,101,0,0,900,901, + 5,110,0,0,901,902,5,103,0,0,902,903,5,116,0,0,903,926,5,104,0,0,904,905, + 5,116,0,0,905,906,5,120,0,0,906,907,5,46,0,0,907,908,5,118,0,0,908,909, + 5,101,0,0,909,910,5,114,0,0,910,911,5,115,0,0,911,912,5,105,0,0,912,913, + 5,111,0,0,913,926,5,110,0,0,914,915,5,116,0,0,915,916,5,120,0,0,916,917, + 5,46,0,0,917,918,5,108,0,0,918,919,5,111,0,0,919,920,5,99,0,0,920,921,5, + 107,0,0,921,922,5,116,0,0,922,923,5,105,0,0,923,924,5,109,0,0,924,926,5, + 101,0,0,925,831,1,0,0,0,925,852,1,0,0,0,925,871,1,0,0,0,925,887,1,0,0,0, + 925,904,1,0,0,0,925,914,1,0,0,0,926,160,1,0,0,0,927,931,7,7,0,0,928,930, + 7,8,0,0,929,928,1,0,0,0,930,933,1,0,0,0,931,929,1,0,0,0,931,932,1,0,0,0, + 932,162,1,0,0,0,933,931,1,0,0,0,934,936,7,9,0,0,935,934,1,0,0,0,936,937, + 1,0,0,0,937,935,1,0,0,0,937,938,1,0,0,0,938,939,1,0,0,0,939,940,6,81,0, + 0,940,164,1,0,0,0,941,942,5,47,0,0,942,943,5,42,0,0,943,947,1,0,0,0,944, + 946,9,0,0,0,945,944,1,0,0,0,946,949,1,0,0,0,947,948,1,0,0,0,947,945,1,0, + 0,0,948,950,1,0,0,0,949,947,1,0,0,0,950,951,5,42,0,0,951,952,5,47,0,0,952, + 953,1,0,0,0,953,954,6,82,1,0,954,166,1,0,0,0,955,956,5,47,0,0,956,957,5, + 47,0,0,957,961,1,0,0,0,958,960,8,10,0,0,959,958,1,0,0,0,960,963,1,0,0,0, + 961,959,1,0,0,0,961,962,1,0,0,0,962,964,1,0,0,0,963,961,1,0,0,0,964,965, + 6,83,1,0,965,168,1,0,0,0,28,0,558,564,570,581,640,643,647,652,658,662,697, + 716,722,729,731,739,741,745,761,779,816,829,925,931,937,947,961,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 8d8c718d..0833d80e 100644 --- a/packages/cashc/src/grammar/CashScriptParser.ts +++ b/packages/cashc/src/grammar/CashScriptParser.ts @@ -79,26 +79,29 @@ export default class CashScriptParser extends Parser { public static readonly T__58 = 59; public static readonly T__59 = 60; public static readonly T__60 = 61; - public static readonly VersionLiteral = 62; - public static readonly BooleanLiteral = 63; - public static readonly NumberUnit = 64; - public static readonly NumberLiteral = 65; - public static readonly NumberPart = 66; - public static readonly ExponentPart = 67; - public static readonly PrimitiveType = 68; - public static readonly UnboundedBytes = 69; - public static readonly BoundedBytes = 70; - public static readonly Bound = 71; - public static readonly StringLiteral = 72; - public static readonly DateLiteral = 73; - public static readonly HexLiteral = 74; - public static readonly TxVar = 75; - public static readonly UnsafeCast = 76; - public static readonly NullaryOp = 77; - public static readonly Identifier = 78; - public static readonly WHITESPACE = 79; - public static readonly COMMENT = 80; - public static readonly LINE_COMMENT = 81; + public static readonly T__61 = 62; + public static readonly T__62 = 63; + public static readonly T__63 = 64; + public static readonly VersionLiteral = 65; + public static readonly BooleanLiteral = 66; + public static readonly NumberUnit = 67; + public static readonly NumberLiteral = 68; + public static readonly NumberPart = 69; + public static readonly ExponentPart = 70; + public static readonly PrimitiveType = 71; + public static readonly UnboundedBytes = 72; + public static readonly BoundedBytes = 73; + public static readonly Bound = 74; + public static readonly StringLiteral = 75; + public static readonly DateLiteral = 76; + public static readonly HexLiteral = 77; + public static readonly TxVar = 78; + public static readonly UnsafeCast = 79; + public static readonly NullaryOp = 80; + public static readonly Identifier = 81; + public static readonly WHITESPACE = 82; + public static readonly COMMENT = 83; + public static readonly LINE_COMMENT = 84; public static readonly EOF = Token.EOF; public static readonly RULE_sourceFile = 0; public static readonly RULE_pragmaDirective = 1; @@ -106,50 +109,58 @@ export default class CashScriptParser extends Parser { public static readonly RULE_pragmaValue = 3; public static readonly RULE_versionConstraint = 4; public static readonly RULE_versionOperator = 5; - public static readonly RULE_contractDefinition = 6; - public static readonly RULE_functionDefinition = 7; - public static readonly RULE_functionBody = 8; - public static readonly RULE_parameterList = 9; - public static readonly RULE_parameter = 10; - public static readonly RULE_block = 11; - public static readonly RULE_statement = 12; - public static readonly RULE_nonControlStatement = 13; - public static readonly RULE_controlStatement = 14; - public static readonly RULE_variableDefinition = 15; - public static readonly RULE_tupleAssignment = 16; - public static readonly RULE_assignStatement = 17; - public static readonly RULE_timeOpStatement = 18; - public static readonly RULE_requireStatement = 19; - public static readonly RULE_consoleStatement = 20; - public static readonly RULE_ifStatement = 21; - public static readonly RULE_loopStatement = 22; - public static readonly RULE_doWhileStatement = 23; - public static readonly RULE_whileStatement = 24; - public static readonly RULE_forStatement = 25; - public static readonly RULE_forInit = 26; - public static readonly RULE_requireMessage = 27; - public static readonly RULE_consoleParameter = 28; - public static readonly RULE_consoleParameterList = 29; - public static readonly RULE_functionCall = 30; - public static readonly RULE_expressionList = 31; - public static readonly RULE_expression = 32; - public static readonly RULE_modifier = 33; - public static readonly RULE_literal = 34; - public static readonly RULE_numberLiteral = 35; - public static readonly RULE_typeName = 36; - public static readonly RULE_typeCast = 37; + public static readonly RULE_importDirective = 6; + public static readonly RULE_topLevelDefinition = 7; + public static readonly RULE_globalFunctionDefinition = 8; + public static readonly RULE_contractDefinition = 9; + public static readonly RULE_contractFunctionDefinition = 10; + public static readonly RULE_functionBody = 11; + public static readonly RULE_parameterList = 12; + public static readonly RULE_parameter = 13; + public static readonly RULE_block = 14; + public static readonly RULE_statement = 15; + public static readonly RULE_nonControlStatement = 16; + public static readonly RULE_functionCallStatement = 17; + public static readonly RULE_returnStatement = 18; + public static readonly RULE_controlStatement = 19; + public static readonly RULE_variableDefinition = 20; + public static readonly RULE_tupleAssignment = 21; + public static readonly RULE_assignStatement = 22; + public static readonly RULE_timeOpStatement = 23; + public static readonly RULE_requireStatement = 24; + public static readonly RULE_consoleStatement = 25; + public static readonly RULE_ifStatement = 26; + public static readonly RULE_loopStatement = 27; + public static readonly RULE_doWhileStatement = 28; + public static readonly RULE_whileStatement = 29; + public static readonly RULE_forStatement = 30; + public static readonly RULE_forInit = 31; + public static readonly RULE_requireMessage = 32; + public static readonly RULE_consoleParameter = 33; + public static readonly RULE_consoleParameterList = 34; + public static readonly RULE_functionCall = 35; + public static readonly RULE_expressionList = 36; + public static readonly RULE_expression = 37; + public static readonly RULE_modifier = 38; + public static readonly RULE_literal = 39; + public static readonly RULE_numberLiteral = 40; + public static readonly RULE_typeName = 41; + public static readonly RULE_typeCast = 42; public static readonly literalNames: (string | null)[] = [ null, "'pragma'", "';'", "'cashscript'", "'^'", "'~'", "'>='", "'>'", "'<'", "'<='", - "'='", "'contract'", - "'{'", "'}'", + "'='", "'import'", "'function'", - "'('", "','", - "')'", "'+='", - "'-='", "'++'", - "'--'", "'require'", + "'returns'", + "'('", "')'", + "'contract'", + "'{'", "'}'", + "','", "'return'", + "'+='", "'-='", + "'++'", "'--'", + "'require'", "'console.log'", "'if'", "'else'", "'do'", "'while'", @@ -213,7 +224,8 @@ export default class CashScriptParser extends Parser { null, null, null, null, null, null, - "VersionLiteral", + null, null, + null, "VersionLiteral", "BooleanLiteral", "NumberUnit", "NumberLiteral", @@ -234,12 +246,13 @@ export default class CashScriptParser extends Parser { // tslint:disable:no-trailing-whitespace public static readonly ruleNames: string[] = [ "sourceFile", "pragmaDirective", "pragmaName", "pragmaValue", "versionConstraint", - "versionOperator", "contractDefinition", "functionDefinition", "functionBody", - "parameterList", "parameter", "block", "statement", "nonControlStatement", - "controlStatement", "variableDefinition", "tupleAssignment", "assignStatement", - "timeOpStatement", "requireStatement", "consoleStatement", "ifStatement", - "loopStatement", "doWhileStatement", "whileStatement", "forStatement", - "forInit", "requireMessage", "consoleParameter", "consoleParameterList", + "versionOperator", "importDirective", "topLevelDefinition", "globalFunctionDefinition", + "contractDefinition", "contractFunctionDefinition", "functionBody", "parameterList", + "parameter", "block", "statement", "nonControlStatement", "functionCallStatement", + "returnStatement", "controlStatement", "variableDefinition", "tupleAssignment", + "assignStatement", "timeOpStatement", "requireStatement", "consoleStatement", + "ifStatement", "loopStatement", "doWhileStatement", "whileStatement", + "forStatement", "forInit", "requireMessage", "consoleParameter", "consoleParameterList", "functionCall", "expressionList", "expression", "modifier", "literal", "numberLiteral", "typeName", "typeCast", ]; @@ -265,23 +278,49 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 79; + this.state = 89; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===1) { { { - this.state = 76; + this.state = 86; this.pragmaDirective(); } } - this.state = 81; + this.state = 91; + this._errHandler.sync(this); + _la = this._input.LA(1); + } + this.state = 95; + this._errHandler.sync(this); + _la = this._input.LA(1); + while (_la===11) { + { + { + this.state = 92; + this.importDirective(); + } + } + this.state = 97; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 82; - this.contractDefinition(); - this.state = 83; + this.state = 101; + this._errHandler.sync(this); + _la = this._input.LA(1); + while (_la===12 || _la===16) { + { + { + this.state = 98; + this.topLevelDefinition(); + } + } + this.state = 103; + this._errHandler.sync(this); + _la = this._input.LA(1); + } + this.state = 104; this.match(CashScriptParser.EOF); } } @@ -306,13 +345,13 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 85; + this.state = 106; this.match(CashScriptParser.T__0); - this.state = 86; + this.state = 107; this.pragmaName(); - this.state = 87; + this.state = 108; this.pragmaValue(); - this.state = 88; + this.state = 109; this.match(CashScriptParser.T__1); } } @@ -337,7 +376,7 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 90; + this.state = 111; this.match(CashScriptParser.T__2); } } @@ -363,14 +402,14 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 92; + this.state = 113; this.versionConstraint(); - this.state = 94; + this.state = 115; this._errHandler.sync(this); _la = this._input.LA(1); - if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0) || _la===62) { + if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0) || _la===65) { { - this.state = 93; + this.state = 114; this.versionConstraint(); } } @@ -399,17 +438,17 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 97; + this.state = 118; this._errHandler.sync(this); _la = this._input.LA(1); if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0)) { { - this.state = 96; + this.state = 117; this.versionOperator(); } } - this.state = 99; + this.state = 120; this.match(CashScriptParser.VersionLiteral); } } @@ -435,7 +474,7 @@ export default class CashScriptParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 101; + this.state = 122; _la = this._input.LA(1); if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 2032) !== 0))) { this._errHandler.recoverInline(this); @@ -461,37 +500,154 @@ export default class CashScriptParser extends Parser { return localctx; } // @RuleVersion(0) + public importDirective(): ImportDirectiveContext { + let localctx: ImportDirectiveContext = new ImportDirectiveContext(this, this._ctx, this.state); + this.enterRule(localctx, 12, CashScriptParser.RULE_importDirective); + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 124; + this.match(CashScriptParser.T__10); + this.state = 125; + this.match(CashScriptParser.StringLiteral); + this.state = 126; + 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 topLevelDefinition(): TopLevelDefinitionContext { + let localctx: TopLevelDefinitionContext = new TopLevelDefinitionContext(this, this._ctx, this.state); + this.enterRule(localctx, 14, CashScriptParser.RULE_topLevelDefinition); + try { + this.state = 130; + this._errHandler.sync(this); + switch (this._input.LA(1)) { + case 12: + this.enterOuterAlt(localctx, 1); + { + this.state = 128; + this.globalFunctionDefinition(); + } + break; + case 16: + this.enterOuterAlt(localctx, 2); + { + this.state = 129; + this.contractDefinition(); + } + break; + default: + throw new NoViableAltException(this); + } + } + 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 globalFunctionDefinition(): GlobalFunctionDefinitionContext { + let localctx: GlobalFunctionDefinitionContext = new GlobalFunctionDefinitionContext(this, this._ctx, this.state); + this.enterRule(localctx, 16, CashScriptParser.RULE_globalFunctionDefinition); + let _la: number; + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 132; + this.match(CashScriptParser.T__11); + this.state = 133; + this.match(CashScriptParser.Identifier); + this.state = 134; + this.parameterList(); + this.state = 140; + this._errHandler.sync(this); + _la = this._input.LA(1); + if (_la===13) { + { + this.state = 135; + this.match(CashScriptParser.T__12); + this.state = 136; + this.match(CashScriptParser.T__13); + this.state = 137; + this.typeName(); + this.state = 138; + this.match(CashScriptParser.T__14); + } + } + + this.state = 142; + this.functionBody(); + } + } + 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 contractDefinition(): ContractDefinitionContext { let localctx: ContractDefinitionContext = new ContractDefinitionContext(this, this._ctx, this.state); - this.enterRule(localctx, 12, CashScriptParser.RULE_contractDefinition); + this.enterRule(localctx, 18, CashScriptParser.RULE_contractDefinition); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 103; - this.match(CashScriptParser.T__10); - this.state = 104; + this.state = 144; + this.match(CashScriptParser.T__15); + this.state = 145; this.match(CashScriptParser.Identifier); - this.state = 105; + this.state = 146; this.parameterList(); - this.state = 106; - this.match(CashScriptParser.T__11); - this.state = 110; + this.state = 147; + this.match(CashScriptParser.T__16); + this.state = 151; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===14) { + while (_la===12) { { { - this.state = 107; - this.functionDefinition(); + this.state = 148; + this.contractFunctionDefinition(); } } - this.state = 112; + this.state = 153; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 113; - this.match(CashScriptParser.T__12); + this.state = 154; + this.match(CashScriptParser.T__17); } } catch (re) { @@ -509,19 +665,19 @@ export default class CashScriptParser extends Parser { return localctx; } // @RuleVersion(0) - public functionDefinition(): FunctionDefinitionContext { - let localctx: FunctionDefinitionContext = new FunctionDefinitionContext(this, this._ctx, this.state); - this.enterRule(localctx, 14, CashScriptParser.RULE_functionDefinition); + public contractFunctionDefinition(): ContractFunctionDefinitionContext { + let localctx: ContractFunctionDefinitionContext = new ContractFunctionDefinitionContext(this, this._ctx, this.state); + this.enterRule(localctx, 20, CashScriptParser.RULE_contractFunctionDefinition); try { this.enterOuterAlt(localctx, 1); { - this.state = 115; - this.match(CashScriptParser.T__13); - this.state = 116; + this.state = 156; + this.match(CashScriptParser.T__11); + this.state = 157; this.match(CashScriptParser.Identifier); - this.state = 117; + this.state = 158; this.parameterList(); - this.state = 118; + this.state = 159; this.functionBody(); } } @@ -542,29 +698,29 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public functionBody(): FunctionBodyContext { let localctx: FunctionBodyContext = new FunctionBodyContext(this, this._ctx, this.state); - this.enterRule(localctx, 16, CashScriptParser.RULE_functionBody); + this.enterRule(localctx, 22, CashScriptParser.RULE_functionBody); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 120; - this.match(CashScriptParser.T__11); - this.state = 124; + this.state = 161; + this.match(CashScriptParser.T__16); + this.state = 165; this._errHandler.sync(this); _la = this._input.LA(1); - while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 499122176) !== 0) || ((((_la - 68)) & ~0x1F) === 0 && ((1 << (_la - 68)) & 1031) !== 0)) { + while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 3994025984) !== 0) || ((((_la - 71)) & ~0x1F) === 0 && ((1 << (_la - 71)) & 1031) !== 0)) { { { - this.state = 121; + this.state = 162; this.statement(); } } - this.state = 126; + this.state = 167; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 127; - this.match(CashScriptParser.T__12); + this.state = 168; + this.match(CashScriptParser.T__17); } } catch (re) { @@ -584,54 +740,54 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public parameterList(): ParameterListContext { let localctx: ParameterListContext = new ParameterListContext(this, this._ctx, this.state); - this.enterRule(localctx, 18, CashScriptParser.RULE_parameterList); + this.enterRule(localctx, 24, CashScriptParser.RULE_parameterList); let _la: number; try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 129; - this.match(CashScriptParser.T__14); - this.state = 141; + this.state = 170; + this.match(CashScriptParser.T__13); + this.state = 182; this._errHandler.sync(this); _la = this._input.LA(1); - if (((((_la - 68)) & ~0x1F) === 0 && ((1 << (_la - 68)) & 7) !== 0)) { + if (((((_la - 71)) & ~0x1F) === 0 && ((1 << (_la - 71)) & 7) !== 0)) { { - this.state = 130; + this.state = 171; this.parameter(); - this.state = 135; + this.state = 176; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 5, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 9, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 131; - this.match(CashScriptParser.T__15); - this.state = 132; + this.state = 172; + this.match(CashScriptParser.T__18); + this.state = 173; this.parameter(); } } } - this.state = 137; + this.state = 178; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 5, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 9, this._ctx); } - this.state = 139; + this.state = 180; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===16) { + if (_la===19) { { - this.state = 138; - this.match(CashScriptParser.T__15); + this.state = 179; + this.match(CashScriptParser.T__18); } } } } - this.state = 143; - this.match(CashScriptParser.T__16); + this.state = 184; + this.match(CashScriptParser.T__14); } } catch (re) { @@ -651,13 +807,13 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public parameter(): ParameterContext { let localctx: ParameterContext = new ParameterContext(this, this._ctx, this.state); - this.enterRule(localctx, 20, CashScriptParser.RULE_parameter); + this.enterRule(localctx, 26, CashScriptParser.RULE_parameter); try { this.enterOuterAlt(localctx, 1); { - this.state = 145; + this.state = 186; this.typeName(); - this.state = 146; + this.state = 187; this.match(CashScriptParser.Identifier); } } @@ -678,48 +834,49 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public block(): BlockContext { let localctx: BlockContext = new BlockContext(this, this._ctx, this.state); - this.enterRule(localctx, 22, CashScriptParser.RULE_block); + this.enterRule(localctx, 28, CashScriptParser.RULE_block); let _la: number; try { - this.state = 157; + this.state = 198; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 12: + case 17: this.enterOuterAlt(localctx, 1); { - this.state = 148; - this.match(CashScriptParser.T__11); - this.state = 152; + this.state = 189; + this.match(CashScriptParser.T__16); + this.state = 193; this._errHandler.sync(this); _la = this._input.LA(1); - while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 499122176) !== 0) || ((((_la - 68)) & ~0x1F) === 0 && ((1 << (_la - 68)) & 1031) !== 0)) { + while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 3994025984) !== 0) || ((((_la - 71)) & ~0x1F) === 0 && ((1 << (_la - 71)) & 1031) !== 0)) { { { - this.state = 149; + this.state = 190; this.statement(); } } - this.state = 154; + this.state = 195; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 155; - this.match(CashScriptParser.T__12); + this.state = 196; + this.match(CashScriptParser.T__17); } break; - case 22: - case 23: - case 24: + case 20: + case 25: case 26: case 27: - case 28: - case 68: - case 69: - case 70: - case 78: + case 29: + case 30: + case 31: + case 71: + case 72: + case 73: + case 81: this.enterOuterAlt(localctx, 2); { - this.state = 156; + this.state = 197; this.statement(); } break; @@ -744,32 +901,33 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public statement(): StatementContext { let localctx: StatementContext = new StatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 24, CashScriptParser.RULE_statement); + this.enterRule(localctx, 30, CashScriptParser.RULE_statement); try { - this.state = 163; + this.state = 204; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 24: - case 26: case 27: - case 28: + case 29: + case 30: + case 31: this.enterOuterAlt(localctx, 1); { - this.state = 159; + this.state = 200; this.controlStatement(); } break; - case 22: - case 23: - case 68: - case 69: - case 70: - case 78: + case 20: + case 25: + case 26: + case 71: + case 72: + case 73: + case 81: this.enterOuterAlt(localctx, 2); { - this.state = 160; + this.state = 201; this.nonControlStatement(); - this.state = 161; + this.state = 202; this.match(CashScriptParser.T__1); } break; @@ -794,53 +952,119 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public nonControlStatement(): NonControlStatementContext { let localctx: NonControlStatementContext = new NonControlStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 26, CashScriptParser.RULE_nonControlStatement); + this.enterRule(localctx, 32, CashScriptParser.RULE_nonControlStatement); try { - this.state = 171; + this.state = 214; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 11, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 15, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 165; + this.state = 206; this.variableDefinition(); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 166; + this.state = 207; this.tupleAssignment(); } break; case 3: this.enterOuterAlt(localctx, 3); { - this.state = 167; + this.state = 208; this.assignStatement(); } break; case 4: this.enterOuterAlt(localctx, 4); { - this.state = 168; + this.state = 209; this.timeOpStatement(); } break; case 5: this.enterOuterAlt(localctx, 5); { - this.state = 169; + this.state = 210; this.requireStatement(); } break; case 6: this.enterOuterAlt(localctx, 6); { - this.state = 170; + this.state = 211; + this.functionCallStatement(); + } + break; + case 7: + this.enterOuterAlt(localctx, 7); + { + this.state = 212; this.consoleStatement(); } break; + case 8: + this.enterOuterAlt(localctx, 8); + { + this.state = 213; + this.returnStatement(); + } + break; + } + } + 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 functionCallStatement(): FunctionCallStatementContext { + let localctx: FunctionCallStatementContext = new FunctionCallStatementContext(this, this._ctx, this.state); + this.enterRule(localctx, 34, CashScriptParser.RULE_functionCallStatement); + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 216; + this.functionCall(); + } + } + 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 returnStatement(): ReturnStatementContext { + let localctx: ReturnStatementContext = new ReturnStatementContext(this, this._ctx, this.state); + this.enterRule(localctx, 36, CashScriptParser.RULE_returnStatement); + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 218; + this.match(CashScriptParser.T__19); + this.state = 219; + this.expression(0); } } catch (re) { @@ -860,24 +1084,24 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public controlStatement(): ControlStatementContext { let localctx: ControlStatementContext = new ControlStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 28, CashScriptParser.RULE_controlStatement); + this.enterRule(localctx, 38, CashScriptParser.RULE_controlStatement); try { - this.state = 175; + this.state = 223; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 24: + case 27: this.enterOuterAlt(localctx, 1); { - this.state = 173; + this.state = 221; this.ifStatement(); } break; - case 26: - case 27: - case 28: + case 29: + case 30: + case 31: this.enterOuterAlt(localctx, 2); { - this.state = 174; + this.state = 222; this.loopStatement(); } break; @@ -902,32 +1126,32 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public variableDefinition(): VariableDefinitionContext { let localctx: VariableDefinitionContext = new VariableDefinitionContext(this, this._ctx, this.state); - this.enterRule(localctx, 30, CashScriptParser.RULE_variableDefinition); + this.enterRule(localctx, 40, CashScriptParser.RULE_variableDefinition); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 177; + this.state = 225; this.typeName(); - this.state = 181; + this.state = 229; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===61) { + while (_la===64) { { { - this.state = 178; + this.state = 226; this.modifier(); } } - this.state = 183; + this.state = 231; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 184; + this.state = 232; this.match(CashScriptParser.Identifier); - this.state = 185; + this.state = 233; this.match(CashScriptParser.T__9); - this.state = 186; + this.state = 234; this.expression(0); } } @@ -948,23 +1172,23 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public tupleAssignment(): TupleAssignmentContext { let localctx: TupleAssignmentContext = new TupleAssignmentContext(this, this._ctx, this.state); - this.enterRule(localctx, 32, CashScriptParser.RULE_tupleAssignment); + this.enterRule(localctx, 42, CashScriptParser.RULE_tupleAssignment); try { this.enterOuterAlt(localctx, 1); { - this.state = 188; + this.state = 236; this.typeName(); - this.state = 189; + this.state = 237; this.match(CashScriptParser.Identifier); - this.state = 190; - this.match(CashScriptParser.T__15); - this.state = 191; + this.state = 238; + this.match(CashScriptParser.T__18); + this.state = 239; this.typeName(); - this.state = 192; + this.state = 240; this.match(CashScriptParser.Identifier); - this.state = 193; + this.state = 241; this.match(CashScriptParser.T__9); - this.state = 194; + this.state = 242; this.expression(0); } } @@ -985,40 +1209,40 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public assignStatement(): AssignStatementContext { let localctx: AssignStatementContext = new AssignStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 34, CashScriptParser.RULE_assignStatement); + this.enterRule(localctx, 44, CashScriptParser.RULE_assignStatement); let _la: number; try { - this.state = 201; + this.state = 249; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 14, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 18, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 196; + this.state = 244; this.match(CashScriptParser.Identifier); - this.state = 197; + this.state = 245; localctx._op = this._input.LT(1); _la = this._input.LA(1); - if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 787456) !== 0))) { + if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 6292480) !== 0))) { localctx._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 198; + this.state = 246; this.expression(0); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 199; + this.state = 247; this.match(CashScriptParser.Identifier); - this.state = 200; + this.state = 248; localctx._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===20 || _la===21)) { + if(!(_la===23 || _la===24)) { localctx._op = this._errHandler.recoverInline(this); } else { @@ -1046,35 +1270,35 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public timeOpStatement(): TimeOpStatementContext { let localctx: TimeOpStatementContext = new TimeOpStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 36, CashScriptParser.RULE_timeOpStatement); + this.enterRule(localctx, 46, CashScriptParser.RULE_timeOpStatement); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 203; - this.match(CashScriptParser.T__21); - this.state = 204; - this.match(CashScriptParser.T__14); - this.state = 205; + this.state = 251; + this.match(CashScriptParser.T__24); + this.state = 252; + this.match(CashScriptParser.T__13); + this.state = 253; this.match(CashScriptParser.TxVar); - this.state = 206; + this.state = 254; this.match(CashScriptParser.T__5); - this.state = 207; + this.state = 255; this.expression(0); - this.state = 210; + this.state = 258; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===16) { + if (_la===19) { { - this.state = 208; - this.match(CashScriptParser.T__15); - this.state = 209; + this.state = 256; + this.match(CashScriptParser.T__18); + this.state = 257; this.requireMessage(); } } - this.state = 212; - this.match(CashScriptParser.T__16); + this.state = 260; + this.match(CashScriptParser.T__14); } } catch (re) { @@ -1094,31 +1318,31 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public requireStatement(): RequireStatementContext { let localctx: RequireStatementContext = new RequireStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 38, CashScriptParser.RULE_requireStatement); + this.enterRule(localctx, 48, CashScriptParser.RULE_requireStatement); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 214; - this.match(CashScriptParser.T__21); - this.state = 215; - this.match(CashScriptParser.T__14); - this.state = 216; + this.state = 262; + this.match(CashScriptParser.T__24); + this.state = 263; + this.match(CashScriptParser.T__13); + this.state = 264; this.expression(0); - this.state = 219; + this.state = 267; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===16) { + if (_la===19) { { - this.state = 217; - this.match(CashScriptParser.T__15); - this.state = 218; + this.state = 265; + this.match(CashScriptParser.T__18); + this.state = 266; this.requireMessage(); } } - this.state = 221; - this.match(CashScriptParser.T__16); + this.state = 269; + this.match(CashScriptParser.T__14); } } catch (re) { @@ -1138,13 +1362,13 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public consoleStatement(): ConsoleStatementContext { let localctx: ConsoleStatementContext = new ConsoleStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 40, CashScriptParser.RULE_consoleStatement); + this.enterRule(localctx, 50, CashScriptParser.RULE_consoleStatement); try { this.enterOuterAlt(localctx, 1); { - this.state = 223; - this.match(CashScriptParser.T__22); - this.state = 224; + this.state = 271; + this.match(CashScriptParser.T__25); + this.state = 272; this.consoleParameterList(); } } @@ -1165,28 +1389,28 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public ifStatement(): IfStatementContext { let localctx: IfStatementContext = new IfStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 42, CashScriptParser.RULE_ifStatement); + this.enterRule(localctx, 52, CashScriptParser.RULE_ifStatement); try { this.enterOuterAlt(localctx, 1); { - this.state = 226; - this.match(CashScriptParser.T__23); - this.state = 227; - this.match(CashScriptParser.T__14); - this.state = 228; + this.state = 274; + this.match(CashScriptParser.T__26); + this.state = 275; + this.match(CashScriptParser.T__13); + this.state = 276; this.expression(0); - this.state = 229; - this.match(CashScriptParser.T__16); - this.state = 230; + this.state = 277; + this.match(CashScriptParser.T__14); + this.state = 278; localctx._ifBlock = this.block(); - this.state = 233; + this.state = 281; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 17, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 21, this._ctx) ) { case 1: { - this.state = 231; - this.match(CashScriptParser.T__24); - this.state = 232; + this.state = 279; + this.match(CashScriptParser.T__27); + this.state = 280; localctx._elseBlock = this.block(); } break; @@ -1210,29 +1434,29 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public loopStatement(): LoopStatementContext { let localctx: LoopStatementContext = new LoopStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 44, CashScriptParser.RULE_loopStatement); + this.enterRule(localctx, 54, CashScriptParser.RULE_loopStatement); try { - this.state = 238; + this.state = 286; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 26: + case 29: this.enterOuterAlt(localctx, 1); { - this.state = 235; + this.state = 283; this.doWhileStatement(); } break; - case 27: + case 30: this.enterOuterAlt(localctx, 2); { - this.state = 236; + this.state = 284; this.whileStatement(); } break; - case 28: + case 31: this.enterOuterAlt(localctx, 3); { - this.state = 237; + this.state = 285; this.forStatement(); } break; @@ -1257,23 +1481,23 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public doWhileStatement(): DoWhileStatementContext { let localctx: DoWhileStatementContext = new DoWhileStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 46, CashScriptParser.RULE_doWhileStatement); + this.enterRule(localctx, 56, CashScriptParser.RULE_doWhileStatement); try { this.enterOuterAlt(localctx, 1); { - this.state = 240; - this.match(CashScriptParser.T__25); - this.state = 241; + this.state = 288; + this.match(CashScriptParser.T__28); + this.state = 289; this.block(); - this.state = 242; - this.match(CashScriptParser.T__26); - this.state = 243; - this.match(CashScriptParser.T__14); - this.state = 244; + this.state = 290; + this.match(CashScriptParser.T__29); + this.state = 291; + this.match(CashScriptParser.T__13); + this.state = 292; this.expression(0); - this.state = 245; - this.match(CashScriptParser.T__16); - this.state = 246; + this.state = 293; + this.match(CashScriptParser.T__14); + this.state = 294; this.match(CashScriptParser.T__1); } } @@ -1294,19 +1518,19 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public whileStatement(): WhileStatementContext { let localctx: WhileStatementContext = new WhileStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 48, CashScriptParser.RULE_whileStatement); + this.enterRule(localctx, 58, CashScriptParser.RULE_whileStatement); try { this.enterOuterAlt(localctx, 1); { - this.state = 248; - this.match(CashScriptParser.T__26); - this.state = 249; - this.match(CashScriptParser.T__14); - this.state = 250; + this.state = 296; + this.match(CashScriptParser.T__29); + this.state = 297; + this.match(CashScriptParser.T__13); + this.state = 298; this.expression(0); - this.state = 251; - this.match(CashScriptParser.T__16); - this.state = 252; + this.state = 299; + this.match(CashScriptParser.T__14); + this.state = 300; this.block(); } } @@ -1327,27 +1551,27 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public forStatement(): ForStatementContext { let localctx: ForStatementContext = new ForStatementContext(this, this._ctx, this.state); - this.enterRule(localctx, 50, CashScriptParser.RULE_forStatement); + this.enterRule(localctx, 60, CashScriptParser.RULE_forStatement); try { this.enterOuterAlt(localctx, 1); { - this.state = 254; - this.match(CashScriptParser.T__27); - this.state = 255; - this.match(CashScriptParser.T__14); - this.state = 256; + this.state = 302; + this.match(CashScriptParser.T__30); + this.state = 303; + this.match(CashScriptParser.T__13); + this.state = 304; this.forInit(); - this.state = 257; + this.state = 305; this.match(CashScriptParser.T__1); - this.state = 258; + this.state = 306; this.expression(0); - this.state = 259; + this.state = 307; this.match(CashScriptParser.T__1); - this.state = 260; + this.state = 308; this.assignStatement(); - this.state = 261; - this.match(CashScriptParser.T__16); - this.state = 262; + this.state = 309; + this.match(CashScriptParser.T__14); + this.state = 310; this.block(); } } @@ -1368,24 +1592,24 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public forInit(): ForInitContext { let localctx: ForInitContext = new ForInitContext(this, this._ctx, this.state); - this.enterRule(localctx, 52, CashScriptParser.RULE_forInit); + this.enterRule(localctx, 62, CashScriptParser.RULE_forInit); try { - this.state = 266; + this.state = 314; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 68: - case 69: - case 70: + case 71: + case 72: + case 73: this.enterOuterAlt(localctx, 1); { - this.state = 264; + this.state = 312; this.variableDefinition(); } break; - case 78: + case 81: this.enterOuterAlt(localctx, 2); { - this.state = 265; + this.state = 313; this.assignStatement(); } break; @@ -1410,11 +1634,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, 54, CashScriptParser.RULE_requireMessage); + this.enterRule(localctx, 64, CashScriptParser.RULE_requireMessage); try { this.enterOuterAlt(localctx, 1); { - this.state = 268; + this.state = 316; this.match(CashScriptParser.StringLiteral); } } @@ -1435,26 +1659,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, 56, CashScriptParser.RULE_consoleParameter); + this.enterRule(localctx, 66, CashScriptParser.RULE_consoleParameter); try { - this.state = 272; + this.state = 320; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 78: + case 81: this.enterOuterAlt(localctx, 1); { - this.state = 270; + this.state = 318; this.match(CashScriptParser.Identifier); } break; - case 63: - case 65: - case 72: - case 73: - case 74: + case 66: + case 68: + case 75: + case 76: + case 77: this.enterOuterAlt(localctx, 2); { - this.state = 271; + this.state = 319; this.literal(); } break; @@ -1479,54 +1703,54 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public consoleParameterList(): ConsoleParameterListContext { let localctx: ConsoleParameterListContext = new ConsoleParameterListContext(this, this._ctx, this.state); - this.enterRule(localctx, 58, CashScriptParser.RULE_consoleParameterList); + this.enterRule(localctx, 68, CashScriptParser.RULE_consoleParameterList); let _la: number; try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 274; - this.match(CashScriptParser.T__14); - this.state = 286; + this.state = 322; + this.match(CashScriptParser.T__13); + this.state = 334; this._errHandler.sync(this); _la = this._input.LA(1); - if (((((_la - 63)) & ~0x1F) === 0 && ((1 << (_la - 63)) & 36357) !== 0)) { + if (((((_la - 66)) & ~0x1F) === 0 && ((1 << (_la - 66)) & 36357) !== 0)) { { - this.state = 275; + this.state = 323; this.consoleParameter(); - this.state = 280; + this.state = 328; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 21, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 25, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 276; - this.match(CashScriptParser.T__15); - this.state = 277; + this.state = 324; + this.match(CashScriptParser.T__18); + this.state = 325; this.consoleParameter(); } } } - this.state = 282; + this.state = 330; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 21, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 25, this._ctx); } - this.state = 284; + this.state = 332; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===16) { + if (_la===19) { { - this.state = 283; - this.match(CashScriptParser.T__15); + this.state = 331; + this.match(CashScriptParser.T__18); } } } } - this.state = 288; - this.match(CashScriptParser.T__16); + this.state = 336; + this.match(CashScriptParser.T__14); } } catch (re) { @@ -1546,13 +1770,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, 60, CashScriptParser.RULE_functionCall); + this.enterRule(localctx, 70, CashScriptParser.RULE_functionCall); try { this.enterOuterAlt(localctx, 1); { - this.state = 290; + this.state = 338; this.match(CashScriptParser.Identifier); - this.state = 291; + this.state = 339; this.expressionList(); } } @@ -1573,54 +1797,54 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public expressionList(): ExpressionListContext { let localctx: ExpressionListContext = new ExpressionListContext(this, this._ctx, this.state); - this.enterRule(localctx, 62, CashScriptParser.RULE_expressionList); + this.enterRule(localctx, 72, CashScriptParser.RULE_expressionList); let _la: number; try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 293; - this.match(CashScriptParser.T__14); - this.state = 305; + this.state = 341; + this.match(CashScriptParser.T__13); + this.state = 353; this._errHandler.sync(this); _la = this._input.LA(1); - if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 1610645536) !== 0) || ((((_la - 32)) & ~0x1F) === 0 && ((1 << (_la - 32)) & 2147582017) !== 0) || ((((_la - 65)) & ~0x1F) === 0 && ((1 << (_la - 65)) & 15257) !== 0)) { + if (_la===5 || _la===14 || ((((_la - 32)) & ~0x1F) === 0 && ((1 << (_la - 32)) & 786955) !== 0) || ((((_la - 66)) & ~0x1F) === 0 && ((1 << (_la - 66)) & 61029) !== 0)) { { - this.state = 294; + this.state = 342; this.expression(0); - this.state = 299; + this.state = 347; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 24, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 28, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 295; - this.match(CashScriptParser.T__15); - this.state = 296; + this.state = 343; + this.match(CashScriptParser.T__18); + this.state = 344; this.expression(0); } } } - this.state = 301; + this.state = 349; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 24, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 28, this._ctx); } - this.state = 303; + this.state = 351; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===16) { + if (_la===19) { { - this.state = 302; - this.match(CashScriptParser.T__15); + this.state = 350; + this.match(CashScriptParser.T__18); } } } } - this.state = 307; - this.match(CashScriptParser.T__16); + this.state = 355; + this.match(CashScriptParser.T__14); } } catch (re) { @@ -1650,28 +1874,28 @@ 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 = 64; - this.enterRecursionRule(localctx, 64, CashScriptParser.RULE_expression, _p); + let _startState: number = 74; + this.enterRecursionRule(localctx, 74, CashScriptParser.RULE_expression, _p); let _la: number; try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 358; + this.state = 406; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 31, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 35, this._ctx) ) { case 1: { localctx = new ParenthesisedContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 310; - this.match(CashScriptParser.T__14); - this.state = 311; + this.state = 358; + this.match(CashScriptParser.T__13); + this.state = 359; this.expression(0); - this.state = 312; - this.match(CashScriptParser.T__16); + this.state = 360; + this.match(CashScriptParser.T__14); } break; case 2: @@ -1679,24 +1903,24 @@ export default class CashScriptParser extends Parser { localctx = new CastContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 314; + this.state = 362; this.typeCast(); - this.state = 315; - this.match(CashScriptParser.T__14); - this.state = 316; + this.state = 363; + this.match(CashScriptParser.T__13); + this.state = 364; (localctx as CastContext)._castable = this.expression(0); - this.state = 318; + this.state = 366; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===16) { + if (_la===19) { { - this.state = 317; - this.match(CashScriptParser.T__15); + this.state = 365; + this.match(CashScriptParser.T__18); } } - this.state = 320; - this.match(CashScriptParser.T__16); + this.state = 368; + this.match(CashScriptParser.T__14); } break; case 3: @@ -1704,7 +1928,7 @@ export default class CashScriptParser extends Parser { localctx = new FunctionCallExpressionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 322; + this.state = 370; this.functionCall(); } break; @@ -1713,11 +1937,11 @@ export default class CashScriptParser extends Parser { localctx = new InstantiationContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 323; - this.match(CashScriptParser.T__28); - this.state = 324; + this.state = 371; + this.match(CashScriptParser.T__31); + this.state = 372; this.match(CashScriptParser.Identifier); - this.state = 325; + this.state = 373; this.expressionList(); } break; @@ -1726,18 +1950,18 @@ export default class CashScriptParser extends Parser { localctx = new UnaryIntrospectionOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 326; - (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__31); - this.state = 327; - this.match(CashScriptParser.T__29); - this.state = 328; + this.state = 374; + (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__34); + this.state = 375; + this.match(CashScriptParser.T__32); + this.state = 376; this.expression(0); - this.state = 329; - this.match(CashScriptParser.T__30); - this.state = 330; + this.state = 377; + this.match(CashScriptParser.T__33); + this.state = 378; (localctx as UnaryIntrospectionOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(((((_la - 33)) & ~0x1F) === 0 && ((1 << (_la - 33)) & 31) !== 0))) { + if(!(((((_la - 36)) & ~0x1F) === 0 && ((1 << (_la - 36)) & 31) !== 0))) { (localctx as UnaryIntrospectionOpContext)._op = this._errHandler.recoverInline(this); } else { @@ -1751,18 +1975,18 @@ export default class CashScriptParser extends Parser { localctx = new UnaryIntrospectionOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 332; - (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__37); - this.state = 333; - this.match(CashScriptParser.T__29); - this.state = 334; + this.state = 380; + (localctx as UnaryIntrospectionOpContext)._scope = this.match(CashScriptParser.T__40); + this.state = 381; + this.match(CashScriptParser.T__32); + this.state = 382; this.expression(0); - this.state = 335; - this.match(CashScriptParser.T__30); - this.state = 336; + this.state = 383; + this.match(CashScriptParser.T__33); + this.state = 384; (localctx as UnaryIntrospectionOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(((((_la - 33)) & ~0x1F) === 0 && ((1 << (_la - 33)) & 991) !== 0))) { + if(!(((((_la - 36)) & ~0x1F) === 0 && ((1 << (_la - 36)) & 991) !== 0))) { (localctx as UnaryIntrospectionOpContext)._op = this._errHandler.recoverInline(this); } else { @@ -1776,17 +2000,17 @@ export default class CashScriptParser extends Parser { localctx = new UnaryOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 338; + this.state = 386; (localctx as UnaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===5 || _la===47 || _la===48)) { + if(!(_la===5 || _la===50 || _la===51)) { (localctx as UnaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 339; + this.state = 387; this.expression(15); } break; @@ -1795,48 +2019,48 @@ export default class CashScriptParser extends Parser { localctx = new ArrayContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 340; - this.match(CashScriptParser.T__29); - this.state = 352; + this.state = 388; + this.match(CashScriptParser.T__32); + this.state = 400; this._errHandler.sync(this); _la = this._input.LA(1); - if ((((_la) & ~0x1F) === 0 && ((1 << _la) & 1610645536) !== 0) || ((((_la - 32)) & ~0x1F) === 0 && ((1 << (_la - 32)) & 2147582017) !== 0) || ((((_la - 65)) & ~0x1F) === 0 && ((1 << (_la - 65)) & 15257) !== 0)) { + if (_la===5 || _la===14 || ((((_la - 32)) & ~0x1F) === 0 && ((1 << (_la - 32)) & 786955) !== 0) || ((((_la - 66)) & ~0x1F) === 0 && ((1 << (_la - 66)) & 61029) !== 0)) { { - this.state = 341; + this.state = 389; this.expression(0); - this.state = 346; + this.state = 394; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 28, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 32, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 342; - this.match(CashScriptParser.T__15); - this.state = 343; + this.state = 390; + this.match(CashScriptParser.T__18); + this.state = 391; this.expression(0); } } } - this.state = 348; + this.state = 396; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 28, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 32, this._ctx); } - this.state = 350; + this.state = 398; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===16) { + if (_la===19) { { - this.state = 349; - this.match(CashScriptParser.T__15); + this.state = 397; + this.match(CashScriptParser.T__18); } } } } - this.state = 354; - this.match(CashScriptParser.T__30); + this.state = 402; + this.match(CashScriptParser.T__33); } break; case 9: @@ -1844,7 +2068,7 @@ export default class CashScriptParser extends Parser { localctx = new NullaryOpContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 355; + this.state = 403; this.match(CashScriptParser.NullaryOp); } break; @@ -1853,7 +2077,7 @@ export default class CashScriptParser extends Parser { localctx = new IdentifierContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 356; + this.state = 404; this.match(CashScriptParser.Identifier); } break; @@ -1862,15 +2086,15 @@ export default class CashScriptParser extends Parser { localctx = new LiteralExpressionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 357; + this.state = 405; this.literal(); } break; } this._ctx.stop = this._input.LT(-1); - this.state = 412; + this.state = 460; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 33, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 37, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { if (this._parseListeners != null) { @@ -1878,29 +2102,29 @@ export default class CashScriptParser extends Parser { } _prevctx = localctx; { - this.state = 410; + this.state = 458; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 32, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 36, 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 = 360; + this.state = 408; if (!(this.precpred(this._ctx, 14))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 14)"); } - this.state = 361; + this.state = 409; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(((((_la - 49)) & ~0x1F) === 0 && ((1 << (_la - 49)) & 7) !== 0))) { + if(!(((((_la - 52)) & ~0x1F) === 0 && ((1 << (_la - 52)) & 7) !== 0))) { (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 362; + this.state = 410; (localctx as BinaryOpContext)._right = this.expression(15); } break; @@ -1909,21 +2133,21 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 363; + this.state = 411; if (!(this.precpred(this._ctx, 13))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 13)"); } - this.state = 364; + this.state = 412; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===48 || _la===52)) { + if(!(_la===51 || _la===55)) { (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 365; + this.state = 413; (localctx as BinaryOpContext)._right = this.expression(14); } break; @@ -1932,21 +2156,21 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 366; + this.state = 414; if (!(this.precpred(this._ctx, 12))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 12)"); } - this.state = 367; + this.state = 415; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===53 || _la===54)) { + if(!(_la===56 || _la===57)) { (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 368; + this.state = 416; (localctx as BinaryOpContext)._right = this.expression(13); } break; @@ -1955,11 +2179,11 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 369; + this.state = 417; if (!(this.precpred(this._ctx, 11))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 11)"); } - this.state = 370; + this.state = 418; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 960) !== 0))) { @@ -1969,7 +2193,7 @@ export default class CashScriptParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 371; + this.state = 419; (localctx as BinaryOpContext)._right = this.expression(12); } break; @@ -1978,21 +2202,21 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 372; + this.state = 420; if (!(this.precpred(this._ctx, 10))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 10)"); } - this.state = 373; + this.state = 421; (localctx as BinaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===55 || _la===56)) { + if(!(_la===58 || _la===59)) { (localctx as BinaryOpContext)._op = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 374; + this.state = 422; (localctx as BinaryOpContext)._right = this.expression(11); } break; @@ -2001,13 +2225,13 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 375; + this.state = 423; if (!(this.precpred(this._ctx, 9))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 9)"); } - this.state = 376; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__56); - this.state = 377; + this.state = 424; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__59); + this.state = 425; (localctx as BinaryOpContext)._right = this.expression(10); } break; @@ -2016,13 +2240,13 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 378; + this.state = 426; if (!(this.precpred(this._ctx, 8))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 8)"); } - this.state = 379; + this.state = 427; (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__3); - this.state = 380; + this.state = 428; (localctx as BinaryOpContext)._right = this.expression(9); } break; @@ -2031,13 +2255,13 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 381; + this.state = 429; if (!(this.precpred(this._ctx, 7))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 7)"); } - this.state = 382; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__57); - this.state = 383; + this.state = 430; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__60); + this.state = 431; (localctx as BinaryOpContext)._right = this.expression(8); } break; @@ -2046,13 +2270,13 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 384; + this.state = 432; if (!(this.precpred(this._ctx, 6))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 6)"); } - this.state = 385; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__58); - this.state = 386; + this.state = 433; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__61); + this.state = 434; (localctx as BinaryOpContext)._right = this.expression(7); } break; @@ -2061,13 +2285,13 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 387; + this.state = 435; if (!(this.precpred(this._ctx, 5))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 5)"); } - this.state = 388; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__59); - this.state = 389; + this.state = 436; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__62); + this.state = 437; (localctx as BinaryOpContext)._right = this.expression(6); } break; @@ -2075,30 +2299,30 @@ export default class CashScriptParser extends Parser { { localctx = new TupleIndexOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 390; + this.state = 438; if (!(this.precpred(this._ctx, 21))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 21)"); } - this.state = 391; - this.match(CashScriptParser.T__29); - this.state = 392; + this.state = 439; + this.match(CashScriptParser.T__32); + this.state = 440; (localctx as TupleIndexOpContext)._index = this.match(CashScriptParser.NumberLiteral); - this.state = 393; - this.match(CashScriptParser.T__30); + this.state = 441; + this.match(CashScriptParser.T__33); } break; case 12: { localctx = new UnaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 394; + this.state = 442; if (!(this.precpred(this._ctx, 18))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 18)"); } - this.state = 395; + this.state = 443; (localctx as UnaryOpContext)._op = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===43 || _la===44)) { + if(!(_la===46 || _la===47)) { (localctx as UnaryOpContext)._op = this._errHandler.recoverInline(this); } else { @@ -2112,18 +2336,18 @@ export default class CashScriptParser extends Parser { localctx = new BinaryOpContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as BinaryOpContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 396; + this.state = 444; if (!(this.precpred(this._ctx, 17))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 17)"); } - this.state = 397; - (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__44); - this.state = 398; - this.match(CashScriptParser.T__14); - this.state = 399; + this.state = 445; + (localctx as BinaryOpContext)._op = this.match(CashScriptParser.T__47); + this.state = 446; + this.match(CashScriptParser.T__13); + this.state = 447; (localctx as BinaryOpContext)._right = this.expression(0); - this.state = 400; - this.match(CashScriptParser.T__16); + this.state = 448; + this.match(CashScriptParser.T__14); } break; case 14: @@ -2131,30 +2355,30 @@ export default class CashScriptParser extends Parser { localctx = new SliceContext(this, new ExpressionContext(this, _parentctx, _parentState)); (localctx as SliceContext)._element = _prevctx; this.pushNewRecursionContext(localctx, _startState, CashScriptParser.RULE_expression); - this.state = 402; + this.state = 450; if (!(this.precpred(this._ctx, 16))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 16)"); } - this.state = 403; - this.match(CashScriptParser.T__45); - this.state = 404; - this.match(CashScriptParser.T__14); - this.state = 405; + this.state = 451; + this.match(CashScriptParser.T__48); + this.state = 452; + this.match(CashScriptParser.T__13); + this.state = 453; (localctx as SliceContext)._start = this.expression(0); - this.state = 406; - this.match(CashScriptParser.T__15); - this.state = 407; + this.state = 454; + this.match(CashScriptParser.T__18); + this.state = 455; (localctx as SliceContext)._end = this.expression(0); - this.state = 408; - this.match(CashScriptParser.T__16); + this.state = 456; + this.match(CashScriptParser.T__14); } break; } } } - this.state = 414; + this.state = 462; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 33, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 37, this._ctx); } } } @@ -2175,12 +2399,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, 66, CashScriptParser.RULE_modifier); + this.enterRule(localctx, 76, CashScriptParser.RULE_modifier); try { this.enterOuterAlt(localctx, 1); { - this.state = 415; - this.match(CashScriptParser.T__60); + this.state = 463; + this.match(CashScriptParser.T__63); } } catch (re) { @@ -2200,43 +2424,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, 68, CashScriptParser.RULE_literal); + this.enterRule(localctx, 78, CashScriptParser.RULE_literal); try { - this.state = 422; + this.state = 470; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 63: + case 66: this.enterOuterAlt(localctx, 1); { - this.state = 417; + this.state = 465; this.match(CashScriptParser.BooleanLiteral); } break; - case 65: + case 68: this.enterOuterAlt(localctx, 2); { - this.state = 418; + this.state = 466; this.numberLiteral(); } break; - case 72: + case 75: this.enterOuterAlt(localctx, 3); { - this.state = 419; + this.state = 467; this.match(CashScriptParser.StringLiteral); } break; - case 73: + case 76: this.enterOuterAlt(localctx, 4); { - this.state = 420; + this.state = 468; this.match(CashScriptParser.DateLiteral); } break; - case 74: + case 77: this.enterOuterAlt(localctx, 5); { - this.state = 421; + this.state = 469; this.match(CashScriptParser.HexLiteral); } break; @@ -2261,18 +2485,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, 70, CashScriptParser.RULE_numberLiteral); + this.enterRule(localctx, 80, CashScriptParser.RULE_numberLiteral); try { this.enterOuterAlt(localctx, 1); { - this.state = 424; + this.state = 472; this.match(CashScriptParser.NumberLiteral); - this.state = 426; + this.state = 474; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 35, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 39, this._ctx) ) { case 1: { - this.state = 425; + this.state = 473; this.match(CashScriptParser.NumberUnit); } break; @@ -2296,14 +2520,14 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public typeName(): TypeNameContext { let localctx: TypeNameContext = new TypeNameContext(this, this._ctx, this.state); - this.enterRule(localctx, 72, CashScriptParser.RULE_typeName); + this.enterRule(localctx, 82, CashScriptParser.RULE_typeName); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 428; + this.state = 476; _la = this._input.LA(1); - if(!(((((_la - 68)) & ~0x1F) === 0 && ((1 << (_la - 68)) & 7) !== 0))) { + if(!(((((_la - 71)) & ~0x1F) === 0 && ((1 << (_la - 71)) & 7) !== 0))) { this._errHandler.recoverInline(this); } else { @@ -2329,14 +2553,14 @@ export default class CashScriptParser extends Parser { // @RuleVersion(0) public typeCast(): TypeCastContext { let localctx: TypeCastContext = new TypeCastContext(this, this._ctx, this.state); - this.enterRule(localctx, 74, CashScriptParser.RULE_typeCast); + this.enterRule(localctx, 84, CashScriptParser.RULE_typeCast); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 430; + this.state = 478; _la = this._input.LA(1); - if(!(((((_la - 68)) & ~0x1F) === 0 && ((1 << (_la - 68)) & 259) !== 0))) { + if(!(((((_la - 71)) & ~0x1F) === 0 && ((1 << (_la - 71)) & 259) !== 0))) { this._errHandler.recoverInline(this); } else { @@ -2362,7 +2586,7 @@ export default class CashScriptParser extends Parser { public sempred(localctx: RuleContext, ruleIndex: number, predIndex: number): boolean { switch (ruleIndex) { - case 32: + case 37: return this.expression_sempred(localctx as ExpressionContext, predIndex); } return true; @@ -2401,149 +2625,165 @@ export default class CashScriptParser extends Parser { return true; } - public static readonly _serializedATN: number[] = [4,1,81,433,2,0,7,0,2, + public static readonly _serializedATN: number[] = [4,1,84,481,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,1,0,5,0,78, - 8,0,10,0,12,0,81,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,95,8,3,1,4,3,4,98,8,4,1,4,1,4,1,5,1,5,1,6,1,6,1,6,1,6,1,6,5,6,109,8,6, - 10,6,12,6,112,9,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,8,1,8,5,8,123,8,8,10,8, - 12,8,126,9,8,1,8,1,8,1,9,1,9,1,9,1,9,5,9,134,8,9,10,9,12,9,137,9,9,1,9, - 3,9,140,8,9,3,9,142,8,9,1,9,1,9,1,10,1,10,1,10,1,11,1,11,5,11,151,8,11, - 10,11,12,11,154,9,11,1,11,1,11,3,11,158,8,11,1,12,1,12,1,12,1,12,3,12,164, - 8,12,1,13,1,13,1,13,1,13,1,13,1,13,3,13,172,8,13,1,14,1,14,3,14,176,8,14, - 1,15,1,15,5,15,180,8,15,10,15,12,15,183,9,15,1,15,1,15,1,15,1,15,1,16,1, - 16,1,16,1,16,1,16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,3,17,202,8,17, - 1,18,1,18,1,18,1,18,1,18,1,18,1,18,3,18,211,8,18,1,18,1,18,1,19,1,19,1, - 19,1,19,1,19,3,19,220,8,19,1,19,1,19,1,20,1,20,1,20,1,21,1,21,1,21,1,21, - 1,21,1,21,1,21,3,21,234,8,21,1,22,1,22,1,22,3,22,239,8,22,1,23,1,23,1,23, - 1,23,1,23,1,23,1,23,1,23,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,25,1,25,1,25,1,26,1,26,3,26,267,8,26,1,27,1,27,1,28, - 1,28,3,28,273,8,28,1,29,1,29,1,29,1,29,5,29,279,8,29,10,29,12,29,282,9, - 29,1,29,3,29,285,8,29,3,29,287,8,29,1,29,1,29,1,30,1,30,1,30,1,31,1,31, - 1,31,1,31,5,31,298,8,31,10,31,12,31,301,9,31,1,31,3,31,304,8,31,3,31,306, - 8,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,3,32,319,8, - 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,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,5,32,345,8,32,10,32,12, - 32,348,9,32,1,32,3,32,351,8,32,3,32,353,8,32,1,32,1,32,1,32,1,32,3,32,359, - 8,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,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,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,32,1,32,1,32,1,32,1,32,1,32,5,32,411,8,32,10,32,12,32,414,9,32, - 1,33,1,33,1,34,1,34,1,34,1,34,1,34,3,34,423,8,34,1,35,1,35,3,35,427,8,35, - 1,36,1,36,1,37,1,37,1,37,0,1,64,38,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,64,66,68,70,72,74, - 0,14,1,0,4,10,2,0,10,10,18,19,1,0,20,21,1,0,33,37,2,0,33,37,39,42,2,0,5, - 5,47,48,1,0,49,51,2,0,48,48,52,52,1,0,53,54,1,0,6,9,1,0,55,56,1,0,43,44, - 1,0,68,70,2,0,68,69,76,76,459,0,79,1,0,0,0,2,85,1,0,0,0,4,90,1,0,0,0,6, - 92,1,0,0,0,8,97,1,0,0,0,10,101,1,0,0,0,12,103,1,0,0,0,14,115,1,0,0,0,16, - 120,1,0,0,0,18,129,1,0,0,0,20,145,1,0,0,0,22,157,1,0,0,0,24,163,1,0,0,0, - 26,171,1,0,0,0,28,175,1,0,0,0,30,177,1,0,0,0,32,188,1,0,0,0,34,201,1,0, - 0,0,36,203,1,0,0,0,38,214,1,0,0,0,40,223,1,0,0,0,42,226,1,0,0,0,44,238, - 1,0,0,0,46,240,1,0,0,0,48,248,1,0,0,0,50,254,1,0,0,0,52,266,1,0,0,0,54, - 268,1,0,0,0,56,272,1,0,0,0,58,274,1,0,0,0,60,290,1,0,0,0,62,293,1,0,0,0, - 64,358,1,0,0,0,66,415,1,0,0,0,68,422,1,0,0,0,70,424,1,0,0,0,72,428,1,0, - 0,0,74,430,1,0,0,0,76,78,3,2,1,0,77,76,1,0,0,0,78,81,1,0,0,0,79,77,1,0, - 0,0,79,80,1,0,0,0,80,82,1,0,0,0,81,79,1,0,0,0,82,83,3,12,6,0,83,84,5,0, - 0,1,84,1,1,0,0,0,85,86,5,1,0,0,86,87,3,4,2,0,87,88,3,6,3,0,88,89,5,2,0, - 0,89,3,1,0,0,0,90,91,5,3,0,0,91,5,1,0,0,0,92,94,3,8,4,0,93,95,3,8,4,0,94, - 93,1,0,0,0,94,95,1,0,0,0,95,7,1,0,0,0,96,98,3,10,5,0,97,96,1,0,0,0,97,98, - 1,0,0,0,98,99,1,0,0,0,99,100,5,62,0,0,100,9,1,0,0,0,101,102,7,0,0,0,102, - 11,1,0,0,0,103,104,5,11,0,0,104,105,5,78,0,0,105,106,3,18,9,0,106,110,5, - 12,0,0,107,109,3,14,7,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,13, - 1,0,0,0,115,116,5,14,0,0,116,117,5,78,0,0,117,118,3,18,9,0,118,119,3,16, - 8,0,119,15,1,0,0,0,120,124,5,12,0,0,121,123,3,24,12,0,122,121,1,0,0,0,123, - 126,1,0,0,0,124,122,1,0,0,0,124,125,1,0,0,0,125,127,1,0,0,0,126,124,1,0, - 0,0,127,128,5,13,0,0,128,17,1,0,0,0,129,141,5,15,0,0,130,135,3,20,10,0, - 131,132,5,16,0,0,132,134,3,20,10,0,133,131,1,0,0,0,134,137,1,0,0,0,135, - 133,1,0,0,0,135,136,1,0,0,0,136,139,1,0,0,0,137,135,1,0,0,0,138,140,5,16, - 0,0,139,138,1,0,0,0,139,140,1,0,0,0,140,142,1,0,0,0,141,130,1,0,0,0,141, - 142,1,0,0,0,142,143,1,0,0,0,143,144,5,17,0,0,144,19,1,0,0,0,145,146,3,72, - 36,0,146,147,5,78,0,0,147,21,1,0,0,0,148,152,5,12,0,0,149,151,3,24,12,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,158,5,13,0,0,156,158,3,24,12,0,157,148,1,0, - 0,0,157,156,1,0,0,0,158,23,1,0,0,0,159,164,3,28,14,0,160,161,3,26,13,0, - 161,162,5,2,0,0,162,164,1,0,0,0,163,159,1,0,0,0,163,160,1,0,0,0,164,25, - 1,0,0,0,165,172,3,30,15,0,166,172,3,32,16,0,167,172,3,34,17,0,168,172,3, - 36,18,0,169,172,3,38,19,0,170,172,3,40,20,0,171,165,1,0,0,0,171,166,1,0, - 0,0,171,167,1,0,0,0,171,168,1,0,0,0,171,169,1,0,0,0,171,170,1,0,0,0,172, - 27,1,0,0,0,173,176,3,42,21,0,174,176,3,44,22,0,175,173,1,0,0,0,175,174, - 1,0,0,0,176,29,1,0,0,0,177,181,3,72,36,0,178,180,3,66,33,0,179,178,1,0, - 0,0,180,183,1,0,0,0,181,179,1,0,0,0,181,182,1,0,0,0,182,184,1,0,0,0,183, - 181,1,0,0,0,184,185,5,78,0,0,185,186,5,10,0,0,186,187,3,64,32,0,187,31, - 1,0,0,0,188,189,3,72,36,0,189,190,5,78,0,0,190,191,5,16,0,0,191,192,3,72, - 36,0,192,193,5,78,0,0,193,194,5,10,0,0,194,195,3,64,32,0,195,33,1,0,0,0, - 196,197,5,78,0,0,197,198,7,1,0,0,198,202,3,64,32,0,199,200,5,78,0,0,200, - 202,7,2,0,0,201,196,1,0,0,0,201,199,1,0,0,0,202,35,1,0,0,0,203,204,5,22, - 0,0,204,205,5,15,0,0,205,206,5,75,0,0,206,207,5,6,0,0,207,210,3,64,32,0, - 208,209,5,16,0,0,209,211,3,54,27,0,210,208,1,0,0,0,210,211,1,0,0,0,211, - 212,1,0,0,0,212,213,5,17,0,0,213,37,1,0,0,0,214,215,5,22,0,0,215,216,5, - 15,0,0,216,219,3,64,32,0,217,218,5,16,0,0,218,220,3,54,27,0,219,217,1,0, - 0,0,219,220,1,0,0,0,220,221,1,0,0,0,221,222,5,17,0,0,222,39,1,0,0,0,223, - 224,5,23,0,0,224,225,3,58,29,0,225,41,1,0,0,0,226,227,5,24,0,0,227,228, - 5,15,0,0,228,229,3,64,32,0,229,230,5,17,0,0,230,233,3,22,11,0,231,232,5, - 25,0,0,232,234,3,22,11,0,233,231,1,0,0,0,233,234,1,0,0,0,234,43,1,0,0,0, - 235,239,3,46,23,0,236,239,3,48,24,0,237,239,3,50,25,0,238,235,1,0,0,0,238, - 236,1,0,0,0,238,237,1,0,0,0,239,45,1,0,0,0,240,241,5,26,0,0,241,242,3,22, - 11,0,242,243,5,27,0,0,243,244,5,15,0,0,244,245,3,64,32,0,245,246,5,17,0, - 0,246,247,5,2,0,0,247,47,1,0,0,0,248,249,5,27,0,0,249,250,5,15,0,0,250, - 251,3,64,32,0,251,252,5,17,0,0,252,253,3,22,11,0,253,49,1,0,0,0,254,255, - 5,28,0,0,255,256,5,15,0,0,256,257,3,52,26,0,257,258,5,2,0,0,258,259,3,64, - 32,0,259,260,5,2,0,0,260,261,3,34,17,0,261,262,5,17,0,0,262,263,3,22,11, - 0,263,51,1,0,0,0,264,267,3,30,15,0,265,267,3,34,17,0,266,264,1,0,0,0,266, - 265,1,0,0,0,267,53,1,0,0,0,268,269,5,72,0,0,269,55,1,0,0,0,270,273,5,78, - 0,0,271,273,3,68,34,0,272,270,1,0,0,0,272,271,1,0,0,0,273,57,1,0,0,0,274, - 286,5,15,0,0,275,280,3,56,28,0,276,277,5,16,0,0,277,279,3,56,28,0,278,276, - 1,0,0,0,279,282,1,0,0,0,280,278,1,0,0,0,280,281,1,0,0,0,281,284,1,0,0,0, - 282,280,1,0,0,0,283,285,5,16,0,0,284,283,1,0,0,0,284,285,1,0,0,0,285,287, - 1,0,0,0,286,275,1,0,0,0,286,287,1,0,0,0,287,288,1,0,0,0,288,289,5,17,0, - 0,289,59,1,0,0,0,290,291,5,78,0,0,291,292,3,62,31,0,292,61,1,0,0,0,293, - 305,5,15,0,0,294,299,3,64,32,0,295,296,5,16,0,0,296,298,3,64,32,0,297,295, - 1,0,0,0,298,301,1,0,0,0,299,297,1,0,0,0,299,300,1,0,0,0,300,303,1,0,0,0, - 301,299,1,0,0,0,302,304,5,16,0,0,303,302,1,0,0,0,303,304,1,0,0,0,304,306, - 1,0,0,0,305,294,1,0,0,0,305,306,1,0,0,0,306,307,1,0,0,0,307,308,5,17,0, - 0,308,63,1,0,0,0,309,310,6,32,-1,0,310,311,5,15,0,0,311,312,3,64,32,0,312, - 313,5,17,0,0,313,359,1,0,0,0,314,315,3,74,37,0,315,316,5,15,0,0,316,318, - 3,64,32,0,317,319,5,16,0,0,318,317,1,0,0,0,318,319,1,0,0,0,319,320,1,0, - 0,0,320,321,5,17,0,0,321,359,1,0,0,0,322,359,3,60,30,0,323,324,5,29,0,0, - 324,325,5,78,0,0,325,359,3,62,31,0,326,327,5,32,0,0,327,328,5,30,0,0,328, - 329,3,64,32,0,329,330,5,31,0,0,330,331,7,3,0,0,331,359,1,0,0,0,332,333, - 5,38,0,0,333,334,5,30,0,0,334,335,3,64,32,0,335,336,5,31,0,0,336,337,7, - 4,0,0,337,359,1,0,0,0,338,339,7,5,0,0,339,359,3,64,32,15,340,352,5,30,0, - 0,341,346,3,64,32,0,342,343,5,16,0,0,343,345,3,64,32,0,344,342,1,0,0,0, - 345,348,1,0,0,0,346,344,1,0,0,0,346,347,1,0,0,0,347,350,1,0,0,0,348,346, - 1,0,0,0,349,351,5,16,0,0,350,349,1,0,0,0,350,351,1,0,0,0,351,353,1,0,0, - 0,352,341,1,0,0,0,352,353,1,0,0,0,353,354,1,0,0,0,354,359,5,31,0,0,355, - 359,5,77,0,0,356,359,5,78,0,0,357,359,3,68,34,0,358,309,1,0,0,0,358,314, - 1,0,0,0,358,322,1,0,0,0,358,323,1,0,0,0,358,326,1,0,0,0,358,332,1,0,0,0, - 358,338,1,0,0,0,358,340,1,0,0,0,358,355,1,0,0,0,358,356,1,0,0,0,358,357, - 1,0,0,0,359,412,1,0,0,0,360,361,10,14,0,0,361,362,7,6,0,0,362,411,3,64, - 32,15,363,364,10,13,0,0,364,365,7,7,0,0,365,411,3,64,32,14,366,367,10,12, - 0,0,367,368,7,8,0,0,368,411,3,64,32,13,369,370,10,11,0,0,370,371,7,9,0, - 0,371,411,3,64,32,12,372,373,10,10,0,0,373,374,7,10,0,0,374,411,3,64,32, - 11,375,376,10,9,0,0,376,377,5,57,0,0,377,411,3,64,32,10,378,379,10,8,0, - 0,379,380,5,4,0,0,380,411,3,64,32,9,381,382,10,7,0,0,382,383,5,58,0,0,383, - 411,3,64,32,8,384,385,10,6,0,0,385,386,5,59,0,0,386,411,3,64,32,7,387,388, - 10,5,0,0,388,389,5,60,0,0,389,411,3,64,32,6,390,391,10,21,0,0,391,392,5, - 30,0,0,392,393,5,65,0,0,393,411,5,31,0,0,394,395,10,18,0,0,395,411,7,11, - 0,0,396,397,10,17,0,0,397,398,5,45,0,0,398,399,5,15,0,0,399,400,3,64,32, - 0,400,401,5,17,0,0,401,411,1,0,0,0,402,403,10,16,0,0,403,404,5,46,0,0,404, - 405,5,15,0,0,405,406,3,64,32,0,406,407,5,16,0,0,407,408,3,64,32,0,408,409, - 5,17,0,0,409,411,1,0,0,0,410,360,1,0,0,0,410,363,1,0,0,0,410,366,1,0,0, - 0,410,369,1,0,0,0,410,372,1,0,0,0,410,375,1,0,0,0,410,378,1,0,0,0,410,381, - 1,0,0,0,410,384,1,0,0,0,410,387,1,0,0,0,410,390,1,0,0,0,410,394,1,0,0,0, - 410,396,1,0,0,0,410,402,1,0,0,0,411,414,1,0,0,0,412,410,1,0,0,0,412,413, - 1,0,0,0,413,65,1,0,0,0,414,412,1,0,0,0,415,416,5,61,0,0,416,67,1,0,0,0, - 417,423,5,63,0,0,418,423,3,70,35,0,419,423,5,72,0,0,420,423,5,73,0,0,421, - 423,5,74,0,0,422,417,1,0,0,0,422,418,1,0,0,0,422,419,1,0,0,0,422,420,1, - 0,0,0,422,421,1,0,0,0,423,69,1,0,0,0,424,426,5,65,0,0,425,427,5,64,0,0, - 426,425,1,0,0,0,426,427,1,0,0,0,427,71,1,0,0,0,428,429,7,12,0,0,429,73, - 1,0,0,0,430,431,7,13,0,0,431,75,1,0,0,0,36,79,94,97,110,124,135,139,141, - 152,157,163,171,175,181,201,210,219,233,238,266,272,280,284,286,299,303, - 305,318,346,350,352,358,410,412,422,426]; + 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,1,0,5,0,88,8,0,10,0,12,0,91,9,0,1, + 0,5,0,94,8,0,10,0,12,0,97,9,0,1,0,5,0,100,8,0,10,0,12,0,103,9,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,116,8,3,1,4,3,4,119,8,4,1,4,1,4, + 1,5,1,5,1,6,1,6,1,6,1,6,1,7,1,7,3,7,131,8,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8, + 1,8,3,8,141,8,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,5,9,150,8,9,10,9,12,9,153,9, + 9,1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,11,1,11,5,11,164,8,11,10,11,12,11, + 167,9,11,1,11,1,11,1,12,1,12,1,12,1,12,5,12,175,8,12,10,12,12,12,178,9, + 12,1,12,3,12,181,8,12,3,12,183,8,12,1,12,1,12,1,13,1,13,1,13,1,14,1,14, + 5,14,192,8,14,10,14,12,14,195,9,14,1,14,1,14,3,14,199,8,14,1,15,1,15,1, + 15,1,15,3,15,205,8,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,3,16,215, + 8,16,1,17,1,17,1,18,1,18,1,18,1,19,1,19,3,19,224,8,19,1,20,1,20,5,20,228, + 8,20,10,20,12,20,231,9,20,1,20,1,20,1,20,1,20,1,21,1,21,1,21,1,21,1,21, + 1,21,1,21,1,21,1,22,1,22,1,22,1,22,1,22,3,22,250,8,22,1,23,1,23,1,23,1, + 23,1,23,1,23,1,23,3,23,259,8,23,1,23,1,23,1,24,1,24,1,24,1,24,1,24,3,24, + 268,8,24,1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,26,1,26,1,26,3, + 26,282,8,26,1,27,1,27,1,27,3,27,287,8,27,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,30,1,30,1,30,1,30,1,30,1,30,1, + 30,1,30,1,30,1,30,1,31,1,31,3,31,315,8,31,1,32,1,32,1,33,1,33,3,33,321, + 8,33,1,34,1,34,1,34,1,34,5,34,327,8,34,10,34,12,34,330,9,34,1,34,3,34,333, + 8,34,3,34,335,8,34,1,34,1,34,1,35,1,35,1,35,1,36,1,36,1,36,1,36,5,36,346, + 8,36,10,36,12,36,349,9,36,1,36,3,36,352,8,36,3,36,354,8,36,1,36,1,36,1, + 37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,3,37,367,8,37,1,37,1,37,1,37, + 1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1, + 37,1,37,1,37,1,37,1,37,1,37,1,37,5,37,393,8,37,10,37,12,37,396,9,37,1,37, + 3,37,399,8,37,3,37,401,8,37,1,37,1,37,1,37,1,37,3,37,407,8,37,1,37,1,37, + 1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1, + 37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37, + 1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1, + 37,1,37,1,37,1,37,1,37,5,37,459,8,37,10,37,12,37,462,9,37,1,38,1,38,1,39, + 1,39,1,39,1,39,1,39,3,39,471,8,39,1,40,1,40,3,40,475,8,40,1,41,1,41,1,42, + 1,42,1,42,0,1,74,43,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,64,66,68,70,72,74,76,78,80,82,84, + 0,14,1,0,4,10,2,0,10,10,21,22,1,0,23,24,1,0,36,40,2,0,36,40,42,45,2,0,5, + 5,50,51,1,0,52,54,2,0,51,51,55,55,1,0,56,57,1,0,6,9,1,0,58,59,1,0,46,47, + 1,0,71,73,2,0,71,72,79,79,508,0,89,1,0,0,0,2,106,1,0,0,0,4,111,1,0,0,0, + 6,113,1,0,0,0,8,118,1,0,0,0,10,122,1,0,0,0,12,124,1,0,0,0,14,130,1,0,0, + 0,16,132,1,0,0,0,18,144,1,0,0,0,20,156,1,0,0,0,22,161,1,0,0,0,24,170,1, + 0,0,0,26,186,1,0,0,0,28,198,1,0,0,0,30,204,1,0,0,0,32,214,1,0,0,0,34,216, + 1,0,0,0,36,218,1,0,0,0,38,223,1,0,0,0,40,225,1,0,0,0,42,236,1,0,0,0,44, + 249,1,0,0,0,46,251,1,0,0,0,48,262,1,0,0,0,50,271,1,0,0,0,52,274,1,0,0,0, + 54,286,1,0,0,0,56,288,1,0,0,0,58,296,1,0,0,0,60,302,1,0,0,0,62,314,1,0, + 0,0,64,316,1,0,0,0,66,320,1,0,0,0,68,322,1,0,0,0,70,338,1,0,0,0,72,341, + 1,0,0,0,74,406,1,0,0,0,76,463,1,0,0,0,78,470,1,0,0,0,80,472,1,0,0,0,82, + 476,1,0,0,0,84,478,1,0,0,0,86,88,3,2,1,0,87,86,1,0,0,0,88,91,1,0,0,0,89, + 87,1,0,0,0,89,90,1,0,0,0,90,95,1,0,0,0,91,89,1,0,0,0,92,94,3,12,6,0,93, + 92,1,0,0,0,94,97,1,0,0,0,95,93,1,0,0,0,95,96,1,0,0,0,96,101,1,0,0,0,97, + 95,1,0,0,0,98,100,3,14,7,0,99,98,1,0,0,0,100,103,1,0,0,0,101,99,1,0,0,0, + 101,102,1,0,0,0,102,104,1,0,0,0,103,101,1,0,0,0,104,105,5,0,0,1,105,1,1, + 0,0,0,106,107,5,1,0,0,107,108,3,4,2,0,108,109,3,6,3,0,109,110,5,2,0,0,110, + 3,1,0,0,0,111,112,5,3,0,0,112,5,1,0,0,0,113,115,3,8,4,0,114,116,3,8,4,0, + 115,114,1,0,0,0,115,116,1,0,0,0,116,7,1,0,0,0,117,119,3,10,5,0,118,117, + 1,0,0,0,118,119,1,0,0,0,119,120,1,0,0,0,120,121,5,65,0,0,121,9,1,0,0,0, + 122,123,7,0,0,0,123,11,1,0,0,0,124,125,5,11,0,0,125,126,5,75,0,0,126,127, + 5,2,0,0,127,13,1,0,0,0,128,131,3,16,8,0,129,131,3,18,9,0,130,128,1,0,0, + 0,130,129,1,0,0,0,131,15,1,0,0,0,132,133,5,12,0,0,133,134,5,81,0,0,134, + 140,3,24,12,0,135,136,5,13,0,0,136,137,5,14,0,0,137,138,3,82,41,0,138,139, + 5,15,0,0,139,141,1,0,0,0,140,135,1,0,0,0,140,141,1,0,0,0,141,142,1,0,0, + 0,142,143,3,22,11,0,143,17,1,0,0,0,144,145,5,16,0,0,145,146,5,81,0,0,146, + 147,3,24,12,0,147,151,5,17,0,0,148,150,3,20,10,0,149,148,1,0,0,0,150,153, + 1,0,0,0,151,149,1,0,0,0,151,152,1,0,0,0,152,154,1,0,0,0,153,151,1,0,0,0, + 154,155,5,18,0,0,155,19,1,0,0,0,156,157,5,12,0,0,157,158,5,81,0,0,158,159, + 3,24,12,0,159,160,3,22,11,0,160,21,1,0,0,0,161,165,5,17,0,0,162,164,3,30, + 15,0,163,162,1,0,0,0,164,167,1,0,0,0,165,163,1,0,0,0,165,166,1,0,0,0,166, + 168,1,0,0,0,167,165,1,0,0,0,168,169,5,18,0,0,169,23,1,0,0,0,170,182,5,14, + 0,0,171,176,3,26,13,0,172,173,5,19,0,0,173,175,3,26,13,0,174,172,1,0,0, + 0,175,178,1,0,0,0,176,174,1,0,0,0,176,177,1,0,0,0,177,180,1,0,0,0,178,176, + 1,0,0,0,179,181,5,19,0,0,180,179,1,0,0,0,180,181,1,0,0,0,181,183,1,0,0, + 0,182,171,1,0,0,0,182,183,1,0,0,0,183,184,1,0,0,0,184,185,5,15,0,0,185, + 25,1,0,0,0,186,187,3,82,41,0,187,188,5,81,0,0,188,27,1,0,0,0,189,193,5, + 17,0,0,190,192,3,30,15,0,191,190,1,0,0,0,192,195,1,0,0,0,193,191,1,0,0, + 0,193,194,1,0,0,0,194,196,1,0,0,0,195,193,1,0,0,0,196,199,5,18,0,0,197, + 199,3,30,15,0,198,189,1,0,0,0,198,197,1,0,0,0,199,29,1,0,0,0,200,205,3, + 38,19,0,201,202,3,32,16,0,202,203,5,2,0,0,203,205,1,0,0,0,204,200,1,0,0, + 0,204,201,1,0,0,0,205,31,1,0,0,0,206,215,3,40,20,0,207,215,3,42,21,0,208, + 215,3,44,22,0,209,215,3,46,23,0,210,215,3,48,24,0,211,215,3,34,17,0,212, + 215,3,50,25,0,213,215,3,36,18,0,214,206,1,0,0,0,214,207,1,0,0,0,214,208, + 1,0,0,0,214,209,1,0,0,0,214,210,1,0,0,0,214,211,1,0,0,0,214,212,1,0,0,0, + 214,213,1,0,0,0,215,33,1,0,0,0,216,217,3,70,35,0,217,35,1,0,0,0,218,219, + 5,20,0,0,219,220,3,74,37,0,220,37,1,0,0,0,221,224,3,52,26,0,222,224,3,54, + 27,0,223,221,1,0,0,0,223,222,1,0,0,0,224,39,1,0,0,0,225,229,3,82,41,0,226, + 228,3,76,38,0,227,226,1,0,0,0,228,231,1,0,0,0,229,227,1,0,0,0,229,230,1, + 0,0,0,230,232,1,0,0,0,231,229,1,0,0,0,232,233,5,81,0,0,233,234,5,10,0,0, + 234,235,3,74,37,0,235,41,1,0,0,0,236,237,3,82,41,0,237,238,5,81,0,0,238, + 239,5,19,0,0,239,240,3,82,41,0,240,241,5,81,0,0,241,242,5,10,0,0,242,243, + 3,74,37,0,243,43,1,0,0,0,244,245,5,81,0,0,245,246,7,1,0,0,246,250,3,74, + 37,0,247,248,5,81,0,0,248,250,7,2,0,0,249,244,1,0,0,0,249,247,1,0,0,0,250, + 45,1,0,0,0,251,252,5,25,0,0,252,253,5,14,0,0,253,254,5,78,0,0,254,255,5, + 6,0,0,255,258,3,74,37,0,256,257,5,19,0,0,257,259,3,64,32,0,258,256,1,0, + 0,0,258,259,1,0,0,0,259,260,1,0,0,0,260,261,5,15,0,0,261,47,1,0,0,0,262, + 263,5,25,0,0,263,264,5,14,0,0,264,267,3,74,37,0,265,266,5,19,0,0,266,268, + 3,64,32,0,267,265,1,0,0,0,267,268,1,0,0,0,268,269,1,0,0,0,269,270,5,15, + 0,0,270,49,1,0,0,0,271,272,5,26,0,0,272,273,3,68,34,0,273,51,1,0,0,0,274, + 275,5,27,0,0,275,276,5,14,0,0,276,277,3,74,37,0,277,278,5,15,0,0,278,281, + 3,28,14,0,279,280,5,28,0,0,280,282,3,28,14,0,281,279,1,0,0,0,281,282,1, + 0,0,0,282,53,1,0,0,0,283,287,3,56,28,0,284,287,3,58,29,0,285,287,3,60,30, + 0,286,283,1,0,0,0,286,284,1,0,0,0,286,285,1,0,0,0,287,55,1,0,0,0,288,289, + 5,29,0,0,289,290,3,28,14,0,290,291,5,30,0,0,291,292,5,14,0,0,292,293,3, + 74,37,0,293,294,5,15,0,0,294,295,5,2,0,0,295,57,1,0,0,0,296,297,5,30,0, + 0,297,298,5,14,0,0,298,299,3,74,37,0,299,300,5,15,0,0,300,301,3,28,14,0, + 301,59,1,0,0,0,302,303,5,31,0,0,303,304,5,14,0,0,304,305,3,62,31,0,305, + 306,5,2,0,0,306,307,3,74,37,0,307,308,5,2,0,0,308,309,3,44,22,0,309,310, + 5,15,0,0,310,311,3,28,14,0,311,61,1,0,0,0,312,315,3,40,20,0,313,315,3,44, + 22,0,314,312,1,0,0,0,314,313,1,0,0,0,315,63,1,0,0,0,316,317,5,75,0,0,317, + 65,1,0,0,0,318,321,5,81,0,0,319,321,3,78,39,0,320,318,1,0,0,0,320,319,1, + 0,0,0,321,67,1,0,0,0,322,334,5,14,0,0,323,328,3,66,33,0,324,325,5,19,0, + 0,325,327,3,66,33,0,326,324,1,0,0,0,327,330,1,0,0,0,328,326,1,0,0,0,328, + 329,1,0,0,0,329,332,1,0,0,0,330,328,1,0,0,0,331,333,5,19,0,0,332,331,1, + 0,0,0,332,333,1,0,0,0,333,335,1,0,0,0,334,323,1,0,0,0,334,335,1,0,0,0,335, + 336,1,0,0,0,336,337,5,15,0,0,337,69,1,0,0,0,338,339,5,81,0,0,339,340,3, + 72,36,0,340,71,1,0,0,0,341,353,5,14,0,0,342,347,3,74,37,0,343,344,5,19, + 0,0,344,346,3,74,37,0,345,343,1,0,0,0,346,349,1,0,0,0,347,345,1,0,0,0,347, + 348,1,0,0,0,348,351,1,0,0,0,349,347,1,0,0,0,350,352,5,19,0,0,351,350,1, + 0,0,0,351,352,1,0,0,0,352,354,1,0,0,0,353,342,1,0,0,0,353,354,1,0,0,0,354, + 355,1,0,0,0,355,356,5,15,0,0,356,73,1,0,0,0,357,358,6,37,-1,0,358,359,5, + 14,0,0,359,360,3,74,37,0,360,361,5,15,0,0,361,407,1,0,0,0,362,363,3,84, + 42,0,363,364,5,14,0,0,364,366,3,74,37,0,365,367,5,19,0,0,366,365,1,0,0, + 0,366,367,1,0,0,0,367,368,1,0,0,0,368,369,5,15,0,0,369,407,1,0,0,0,370, + 407,3,70,35,0,371,372,5,32,0,0,372,373,5,81,0,0,373,407,3,72,36,0,374,375, + 5,35,0,0,375,376,5,33,0,0,376,377,3,74,37,0,377,378,5,34,0,0,378,379,7, + 3,0,0,379,407,1,0,0,0,380,381,5,41,0,0,381,382,5,33,0,0,382,383,3,74,37, + 0,383,384,5,34,0,0,384,385,7,4,0,0,385,407,1,0,0,0,386,387,7,5,0,0,387, + 407,3,74,37,15,388,400,5,33,0,0,389,394,3,74,37,0,390,391,5,19,0,0,391, + 393,3,74,37,0,392,390,1,0,0,0,393,396,1,0,0,0,394,392,1,0,0,0,394,395,1, + 0,0,0,395,398,1,0,0,0,396,394,1,0,0,0,397,399,5,19,0,0,398,397,1,0,0,0, + 398,399,1,0,0,0,399,401,1,0,0,0,400,389,1,0,0,0,400,401,1,0,0,0,401,402, + 1,0,0,0,402,407,5,34,0,0,403,407,5,80,0,0,404,407,5,81,0,0,405,407,3,78, + 39,0,406,357,1,0,0,0,406,362,1,0,0,0,406,370,1,0,0,0,406,371,1,0,0,0,406, + 374,1,0,0,0,406,380,1,0,0,0,406,386,1,0,0,0,406,388,1,0,0,0,406,403,1,0, + 0,0,406,404,1,0,0,0,406,405,1,0,0,0,407,460,1,0,0,0,408,409,10,14,0,0,409, + 410,7,6,0,0,410,459,3,74,37,15,411,412,10,13,0,0,412,413,7,7,0,0,413,459, + 3,74,37,14,414,415,10,12,0,0,415,416,7,8,0,0,416,459,3,74,37,13,417,418, + 10,11,0,0,418,419,7,9,0,0,419,459,3,74,37,12,420,421,10,10,0,0,421,422, + 7,10,0,0,422,459,3,74,37,11,423,424,10,9,0,0,424,425,5,60,0,0,425,459,3, + 74,37,10,426,427,10,8,0,0,427,428,5,4,0,0,428,459,3,74,37,9,429,430,10, + 7,0,0,430,431,5,61,0,0,431,459,3,74,37,8,432,433,10,6,0,0,433,434,5,62, + 0,0,434,459,3,74,37,7,435,436,10,5,0,0,436,437,5,63,0,0,437,459,3,74,37, + 6,438,439,10,21,0,0,439,440,5,33,0,0,440,441,5,68,0,0,441,459,5,34,0,0, + 442,443,10,18,0,0,443,459,7,11,0,0,444,445,10,17,0,0,445,446,5,48,0,0,446, + 447,5,14,0,0,447,448,3,74,37,0,448,449,5,15,0,0,449,459,1,0,0,0,450,451, + 10,16,0,0,451,452,5,49,0,0,452,453,5,14,0,0,453,454,3,74,37,0,454,455,5, + 19,0,0,455,456,3,74,37,0,456,457,5,15,0,0,457,459,1,0,0,0,458,408,1,0,0, + 0,458,411,1,0,0,0,458,414,1,0,0,0,458,417,1,0,0,0,458,420,1,0,0,0,458,423, + 1,0,0,0,458,426,1,0,0,0,458,429,1,0,0,0,458,432,1,0,0,0,458,435,1,0,0,0, + 458,438,1,0,0,0,458,442,1,0,0,0,458,444,1,0,0,0,458,450,1,0,0,0,459,462, + 1,0,0,0,460,458,1,0,0,0,460,461,1,0,0,0,461,75,1,0,0,0,462,460,1,0,0,0, + 463,464,5,64,0,0,464,77,1,0,0,0,465,471,5,66,0,0,466,471,3,80,40,0,467, + 471,5,75,0,0,468,471,5,76,0,0,469,471,5,77,0,0,470,465,1,0,0,0,470,466, + 1,0,0,0,470,467,1,0,0,0,470,468,1,0,0,0,470,469,1,0,0,0,471,79,1,0,0,0, + 472,474,5,68,0,0,473,475,5,67,0,0,474,473,1,0,0,0,474,475,1,0,0,0,475,81, + 1,0,0,0,476,477,7,12,0,0,477,83,1,0,0,0,478,479,7,13,0,0,479,85,1,0,0,0, + 40,89,95,101,115,118,130,140,151,165,176,180,182,193,198,204,214,223,229, + 249,258,267,281,286,314,320,328,332,334,347,351,353,366,394,398,400,406, + 458,460,470,474]; private static __ATN: ATN; public static get _ATN(): ATN { @@ -2564,9 +2804,6 @@ export class SourceFileContext extends ParserRuleContext { super(parent, invokingState); this.parser = parser; } - public contractDefinition(): ContractDefinitionContext { - return this.getTypedRuleContext(ContractDefinitionContext, 0) as ContractDefinitionContext; - } public EOF(): TerminalNode { return this.getToken(CashScriptParser.EOF, 0); } @@ -2576,6 +2813,18 @@ export class SourceFileContext extends ParserRuleContext { public pragmaDirective(i: number): PragmaDirectiveContext { return this.getTypedRuleContext(PragmaDirectiveContext, i) as PragmaDirectiveContext; } + public importDirective_list(): ImportDirectiveContext[] { + return this.getTypedRuleContexts(ImportDirectiveContext) as ImportDirectiveContext[]; + } + public importDirective(i: number): ImportDirectiveContext { + return this.getTypedRuleContext(ImportDirectiveContext, i) as ImportDirectiveContext; + } + public topLevelDefinition_list(): TopLevelDefinitionContext[] { + return this.getTypedRuleContexts(TopLevelDefinitionContext) as TopLevelDefinitionContext[]; + } + public topLevelDefinition(i: number): TopLevelDefinitionContext { + return this.getTypedRuleContext(TopLevelDefinitionContext, i) as TopLevelDefinitionContext; + } public get ruleIndex(): number { return CashScriptParser.RULE_sourceFile; } @@ -2703,6 +2952,84 @@ export class VersionOperatorContext extends ParserRuleContext { } +export class ImportDirectiveContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public StringLiteral(): TerminalNode { + return this.getToken(CashScriptParser.StringLiteral, 0); + } + public get ruleIndex(): number { + return CashScriptParser.RULE_importDirective; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitImportDirective) { + return visitor.visitImportDirective(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class TopLevelDefinitionContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public globalFunctionDefinition(): GlobalFunctionDefinitionContext { + return this.getTypedRuleContext(GlobalFunctionDefinitionContext, 0) as GlobalFunctionDefinitionContext; + } + public contractDefinition(): ContractDefinitionContext { + return this.getTypedRuleContext(ContractDefinitionContext, 0) as ContractDefinitionContext; + } + public get ruleIndex(): number { + return CashScriptParser.RULE_topLevelDefinition; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitTopLevelDefinition) { + return visitor.visitTopLevelDefinition(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class GlobalFunctionDefinitionContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public Identifier(): TerminalNode { + return this.getToken(CashScriptParser.Identifier, 0); + } + public parameterList(): ParameterListContext { + return this.getTypedRuleContext(ParameterListContext, 0) as ParameterListContext; + } + public functionBody(): FunctionBodyContext { + return this.getTypedRuleContext(FunctionBodyContext, 0) as FunctionBodyContext; + } + public typeName(): TypeNameContext { + return this.getTypedRuleContext(TypeNameContext, 0) as TypeNameContext; + } + public get ruleIndex(): number { + return CashScriptParser.RULE_globalFunctionDefinition; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitGlobalFunctionDefinition) { + return visitor.visitGlobalFunctionDefinition(this); + } else { + return visitor.visitChildren(this); + } + } +} + + export class ContractDefinitionContext extends ParserRuleContext { constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { super(parent, invokingState); @@ -2714,11 +3041,11 @@ export class ContractDefinitionContext extends ParserRuleContext { public parameterList(): ParameterListContext { return this.getTypedRuleContext(ParameterListContext, 0) as ParameterListContext; } - public functionDefinition_list(): FunctionDefinitionContext[] { - return this.getTypedRuleContexts(FunctionDefinitionContext) as FunctionDefinitionContext[]; + public contractFunctionDefinition_list(): ContractFunctionDefinitionContext[] { + return this.getTypedRuleContexts(ContractFunctionDefinitionContext) as ContractFunctionDefinitionContext[]; } - public functionDefinition(i: number): FunctionDefinitionContext { - return this.getTypedRuleContext(FunctionDefinitionContext, i) as FunctionDefinitionContext; + public contractFunctionDefinition(i: number): ContractFunctionDefinitionContext { + return this.getTypedRuleContext(ContractFunctionDefinitionContext, i) as ContractFunctionDefinitionContext; } public get ruleIndex(): number { return CashScriptParser.RULE_contractDefinition; @@ -2734,7 +3061,7 @@ export class ContractDefinitionContext extends ParserRuleContext { } -export class FunctionDefinitionContext extends ParserRuleContext { +export class ContractFunctionDefinitionContext extends ParserRuleContext { constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { super(parent, invokingState); this.parser = parser; @@ -2749,12 +3076,12 @@ export class FunctionDefinitionContext extends ParserRuleContext { return this.getTypedRuleContext(FunctionBodyContext, 0) as FunctionBodyContext; } public get ruleIndex(): number { - return CashScriptParser.RULE_functionDefinition; + return CashScriptParser.RULE_contractFunctionDefinition; } // @Override public accept(visitor: CashScriptVisitor): Result { - if (visitor.visitFunctionDefinition) { - return visitor.visitFunctionDefinition(this); + if (visitor.visitContractFunctionDefinition) { + return visitor.visitContractFunctionDefinition(this); } else { return visitor.visitChildren(this); } @@ -2907,9 +3234,15 @@ export class NonControlStatementContext extends ParserRuleContext { public requireStatement(): RequireStatementContext { return this.getTypedRuleContext(RequireStatementContext, 0) as RequireStatementContext; } + public functionCallStatement(): FunctionCallStatementContext { + return this.getTypedRuleContext(FunctionCallStatementContext, 0) as FunctionCallStatementContext; + } public consoleStatement(): ConsoleStatementContext { return this.getTypedRuleContext(ConsoleStatementContext, 0) as ConsoleStatementContext; } + public returnStatement(): ReturnStatementContext { + return this.getTypedRuleContext(ReturnStatementContext, 0) as ReturnStatementContext; + } public get ruleIndex(): number { return CashScriptParser.RULE_nonControlStatement; } @@ -2924,6 +3257,50 @@ export class NonControlStatementContext extends ParserRuleContext { } +export class FunctionCallStatementContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public functionCall(): FunctionCallContext { + return this.getTypedRuleContext(FunctionCallContext, 0) as FunctionCallContext; + } + public get ruleIndex(): number { + return CashScriptParser.RULE_functionCallStatement; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitFunctionCallStatement) { + return visitor.visitFunctionCallStatement(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class ReturnStatementContext extends ParserRuleContext { + constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public expression(): ExpressionContext { + return this.getTypedRuleContext(ExpressionContext, 0) as ExpressionContext; + } + public get ruleIndex(): number { + return CashScriptParser.RULE_returnStatement; + } + // @Override + public accept(visitor: CashScriptVisitor): Result { + if (visitor.visitReturnStatement) { + return visitor.visitReturnStatement(this); + } else { + return visitor.visitChildren(this); + } + } +} + + export class ControlStatementContext extends ParserRuleContext { constructor(parser?: CashScriptParser, parent?: ParserRuleContext, invokingState?: number) { super(parent, invokingState); diff --git a/packages/cashc/src/grammar/CashScriptVisitor.ts b/packages/cashc/src/grammar/CashScriptVisitor.ts index ffb8f081..6b47aa00 100644 --- a/packages/cashc/src/grammar/CashScriptVisitor.ts +++ b/packages/cashc/src/grammar/CashScriptVisitor.ts @@ -9,14 +9,19 @@ import { PragmaNameContext } from "./CashScriptParser.js"; import { PragmaValueContext } from "./CashScriptParser.js"; import { VersionConstraintContext } from "./CashScriptParser.js"; import { VersionOperatorContext } from "./CashScriptParser.js"; +import { ImportDirectiveContext } from "./CashScriptParser.js"; +import { TopLevelDefinitionContext } from "./CashScriptParser.js"; +import { GlobalFunctionDefinitionContext } from "./CashScriptParser.js"; import { ContractDefinitionContext } from "./CashScriptParser.js"; -import { FunctionDefinitionContext } from "./CashScriptParser.js"; +import { ContractFunctionDefinitionContext } from "./CashScriptParser.js"; import { FunctionBodyContext } from "./CashScriptParser.js"; import { ParameterListContext } from "./CashScriptParser.js"; import { ParameterContext } from "./CashScriptParser.js"; import { BlockContext } from "./CashScriptParser.js"; import { StatementContext } from "./CashScriptParser.js"; import { NonControlStatementContext } from "./CashScriptParser.js"; +import { FunctionCallStatementContext } from "./CashScriptParser.js"; +import { ReturnStatementContext } from "./CashScriptParser.js"; import { ControlStatementContext } from "./CashScriptParser.js"; import { VariableDefinitionContext } from "./CashScriptParser.js"; import { TupleAssignmentContext } from "./CashScriptParser.js"; @@ -99,6 +104,24 @@ export default class CashScriptVisitor extends ParseTreeVisitor * @return the visitor result */ visitVersionOperator?: (ctx: VersionOperatorContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.importDirective`. + * @param ctx the parse tree + * @return the visitor result + */ + visitImportDirective?: (ctx: ImportDirectiveContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.topLevelDefinition`. + * @param ctx the parse tree + * @return the visitor result + */ + visitTopLevelDefinition?: (ctx: TopLevelDefinitionContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.globalFunctionDefinition`. + * @param ctx the parse tree + * @return the visitor result + */ + visitGlobalFunctionDefinition?: (ctx: GlobalFunctionDefinitionContext) => Result; /** * Visit a parse tree produced by `CashScriptParser.contractDefinition`. * @param ctx the parse tree @@ -106,11 +129,11 @@ export default class CashScriptVisitor extends ParseTreeVisitor */ visitContractDefinition?: (ctx: ContractDefinitionContext) => Result; /** - * Visit a parse tree produced by `CashScriptParser.functionDefinition`. + * Visit a parse tree produced by `CashScriptParser.contractFunctionDefinition`. * @param ctx the parse tree * @return the visitor result */ - visitFunctionDefinition?: (ctx: FunctionDefinitionContext) => Result; + visitContractFunctionDefinition?: (ctx: ContractFunctionDefinitionContext) => Result; /** * Visit a parse tree produced by `CashScriptParser.functionBody`. * @param ctx the parse tree @@ -147,6 +170,18 @@ export default class CashScriptVisitor extends ParseTreeVisitor * @return the visitor result */ visitNonControlStatement?: (ctx: NonControlStatementContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.functionCallStatement`. + * @param ctx the parse tree + * @return the visitor result + */ + visitFunctionCallStatement?: (ctx: FunctionCallStatementContext) => Result; + /** + * Visit a parse tree produced by `CashScriptParser.returnStatement`. + * @param ctx the parse tree + * @return the visitor result + */ + visitReturnStatement?: (ctx: ReturnStatementContext) => Result; /** * Visit a parse tree produced by `CashScriptParser.controlStatement`. * @param ctx the parse tree diff --git a/packages/cashc/src/parser.ts b/packages/cashc/src/parser.ts new file mode 100644 index 00000000..e7e0e799 --- /dev/null +++ b/packages/cashc/src/parser.ts @@ -0,0 +1,30 @@ +import { CharStream, CommonTokenStream } from 'antlr4'; +import { Ast } from './ast/AST.js'; +import AstBuilder from './ast/AstBuilder.js'; +import { ThrowingErrorListener, CashScriptErrorListener, ForwardingErrorListener } from './ast/error-listeners.js'; +import CashScriptLexer from './grammar/CashScriptLexer.js'; +import CashScriptParser from './grammar/CashScriptParser.js'; + +export function parseCode( + code: string, + errorListener: CashScriptErrorListener = ThrowingErrorListener.INSTANCE, +): Ast { + const syntaxErrorListener = new ForwardingErrorListener(errorListener); + + // Lexing (throwing on errors) + const inputStream = new CharStream(code); + const lexer = new CashScriptLexer(inputStream); + lexer.removeErrorListeners(); + lexer.addErrorListener(syntaxErrorListener); + const tokenStream = new CommonTokenStream(lexer); + + // Parsing (throwing on errors) + const parser = new CashScriptParser(tokenStream); + parser.removeErrorListeners(); + parser.addErrorListener(syntaxErrorListener); + const parseTree = parser.sourceFile(); + syntaxErrorListener.throwFirstError(); + + // AST building + return new AstBuilder(parseTree).build() as Ast; +} diff --git a/packages/cashc/src/print/OutputSourceCodeTraversal.ts b/packages/cashc/src/print/OutputSourceCodeTraversal.ts index 70f62db2..7f703f8a 100644 --- a/packages/cashc/src/print/OutputSourceCodeTraversal.ts +++ b/packages/cashc/src/print/OutputSourceCodeTraversal.ts @@ -2,6 +2,8 @@ import { binToHex } from '@bitauth/libauth'; import { SymbolTable } from '../ast/SymbolTable.js'; import { Node, + SourceFileNode, + ImportNode, ContractNode, ParameterNode, VariableDefinitionNode, @@ -22,11 +24,13 @@ import { ArrayNode, TupleIndexOpNode, RequireNode, + ReturnNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, ConsoleParameterNode, + FunctionCallStatementNode, SliceNode, DoWhileNode, WhileNode, @@ -61,6 +65,18 @@ export default class OutputSourceCodeTraversal extends AstTraversal { this.addOutput(` --> ST: ${symbolTable}`); } + visitSourceFile(node: SourceFileNode): Node { + node.imports = this.visitList(node.imports) as ImportNode[]; + node.functions = this.visitList(node.functions) as FunctionDefinitionNode[]; + if (node.contract) node.contract = this.visit(node.contract) as ContractNode; + return node; + } + + visitImport(node: ImportNode): Node { + this.addOutput(`import "${node.path}";\n`, true); + return node; + } + visitContract(node: ContractNode): Node { this.addOutput(`contract ${node.name}(`, true); node.parameters = this.visitCommaList(node.parameters) as ParameterNode[]; @@ -80,6 +96,7 @@ export default class OutputSourceCodeTraversal extends AstTraversal { this.addOutput(`function ${node.name}(`, true); node.parameters = this.visitCommaList(node.parameters) as ParameterNode[]; this.addOutput(')'); + if (node.returnType) this.addOutput(` returns (${node.returnType})`); this.outputSymbolTable(node.symbolTable); this.addOutput(' '); @@ -147,6 +164,18 @@ export default class OutputSourceCodeTraversal extends AstTraversal { return node; } + visitReturn(node: ReturnNode): Node { + this.addOutput('return ', true); + node.expression = this.visit(node.expression); + return node; + } + + visitFunctionCallStatement(node: FunctionCallStatementNode): Node { + this.addOutput('', true); + node.functionCall = this.visit(node.functionCall) as FunctionCallNode; + return node; + } + visitConsoleStatement(node: ConsoleStatementNode): Node { this.addOutput('console.log(', true); node.parameters = this.visitCommaList(node.parameters) as ConsoleParameterNode[]; diff --git a/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts b/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts index 2974f16c..e5d9115f 100644 --- a/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts +++ b/packages/cashc/src/semantic/EnsureFinalRequireTraversal.ts @@ -2,7 +2,9 @@ import { ContractNode, ParameterNode, FunctionDefinitionNode, + FunctionKind, RequireNode, + ReturnNode, TimeOpNode, BranchNode, ConsoleStatementNode, @@ -10,9 +12,17 @@ import { WhileNode, ForNode, BlockNode, + StatementNode, + Node, } from '../ast/AST.js'; import AstTraversal from '../ast/AstTraversal.js'; -import { EmptyContractError, EmptyFunctionError, FinalRequireStatementError } from '../Errors.js'; +import { + EmptyContractError, + EmptyFunctionError, + FinalRequireStatementError, + MissingReturnError, + MisplacedReturnError, +} from '../Errors.js'; export default class EnsureFinalRequireTraversal extends AstTraversal { visitContract(node: ContractNode): ContractNode { @@ -34,12 +44,57 @@ export default class EnsureFinalRequireTraversal extends AstTraversal { throw new EmptyFunctionError(node); } - ensureFinalStatementIsRequire(node.body); + if (node.kind === FunctionKind.CONTRACT) { + ensureFinalStatementIsRequire(node.body); + } else if (node.returnType !== undefined) { + ensureSingleTailReturn(node.body); + } return node; } } +// TODO: This code is a bit convoluted, but we're likely to make changes to allow early returns before a mainline release, +// so we're leaving this code as-is for now. + +function ensureSingleTailReturn(body: BlockNode): void { + const statements = body.statements ?? []; + const finalStatement = statements[statements.length - 1]; + if (!(finalStatement instanceof ReturnNode)) { + throw new MissingReturnError(finalStatement ?? body); + } + + const stray = findReturn(statements.slice(0, -1)); + if (stray) throw new MisplacedReturnError(stray); +} + +function findReturn(statements: StatementNode[]): ReturnNode | undefined { + for (const statement of statements) { + if (statement instanceof ReturnNode) return statement; + for (const list of nestedStatementLists(statement)) { + const found = findReturn(list); + if (found) return found; + } + } + return undefined; +} + +function nestedStatementLists(statement: StatementNode): StatementNode[][] { + const asStatements = (block?: Node): StatementNode[] => { + if (!block) return []; + if (block instanceof BlockNode) return block.statements ?? []; + return [block as StatementNode]; + }; + + if (statement instanceof BranchNode) { + return [asStatements(statement.ifBlock), asStatements(statement.elseBlock)]; + } + if (statement instanceof DoWhileNode || statement instanceof WhileNode || statement instanceof ForNode) { + return [asStatements(statement.block)]; + } + return []; +} + function ensureFinalStatementIsRequire(block: BlockNode): void { const statementsWithoutLogs = (block.statements ?? []).filter((statement) => !(statement instanceof ConsoleStatementNode)); const finalStatement = statementsWithoutLogs[statementsWithoutLogs.length - 1]; diff --git a/packages/cashc/src/semantic/InjectLocktimeGuardTraversal.ts b/packages/cashc/src/semantic/InjectLocktimeGuardTraversal.ts index 1aa0983f..6137d6e3 100644 --- a/packages/cashc/src/semantic/InjectLocktimeGuardTraversal.ts +++ b/packages/cashc/src/semantic/InjectLocktimeGuardTraversal.ts @@ -1,10 +1,13 @@ import { PrimitiveType } from '@cashscript/utils'; import { BlockNode, + ContractNode, + FunctionCallNode, FunctionDefinitionNode, IntLiteralNode, Node, NullaryOpNode, + SourceFileNode, TimeOpNode, } from '../ast/AST.js'; import AstTraversal from '../ast/AstTraversal.js'; @@ -12,45 +15,90 @@ import { TimeOp } from '../ast/Globals.js'; import { Location } from '../ast/Location.js'; import { NullaryOperator } from '../ast/Operator.js'; -// Per BCH consensus, `tx.locktime` is only protocol-enforced if at least one input has a non-final sequence number -// If a require(tx.time >= ...) check or a require(this.age >= ...) with a compile-time int literal below 2^31 is -// present, then `tx.locktime` is protocol-enforced. If no such check is present, then we add a -// synthetic require(tx.time >= tx.locktime) check. +// Per BCH consensus, `tx.locktime` is only protocol-enforced if at least one input has a non-final +// sequence number. A require(tx.time >= ...) check — or a require(this.age >= ...) with a compile-time +// int literal below 2^31 — forces that non-finality. When a spending path uses `tx.locktime` without +// such a check, we inject a synthetic require(tx.time >= tx.locktime) guard at the start of the function. export default class InjectLocktimeGuardTraversal extends AstTraversal { - private hasTimeCheckOnPath = false; - private functionNeedsGuard = false; + // Keep track of which global functions require a locktime guard when called. + private globalFunctionRequiresLocktimeGuard = new Map(); - visitFunctionDefinition(node: FunctionDefinitionNode): Node { - this.hasTimeCheckOnPath = false; - this.functionNeedsGuard = false; - - super.visitFunctionDefinition(node); + visitSourceFile(node: SourceFileNode): Node { + // Only contract spending functions are traversed (and guarded); globals are analysed on demand. + node.contract = this.visitOptional(node.contract) as ContractNode | undefined; + return node; + } - if (this.functionNeedsGuard) { + visitFunctionDefinition(node: FunctionDefinitionNode): Node { + if (this.requiresLocktimeGuard(node.body)) { node.body.statements = [createLocktimeGuard(node), ...(node.body.statements ?? [])]; } return node; } + private requiresLocktimeGuard(body: BlockNode): boolean { + const analyser = new LocktimeGuardRequirementAnalyser((func) => this.checkGlobalFunctionRequiresLocktimeGuard(func)); + analyser.visit(body); + return analyser.requiresLocktimeGuard; + } + + // Memoised, cycle-safe analysis of a single global function. + private checkGlobalFunctionRequiresLocktimeGuard(func: FunctionDefinitionNode): boolean { + const memoised = this.globalFunctionRequiresLocktimeGuard.get(func); + if (memoised !== undefined) return memoised; + + this.globalFunctionRequiresLocktimeGuard.set(func, false); // seed: a re-entrant (cyclic) call contributes nothing + const requiresLocktimeGuard = this.requiresLocktimeGuard(func.body); + this.globalFunctionRequiresLocktimeGuard.set(func, requiresLocktimeGuard); + return requiresLocktimeGuard; + } +} + +class LocktimeGuardRequirementAnalyser extends AstTraversal { + requiresLocktimeGuard = false; + private isAlreadyCovered = false; + + constructor( + private checkGlobalFunctionRequiresLocktimeGuard: (func: FunctionDefinitionNode) => boolean, + ) { + super(); + } + visitBlock(node: BlockNode): Node { - const previous = this.hasTimeCheckOnPath; + const enclosingIsAlreadyCovered = this.isAlreadyCovered; - // Check whether there are any locktime checks on the same execution path, BEFORE entering the block body. - // So even if there are locktime checks after the `tx.locktime` access, it counts as a locktime check + // A time check anywhere in this block covers the whole block (order within the block is irrelevant); + // a sibling branch's check does not, since each branch body is its own block. if (node.statements?.some(isLocktimeCheck)) { - this.hasTimeCheckOnPath = true; + this.isAlreadyCovered = true; } + super.visitBlock(node); - this.hasTimeCheckOnPath = previous; + + this.isAlreadyCovered = enclosingIsAlreadyCovered; return node; } visitNullaryOp(node: NullaryOpNode): Node { - if (node.operator === NullaryOperator.LOCKTIME && !this.hasTimeCheckOnPath) { - this.functionNeedsGuard = true; + if (node.operator === NullaryOperator.LOCKTIME && !this.isAlreadyCovered) { + this.requiresLocktimeGuard = true; } return node; } + + visitFunctionCall(node: FunctionCallNode): Node { + node = super.visitFunctionCall(node) as FunctionCallNode; + if (this.isAlreadyCovered) return node; + + const functionDefinition = node.identifier.symbol?.definition; + if (!functionDefinition || !(functionDefinition instanceof FunctionDefinitionNode)) return node; + + if (this.checkGlobalFunctionRequiresLocktimeGuard(functionDefinition)) { + this.requiresLocktimeGuard = true; + } + + return node; + } } // Note that `require(tx.time >= ...)` checks are always sufficient to enforce the non-finality of the spending input, diff --git a/packages/cashc/src/semantic/SymbolTableTraversal.ts b/packages/cashc/src/semantic/SymbolTableTraversal.ts index 8b980b49..41b49cd4 100644 --- a/packages/cashc/src/semantic/SymbolTableTraversal.ts +++ b/packages/cashc/src/semantic/SymbolTableTraversal.ts @@ -1,9 +1,11 @@ import { GLOBAL_SYMBOL_TABLE, Modifier } from '../ast/Globals.js'; import { + SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, + FunctionKind, IdentifierNode, StatementNode, BlockNode, @@ -29,11 +31,32 @@ import { export default class SymbolTableTraversal extends AstTraversal { private symbolTables: SymbolTable[] = [GLOBAL_SYMBOL_TABLE]; - private functionNames: Map = new Map(); + private contractFunctionNames: Map = new Map(); private currentFunction: FunctionDefinitionNode; private expectedSymbolType: SymbolType = SymbolType.VARIABLE; private insideConsoleStatement: boolean = false; + visitSourceFile(node: SourceFileNode): Node { + const globalFunctionTable = new SymbolTable(this.symbolTables[0]); + + node.functions.forEach((functionNode, functionId) => { + if (globalFunctionTable.get(functionNode.name)) { + throw new FunctionRedefinitionError(functionNode); + } + const symbol = Symbol.userFunction(functionNode, functionId); + globalFunctionTable.set(symbol); + }); + + node.symbolTable = globalFunctionTable; + this.symbolTables.unshift(globalFunctionTable); + + node.functions = this.visitList(node.functions) as FunctionDefinitionNode[]; + node.contract = this.visitOptional(node.contract) as ContractNode | undefined; + + this.symbolTables.shift(); + return node; + } + visitContract(node: ContractNode): Node { node.symbolTable = new SymbolTable(this.symbolTables[0]); this.symbolTables.unshift(node.symbolTable); @@ -62,12 +85,12 @@ export default class SymbolTableTraversal extends AstTraversal { visitFunctionDefinition(node: FunctionDefinitionNode): Node { this.currentFunction = node; - // Checked for function redefinition, but they are not included in the - // symbol table, as internal function calls are not supported. - if (this.functionNames.get(node.name)) { - throw new FunctionRedefinitionError(node); + if (node.kind === FunctionKind.CONTRACT) { + if (this.contractFunctionNames.get(node.name)) { + throw new FunctionRedefinitionError(node); + } + this.contractFunctionNames.set(node.name, true); } - this.functionNames.set(node.name, true); node.symbolTable = new SymbolTable(this.symbolTables[0]); this.symbolTables.unshift(node.symbolTable); @@ -185,17 +208,17 @@ export default class SymbolTableTraversal extends AstTraversal { } visitIdentifier(node: IdentifierNode): Node { - const definition = this.symbolTables[0].get(node.name); - if (!definition) { + const symbol = this.symbolTables[0].get(node.name); + if (!symbol) { throw new UndefinedReferenceError(node); } - if (definition.symbolType !== this.expectedSymbolType) { + if (symbol.symbolType !== this.expectedSymbolType) { throw new InvalidSymbolTypeError(node, this.expectedSymbolType); } - node.definition = definition; - node.definition.references.push(node); + node.symbol = symbol; + node.symbol.references.push(node); // Keep track of final use of variables for code generation (excluding console statements) if (!this.insideConsoleStatement) { diff --git a/packages/cashc/src/semantic/TypeCheckTraversal.ts b/packages/cashc/src/semantic/TypeCheckTraversal.ts index 5e6742c9..4c5d120c 100644 --- a/packages/cashc/src/semantic/TypeCheckTraversal.ts +++ b/packages/cashc/src/semantic/TypeCheckTraversal.ts @@ -14,6 +14,9 @@ import { BranchNode, CastNode, FunctionCallNode, + FunctionCallStatementNode, + FunctionDefinitionNode, + ParameterNode, UnaryOpNode, BinaryOpNode, IdentifierNode, @@ -22,6 +25,7 @@ import { ArrayNode, TupleIndexOpNode, RequireNode, + ReturnNode, Node, InstantiationNode, TupleAssignmentNode, @@ -47,6 +51,8 @@ import { IndexOutOfBoundsError, TupleAssignmentError, BitshiftBitcountNegativeError, + UnusedFunctionReturnError, + ReturnTypeError, } from '../Errors.js'; import { BinaryOperator, NullaryOperator, UnaryOperator } from '../ast/Operator.js'; import { GlobalFunction } from '../ast/Globals.js'; @@ -54,6 +60,8 @@ import { Symbol } from '../ast/SymbolTable.js'; import { resultingTypeForBinaryOp } from '../utils.js'; export default class TypeCheckTraversal extends AstTraversal { + private currentFunctionReturnType: Type = PrimitiveType.VOID; + visitVariableDefinition(node: VariableDefinitionNode): Node { node.expression = this.visit(node.expression); expectAssignable(node, node.expression.type, node.type); @@ -178,15 +186,38 @@ export default class TypeCheckTraversal extends AstTraversal { return node; } + visitFunctionCallStatement(node: FunctionCallStatementNode): Node { + node.functionCall = this.visit(node.functionCall) as FunctionCallNode; + if (node.functionCall.type !== PrimitiveType.VOID) { + throw new UnusedFunctionReturnError(node.functionCall); + } + return node; + } + + visitFunctionDefinition(node: FunctionDefinitionNode): Node { + this.currentFunctionReturnType = node.returnType ?? PrimitiveType.VOID; + node.parameters = this.visitList(node.parameters) as ParameterNode[]; + node.body = this.visit(node.body) as BlockNode; + return node; + } + + visitReturn(node: ReturnNode): Node { + node.expression = this.visit(node.expression); + if (!implicitlyCastable(node.expression.type, this.currentFunctionReturnType)) { + throw new ReturnTypeError(node.expression, node.expression.type, this.currentFunctionReturnType); + } + return node; + } + visitFunctionCall(node: FunctionCallNode): Node { node.identifier = this.visit(node.identifier) as IdentifierNode; node.parameters = this.visitList(node.parameters); - const { definition, type } = node.identifier; - if (!definition || !definition.parameters) return node; // already checked in symbol table + const { symbol, type } = node.identifier; + if (!symbol || !symbol.parameters) return node; // already checked in symbol table const parameterTypes = node.parameters.map((p) => p.type!); - expectParameters(node, parameterTypes, definition.parameters); + expectParameters(node, parameterTypes, symbol.parameters); // Additional array length check for checkMultiSig if (node.identifier.name === GlobalFunction.CHECKMULTISIG) { @@ -211,11 +242,11 @@ export default class TypeCheckTraversal extends AstTraversal { node.identifier = this.visit(node.identifier) as IdentifierNode; node.parameters = this.visitList(node.parameters); - const { definition, type } = node.identifier; - if (!definition || !definition.parameters) return node; // already checked in symbol table + const { symbol, type } = node.identifier; + if (!symbol || !symbol.parameters) return node; // already checked in symbol table const parameterTypes = node.parameters.map((p) => p.type!); - expectParameters(node, parameterTypes, definition.parameters); + expectParameters(node, parameterTypes, symbol.parameters); node.type = type; return node; @@ -405,8 +436,8 @@ export default class TypeCheckTraversal extends AstTraversal { } visitIdentifier(node: IdentifierNode): Node { - if (!node.definition) return node; - node.type = node.definition.type; + if (!node.symbol) return node; + node.type = node.symbol.type; return node; } } @@ -599,13 +630,13 @@ function extractSingleBytesNarrowing(expr: BinaryOpNode): Narrowing | undefined const { sizeNode, literalNode } = match; if (!(sizeNode.expression instanceof IdentifierNode)) return undefined; - const { definition } = sizeNode.expression; - if (!definition || !(definition.type instanceof BytesType) || definition.type.bound !== undefined) return undefined; + const { symbol } = sizeNode.expression; + if (!symbol || !(symbol.type instanceof BytesType) || symbol.type.bound !== undefined) return undefined; const bound = Number(literalNode.value); if (bound <= 0) return undefined; - return { symbol: definition, bound }; + return { symbol, bound }; } // Matches expr.length N or N expr.length, returning the SIZE node and int literal. diff --git a/packages/cashc/test/ast/AST.test.ts b/packages/cashc/test/ast/AST.test.ts index 7a7c0076..a9d0deb1 100644 --- a/packages/cashc/test/ast/AST.test.ts +++ b/packages/cashc/test/ast/AST.test.ts @@ -12,7 +12,7 @@ import fs from 'fs'; import { URL } from 'url'; import { fixtures } from './fixtures.js'; -import { parseCode } from '../../src/compiler.js'; +import { parseCode } from '../../src/parser.js'; import { readCashFiles } from '../test-utils.js'; import { Ast } from '../../src/ast/AST.js'; import OutputSourceCodeTraversal from '../../src/print/OutputSourceCodeTraversal.js'; diff --git a/packages/cashc/test/ast/Location.test.ts b/packages/cashc/test/ast/Location.test.ts index 4f7d9418..65894d30 100644 --- a/packages/cashc/test/ast/Location.test.ts +++ b/packages/cashc/test/ast/Location.test.ts @@ -1,6 +1,7 @@ import fs from 'fs'; import { URL } from 'url'; -import { compileString, parseCode } from '../../src/compiler.js'; +import { compileString } from '../../src/compiler.js'; +import { parseCode } from '../../src/parser.js'; import { buildLineToAsmMap, bytecodeToAsm, bytecodeToScript } from '@cashscript/utils'; import { hexToBin } from '@bitauth/libauth'; @@ -9,7 +10,7 @@ describe('Location', () => { const code = fs.readFileSync(new URL('../valid-contract-files/simple_functions.cash', import.meta.url), { encoding: 'utf-8' }); const ast = parseCode(code); - const f = ast.contract.functions[0]; + const f = ast.contract!.functions[0]; expect(f.location).toBeDefined(); expect((f.location).text(code)).toEqual('function hello(sig s, pubkey pk) {\n require(checkSig(s, pk));\n }'); @@ -84,7 +85,7 @@ contract test() { const code = fs.readFileSync(new URL('../valid-contract-files/simple_functions.cash', import.meta.url), { encoding: 'utf-8' }); const ast = parseCode(code); - const secondFunction = ast.contract.functions[1]; + const secondFunction = ast.contract!.functions[1]; expect(secondFunction.location).toBeDefined(); expect(secondFunction.location.start).toEqual({ line: 6, column: 4 }); diff --git a/packages/cashc/test/ast/fixtures.ts b/packages/cashc/test/ast/fixtures.ts index 12cc323c..c54d2a0f 100644 --- a/packages/cashc/test/ast/fixtures.ts +++ b/packages/cashc/test/ast/fixtures.ts @@ -6,6 +6,7 @@ import { Ast, ParameterNode, FunctionDefinitionNode, + FunctionKind, BlockNode, RequireNode, BinaryOpNode, @@ -45,6 +46,7 @@ export const fixtures: Fixture[] = [ 'P2PKH', [new ParameterNode(new BytesType(20), 'pkh')], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'spend', [ new ParameterNode(PrimitiveType.PUBKEY, 'pk'), @@ -76,6 +78,7 @@ export const fixtures: Fixture[] = [ 'Reassignment', [new ParameterNode(PrimitiveType.INT, 'x'), new ParameterNode(PrimitiveType.STRING, 'y')], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'hello', [new ParameterNode(PrimitiveType.PUBKEY, 'pk'), new ParameterNode(PrimitiveType.SIG, 's')], new BlockNode([ @@ -150,6 +153,7 @@ export const fixtures: Fixture[] = [ [new ParameterNode(PrimitiveType.INT, 'x'), new ParameterNode(PrimitiveType.INT, 'y')], [ new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'transfer', [new ParameterNode(PrimitiveType.INT, 'a'), new ParameterNode(PrimitiveType.INT, 'b')], new BlockNode([ @@ -233,6 +237,7 @@ export const fixtures: Fixture[] = [ ]), ), new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'timeout', [new ParameterNode(PrimitiveType.INT, 'b')], new BlockNode([ @@ -312,6 +317,7 @@ export const fixtures: Fixture[] = [ new ParameterNode(PrimitiveType.PUBKEY, 'pk3'), ], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'spend', [ new ParameterNode(PrimitiveType.SIG, 's1'), @@ -351,6 +357,7 @@ export const fixtures: Fixture[] = [ new ParameterNode(PrimitiveType.INT, 'priceTarget'), ], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'spend', [ new ParameterNode(PrimitiveType.SIG, 'ownerSig'), @@ -436,6 +443,7 @@ export const fixtures: Fixture[] = [ 'Covenant', [], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'spend', [], new BlockNode([ @@ -651,6 +659,7 @@ export const fixtures: Fixture[] = [ ], [ new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'receive', [], new BlockNode([ @@ -772,6 +781,7 @@ export const fixtures: Fixture[] = [ ]), ), new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'reclaim', [ new ParameterNode(PrimitiveType.PUBKEY, 'pk'), @@ -810,6 +820,7 @@ export const fixtures: Fixture[] = [ 'Announcement', [], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'announce', [], new BlockNode([ @@ -913,6 +924,7 @@ export const fixtures: Fixture[] = [ [], [ new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'spend', [new ParameterNode(PrimitiveType.INT, 'value')], new BlockNode([ @@ -957,6 +969,7 @@ export const fixtures: Fixture[] = [ 'Loopy', [], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'doLoop', [], new BlockNode([ @@ -1005,6 +1018,7 @@ export const fixtures: Fixture[] = [ 'WhileLoopBasic', [], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'spend', [], new BlockNode([ @@ -1050,6 +1064,7 @@ export const fixtures: Fixture[] = [ 'ForLoopBasic', [], [new FunctionDefinitionNode( + FunctionKind.CONTRACT, 'spend', [], new BlockNode([ diff --git a/packages/cashc/test/compiler/AssignTypeError/void_function_as_value.cash b/packages/cashc/test/compiler/AssignTypeError/void_function_as_value.cash new file mode 100644 index 00000000..f4a16022 --- /dev/null +++ b/packages/cashc/test/compiler/AssignTypeError/void_function_as_value.cash @@ -0,0 +1,10 @@ +function check(int a) { + require(a > 0); +} + +contract Test() { + function spend(int x) { + int y = check(x); + require(y == 0); + } +} diff --git a/packages/cashc/test/compiler/MisplacedReturnError/conditional_return.cash b/packages/cashc/test/compiler/MisplacedReturnError/conditional_return.cash new file mode 100644 index 00000000..db96fdca --- /dev/null +++ b/packages/cashc/test/compiler/MisplacedReturnError/conditional_return.cash @@ -0,0 +1,12 @@ +function clamp(int a) returns (int) { + if (a > 10) { + return 10; + } + return a; +} + +contract Test() { + function spend(int x) { + require(clamp(x) == 5); + } +} diff --git a/packages/cashc/test/compiler/MissingReturnError/global_function_missing_return.cash b/packages/cashc/test/compiler/MissingReturnError/global_function_missing_return.cash new file mode 100644 index 00000000..33c5843f --- /dev/null +++ b/packages/cashc/test/compiler/MissingReturnError/global_function_missing_return.cash @@ -0,0 +1,10 @@ +function broken(int a) returns (int) { + int b = a + 1; + require(b > 0); +} + +contract Test() { + function spend(int x) { + require(broken(x) == 2); + } +} diff --git a/packages/cashc/test/compiler/ParseError/import_after_contract.cash b/packages/cashc/test/compiler/ParseError/import_after_contract.cash new file mode 100644 index 00000000..33b18164 --- /dev/null +++ b/packages/cashc/test/compiler/ParseError/import_after_contract.cash @@ -0,0 +1,7 @@ +contract Test() { + function spend() { + require(true); + } +} + +import "./helpers.cash"; diff --git a/packages/cashc/test/compiler/ParseError/import_after_function.cash b/packages/cashc/test/compiler/ParseError/import_after_function.cash new file mode 100644 index 00000000..ee2d7c60 --- /dev/null +++ b/packages/cashc/test/compiler/ParseError/import_after_function.cash @@ -0,0 +1,11 @@ +function helper(int a) returns (int) { + return a + 1; +} + +import "./other.cash"; + +contract Test() { + function spend(int x) { + require(helper(x) == 2); + } +} diff --git a/packages/cashc/test/compiler/RedefinitionError/duplicate_global_function.cash b/packages/cashc/test/compiler/RedefinitionError/duplicate_global_function.cash new file mode 100644 index 00000000..41ed861d --- /dev/null +++ b/packages/cashc/test/compiler/RedefinitionError/duplicate_global_function.cash @@ -0,0 +1,13 @@ +function foo(int a) returns (int) { + return a + 1; +} + +function foo(int a) returns (int) { + return a + 2; +} + +contract DuplicateGlobalFunction() { + function spend() { + require(foo(1) == 2); + } +} diff --git a/packages/cashc/test/compiler/ReturnTypeError/return_in_contract_function.cash b/packages/cashc/test/compiler/ReturnTypeError/return_in_contract_function.cash new file mode 100644 index 00000000..1f7c67b9 --- /dev/null +++ b/packages/cashc/test/compiler/ReturnTypeError/return_in_contract_function.cash @@ -0,0 +1,5 @@ +contract Test() { + function spend(int x) { + return x; + } +} diff --git a/packages/cashc/test/compiler/ReturnTypeError/wrong_return_type.cash b/packages/cashc/test/compiler/ReturnTypeError/wrong_return_type.cash new file mode 100644 index 00000000..e3cb3efa --- /dev/null +++ b/packages/cashc/test/compiler/ReturnTypeError/wrong_return_type.cash @@ -0,0 +1,9 @@ +function toBytes(int a) returns (bytes32) { + return a; +} + +contract Test() { + function spend(int x) { + require(toBytes(x) == 0x0000000000000000000000000000000000000000000000000000000000000000); + } +} diff --git a/packages/cashc/test/compiler/ParseError/nonvoid_function_call.cash b/packages/cashc/test/compiler/UnusedFunctionReturnError/nonvoid_function_call.cash similarity index 100% rename from packages/cashc/test/compiler/ParseError/nonvoid_function_call.cash rename to packages/cashc/test/compiler/UnusedFunctionReturnError/nonvoid_function_call.cash diff --git a/packages/cashc/test/compiler/UnusedVariableError/unused_global_function_local.cash b/packages/cashc/test/compiler/UnusedVariableError/unused_global_function_local.cash new file mode 100644 index 00000000..a37120dd --- /dev/null +++ b/packages/cashc/test/compiler/UnusedVariableError/unused_global_function_local.cash @@ -0,0 +1,10 @@ +function withUnusedLocal(int a) returns (int) { + int unused = a + 1; + return a; +} + +contract UnusedGlobalFunctionLocal() { + function spend() { + require(withUnusedLocal(1) == 1); + } +} diff --git a/packages/cashc/test/compiler/UnusedVariableError/unused_global_function_parameter.cash b/packages/cashc/test/compiler/UnusedVariableError/unused_global_function_parameter.cash new file mode 100644 index 00000000..815d952e --- /dev/null +++ b/packages/cashc/test/compiler/UnusedVariableError/unused_global_function_parameter.cash @@ -0,0 +1,9 @@ +function withUnusedParameter(int a, int b) returns (int) { + return a; +} + +contract UnusedGlobalFunctionParameter() { + function spend() { + require(withUnusedParameter(1, 2) == 1); + } +} diff --git a/packages/cashc/test/generation/fixtures.ts b/packages/cashc/test/generation/fixtures.ts index c03ac203..61c1316e 100644 --- a/packages/cashc/test/generation/fixtures.ts +++ b/packages/cashc/test/generation/fixtures.ts @@ -1408,4 +1408,142 @@ export const fixtures: Fixture[] = [ fingerprint: '606e540c38f161868964b683aeb0ddf93094dc36607397ef9b9f507f9028bc37', }, }, + { + // A single global function — the basic OP_DEFINE / OP_INVOKE calling convention. + fn: 'global_function_simple.cash', + artifact: { + contractName: 'GlobalFunctionSimple', + constructorInputs: [], + abi: [{ name: 'spend', inputs: [{ name: 'x', type: 'int' }] }], + bytecode: + // OP_DEFINE double (id 0): return a * 2 + '5295 OP_0 OP_DEFINE ' + // require(double(x) == 6) + + 'OP_0 OP_INVOKE OP_6 OP_NUMEQUAL', + debug: { + bytecode: '0252950089008a569c', + logs: [], + requires: [ + { ip: 7, line: 7 }, + ], + sourceMap: '1::3:1;;::::1;7:16:7:25;;:29::30:0;:8::32:1', + }, + source: fs.readFileSync(new URL('../valid-contract-files/global_function_simple.cash', import.meta.url), { encoding: 'utf-8' }), + compiler: { + name: 'cashc', + version, + options: { + enforceFunctionParameterTypes: true, + enforceLocktimeGuard: true, + }, + }, + updatedAt: '', + fingerprint: 'ef6dd7819e66a430286fe16f3d6dad7e026cf1970eda6bc620be7e7a3bdd2a4d', + }, + }, + { + // A multi-parameter global function — locks in the parameter stack-seeding and argument order + // (the contract OP_SWAPs x and y into place; the body computes a - b directly). + fn: 'global_function_multi_param.cash', + artifact: { + contractName: 'GlobalFunctionMultiParam', + constructorInputs: [], + abi: [{ name: 'spend', inputs: [{ name: 'x', type: 'int' }, { name: 'y', type: 'int' }] }], + bytecode: + // OP_DEFINE sub (id 0): return a - b + '94 OP_0 OP_DEFINE ' + // require(sub(x, y) == 7) + + 'OP_SWAP OP_0 OP_INVOKE OP_7 OP_NUMEQUAL', + debug: { + bytecode: '019400897c008a579c', + logs: [], + requires: [ + { ip: 8, line: 7 }, + ], + sourceMap: '1::3:1;;::::1;7:23:7:24:0;:16::25:1;;:29::30:0;:8::32:1', + }, + source: fs.readFileSync(new URL('../valid-contract-files/global_function_multi_param.cash', import.meta.url), { encoding: 'utf-8' }), + compiler: { + name: 'cashc', + version, + options: { + enforceFunctionParameterTypes: true, + enforceLocktimeGuard: true, + }, + }, + updatedAt: '', + fingerprint: '8fc72a3f89ee3238266d6dd9ad3919f7238c8d6a31296cc8925968a31c78c7dc', + }, + }, + { + // A void global function called as a statement — no return value, and the void stack-cleanup path. + fn: 'global_function_void.cash', + artifact: { + contractName: 'GlobalFunctionVoid', + constructorInputs: [], + abi: [{ name: 'spend', inputs: [{ name: 'x', type: 'int' }] }], + bytecode: + // OP_DEFINE requirePositive (id 0): require(a > 0) + '00a069 OP_0 OP_DEFINE ' + // requirePositive(x); require(x < 100) + + 'OP_DUP OP_0 OP_INVOKE 64 OP_LESSTHAN', + debug: { + bytecode: '0300a069008976008a01649f', + logs: [], + requires: [ + { ip: 8, line: 8 }, + ], + sourceMap: '1::3:1;;::::1;7:24:7:25:0;:8::26:1;;8:20:8:23:0;:8::25:1', + }, + source: fs.readFileSync(new URL('../valid-contract-files/global_function_void.cash', import.meta.url), { encoding: 'utf-8' }), + compiler: { + name: 'cashc', + version, + options: { + enforceFunctionParameterTypes: true, + enforceLocktimeGuard: true, + }, + }, + updatedAt: '', + fingerprint: '4d5e07b068e501eb26e61aab0d53214aa42590858253b1106d6074d494fde557', + }, + }, + { + // Imports resolved across a diamond (mid1 and mid2 both import leaf): leaf is defined once, and + // m1/m2 invoke it transitively. + fn: '../import-fixtures/diamond.cash', + artifact: { + contractName: 'Diamond', + constructorInputs: [], + abi: [{ name: 'spend', inputs: [{ name: 'x', type: 'int' }] }], + bytecode: + // OP_DEFINE leaf (id 0): return a + 1 + '8b OP_0 OP_DEFINE ' + // OP_DEFINE m1 (id 1): return leaf(a) * 2 + + '008a5295 OP_1 OP_DEFINE ' + // OP_DEFINE m2 (id 2): return leaf(a) + 3 + + '008a5393 OP_2 OP_DEFINE ' + // require(m1(x) + m2(x) == 18) + + 'OP_DUP OP_1 OP_INVOKE OP_SWAP OP_2 OP_INVOKE OP_ADD 12 OP_NUMEQUAL', + debug: { + bytecode: '018b008904008a5295518904008a5393528976518a7c528a9301129c', + logs: [], + requires: [ + { ip: 18, line: 6 }, + ], + sourceMap: '1::3:1;;::::1;2::4::0;;::::1;::::0;;::::1;6:19:6:20:0;:16::21:1;;:27::28:0;:24::29:1;;:16;:33::35:0;:8::37:1', + }, + source: fs.readFileSync(new URL('../import-fixtures/diamond.cash', import.meta.url), { encoding: 'utf-8' }), + compiler: { + name: 'cashc', + version, + options: { + enforceFunctionParameterTypes: true, + enforceLocktimeGuard: true, + }, + }, + updatedAt: '', + fingerprint: '316a3305152ec0695bf80303736c79dd1f9cc2f1dbccf57d9965094401363307', + }, + }, ]; diff --git a/packages/cashc/test/import-fixtures/cycle_a.cash b/packages/cashc/test/import-fixtures/cycle_a.cash new file mode 100644 index 00000000..5197f26e --- /dev/null +++ b/packages/cashc/test/import-fixtures/cycle_a.cash @@ -0,0 +1,5 @@ +import "./cycle_b.cash"; + +function a(int n) returns (int) { + return n + 1; +} diff --git a/packages/cashc/test/import-fixtures/cycle_b.cash b/packages/cashc/test/import-fixtures/cycle_b.cash new file mode 100644 index 00000000..da059e51 --- /dev/null +++ b/packages/cashc/test/import-fixtures/cycle_b.cash @@ -0,0 +1,5 @@ +import "./cycle_a.cash"; + +function b(int n) returns (int) { + return n * 2; +} diff --git a/packages/cashc/test/import-fixtures/cycle_main.cash b/packages/cashc/test/import-fixtures/cycle_main.cash new file mode 100644 index 00000000..6f54878b --- /dev/null +++ b/packages/cashc/test/import-fixtures/cycle_main.cash @@ -0,0 +1,7 @@ +import "./cycle_a.cash"; + +contract Cycle() { + function spend(int x) { + require(a(x) + b(x) == 7); + } +} diff --git a/packages/cashc/test/import-fixtures/diamond.cash b/packages/cashc/test/import-fixtures/diamond.cash new file mode 100644 index 00000000..e3629cb4 --- /dev/null +++ b/packages/cashc/test/import-fixtures/diamond.cash @@ -0,0 +1,8 @@ +import "./mid1.cash"; +import "./mid2.cash"; + +contract Diamond() { + function spend(int x) { + require(m1(x) + m2(x) == 18); + } +} diff --git a/packages/cashc/test/import-fixtures/duplicate_import_helper.cash b/packages/cashc/test/import-fixtures/duplicate_import_helper.cash new file mode 100644 index 00000000..03a29aa0 --- /dev/null +++ b/packages/cashc/test/import-fixtures/duplicate_import_helper.cash @@ -0,0 +1,3 @@ +function shared(int a) returns (int) { + return a + 99; +} diff --git a/packages/cashc/test/import-fixtures/duplicate_import_main.cash b/packages/cashc/test/import-fixtures/duplicate_import_main.cash new file mode 100644 index 00000000..2ec04682 --- /dev/null +++ b/packages/cashc/test/import-fixtures/duplicate_import_main.cash @@ -0,0 +1,11 @@ +import "./duplicate_import_helper.cash"; + +function shared(int a) returns (int) { + return a + 1; +} + +contract DuplicateImport() { + function spend() { + require(shared(1) == 2); + } +} diff --git a/packages/cashc/test/import-fixtures/leaf.cash b/packages/cashc/test/import-fixtures/leaf.cash new file mode 100644 index 00000000..c3d21091 --- /dev/null +++ b/packages/cashc/test/import-fixtures/leaf.cash @@ -0,0 +1,3 @@ +function leaf(int a) returns (int) { + return a + 1; +} diff --git a/packages/cashc/test/import-fixtures/main.cash b/packages/cashc/test/import-fixtures/main.cash new file mode 100644 index 00000000..f9c1a552 --- /dev/null +++ b/packages/cashc/test/import-fixtures/main.cash @@ -0,0 +1,7 @@ +import "./math.cash"; + +contract Main() { + function spend(int x) { + require(double(addOne(x)) == 8); + } +} diff --git a/packages/cashc/test/import-fixtures/math.cash b/packages/cashc/test/import-fixtures/math.cash new file mode 100644 index 00000000..9d74e692 --- /dev/null +++ b/packages/cashc/test/import-fixtures/math.cash @@ -0,0 +1,7 @@ +function addOne(int a) returns (int) { + return a + 1; +} + +function double(int a) returns (int) { + return a * 2; +} diff --git a/packages/cashc/test/import-fixtures/mid1.cash b/packages/cashc/test/import-fixtures/mid1.cash new file mode 100644 index 00000000..096decc5 --- /dev/null +++ b/packages/cashc/test/import-fixtures/mid1.cash @@ -0,0 +1,4 @@ +import "./leaf.cash"; +function m1(int a) returns (int) { + return leaf(a) * 2; +} diff --git a/packages/cashc/test/import-fixtures/mid2.cash b/packages/cashc/test/import-fixtures/mid2.cash new file mode 100644 index 00000000..cdc964c0 --- /dev/null +++ b/packages/cashc/test/import-fixtures/mid2.cash @@ -0,0 +1,4 @@ +import "./leaf.cash"; +function m2(int a) returns (int) { + return leaf(a) + 3; +} diff --git a/packages/cashc/test/imports.test.ts b/packages/cashc/test/imports.test.ts new file mode 100644 index 00000000..4eb960fc --- /dev/null +++ b/packages/cashc/test/imports.test.ts @@ -0,0 +1,46 @@ +import { fileURLToPath } from 'url'; +import { compileFile, compileString } from '../src/index.js'; +import { ImportResolutionError, FunctionRedefinitionError } from '../src/Errors.js'; + +const fixture = (name: string): string => fileURLToPath(new URL(`./import-fixtures/${name}`, import.meta.url)); + +describe('Imports', () => { + it('merges global functions from an imported file', () => { + const artifact = compileFile(fixture('main.cash')); + expect(artifact.contractName).toEqual('Main'); + expect(artifact.bytecode).toContain('OP_INVOKE'); + // both imported functions are defined (one OP_DEFINE each) + expect([...artifact.bytecode.matchAll(/OP_DEFINE/g)]).toHaveLength(2); + }); + + it('de-duplicates a diamond import so a shared leaf is defined once', () => { + // Diamond imports mid1 and mid2, which both import leaf. The leaf function must be merged once + // (otherwise it would be a redefinition): leaf, m1, m2 = 3 OP_DEFINEs. + const artifact = compileFile(fixture('diamond.cash')); + expect(artifact.contractName).toEqual('Diamond'); + expect([...artifact.bytecode.matchAll(/OP_DEFINE/g)]).toHaveLength(3); + }); + + it('throws when compiling a string with imports but no base path', () => { + const code = 'import "./math.cash";\ncontract C() { function spend() { require(true); } }'; + expect(() => compileString(code)).toThrow(ImportResolutionError); + }); + + it('throws when an imported file cannot be found', () => { + const code = 'import "./does-not-exist.cash";\ncontract C() { function spend() { require(true); } }'; + expect(() => compileString(code, { basePath: fixture('') })).toThrow(ImportResolutionError); + }); + + it('throws when an imported function collides with a local function of the same name', () => { + // duplicate_import_main defines `shared` and imports a file that also defines `shared`. + expect(() => compileFile(fixture('duplicate_import_main.cash'))).toThrow(FunctionRedefinitionError); + }); + + it('resolves a cyclic import without infinite looping', () => { + // cycle_a imports cycle_b which imports cycle_a back; de-duplication by absolute path breaks the + // cycle, and both functions (a and b) end up defined exactly once. + const artifact = compileFile(fixture('cycle_main.cash')); + expect(artifact.contractName).toEqual('Cycle'); + expect([...artifact.bytecode.matchAll(/OP_DEFINE/g)]).toHaveLength(2); + }); +}); diff --git a/packages/cashc/test/semantic/InjectLocktimeGuardTraversal.test.ts b/packages/cashc/test/semantic/InjectLocktimeGuardTraversal.test.ts index fc89f420..c99f9113 100644 --- a/packages/cashc/test/semantic/InjectLocktimeGuardTraversal.test.ts +++ b/packages/cashc/test/semantic/InjectLocktimeGuardTraversal.test.ts @@ -213,3 +213,102 @@ describe('InjectLocktimeGuardTraversal', () => { expect(compileString(src, { enforceLocktimeGuard: false }).bytecode.startsWith(GUARD_PREFIX)).toBe(false); }); }); + +// The guard is only injected into contract spending functions, never into global functions (non-finality +// is a transaction-wide property, so a single guard on the spending path covers any tx.locktime accessed +// inside invoked global functions). Whether a contract function needs the guard is therefore decided by +// looking through the global functions it (transitively) invokes. The injected guard is a require with a +// distinctive message, which is detectable even when the OP_DEFINE prologue precedes the contract body. +describe('InjectLocktimeGuardTraversal — global functions', () => { + const GUARD_MESSAGE = 'non-final sequence number'; + const guardInjected = (src: string): boolean => (compileString(src).debug?.requires ?? []) + .some((statement) => statement.message?.includes(GUARD_MESSAGE)); + + it('injects guard in the contract when an invoked global uses tx.locktime', () => { + const src = ` + function usesLocktime() returns (int) { return tx.locktime; } + contract T() { + function spend() { + require(usesLocktime() >= 100); + } + }`; + expect(guardInjected(src)).toBe(true); + }); + + it('does not inject when the contract has a tx.time check before invoking the global', () => { + const src = ` + function usesLocktime() returns (int) { return tx.locktime; } + contract T() { + function spend() { + require(tx.time >= 100); + require(usesLocktime() >= 100); + } + }`; + expect(guardInjected(src)).toBe(false); + }); + + it('does not inject when the invoked global covers its own tx.locktime with a tx.time check', () => { + const src = ` + function usesLocktime() returns (int) { require(tx.time >= 100); return tx.locktime; } + contract T() { + function spend() { + require(usesLocktime() >= 0); + } + }`; + expect(guardInjected(src)).toBe(false); + }); + + it('injects guard for tx.locktime reached transitively through nested global invocations', () => { + const src = ` + function inner() returns (int) { return tx.locktime; } + function outer() returns (int) { return inner(); } + contract T() { + function spend() { + require(outer() >= 100); + } + }`; + expect(guardInjected(src)).toBe(true); + }); + + it('does not inject when a caller global covers the callee with its own tx.time check', () => { + const src = ` + function inner() returns (int) { return tx.locktime; } + function outer() returns (int) { require(tx.time >= 100); return inner(); } + contract T() { + function spend() { + require(outer() >= 0); + } + }`; + expect(guardInjected(src)).toBe(false); + }); + + it('injects guard when an invoked global only uses tx.locktime inside a branch', () => { + const src = ` + function maybeLocktime(int a) { + if (a > 0) { + int x = tx.locktime; + require(x >= 100); + } else { + require(a == 0); + } + } + contract T() { + function spend(int x) { + maybeLocktime(x); + require(x >= 0); + } + }`; + expect(guardInjected(src)).toBe(true); + }); + + it('does not inject when an invoked global does not use tx.locktime', () => { + const src = ` + function double(int a) returns (int) { return a * 2; } + contract T() { + function spend(int x) { + require(double(x) >= 2); + } + }`; + expect(guardInjected(src)).toBe(false); + }); +}); diff --git a/packages/cashc/test/valid-contract-files/global_function_in_control_flow.cash b/packages/cashc/test/valid-contract-files/global_function_in_control_flow.cash new file mode 100644 index 00000000..9d9d6a4b --- /dev/null +++ b/packages/cashc/test/valid-contract-files/global_function_in_control_flow.cash @@ -0,0 +1,17 @@ +function triple(int a) returns (int) { + return a * 3; +} + +contract GlobalFunctionInControlFlow() { + function spend(int x, bool useLoop) { + int total = 0; + if (useLoop) { + for (int i = 0; i < 3; i = i + 1) { + total = total + triple(x); + } + } else { + total = triple(x); + } + require(total == 9); + } +} diff --git a/packages/cashc/test/valid-contract-files/global_function_multi_param.cash b/packages/cashc/test/valid-contract-files/global_function_multi_param.cash new file mode 100644 index 00000000..badac11d --- /dev/null +++ b/packages/cashc/test/valid-contract-files/global_function_multi_param.cash @@ -0,0 +1,9 @@ +function sub(int a, int b) returns (int) { + return a - b; +} + +contract GlobalFunctionMultiParam() { + function spend(int x, int y) { + require(sub(x, y) == 7); + } +} diff --git a/packages/cashc/test/valid-contract-files/global_function_nested.cash b/packages/cashc/test/valid-contract-files/global_function_nested.cash new file mode 100644 index 00000000..cc350bcb --- /dev/null +++ b/packages/cashc/test/valid-contract-files/global_function_nested.cash @@ -0,0 +1,13 @@ +function addOne(int a) returns (int) { + return a + 1; +} + +function doubleIncremented(int a) returns (int) { + return addOne(a) * 2; +} + +contract GlobalFunctionNested() { + function spend(int x) { + require(doubleIncremented(x) == 8); + } +} diff --git a/packages/cashc/test/valid-contract-files/global_function_simple.cash b/packages/cashc/test/valid-contract-files/global_function_simple.cash new file mode 100644 index 00000000..851f6cd7 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/global_function_simple.cash @@ -0,0 +1,9 @@ +function double(int a) returns (int) { + return a * 2; +} + +contract GlobalFunctionSimple() { + function spend(int x) { + require(double(x) == 6); + } +} diff --git a/packages/cashc/test/valid-contract-files/global_function_void.cash b/packages/cashc/test/valid-contract-files/global_function_void.cash new file mode 100644 index 00000000..945569f7 --- /dev/null +++ b/packages/cashc/test/valid-contract-files/global_function_void.cash @@ -0,0 +1,10 @@ +function requirePositive(int a) { + require(a > 0); +} + +contract GlobalFunctionVoid() { + function spend(int x) { + requirePositive(x); + require(x < 100); + } +} diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index 3215217d..63c51937 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -46,6 +46,7 @@ export enum PrimitiveType { SIG = 'sig', DATASIG = 'datasig', ANY = 'any', + VOID = 'void', } const ExplicitlyCastableTo: { [key in PrimitiveType]: PrimitiveType[] } = { @@ -56,11 +57,15 @@ const ExplicitlyCastableTo: { [key in PrimitiveType]: PrimitiveType[] } = { [PrimitiveType.SIG]: [PrimitiveType.SIG], [PrimitiveType.DATASIG]: [PrimitiveType.DATASIG], [PrimitiveType.ANY]: [], + [PrimitiveType.VOID]: [], }; export function explicitlyCastable(from?: Type, to?: Type): boolean { if (!from || !to) return false; + // `void` is not a real value type, so it can never participate in a cast + if (from === PrimitiveType.VOID || to === PrimitiveType.VOID) return false; + // Tuples can't be cast if (from instanceof TupleType || to instanceof TupleType) return false; @@ -111,6 +116,9 @@ export function explicitlyCastable(from?: Type, to?: Type): boolean { export function implicitlyCastable(actual?: Type, expected?: Type): boolean { if (!actual || !expected) return false; + // `void` is not a real value type, so it can never be assigned to or from (not even to `any`) + if (actual === PrimitiveType.VOID || expected === PrimitiveType.VOID) return false; + if (actual instanceof TupleType && expected instanceof TupleType) { const leftIsCompatible = implicitlyCastable(actual.leftType, expected.leftType); const rightIsCompatible = implicitlyCastable(actual.rightType, expected.rightType); diff --git a/website/docs/compiler/compiler.md b/website/docs/compiler/compiler.md index de6e48c8..f5de753d 100644 --- a/website/docs/compiler/compiler.md +++ b/website/docs/compiler/compiler.md @@ -82,6 +82,10 @@ Compiles a CashScript contract from a source file. This compile method is handy const P2PKH = compileFile(new URL('p2pkh.cash', import.meta.url)); ``` +:::note +If the contract uses `import` directives to pull in [user-defined functions](/docs/language/contracts#user-defined-functions) from other files, `compileFile` resolves those imports relative to the source file's directory automatically. +::: + ### compileString() ```ts compileString(sourceCode: string, compilerOptions?: CompilerOptions): Artifact @@ -97,6 +101,10 @@ const source = await result.text(); const P2PKH = compileString(source); ``` +:::note +`compileString` has no source file to resolve `import` directives against. To compile a contract that imports [user-defined functions](/docs/language/contracts#user-defined-functions) from other files, use [`compileFile`](#compilefile) instead. +::: + ### Compiler Options ```ts interface CompilerOptions { diff --git a/website/docs/compiler/grammar.md b/website/docs/compiler/grammar.md index 93f5d8d7..06093188 100644 --- a/website/docs/compiler/grammar.md +++ b/website/docs/compiler/grammar.md @@ -7,7 +7,7 @@ description: ANTLR4 language grammar for CashScript grammar CashScript; sourceFile - : pragmaDirective* contractDefinition EOF + : pragmaDirective* importDirective* topLevelDefinition* EOF ; pragmaDirective @@ -30,11 +30,24 @@ versionOperator : '^' | '~' | '>=' | '>' | '<' | '<=' | '=' ; +importDirective + : 'import' StringLiteral ';' + ; + +topLevelDefinition + : globalFunctionDefinition + | contractDefinition + ; + +globalFunctionDefinition + : 'function' Identifier parameterList ('returns' '(' typeName ')')? functionBody + ; + contractDefinition - : 'contract' Identifier parameterList '{' functionDefinition* '}' + : 'contract' Identifier parameterList '{' contractFunctionDefinition* '}' ; -functionDefinition +contractFunctionDefinition : 'function' Identifier parameterList functionBody ; @@ -66,7 +79,17 @@ nonControlStatement | assignStatement | timeOpStatement | requireStatement + | functionCallStatement | consoleStatement + | returnStatement + ; + +functionCallStatement + : functionCall + ; + +returnStatement + : 'return' expression ; controlStatement @@ -140,7 +163,7 @@ consoleParameterList ; functionCall - : Identifier expressionList // Only built-in functions are accepted + : Identifier expressionList // Built-in global functions and user-defined global functions ; expressionList diff --git a/website/docs/language/contracts.md b/website/docs/language/contracts.md index b6e45949..fcd71867 100644 --- a/website/docs/language/contracts.md +++ b/website/docs/language/contracts.md @@ -60,7 +60,7 @@ contract TransferWithTimeout(pubkey sender, pubkey recipient, int timeout) { ``` :::note -The functions described here are top-level contract functions, which act as the entry points for spending from the contract. CashScript does not yet support user-defined reusable functions that can be called from within other functions. Callable functions are likely coming in CashScript v0.14, which would also allow function calls inside loops and loops inside reusable functions. +The functions described here are top-level contract functions, which act as the entry points for spending from the contract. CashScript also supports user-defined reusable functions that are declared at the top level of a file (outside the contract) and can be called from contract functions and from each other. See [User-defined functions](#user-defined-functions) below. ::: ### Function Arguments @@ -79,6 +79,76 @@ In CashScript the types for the function arguments are **not** enforced automati The typings for function arguments are enforced by default for boolean values and bounded bytes types such as `bytes20` and `bytes32`. ::: +## User-defined functions +Reusable functions are declared at the **top level** of a `.cash` file, outside the contract. They are compiled to the BCH VM's native function opcodes (`OP_DEFINE`/`OP_INVOKE`, available since the May 2026 upgrade), so a function's body is stored once and shared across every call site rather than duplicated. + +A function may return a **single value** using a `returns (T)` clause, and is called from contract functions or from other top-level functions: + +```solidity +pragma cashscript ^0.14.0; + +function double(int a) returns (int) { + return a * 2; +} + +function addThenDouble(int a, int b) returns (int) { + return double(a + b); +} + +contract Example() { + function spend(int x) { + require(addThenDouble(x, 1) == 8); + } +} +``` + +A function without a `returns` clause is a **void** function — it performs only `require` checks and is called as a statement: + +```solidity +function requirePositive(int a) { + require(a > 0); +} + +contract Example() { + function spend(int x) { + requirePositive(x); + require(x < 100); + } +} +``` + +### Importing functions from other files +Top-level functions can be split across files and pulled in with an `import` directive, which makes the imported file's functions available as if they were declared locally. All `import` directives must appear at the **top of the file** — after any `pragma` directives and before any function or contract definitions. Imports are resolved relative to the importing file, so they require compiling from a file (`compileFile`): + +```solidity +// math.cash +function double(int a) returns (int) { + return a * 2; +} +``` + +```solidity +// main.cash +pragma cashscript ^0.14.0; +import "./math.cash"; + +contract Main() { + function spend(int x) { + require(double(x) == 8); + } +} +``` + +Imported function names share a single global namespace, so a name may only be defined once across the whole import graph. Files reached through more than one import path (diamond imports) are resolved once. + +### Limitations +This first version of user-defined functions is intentionally limited in scope: + +- Functions return **at most one value** (no multiple/tuple returns), and a value-returning function must end with a single `return` statement (no early or conditional returns — compute into a variable and return it at the end). +- No safety checks are present to prevent functions from calling each other recursively or disallow signature checks inside functions. +- No advanced optimisations are performed yet on user-defined functions. +- The local debugging tools in the SDK don't properly support user-defined functions yet. + ## Statements CashScript functions are made up of a collection of statements that determine whether money may be spent from the contract. diff --git a/website/docs/releases/release-notes.md b/website/docs/releases/release-notes.md index 12b56417..160d49f8 100644 --- a/website/docs/releases/release-notes.md +++ b/website/docs/releases/release-notes.md @@ -2,6 +2,14 @@ title: Release Notes --- +## v0.14.0-next.0 + +⚠️ Note that this is a pre-release version and is not yet stable. There will likely be breaking changes to the APIs and compiler output in subsequent pre-releases. + +#### cashc compiler +- :sparkles: Add support for user-defined reusable functions. +- :sparkles: Add support for `import` directives to share user-defined functions across files. + ## v0.13.2 #### cashc compiler From 4dbf78844691942776d0b94d97b08f7cc79c2fb6 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Fri, 26 Jun 2026 15:42:15 +0200 Subject: [PATCH 2/4] Add dead code elimination for unreachable functions --- packages/cashc/src/ast/SymbolTable.ts | 10 +- packages/cashc/src/compiler.ts | 4 + .../src/generation/GenerateTargetTraversal.ts | 3 +- .../semantic/DeadCodeEliminationTraversal.ts | 40 +++++ .../cashc/test/dead-code-elimination.test.ts | 162 ++++++++++++++++++ packages/cashc/test/generation/fixtures.ts | 17 +- 6 files changed, 225 insertions(+), 11 deletions(-) create mode 100644 packages/cashc/src/semantic/DeadCodeEliminationTraversal.ts create mode 100644 packages/cashc/test/dead-code-elimination.test.ts diff --git a/packages/cashc/src/ast/SymbolTable.ts b/packages/cashc/src/ast/SymbolTable.ts index 852be038..36a25525 100644 --- a/packages/cashc/src/ast/SymbolTable.ts +++ b/packages/cashc/src/ast/SymbolTable.ts @@ -35,8 +35,14 @@ export class Symbol { static userFunction(node: FunctionDefinitionNode, functionId: number): Symbol { const parameterTypes = node.parameters.map((parameter) => parameter.type); const returnType = node.returnType ?? PrimitiveType.VOID; - const bytecode = [encodeInt(BigInt(functionId)), Op.OP_INVOKE]; - return new Symbol(node.name, returnType, SymbolType.FUNCTION, node, parameterTypes, bytecode, functionId); + const symbol = new Symbol(node.name, returnType, SymbolType.FUNCTION, node, parameterTypes); + symbol.setFunctionId(functionId); + return symbol; + } + + setFunctionId(functionId: number): void { + this.functionId = functionId; + this.bytecode = [encodeInt(BigInt(functionId)), Op.OP_INVOKE]; } static class(name: string, type: Type, parameters: Type[]): Symbol { diff --git a/packages/cashc/src/compiler.ts b/packages/cashc/src/compiler.ts index 44963727..bcaac77d 100644 --- a/packages/cashc/src/compiler.ts +++ b/packages/cashc/src/compiler.ts @@ -25,6 +25,7 @@ import SymbolTableTraversal from './semantic/SymbolTableTraversal.js'; import TypeCheckTraversal from './semantic/TypeCheckTraversal.js'; import EnsureFinalRequireTraversal from './semantic/EnsureFinalRequireTraversal.js'; import InjectLocktimeGuardTraversal from './semantic/InjectLocktimeGuardTraversal.js'; +import DeadCodeEliminationTraversal from './semantic/DeadCodeEliminationTraversal.js'; export const DEFAULT_COMPILER_OPTIONS: CompilerOptions = { enforceFunctionParameterTypes: true, @@ -64,6 +65,9 @@ export function compileString(code: string, compilerOptions: CompileOptions = {} ast = ast.accept(new InjectLocktimeGuardTraversal()) as Ast; } + // Dead-code elimination: drop global functions that are never invoked before code generation + ast = ast.accept(new DeadCodeEliminationTraversal()) as Ast; + // Code generation const traversal = new GenerateTargetTraversal(mergedCompilerOptions); ast = ast.accept(traversal) as Ast; diff --git a/packages/cashc/src/generation/GenerateTargetTraversal.ts b/packages/cashc/src/generation/GenerateTargetTraversal.ts index 286168c0..73e7e5e2 100644 --- a/packages/cashc/src/generation/GenerateTargetTraversal.ts +++ b/packages/cashc/src/generation/GenerateTargetTraversal.ts @@ -165,7 +165,8 @@ export default class GenerateTargetTraversal extends AstTraversal { bodyTraversal.currentFunction = node; bodyTraversal.constructorParameterCount = 0; - // Seed the stack with parameters in reverse order so the last parameter is on top (simila to how builtin functions work) + // Seed the stack with parameters in reverse order so the last parameter is on top + // (similar to how builtin functions work) for (let i = node.parameters.length - 1; i >= 0; i -= 1) { bodyTraversal.visit(node.parameters[i]); } diff --git a/packages/cashc/src/semantic/DeadCodeEliminationTraversal.ts b/packages/cashc/src/semantic/DeadCodeEliminationTraversal.ts new file mode 100644 index 00000000..65741490 --- /dev/null +++ b/packages/cashc/src/semantic/DeadCodeEliminationTraversal.ts @@ -0,0 +1,40 @@ +import { + FunctionCallNode, + FunctionDefinitionNode, + Node, + SourceFileNode, +} from '../ast/AST.js'; +import AstTraversal from '../ast/AstTraversal.js'; + +export default class DeadCodeEliminationTraversal extends AstTraversal { + private reachableFunctions = new Set(); + + visitSourceFile(node: SourceFileNode): Node { + super.visitOptional(node.contract); + + // Set the node.functions to the reachable functions and re-index functionIds, the order is based on insertion + // into the set, which is most stable for the functionId as it is based on contract structure rather than + // name or order of declaration. + node.functions = [...this.reachableFunctions]; + node.functions.forEach((func, index) => { + node.symbolTable!.getFromThis(func.name)!.setFunctionId(index); + }); + + return node; + } + + visitFunctionCall(node: FunctionCallNode): Node { + node = super.visitFunctionCall(node) as FunctionCallNode; + + const functionDefinition = node.identifier.symbol?.definition; + if (!functionDefinition || !(functionDefinition instanceof FunctionDefinitionNode)) return node; + + // Only descend into a function the first time it is reached to prevent infinite recursion. + if (!this.reachableFunctions.has(functionDefinition)) { + this.reachableFunctions.add(functionDefinition); + this.visit(functionDefinition.body); + } + + return node; + } +} diff --git a/packages/cashc/test/dead-code-elimination.test.ts b/packages/cashc/test/dead-code-elimination.test.ts new file mode 100644 index 00000000..6a493e01 --- /dev/null +++ b/packages/cashc/test/dead-code-elimination.test.ts @@ -0,0 +1,162 @@ +import { fileURLToPath } from 'url'; +import { compileString } from '../src/index.js'; + +const fixtureDir = fileURLToPath(new URL('./import-fixtures/', import.meta.url)); +const countOpDefines = (bytecode: string): number => [...bytecode.matchAll(/OP_DEFINE/g)].length; + +describe('Dead-code elimination', () => { + it('does not define a global function that is never invoked', () => { + const code = ` + function used(int a) returns (int) { return a + 1; } + function unused(int a) returns (int) { return a * 2; } + + contract Test() { + function spend(int x) { + require(used(x) == 6); + } + }`; + + const artifact = compileString(code); + expect(countOpDefines(artifact.bytecode)).toEqual(1); + expect(artifact.bytecode).toContain('OP_INVOKE'); + }); + + it('eliminates functions that are only reachable through other dead functions', () => { + const code = ` + function used(int a) returns (int) { return a + 1; } + function deadCaller(int a) returns (int) { return deadLeaf(a); } + function deadLeaf(int a) returns (int) { return a * 2; } + + contract Test() { + function spend(int x) { + require(used(x) == 6); + } + }`; + + // Only `used` is reachable; both `deadCaller` and the function it calls (`deadLeaf`) are dropped. + const artifact = compileString(code); + expect(countOpDefines(artifact.bytecode)).toEqual(1); + }); + + it('keeps a function that is only reachable transitively', () => { + const code = ` + function outer(int a) returns (int) { return inner(a) + 1; } + function inner(int a) returns (int) { return a * 2; } + + contract Test() { + function spend(int x) { + require(outer(x) == 7); + } + }`; + + // `outer` is called directly and `inner` only through `outer` — both must be defined. + const artifact = compileString(code); + expect(countOpDefines(artifact.bytecode)).toEqual(2); + }); + + it('keeps a recursive function without looping forever', () => { + const code = ` + function f(int n) returns (int) { return f(n); } + + contract Test() { + function spend(int x) { + require(f(x) == 0); + } + }`; + + const artifact = compileString(code); + expect(countOpDefines(artifact.bytecode)).toEqual(1); + }); + + it('keeps mutually recursive functions that are reachable', () => { + const code = ` + function a(int n) returns (int) { return b(n); } + function b(int n) returns (int) { return a(n); } + + contract Test() { + function spend(int x) { + require(a(x) == 0); + } + }`; + + const artifact = compileString(code); + expect(countOpDefines(artifact.bytecode)).toEqual(2); + }); + + it('eliminates a mutually recursive cycle that is never reached', () => { + const code = ` + function used(int n) returns (int) { return n + 1; } + function deadA(int n) returns (int) { return deadB(n); } + function deadB(int n) returns (int) { return deadA(n); } + + contract Test() { + function spend(int x) { + require(used(x) == 1); + } + }`; + + // deadA <-> deadB form a cycle but neither is reachable, so both are dropped. + const artifact = compileString(code); + expect(countOpDefines(artifact.bytecode)).toEqual(1); + }); + + it('eliminates an unused imported function', () => { + // math.cash exports both `addOne` and `double`; only `double` is used here, so `addOne` is dropped. + const code = 'import "./math.cash";\ncontract Test() { function spend(int x) { require(double(x) == 8); } }'; + + const artifact = compileString(code, { basePath: fixtureDir }); + expect(countOpDefines(artifact.bytecode)).toEqual(1); + }); +}); + +describe('Stable function id assignment', () => { + it('reordering function declarations does not change the bytecode', () => { + const ordered = ` + function a(int n) returns (int) { return n + 1; } + function b(int n) returns (int) { return n * 2; } + + contract Test() { + function spend(int x) { + require(b(x) + a(x) == 10); + } + }`; + + const reordered = ` + function b(int n) returns (int) { return n * 2; } + function a(int n) returns (int) { return n + 1; } + + contract Test() { + function spend(int x) { + require(b(x) + a(x) == 10); + } + }`; + + // functionIds follow call order (b, then a) rather than declaration order, so swapping the two + // declarations produces byte-identical output. + expect(compileString(reordered).bytecode).toEqual(compileString(ordered).bytecode); + }); + + it('renaming a function does not change the bytecode', () => { + const original = ` + function apple(int n) returns (int) { return n + 1; } + function mango(int n) returns (int) { return n * 2; } + + contract Test() { + function spend(int x) { + require(mango(x) + apple(x) == 10); + } + }`; + + const renamed = ` + function zebra(int n) returns (int) { return n + 1; } + function mango(int n) returns (int) { return n * 2; } + + contract Test() { + function spend(int x) { + require(mango(x) + zebra(x) == 10); + } + }`; + + expect(compileString(renamed).bytecode).toEqual(compileString(original).bytecode); + }); +}); diff --git a/packages/cashc/test/generation/fixtures.ts b/packages/cashc/test/generation/fixtures.ts index 61c1316e..a8a6c2ec 100644 --- a/packages/cashc/test/generation/fixtures.ts +++ b/packages/cashc/test/generation/fixtures.ts @@ -1517,21 +1517,22 @@ export const fixtures: Fixture[] = [ constructorInputs: [], abi: [{ name: 'spend', inputs: [{ name: 'x', type: 'int' }] }], bytecode: - // OP_DEFINE leaf (id 0): return a + 1 - '8b OP_0 OP_DEFINE ' - // OP_DEFINE m1 (id 1): return leaf(a) * 2 - + '008a5295 OP_1 OP_DEFINE ' + // Functions are defined in call order (DFS from the contract), so m1 is id 0, leaf id 1, m2 id 2. + // OP_DEFINE m1 (id 0): return leaf(a) * 2 + '518a5295 OP_0 OP_DEFINE ' + // OP_DEFINE leaf (id 1): return a + 1 + + '8b OP_1 OP_DEFINE ' // OP_DEFINE m2 (id 2): return leaf(a) + 3 - + '008a5393 OP_2 OP_DEFINE ' + + '518a5393 OP_2 OP_DEFINE ' // require(m1(x) + m2(x) == 18) - + 'OP_DUP OP_1 OP_INVOKE OP_SWAP OP_2 OP_INVOKE OP_ADD 12 OP_NUMEQUAL', + + 'OP_DUP OP_0 OP_INVOKE OP_SWAP OP_2 OP_INVOKE OP_ADD 12 OP_NUMEQUAL', debug: { - bytecode: '018b008904008a5295518904008a5393528976518a7c528a9301129c', + bytecode: '04518a52950089018b518904518a5393528976008a7c528a9301129c', logs: [], requires: [ { ip: 18, line: 6 }, ], - sourceMap: '1::3:1;;::::1;2::4::0;;::::1;::::0;;::::1;6:19:6:20:0;:16::21:1;;:27::28:0;:24::29:1;;:16;:33::35:0;:8::37:1', + sourceMap: '2::4:1;;::::1;1::3::0;;::::1;2::4::0;;::::1;6:19:6:20:0;:16::21:1;;:27::28:0;:24::29:1;;:16;:33::35:0;:8::37:1', }, source: fs.readFileSync(new URL('../import-fixtures/diamond.cash', import.meta.url), { encoding: 'utf-8' }), compiler: { From 2ea38ea9ccaf828bc4eb67f75cd39b0d5733aad5 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Fri, 26 Jun 2026 15:52:32 +0200 Subject: [PATCH 3/4] Add recursion note to functions docs --- website/docs/language/contracts.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/docs/language/contracts.md b/website/docs/language/contracts.md index fcd71867..c9ff2a29 100644 --- a/website/docs/language/contracts.md +++ b/website/docs/language/contracts.md @@ -149,6 +149,10 @@ This first version of user-defined functions is intentionally limited in scope: - No advanced optimisations are performed yet on user-defined functions. - The local debugging tools in the SDK don't properly support user-defined functions yet. +:::note +Recursive and mutually recursive functions are allowed and compile fine. At runtime the VM control stack is limited to 100 entries, shared between recursion depth and nested `if` and loop blocks, so excessively deep recursion will fail when the contract gets spent. +::: + ## Statements CashScript functions are made up of a collection of statements that determine whether money may be spent from the contract. From 7edbfc453eaf18b2e8e42c03917690f884eedad9 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Fri, 26 Jun 2026 16:04:43 +0200 Subject: [PATCH 4/4] Add checks so that check(Multi)Sig and this.activeBytecode cannot be used inside user-functions --- packages/cashc/src/Errors.ts | 13 ++++++ packages/cashc/src/compiler.ts | 2 + .../semantic/EnsureFunctionsSafeTraversal.ts | 46 +++++++++++++++++++ .../active_bytecode_in_function.cash | 9 ++++ .../checkmultisig_in_function.cash | 9 ++++ .../checksig_in_function.cash | 9 ++++ .../checkdatasig_in_function.cash | 9 ++++ website/docs/language/contracts.md | 5 +- 8 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 packages/cashc/src/semantic/EnsureFunctionsSafeTraversal.ts create mode 100644 packages/cashc/test/compiler/UnsafeFunctionOperationError/active_bytecode_in_function.cash create mode 100644 packages/cashc/test/compiler/UnsafeFunctionOperationError/checkmultisig_in_function.cash create mode 100644 packages/cashc/test/compiler/UnsafeFunctionOperationError/checksig_in_function.cash create mode 100644 packages/cashc/test/valid-contract-files/checkdatasig_in_function.cash diff --git a/packages/cashc/src/Errors.ts b/packages/cashc/src/Errors.ts index de4c866e..7ff6b409 100644 --- a/packages/cashc/src/Errors.ts +++ b/packages/cashc/src/Errors.ts @@ -164,6 +164,19 @@ export class MisplacedReturnError extends CashScriptError { } } +export class UnsafeFunctionOperationError extends CashScriptError { + constructor( + node: Node, + operation: string, + ) { + super( + node, + `'${operation}' cannot be used inside a user-defined function. Use it directly in a ` + + 'contract function instead, or pass the resulting value into the function as a parameter', + ); + } +} + export class TypeError extends CashScriptError { constructor( node: Node, diff --git a/packages/cashc/src/compiler.ts b/packages/cashc/src/compiler.ts index bcaac77d..efdb9859 100644 --- a/packages/cashc/src/compiler.ts +++ b/packages/cashc/src/compiler.ts @@ -24,6 +24,7 @@ import GenerateTargetTraversal from './generation/GenerateTargetTraversal.js'; import SymbolTableTraversal from './semantic/SymbolTableTraversal.js'; import TypeCheckTraversal from './semantic/TypeCheckTraversal.js'; import EnsureFinalRequireTraversal from './semantic/EnsureFinalRequireTraversal.js'; +import EnsureFunctionsSafeTraversal from './semantic/EnsureFunctionsSafeTraversal.js'; import InjectLocktimeGuardTraversal from './semantic/InjectLocktimeGuardTraversal.js'; import DeadCodeEliminationTraversal from './semantic/DeadCodeEliminationTraversal.js'; @@ -60,6 +61,7 @@ export function compileString(code: string, compilerOptions: CompileOptions = {} // Semantic analysis ast = ast.accept(new SymbolTableTraversal()) as Ast; ast = ast.accept(new TypeCheckTraversal()) as Ast; + ast = ast.accept(new EnsureFunctionsSafeTraversal()) as Ast; ast = ast.accept(new EnsureFinalRequireTraversal()) as Ast; if (mergedCompilerOptions.enforceLocktimeGuard) { ast = ast.accept(new InjectLocktimeGuardTraversal()) as Ast; diff --git a/packages/cashc/src/semantic/EnsureFunctionsSafeTraversal.ts b/packages/cashc/src/semantic/EnsureFunctionsSafeTraversal.ts new file mode 100644 index 00000000..dabd9ab4 --- /dev/null +++ b/packages/cashc/src/semantic/EnsureFunctionsSafeTraversal.ts @@ -0,0 +1,46 @@ +import { + FunctionCallNode, + FunctionDefinitionNode, + FunctionKind, + Node, + NullaryOpNode, +} from '../ast/AST.js'; +import AstTraversal from '../ast/AstTraversal.js'; +import { GlobalFunction } from '../ast/Globals.js'; +import { NullaryOperator } from '../ast/Operator.js'; +import { UnsafeFunctionOperationError } from '../Errors.js'; + +// checkSig and checkMultisig, as well as this.activeBytecode use the function's bytecode instead of the contract's. +// This is almost never what a developer would expect, so we reject using these inside global functions altogether. +export default class EnsureFunctionsSafeTraversal extends AstTraversal { + private insideGlobalFunction = false; + + visitFunctionDefinition(node: FunctionDefinitionNode): Node { + const enclosingInsideGlobalFunction = this.insideGlobalFunction; + this.insideGlobalFunction = node.kind === FunctionKind.GLOBAL; + + node = super.visitFunctionDefinition(node) as FunctionDefinitionNode; + + this.insideGlobalFunction = enclosingInsideGlobalFunction; + return node; + } + + visitNullaryOp(node: NullaryOpNode): Node { + if (this.insideGlobalFunction && node.operator === NullaryOperator.BYTECODE) { + throw new UnsafeFunctionOperationError(node, node.operator); + } + + return node; + } + + visitFunctionCall(node: FunctionCallNode): Node { + node = super.visitFunctionCall(node) as FunctionCallNode; + + const UNSAFE_FUNCTIONS: string[] = [GlobalFunction.CHECKSIG, GlobalFunction.CHECKMULTISIG]; + if (this.insideGlobalFunction && UNSAFE_FUNCTIONS.includes(node.identifier.name)) { + throw new UnsafeFunctionOperationError(node, node.identifier.name); + } + + return node; + } +} diff --git a/packages/cashc/test/compiler/UnsafeFunctionOperationError/active_bytecode_in_function.cash b/packages/cashc/test/compiler/UnsafeFunctionOperationError/active_bytecode_in_function.cash new file mode 100644 index 00000000..52af373c --- /dev/null +++ b/packages/cashc/test/compiler/UnsafeFunctionOperationError/active_bytecode_in_function.cash @@ -0,0 +1,9 @@ +function bodyMatches(bytes expected) returns (bool) { + return this.activeBytecode == expected; +} + +contract Test() { + function spend(bytes expected) { + require(bodyMatches(expected)); + } +} diff --git a/packages/cashc/test/compiler/UnsafeFunctionOperationError/checkmultisig_in_function.cash b/packages/cashc/test/compiler/UnsafeFunctionOperationError/checkmultisig_in_function.cash new file mode 100644 index 00000000..d2a20087 --- /dev/null +++ b/packages/cashc/test/compiler/UnsafeFunctionOperationError/checkmultisig_in_function.cash @@ -0,0 +1,9 @@ +function verifyMulti(sig s1, sig s2, pubkey pk1, pubkey pk2) returns (bool) { + return checkMultiSig([s1, s2], [pk1, pk2]); +} + +contract Test() { + function spend(sig s1, sig s2, pubkey pk1, pubkey pk2) { + require(verifyMulti(s1, s2, pk1, pk2)); + } +} diff --git a/packages/cashc/test/compiler/UnsafeFunctionOperationError/checksig_in_function.cash b/packages/cashc/test/compiler/UnsafeFunctionOperationError/checksig_in_function.cash new file mode 100644 index 00000000..ddd69039 --- /dev/null +++ b/packages/cashc/test/compiler/UnsafeFunctionOperationError/checksig_in_function.cash @@ -0,0 +1,9 @@ +function verify(sig s, pubkey pk) returns (bool) { + return checkSig(s, pk); +} + +contract Test() { + function spend(sig s, pubkey pk) { + require(verify(s, pk)); + } +} diff --git a/packages/cashc/test/valid-contract-files/checkdatasig_in_function.cash b/packages/cashc/test/valid-contract-files/checkdatasig_in_function.cash new file mode 100644 index 00000000..0ba76f2e --- /dev/null +++ b/packages/cashc/test/valid-contract-files/checkdatasig_in_function.cash @@ -0,0 +1,9 @@ +function verifyData(datasig s, bytes message, pubkey pk) returns (bool) { + return checkDataSig(s, message, pk); +} + +contract Test() { + function spend(datasig s, bytes message, pubkey pk) { + require(verifyData(s, message, pk)); + } +} diff --git a/website/docs/language/contracts.md b/website/docs/language/contracts.md index c9ff2a29..e160d30a 100644 --- a/website/docs/language/contracts.md +++ b/website/docs/language/contracts.md @@ -141,11 +141,14 @@ contract Main() { Imported function names share a single global namespace, so a name may only be defined once across the whole import graph. Files reached through more than one import path (diamond imports) are resolved once. +:::info +`checkSig`, `checkMultiSig` and `this.activeBytecode` cannot be used inside a user-defined function, since they would apply to the function body rather than the contract. Use them in a contract function instead (`checkDataSig` is allowed). +::: + ### Limitations This first version of user-defined functions is intentionally limited in scope: - Functions return **at most one value** (no multiple/tuple returns), and a value-returning function must end with a single `return` statement (no early or conditional returns — compute into a variable and return it at the end). -- No safety checks are present to prevent functions from calling each other recursively or disallow signature checks inside functions. - No advanced optimisations are performed yet on user-defined functions. - The local debugging tools in the SDK don't properly support user-defined functions yet.