/* AutoGenerated Code, changes may be overwritten * INPUT GRAMMAR: * Program := Statement* PROGRAM_END * Statement := Enum | Interface | Module | Expression * Module := 'EVERYTHING' _ 'CHANGED' _ 'WHEN' _ name=PASCAL_CASE _ 'EXISTS' _ SCOPE_START _ body=ModuleBody _ SCOPE_END * ModuleBody := Constructor? _? Declaration* * Constructor := 'PRACTICALLY' _ 'IMPOSSIBLE' _ 'TO' _ 'HAVE' _ module=Identifier _ 'WITHOUT' _ args=ArgList _ SCOPE_START _ body=FunctionBody _ SCOPE_END * Expression := FunctionCall | BinaryExpression | UnaryOperation | Literal | Declaration * FunctionCall := name=Identifier _ 'OF' _ args={{Expression _? COMMA _?}* Expression} * BinaryExpression := left=Expression op=BinaryOperation right=Expression * BinaryOperation := ArithmeticOperation | ComparisonOperation | BooleanOperation * ArithmeticOperation := '\+' | '\-' | '/' | '\%' | '\*\*' | '\*' | '>>' | '<<' * ComparisonOperation := '<' | '>' | '<=' | '>=' * BooleanOperation := '||' | '|' | '&&' | '&' * Declaration := VarDeclaration | FunctionDeclaration * VarDeclaration := 'EXPERTS' _ 'CLAIM' _ var=CAMEL_CASE _ 'TO' _ 'BE' _ Type _ val={option=OptionMatch | 'OF' _ expr=Expression} * OptionMatch := 'WHO' _ 'IS' _ 'DATING' _ SCOPE_START _ {some=SomeMatch _ none=NoneMatch} | {none=NoneMatch _ some=SomeMatch} _ SCOPE_END * SomeMatch := 'Someone' LPAREN name=Identifier RPAREN _ 'SO' _ expr=Expression * NoneMatch := 'Nobody' _ 'SO' _ expr=Expression * Literal := String | Integer | Float | StructInit | Identifier * String := '(["\'])(?:(?=(\\?))\2.)*?\1' * Integer := '^-?0*\d+$' * Float := '^-?\d+(\.\d+)?$' * UnaryOperation := PrefixOperation Expression | Expression PostfixOperation * PrefixOperation := '!' | '~' * PostfixOperation := LBRACKET index=POSITIVE_INT RBRACKET * StructInit := 'STUFF' _ 'MADE' _ 'OF' _ SCOPE_START _ init=Declaration* _ SCOPE_END * Type := name={PASCAL_CASE} | {name=PASCAL_CASE _ generic=Generic} | {tupleType=Type _ LBRACKET _ tupleLength=POSITIVE_INT _ RBRACKET} | union={Type _ 'OR' _ Type} * Generic := LPAREN _? generic={{Type _? COMMA _?}* Type} RPAREN * FunctionDeclaration := FunctionSignature _ SCOPE_START _ body=FunctionBody _ SCOPE_END * FunctionBody := {Expression | ReturnStatement}* * FunctionSignature := 'DISCOVER' _ 'HOW' _ 'TO' _ name=CAMEL_CASE _ 'WITH' _ args=ArgList _ 'GIVES' _ 'YOU' _ return=Type * ArgList := args={{type=Type name=CAMEL_CASE COMMA _?}* type=Type name=CAMEL_CASE} * ReturnStatement := 'SHOCKING' _ 'DEVELOPMENT' _ Expression * Interface := 'STUFF' _ 'OF' _ name=PASCAL_CASE _ 'LOOKS' _ 'LIKE' SCOPE_START methods={ FunctionSignature* } * Enum := 'ONLY' _ 'OPTIONS' _ 'OF' name=PASCAL_CASE _ 'ARE' _ SCOPE_START _ options=EnumBody* _ SCOPE_END * EnumBody := name=Identifier COMMA * Identifier := '[a-zA-Z][\w\d|\.]*' * SCOPE_START := 'RUMOR' _ 'HAS' _ 'IT' * SCOPE_END := 'END' _ 'OF' _ 'STORY' * PROGRAM_END := 'PLEASE' _ 'LIKE' _ 'AND' _ 'SUBSCRIBE' * PASCAL_CASE := '[A-Z][\w\d]*' * CAMEL_CASE := '[a-z][\w\d]*' * LPAREN := '\(' * RPAREN := '\)' * LBRACKET := '\[' * RBRACKET := '\]' * COMMA := ',' * POSITIVE_INT := '^[1-9][0-9]*$' * _ := '\s' */ type Nullable = T | null; type $$RuleType = () => Nullable; export interface ASTNodeIntf { kind: ASTKinds; } export enum ASTKinds { Program = "Program", Statement_1 = "Statement_1", Statement_2 = "Statement_2", Statement_3 = "Statement_3", Statement_4 = "Statement_4", Module = "Module", ModuleBody = "ModuleBody", Constructor = "Constructor", Expression_1 = "Expression_1", Expression_2 = "Expression_2", Expression_3 = "Expression_3", Expression_4 = "Expression_4", Expression_5 = "Expression_5", FunctionCall = "FunctionCall", FunctionCall_$0 = "FunctionCall_$0", FunctionCall_$0_$0 = "FunctionCall_$0_$0", BinaryExpression = "BinaryExpression", BinaryOperation_1 = "BinaryOperation_1", BinaryOperation_2 = "BinaryOperation_2", BinaryOperation_3 = "BinaryOperation_3", ArithmeticOperation_1 = "ArithmeticOperation_1", ArithmeticOperation_2 = "ArithmeticOperation_2", ArithmeticOperation_3 = "ArithmeticOperation_3", ArithmeticOperation_4 = "ArithmeticOperation_4", ArithmeticOperation_5 = "ArithmeticOperation_5", ArithmeticOperation_6 = "ArithmeticOperation_6", ArithmeticOperation_7 = "ArithmeticOperation_7", ArithmeticOperation_8 = "ArithmeticOperation_8", ComparisonOperation_1 = "ComparisonOperation_1", ComparisonOperation_2 = "ComparisonOperation_2", ComparisonOperation_3 = "ComparisonOperation_3", ComparisonOperation_4 = "ComparisonOperation_4", BooleanOperation_1 = "BooleanOperation_1", BooleanOperation_2 = "BooleanOperation_2", BooleanOperation_3 = "BooleanOperation_3", BooleanOperation_4 = "BooleanOperation_4", Declaration_1 = "Declaration_1", Declaration_2 = "Declaration_2", VarDeclaration = "VarDeclaration", VarDeclaration_$0_1 = "VarDeclaration_$0_1", VarDeclaration_$0_2 = "VarDeclaration_$0_2", OptionMatch_1 = "OptionMatch_1", OptionMatch_2 = "OptionMatch_2", OptionMatch_$0 = "OptionMatch_$0", OptionMatch_$1 = "OptionMatch_$1", SomeMatch = "SomeMatch", NoneMatch = "NoneMatch", Literal_1 = "Literal_1", Literal_2 = "Literal_2", Literal_3 = "Literal_3", Literal_4 = "Literal_4", Literal_5 = "Literal_5", String = "String", Integer = "Integer", Float = "Float", UnaryOperation_1 = "UnaryOperation_1", UnaryOperation_2 = "UnaryOperation_2", PrefixOperation_1 = "PrefixOperation_1", PrefixOperation_2 = "PrefixOperation_2", PostfixOperation = "PostfixOperation", StructInit = "StructInit", Type_1 = "Type_1", Type_2 = "Type_2", Type_3 = "Type_3", Type_4 = "Type_4", Type_$0 = "Type_$0", Type_$1 = "Type_$1", Type_$2 = "Type_$2", Type_$3 = "Type_$3", Generic = "Generic", Generic_$0 = "Generic_$0", Generic_$0_$0 = "Generic_$0_$0", FunctionDeclaration = "FunctionDeclaration", FunctionBody = "FunctionBody", FunctionBody_$0_1 = "FunctionBody_$0_1", FunctionBody_$0_2 = "FunctionBody_$0_2", FunctionSignature = "FunctionSignature", ArgList = "ArgList", ArgList_$0 = "ArgList_$0", ArgList_$0_$0 = "ArgList_$0_$0", ReturnStatement = "ReturnStatement", Interface = "Interface", Interface_$0 = "Interface_$0", Enum = "Enum", EnumBody = "EnumBody", Identifier = "Identifier", SCOPE_START = "SCOPE_START", SCOPE_END = "SCOPE_END", PROGRAM_END = "PROGRAM_END", PASCAL_CASE = "PASCAL_CASE", CAMEL_CASE = "CAMEL_CASE", LPAREN = "LPAREN", RPAREN = "RPAREN", LBRACKET = "LBRACKET", RBRACKET = "RBRACKET", COMMA = "COMMA", POSITIVE_INT = "POSITIVE_INT", _ = "_", } export interface Program { kind: ASTKinds.Program; } export type Statement = Statement_1 | Statement_2 | Statement_3 | Statement_4; export type Statement_1 = Enum; export type Statement_2 = Interface; export type Statement_3 = Module; export type Statement_4 = Expression; export interface Module { kind: ASTKinds.Module; name: PASCAL_CASE; body: ModuleBody; } export interface ModuleBody { kind: ASTKinds.ModuleBody; } export interface Constructor { kind: ASTKinds.Constructor; module: Identifier; args: ArgList; body: FunctionBody; } export type Expression = Expression_1 | Expression_2 | Expression_3 | Expression_4 | Expression_5; export type Expression_1 = FunctionCall; export type Expression_2 = BinaryExpression; export type Expression_3 = UnaryOperation; export type Expression_4 = Literal; export type Expression_5 = Declaration; export interface FunctionCall { kind: ASTKinds.FunctionCall; name: Identifier; args: FunctionCall_$0; } export interface FunctionCall_$0 { kind: ASTKinds.FunctionCall_$0; } export interface FunctionCall_$0_$0 { kind: ASTKinds.FunctionCall_$0_$0; } export interface BinaryExpression { kind: ASTKinds.BinaryExpression; left: Expression; op: BinaryOperation; right: Expression; } export type BinaryOperation = BinaryOperation_1 | BinaryOperation_2 | BinaryOperation_3; export type BinaryOperation_1 = ArithmeticOperation; export type BinaryOperation_2 = ComparisonOperation; export type BinaryOperation_3 = BooleanOperation; export type ArithmeticOperation = ArithmeticOperation_1 | ArithmeticOperation_2 | ArithmeticOperation_3 | ArithmeticOperation_4 | ArithmeticOperation_5 | ArithmeticOperation_6 | ArithmeticOperation_7 | ArithmeticOperation_8; export type ArithmeticOperation_1 = string; export type ArithmeticOperation_2 = string; export type ArithmeticOperation_3 = string; export type ArithmeticOperation_4 = string; export type ArithmeticOperation_5 = string; export type ArithmeticOperation_6 = string; export type ArithmeticOperation_7 = string; export type ArithmeticOperation_8 = string; export type ComparisonOperation = ComparisonOperation_1 | ComparisonOperation_2 | ComparisonOperation_3 | ComparisonOperation_4; export type ComparisonOperation_1 = string; export type ComparisonOperation_2 = string; export type ComparisonOperation_3 = string; export type ComparisonOperation_4 = string; export type BooleanOperation = BooleanOperation_1 | BooleanOperation_2 | BooleanOperation_3 | BooleanOperation_4; export type BooleanOperation_1 = string; export type BooleanOperation_2 = string; export type BooleanOperation_3 = string; export type BooleanOperation_4 = string; export type Declaration = Declaration_1 | Declaration_2; export type Declaration_1 = VarDeclaration; export type Declaration_2 = FunctionDeclaration; export interface VarDeclaration { kind: ASTKinds.VarDeclaration; var: CAMEL_CASE; val: VarDeclaration_$0; } export type VarDeclaration_$0 = VarDeclaration_$0_1 | VarDeclaration_$0_2; export interface VarDeclaration_$0_1 { kind: ASTKinds.VarDeclaration_$0_1; option: OptionMatch; } export interface VarDeclaration_$0_2 { kind: ASTKinds.VarDeclaration_$0_2; expr: Expression; } export type OptionMatch = OptionMatch_1 | OptionMatch_2; export interface OptionMatch_1 { kind: ASTKinds.OptionMatch_1; } export interface OptionMatch_2 { kind: ASTKinds.OptionMatch_2; } export interface OptionMatch_$0 { kind: ASTKinds.OptionMatch_$0; some: SomeMatch; none: NoneMatch; } export interface OptionMatch_$1 { kind: ASTKinds.OptionMatch_$1; none: NoneMatch; some: SomeMatch; } export interface SomeMatch { kind: ASTKinds.SomeMatch; name: Identifier; expr: Expression; } export interface NoneMatch { kind: ASTKinds.NoneMatch; expr: Expression; } export type Literal = Literal_1 | Literal_2 | Literal_3 | Literal_4 | Literal_5; export type Literal_1 = String; export type Literal_2 = Integer; export type Literal_3 = Float; export type Literal_4 = StructInit; export type Literal_5 = Identifier; export type String = string; export type Integer = string; export type Float = string; export type UnaryOperation = UnaryOperation_1 | UnaryOperation_2; export interface UnaryOperation_1 { kind: ASTKinds.UnaryOperation_1; } export interface UnaryOperation_2 { kind: ASTKinds.UnaryOperation_2; } export type PrefixOperation = PrefixOperation_1 | PrefixOperation_2; export type PrefixOperation_1 = string; export type PrefixOperation_2 = string; export interface PostfixOperation { kind: ASTKinds.PostfixOperation; index: POSITIVE_INT; } export interface StructInit { kind: ASTKinds.StructInit; init: Declaration[]; } export type Type = Type_1 | Type_2 | Type_3 | Type_4; export interface Type_1 { kind: ASTKinds.Type_1; name: Type_$0; } export type Type_2 = Type_$1; export type Type_3 = Type_$2; export interface Type_4 { kind: ASTKinds.Type_4; union: Type_$3; } export type Type_$0 = PASCAL_CASE; export interface Type_$1 { kind: ASTKinds.Type_$1; name: PASCAL_CASE; generic: Generic; } export interface Type_$2 { kind: ASTKinds.Type_$2; tupleType: Type; tupleLength: POSITIVE_INT; } export interface Type_$3 { kind: ASTKinds.Type_$3; } export interface Generic { kind: ASTKinds.Generic; generic: Generic_$0; } export interface Generic_$0 { kind: ASTKinds.Generic_$0; } export interface Generic_$0_$0 { kind: ASTKinds.Generic_$0_$0; } export interface FunctionDeclaration { kind: ASTKinds.FunctionDeclaration; body: FunctionBody; } export type FunctionBody = FunctionBody_$0[]; export type FunctionBody_$0 = FunctionBody_$0_1 | FunctionBody_$0_2; export type FunctionBody_$0_1 = Expression; export type FunctionBody_$0_2 = ReturnStatement; export interface FunctionSignature { kind: ASTKinds.FunctionSignature; name: CAMEL_CASE; args: ArgList; return: Type; } export interface ArgList { kind: ASTKinds.ArgList; args: ArgList_$0; } export interface ArgList_$0 { kind: ASTKinds.ArgList_$0; type: Type; name: CAMEL_CASE; } export interface ArgList_$0_$0 { kind: ASTKinds.ArgList_$0_$0; type: Type; name: CAMEL_CASE; } export interface ReturnStatement { kind: ASTKinds.ReturnStatement; } export interface Interface { kind: ASTKinds.Interface; name: PASCAL_CASE; methods: Interface_$0; } export type Interface_$0 = FunctionSignature[]; export interface Enum { kind: ASTKinds.Enum; name: PASCAL_CASE; options: EnumBody[]; } export interface EnumBody { kind: ASTKinds.EnumBody; name: Identifier; } export type Identifier = string; export interface SCOPE_START { kind: ASTKinds.SCOPE_START; } export interface SCOPE_END { kind: ASTKinds.SCOPE_END; } export interface PROGRAM_END { kind: ASTKinds.PROGRAM_END; } export type PASCAL_CASE = string; export type CAMEL_CASE = string; export type LPAREN = string; export type RPAREN = string; export type LBRACKET = string; export type RBRACKET = string; export type COMMA = string; export type POSITIVE_INT = string; export type _ = string; export class Parser { private readonly input: string; private pos: PosInfo; private negating: boolean = false; private memoSafe: boolean = true; constructor(input: string) { this.pos = {overallPos: 0, line: 1, offset: 0}; this.input = input; } public reset(pos: PosInfo) { this.pos = pos; } public finished(): boolean { return this.pos.overallPos === this.input.length; } public clearMemos(): void { this.$scope$Program$memo.clear(); this.$scope$Statement$memo.clear(); this.$scope$Module$memo.clear(); this.$scope$ModuleBody$memo.clear(); this.$scope$Constructor$memo.clear(); this.$scope$Expression$memo.clear(); this.$scope$FunctionCall$memo.clear(); this.$scope$FunctionCall_$0$memo.clear(); this.$scope$FunctionCall_$0_$0$memo.clear(); this.$scope$BinaryExpression$memo.clear(); this.$scope$BinaryOperation$memo.clear(); this.$scope$ArithmeticOperation$memo.clear(); this.$scope$ComparisonOperation$memo.clear(); this.$scope$BooleanOperation$memo.clear(); this.$scope$Declaration$memo.clear(); this.$scope$VarDeclaration$memo.clear(); this.$scope$VarDeclaration_$0$memo.clear(); this.$scope$OptionMatch$memo.clear(); this.$scope$OptionMatch_$0$memo.clear(); this.$scope$OptionMatch_$1$memo.clear(); this.$scope$SomeMatch$memo.clear(); this.$scope$NoneMatch$memo.clear(); this.$scope$Literal$memo.clear(); this.$scope$String$memo.clear(); this.$scope$Integer$memo.clear(); this.$scope$Float$memo.clear(); this.$scope$UnaryOperation$memo.clear(); this.$scope$PrefixOperation$memo.clear(); this.$scope$PostfixOperation$memo.clear(); this.$scope$StructInit$memo.clear(); this.$scope$Type$memo.clear(); this.$scope$Type_$0$memo.clear(); this.$scope$Type_$1$memo.clear(); this.$scope$Type_$2$memo.clear(); this.$scope$Type_$3$memo.clear(); this.$scope$Generic$memo.clear(); this.$scope$Generic_$0$memo.clear(); this.$scope$Generic_$0_$0$memo.clear(); this.$scope$FunctionDeclaration$memo.clear(); this.$scope$FunctionBody$memo.clear(); this.$scope$FunctionBody_$0$memo.clear(); this.$scope$FunctionSignature$memo.clear(); this.$scope$ArgList$memo.clear(); this.$scope$ArgList_$0$memo.clear(); this.$scope$ArgList_$0_$0$memo.clear(); this.$scope$ReturnStatement$memo.clear(); this.$scope$Interface$memo.clear(); this.$scope$Interface_$0$memo.clear(); this.$scope$Enum$memo.clear(); this.$scope$EnumBody$memo.clear(); this.$scope$Identifier$memo.clear(); this.$scope$SCOPE_START$memo.clear(); this.$scope$SCOPE_END$memo.clear(); this.$scope$PROGRAM_END$memo.clear(); this.$scope$PASCAL_CASE$memo.clear(); this.$scope$CAMEL_CASE$memo.clear(); this.$scope$LPAREN$memo.clear(); this.$scope$RPAREN$memo.clear(); this.$scope$LBRACKET$memo.clear(); this.$scope$RBRACKET$memo.clear(); this.$scope$COMMA$memo.clear(); this.$scope$POSITIVE_INT$memo.clear(); this.$scope$_$memo.clear(); } protected $scope$Program$memo: Map, PosInfo]> = new Map(); protected $scope$Statement$memo: Map, PosInfo]> = new Map(); protected $scope$Module$memo: Map, PosInfo]> = new Map(); protected $scope$ModuleBody$memo: Map, PosInfo]> = new Map(); protected $scope$Constructor$memo: Map, PosInfo]> = new Map(); protected $scope$Expression$memo: Map, PosInfo]> = new Map(); protected $scope$FunctionCall$memo: Map, PosInfo]> = new Map(); protected $scope$FunctionCall_$0$memo: Map, PosInfo]> = new Map(); protected $scope$FunctionCall_$0_$0$memo: Map, PosInfo]> = new Map(); protected $scope$BinaryExpression$memo: Map, PosInfo]> = new Map(); protected $scope$BinaryOperation$memo: Map, PosInfo]> = new Map(); protected $scope$ArithmeticOperation$memo: Map, PosInfo]> = new Map(); protected $scope$ComparisonOperation$memo: Map, PosInfo]> = new Map(); protected $scope$BooleanOperation$memo: Map, PosInfo]> = new Map(); protected $scope$Declaration$memo: Map, PosInfo]> = new Map(); protected $scope$VarDeclaration$memo: Map, PosInfo]> = new Map(); protected $scope$VarDeclaration_$0$memo: Map, PosInfo]> = new Map(); protected $scope$OptionMatch$memo: Map, PosInfo]> = new Map(); protected $scope$OptionMatch_$0$memo: Map, PosInfo]> = new Map(); protected $scope$OptionMatch_$1$memo: Map, PosInfo]> = new Map(); protected $scope$SomeMatch$memo: Map, PosInfo]> = new Map(); protected $scope$NoneMatch$memo: Map, PosInfo]> = new Map(); protected $scope$Literal$memo: Map, PosInfo]> = new Map(); protected $scope$String$memo: Map, PosInfo]> = new Map(); protected $scope$Integer$memo: Map, PosInfo]> = new Map(); protected $scope$Float$memo: Map, PosInfo]> = new Map(); protected $scope$UnaryOperation$memo: Map, PosInfo]> = new Map(); protected $scope$PrefixOperation$memo: Map, PosInfo]> = new Map(); protected $scope$PostfixOperation$memo: Map, PosInfo]> = new Map(); protected $scope$StructInit$memo: Map, PosInfo]> = new Map(); protected $scope$Type$memo: Map, PosInfo]> = new Map(); protected $scope$Type_$0$memo: Map, PosInfo]> = new Map(); protected $scope$Type_$1$memo: Map, PosInfo]> = new Map(); protected $scope$Type_$2$memo: Map, PosInfo]> = new Map(); protected $scope$Type_$3$memo: Map, PosInfo]> = new Map(); protected $scope$Generic$memo: Map, PosInfo]> = new Map(); protected $scope$Generic_$0$memo: Map, PosInfo]> = new Map(); protected $scope$Generic_$0_$0$memo: Map, PosInfo]> = new Map(); protected $scope$FunctionDeclaration$memo: Map, PosInfo]> = new Map(); protected $scope$FunctionBody$memo: Map, PosInfo]> = new Map(); protected $scope$FunctionBody_$0$memo: Map, PosInfo]> = new Map(); protected $scope$FunctionSignature$memo: Map, PosInfo]> = new Map(); protected $scope$ArgList$memo: Map, PosInfo]> = new Map(); protected $scope$ArgList_$0$memo: Map, PosInfo]> = new Map(); protected $scope$ArgList_$0_$0$memo: Map, PosInfo]> = new Map(); protected $scope$ReturnStatement$memo: Map, PosInfo]> = new Map(); protected $scope$Interface$memo: Map, PosInfo]> = new Map(); protected $scope$Interface_$0$memo: Map, PosInfo]> = new Map(); protected $scope$Enum$memo: Map, PosInfo]> = new Map(); protected $scope$EnumBody$memo: Map, PosInfo]> = new Map(); protected $scope$Identifier$memo: Map, PosInfo]> = new Map(); protected $scope$SCOPE_START$memo: Map, PosInfo]> = new Map(); protected $scope$SCOPE_END$memo: Map, PosInfo]> = new Map(); protected $scope$PROGRAM_END$memo: Map, PosInfo]> = new Map(); protected $scope$PASCAL_CASE$memo: Map, PosInfo]> = new Map(); protected $scope$CAMEL_CASE$memo: Map, PosInfo]> = new Map(); protected $scope$LPAREN$memo: Map, PosInfo]> = new Map(); protected $scope$RPAREN$memo: Map, PosInfo]> = new Map(); protected $scope$LBRACKET$memo: Map, PosInfo]> = new Map(); protected $scope$RBRACKET$memo: Map, PosInfo]> = new Map(); protected $scope$COMMA$memo: Map, PosInfo]> = new Map(); protected $scope$POSITIVE_INT$memo: Map, PosInfo]> = new Map(); protected $scope$_$memo: Map, PosInfo]> = new Map(); public matchProgram($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.loop(() => this.matchStatement($$dpth + 1, $$cr), 0, -1) !== null && this.matchPROGRAM_END($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Program, }; } return $$res; }); }, this.$scope$Program$memo, ); } public matchStatement($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchStatement_1($$dpth + 1, $$cr), () => this.matchStatement_2($$dpth + 1, $$cr), () => this.matchStatement_3($$dpth + 1, $$cr), () => this.matchStatement_4($$dpth + 1, $$cr), ]); }, this.$scope$Statement$memo, ); } public matchStatement_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchEnum($$dpth + 1, $$cr); } public matchStatement_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchInterface($$dpth + 1, $$cr); } public matchStatement_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchModule($$dpth + 1, $$cr); } public matchStatement_4($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchExpression($$dpth + 1, $$cr); } public matchModule($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $scope$body: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:EVERYTHING)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:CHANGED)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:WHEN)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$name = this.matchPASCAL_CASE($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:EXISTS)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_START($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$body = this.matchModuleBody($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_END($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Module, name: $scope$name, body: $scope$body}; } return $$res; }); }, this.$scope$Module$memo, ); } public matchModuleBody($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && ((this.matchConstructor($$dpth + 1, $$cr)) || true) && ((this.match_($$dpth + 1, $$cr)) || true) && this.loop(() => this.matchDeclaration($$dpth + 1, $$cr), 0, -1) !== null ) { $$res = {kind: ASTKinds.ModuleBody, }; } return $$res; }); }, this.$scope$ModuleBody$memo, ); } public matchConstructor($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$module: Nullable; let $scope$args: Nullable; let $scope$body: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:PRACTICALLY)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:IMPOSSIBLE)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:TO)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:HAVE)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$module = this.matchIdentifier($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:WITHOUT)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$args = this.matchArgList($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_START($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$body = this.matchFunctionBody($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_END($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Constructor, module: $scope$module, args: $scope$args, body: $scope$body}; } return $$res; }); }, this.$scope$Constructor$memo, ); } public matchExpression($$dpth: number, $$cr?: ErrorTracker): Nullable { const fn = () => { return this.choice([ () => this.matchExpression_1($$dpth + 1, $$cr), () => this.matchExpression_2($$dpth + 1, $$cr), () => this.matchExpression_3($$dpth + 1, $$cr), () => this.matchExpression_4($$dpth + 1, $$cr), () => this.matchExpression_5($$dpth + 1, $$cr), ]); }; const $scope$pos = this.mark(); const memo = this.$scope$Expression$memo.get($scope$pos.overallPos); if(memo !== undefined) { this.reset(memo[1]); return memo[0]; } const $scope$oldMemoSafe = this.memoSafe; this.memoSafe = false; this.$scope$Expression$memo.set($scope$pos.overallPos, [null, $scope$pos]); let lastRes: Nullable = null; let lastPos: PosInfo = $scope$pos; for(;;) { this.reset($scope$pos); const res = fn(); const end = this.mark(); if(end.overallPos <= lastPos.overallPos) break; lastRes = res; lastPos = end; this.$scope$Expression$memo.set($scope$pos.overallPos, [lastRes, lastPos]); } this.reset(lastPos); this.memoSafe = $scope$oldMemoSafe; return lastRes; } public matchExpression_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchFunctionCall($$dpth + 1, $$cr); } public matchExpression_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchBinaryExpression($$dpth + 1, $$cr); } public matchExpression_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchUnaryOperation($$dpth + 1, $$cr); } public matchExpression_4($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchLiteral($$dpth + 1, $$cr); } public matchExpression_5($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchDeclaration($$dpth + 1, $$cr); } public matchFunctionCall($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $scope$args: Nullable; let $$res: Nullable = null; if (true && ($scope$name = this.matchIdentifier($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:OF)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$args = this.matchFunctionCall_$0($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.FunctionCall, name: $scope$name, args: $scope$args}; } return $$res; }); }, this.$scope$FunctionCall$memo, ); } public matchFunctionCall_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.loop(() => this.matchFunctionCall_$0_$0($$dpth + 1, $$cr), 0, -1) !== null && this.matchExpression($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.FunctionCall_$0, }; } return $$res; }); }, this.$scope$FunctionCall_$0$memo, ); } public matchFunctionCall_$0_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.matchExpression($$dpth + 1, $$cr) !== null && ((this.match_($$dpth + 1, $$cr)) || true) && this.matchCOMMA($$dpth + 1, $$cr) !== null && ((this.match_($$dpth + 1, $$cr)) || true) ) { $$res = {kind: ASTKinds.FunctionCall_$0_$0, }; } return $$res; }); }, this.$scope$FunctionCall_$0_$0$memo, ); } public matchBinaryExpression($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$left: Nullable; let $scope$op: Nullable; let $scope$right: Nullable; let $$res: Nullable = null; if (true && ($scope$left = this.matchExpression($$dpth + 1, $$cr)) !== null && ($scope$op = this.matchBinaryOperation($$dpth + 1, $$cr)) !== null && ($scope$right = this.matchExpression($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.BinaryExpression, left: $scope$left, op: $scope$op, right: $scope$right}; } return $$res; }); }, this.$scope$BinaryExpression$memo, ); } public matchBinaryOperation($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchBinaryOperation_1($$dpth + 1, $$cr), () => this.matchBinaryOperation_2($$dpth + 1, $$cr), () => this.matchBinaryOperation_3($$dpth + 1, $$cr), ]); }, this.$scope$BinaryOperation$memo, ); } public matchBinaryOperation_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchArithmeticOperation($$dpth + 1, $$cr); } public matchBinaryOperation_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchComparisonOperation($$dpth + 1, $$cr); } public matchBinaryOperation_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchBooleanOperation($$dpth + 1, $$cr); } public matchArithmeticOperation($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchArithmeticOperation_1($$dpth + 1, $$cr), () => this.matchArithmeticOperation_2($$dpth + 1, $$cr), () => this.matchArithmeticOperation_3($$dpth + 1, $$cr), () => this.matchArithmeticOperation_4($$dpth + 1, $$cr), () => this.matchArithmeticOperation_5($$dpth + 1, $$cr), () => this.matchArithmeticOperation_6($$dpth + 1, $$cr), () => this.matchArithmeticOperation_7($$dpth + 1, $$cr), () => this.matchArithmeticOperation_8($$dpth + 1, $$cr), ]); }, this.$scope$ArithmeticOperation$memo, ); } public matchArithmeticOperation_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:\+)`, "", $$dpth + 1, $$cr); } public matchArithmeticOperation_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:\-)`, "", $$dpth + 1, $$cr); } public matchArithmeticOperation_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:/)`, "", $$dpth + 1, $$cr); } public matchArithmeticOperation_4($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:\%)`, "", $$dpth + 1, $$cr); } public matchArithmeticOperation_5($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:\*\*)`, "", $$dpth + 1, $$cr); } public matchArithmeticOperation_6($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:\*)`, "", $$dpth + 1, $$cr); } public matchArithmeticOperation_7($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:>>)`, "", $$dpth + 1, $$cr); } public matchArithmeticOperation_8($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:<<)`, "", $$dpth + 1, $$cr); } public matchComparisonOperation($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchComparisonOperation_1($$dpth + 1, $$cr), () => this.matchComparisonOperation_2($$dpth + 1, $$cr), () => this.matchComparisonOperation_3($$dpth + 1, $$cr), () => this.matchComparisonOperation_4($$dpth + 1, $$cr), ]); }, this.$scope$ComparisonOperation$memo, ); } public matchComparisonOperation_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:<)`, "", $$dpth + 1, $$cr); } public matchComparisonOperation_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:>)`, "", $$dpth + 1, $$cr); } public matchComparisonOperation_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:<=)`, "", $$dpth + 1, $$cr); } public matchComparisonOperation_4($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:>=)`, "", $$dpth + 1, $$cr); } public matchBooleanOperation($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchBooleanOperation_1($$dpth + 1, $$cr), () => this.matchBooleanOperation_2($$dpth + 1, $$cr), () => this.matchBooleanOperation_3($$dpth + 1, $$cr), () => this.matchBooleanOperation_4($$dpth + 1, $$cr), ]); }, this.$scope$BooleanOperation$memo, ); } public matchBooleanOperation_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:||)`, "", $$dpth + 1, $$cr); } public matchBooleanOperation_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:|)`, "", $$dpth + 1, $$cr); } public matchBooleanOperation_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:&&)`, "", $$dpth + 1, $$cr); } public matchBooleanOperation_4($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:&)`, "", $$dpth + 1, $$cr); } public matchDeclaration($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchDeclaration_1($$dpth + 1, $$cr), () => this.matchDeclaration_2($$dpth + 1, $$cr), ]); }, this.$scope$Declaration$memo, ); } public matchDeclaration_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchVarDeclaration($$dpth + 1, $$cr); } public matchDeclaration_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchFunctionDeclaration($$dpth + 1, $$cr); } public matchVarDeclaration($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$var: Nullable; let $scope$val: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:EXPERTS)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:CLAIM)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$var = this.matchCAMEL_CASE($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:TO)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:BE)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchType($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$val = this.matchVarDeclaration_$0($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.VarDeclaration, var: $scope$var, val: $scope$val}; } return $$res; }); }, this.$scope$VarDeclaration$memo, ); } public matchVarDeclaration_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchVarDeclaration_$0_1($$dpth + 1, $$cr), () => this.matchVarDeclaration_$0_2($$dpth + 1, $$cr), ]); }, this.$scope$VarDeclaration_$0$memo, ); } public matchVarDeclaration_$0_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $scope$option: Nullable; let $$res: Nullable = null; if (true && ($scope$option = this.matchOptionMatch($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.VarDeclaration_$0_1, option: $scope$option}; } return $$res; }); } public matchVarDeclaration_$0_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $scope$expr: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:OF)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$expr = this.matchExpression($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.VarDeclaration_$0_2, expr: $scope$expr}; } return $$res; }); } public matchOptionMatch($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchOptionMatch_1($$dpth + 1, $$cr), () => this.matchOptionMatch_2($$dpth + 1, $$cr), ]); }, this.$scope$OptionMatch$memo, ); } public matchOptionMatch_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:WHO)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:IS)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:DATING)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_START($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchOptionMatch_$0($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.OptionMatch_1, }; } return $$res; }); } public matchOptionMatch_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.matchOptionMatch_$1($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_END($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.OptionMatch_2, }; } return $$res; }); } public matchOptionMatch_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$some: Nullable; let $scope$none: Nullable; let $$res: Nullable = null; if (true && ($scope$some = this.matchSomeMatch($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$none = this.matchNoneMatch($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.OptionMatch_$0, some: $scope$some, none: $scope$none}; } return $$res; }); }, this.$scope$OptionMatch_$0$memo, ); } public matchOptionMatch_$1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$none: Nullable; let $scope$some: Nullable; let $$res: Nullable = null; if (true && ($scope$none = this.matchNoneMatch($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$some = this.matchSomeMatch($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.OptionMatch_$1, none: $scope$none, some: $scope$some}; } return $$res; }); }, this.$scope$OptionMatch_$1$memo, ); } public matchSomeMatch($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $scope$expr: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:Someone)`, "", $$dpth + 1, $$cr) !== null && this.matchLPAREN($$dpth + 1, $$cr) !== null && ($scope$name = this.matchIdentifier($$dpth + 1, $$cr)) !== null && this.matchRPAREN($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:SO)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$expr = this.matchExpression($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.SomeMatch, name: $scope$name, expr: $scope$expr}; } return $$res; }); }, this.$scope$SomeMatch$memo, ); } public matchNoneMatch($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$expr: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:Nobody)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:SO)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$expr = this.matchExpression($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.NoneMatch, expr: $scope$expr}; } return $$res; }); }, this.$scope$NoneMatch$memo, ); } public matchLiteral($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchLiteral_1($$dpth + 1, $$cr), () => this.matchLiteral_2($$dpth + 1, $$cr), () => this.matchLiteral_3($$dpth + 1, $$cr), () => this.matchLiteral_4($$dpth + 1, $$cr), () => this.matchLiteral_5($$dpth + 1, $$cr), ]); }, this.$scope$Literal$memo, ); } public matchLiteral_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchString($$dpth + 1, $$cr); } public matchLiteral_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchInteger($$dpth + 1, $$cr); } public matchLiteral_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchFloat($$dpth + 1, $$cr); } public matchLiteral_4($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchStructInit($$dpth + 1, $$cr); } public matchLiteral_5($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchIdentifier($$dpth + 1, $$cr); } public matchString($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:(["\'])(?:(?=(\\?))\2.)*?\1)`, "", $$dpth + 1, $$cr); }, this.$scope$String$memo, ); } public matchInteger($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:^-?0*\d+$)`, "", $$dpth + 1, $$cr); }, this.$scope$Integer$memo, ); } public matchFloat($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:^-?\d+(\.\d+)?$)`, "", $$dpth + 1, $$cr); }, this.$scope$Float$memo, ); } public matchUnaryOperation($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchUnaryOperation_1($$dpth + 1, $$cr), () => this.matchUnaryOperation_2($$dpth + 1, $$cr), ]); }, this.$scope$UnaryOperation$memo, ); } public matchUnaryOperation_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.matchPrefixOperation($$dpth + 1, $$cr) !== null && this.matchExpression($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.UnaryOperation_1, }; } return $$res; }); } public matchUnaryOperation_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.matchExpression($$dpth + 1, $$cr) !== null && this.matchPostfixOperation($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.UnaryOperation_2, }; } return $$res; }); } public matchPrefixOperation($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchPrefixOperation_1($$dpth + 1, $$cr), () => this.matchPrefixOperation_2($$dpth + 1, $$cr), ]); }, this.$scope$PrefixOperation$memo, ); } public matchPrefixOperation_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:!)`, "", $$dpth + 1, $$cr); } public matchPrefixOperation_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.regexAccept(String.raw`(?:~)`, "", $$dpth + 1, $$cr); } public matchPostfixOperation($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$index: Nullable; let $$res: Nullable = null; if (true && this.matchLBRACKET($$dpth + 1, $$cr) !== null && ($scope$index = this.matchPOSITIVE_INT($$dpth + 1, $$cr)) !== null && this.matchRBRACKET($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.PostfixOperation, index: $scope$index}; } return $$res; }); }, this.$scope$PostfixOperation$memo, ); } public matchStructInit($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$init: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:STUFF)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:MADE)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:OF)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_START($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$init = this.loop(() => this.matchDeclaration($$dpth + 1, $$cr), 0, -1)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_END($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.StructInit, init: $scope$init}; } return $$res; }); }, this.$scope$StructInit$memo, ); } public matchType($$dpth: number, $$cr?: ErrorTracker): Nullable { const fn = () => { return this.choice([ () => this.matchType_1($$dpth + 1, $$cr), () => this.matchType_2($$dpth + 1, $$cr), () => this.matchType_3($$dpth + 1, $$cr), () => this.matchType_4($$dpth + 1, $$cr), ]); }; const $scope$pos = this.mark(); const memo = this.$scope$Type$memo.get($scope$pos.overallPos); if(memo !== undefined) { this.reset(memo[1]); return memo[0]; } const $scope$oldMemoSafe = this.memoSafe; this.memoSafe = false; this.$scope$Type$memo.set($scope$pos.overallPos, [null, $scope$pos]); let lastRes: Nullable = null; let lastPos: PosInfo = $scope$pos; for(;;) { this.reset($scope$pos); const res = fn(); const end = this.mark(); if(end.overallPos <= lastPos.overallPos) break; lastRes = res; lastPos = end; this.$scope$Type$memo.set($scope$pos.overallPos, [lastRes, lastPos]); } this.reset(lastPos); this.memoSafe = $scope$oldMemoSafe; return lastRes; } public matchType_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $scope$name: Nullable; let $$res: Nullable = null; if (true && ($scope$name = this.matchType_$0($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.Type_1, name: $scope$name}; } return $$res; }); } public matchType_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchType_$1($$dpth + 1, $$cr); } public matchType_3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchType_$2($$dpth + 1, $$cr); } public matchType_4($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.run($$dpth, () => { let $scope$union: Nullable; let $$res: Nullable = null; if (true && ($scope$union = this.matchType_$3($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.Type_4, union: $scope$union}; } return $$res; }); } public matchType_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.matchPASCAL_CASE($$dpth + 1, $$cr); }, this.$scope$Type_$0$memo, ); } public matchType_$1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $scope$generic: Nullable; let $$res: Nullable = null; if (true && ($scope$name = this.matchPASCAL_CASE($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$generic = this.matchGeneric($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.Type_$1, name: $scope$name, generic: $scope$generic}; } return $$res; }); }, this.$scope$Type_$1$memo, ); } public matchType_$2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$tupleType: Nullable; let $scope$tupleLength: Nullable; let $$res: Nullable = null; if (true && ($scope$tupleType = this.matchType($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchLBRACKET($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$tupleLength = this.matchPOSITIVE_INT($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchRBRACKET($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Type_$2, tupleType: $scope$tupleType, tupleLength: $scope$tupleLength}; } return $$res; }); }, this.$scope$Type_$2$memo, ); } public matchType_$3($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.matchType($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:OR)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchType($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Type_$3, }; } return $$res; }); }, this.$scope$Type_$3$memo, ); } public matchGeneric($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$generic: Nullable; let $$res: Nullable = null; if (true && this.matchLPAREN($$dpth + 1, $$cr) !== null && ((this.match_($$dpth + 1, $$cr)) || true) && ($scope$generic = this.matchGeneric_$0($$dpth + 1, $$cr)) !== null && this.matchRPAREN($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Generic, generic: $scope$generic}; } return $$res; }); }, this.$scope$Generic$memo, ); } public matchGeneric_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.loop(() => this.matchGeneric_$0_$0($$dpth + 1, $$cr), 0, -1) !== null && this.matchType($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Generic_$0, }; } return $$res; }); }, this.$scope$Generic_$0$memo, ); } public matchGeneric_$0_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.matchType($$dpth + 1, $$cr) !== null && ((this.match_($$dpth + 1, $$cr)) || true) && this.matchCOMMA($$dpth + 1, $$cr) !== null && ((this.match_($$dpth + 1, $$cr)) || true) ) { $$res = {kind: ASTKinds.Generic_$0_$0, }; } return $$res; }); }, this.$scope$Generic_$0_$0$memo, ); } public matchFunctionDeclaration($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$body: Nullable; let $$res: Nullable = null; if (true && this.matchFunctionSignature($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_START($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$body = this.matchFunctionBody($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_END($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.FunctionDeclaration, body: $scope$body}; } return $$res; }); }, this.$scope$FunctionDeclaration$memo, ); } public matchFunctionBody($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.loop(() => this.matchFunctionBody_$0($$dpth + 1, $$cr), 0, -1); }, this.$scope$FunctionBody$memo, ); } public matchFunctionBody_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.choice([ () => this.matchFunctionBody_$0_1($$dpth + 1, $$cr), () => this.matchFunctionBody_$0_2($$dpth + 1, $$cr), ]); }, this.$scope$FunctionBody_$0$memo, ); } public matchFunctionBody_$0_1($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchExpression($$dpth + 1, $$cr); } public matchFunctionBody_$0_2($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.matchReturnStatement($$dpth + 1, $$cr); } public matchFunctionSignature($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $scope$args: Nullable; let $scope$return: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:DISCOVER)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:HOW)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:TO)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$name = this.matchCAMEL_CASE($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:WITH)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$args = this.matchArgList($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:GIVES)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:YOU)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$return = this.matchType($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.FunctionSignature, name: $scope$name, args: $scope$args, return: $scope$return}; } return $$res; }); }, this.$scope$FunctionSignature$memo, ); } public matchArgList($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$args: Nullable; let $$res: Nullable = null; if (true && ($scope$args = this.matchArgList_$0($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.ArgList, args: $scope$args}; } return $$res; }); }, this.$scope$ArgList$memo, ); } public matchArgList_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$type: Nullable; let $scope$name: Nullable; let $$res: Nullable = null; if (true && this.loop(() => this.matchArgList_$0_$0($$dpth + 1, $$cr), 0, -1) !== null && ($scope$type = this.matchType($$dpth + 1, $$cr)) !== null && ($scope$name = this.matchCAMEL_CASE($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.ArgList_$0, type: $scope$type, name: $scope$name}; } return $$res; }); }, this.$scope$ArgList_$0$memo, ); } public matchArgList_$0_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$type: Nullable; let $scope$name: Nullable; let $$res: Nullable = null; if (true && ($scope$type = this.matchType($$dpth + 1, $$cr)) !== null && ($scope$name = this.matchCAMEL_CASE($$dpth + 1, $$cr)) !== null && this.matchCOMMA($$dpth + 1, $$cr) !== null && ((this.match_($$dpth + 1, $$cr)) || true) ) { $$res = {kind: ASTKinds.ArgList_$0_$0, type: $scope$type, name: $scope$name}; } return $$res; }); }, this.$scope$ArgList_$0_$0$memo, ); } public matchReturnStatement($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:SHOCKING)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:DEVELOPMENT)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchExpression($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.ReturnStatement, }; } return $$res; }); }, this.$scope$ReturnStatement$memo, ); } public matchInterface($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $scope$methods: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:STUFF)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:OF)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$name = this.matchPASCAL_CASE($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:LOOKS)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:LIKE)`, "", $$dpth + 1, $$cr) !== null && this.matchSCOPE_START($$dpth + 1, $$cr) !== null && ($scope$methods = this.matchInterface_$0($$dpth + 1, $$cr)) !== null ) { $$res = {kind: ASTKinds.Interface, name: $scope$name, methods: $scope$methods}; } return $$res; }); }, this.$scope$Interface$memo, ); } public matchInterface_$0($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.loop(() => this.matchFunctionSignature($$dpth + 1, $$cr), 0, -1); }, this.$scope$Interface_$0$memo, ); } public matchEnum($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $scope$options: Nullable; let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:ONLY)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:OPTIONS)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:OF)`, "", $$dpth + 1, $$cr) !== null && ($scope$name = this.matchPASCAL_CASE($$dpth + 1, $$cr)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:ARE)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_START($$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && ($scope$options = this.loop(() => this.matchEnumBody($$dpth + 1, $$cr), 0, -1)) !== null && this.match_($$dpth + 1, $$cr) !== null && this.matchSCOPE_END($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.Enum, name: $scope$name, options: $scope$options}; } return $$res; }); }, this.$scope$Enum$memo, ); } public matchEnumBody($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $scope$name: Nullable; let $$res: Nullable = null; if (true && ($scope$name = this.matchIdentifier($$dpth + 1, $$cr)) !== null && this.matchCOMMA($$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.EnumBody, name: $scope$name}; } return $$res; }); }, this.$scope$EnumBody$memo, ); } public matchIdentifier($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:[a-zA-Z][\w\d|\.]*)`, "", $$dpth + 1, $$cr); }, this.$scope$Identifier$memo, ); } public matchSCOPE_START($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:RUMOR)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:HAS)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:IT)`, "", $$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.SCOPE_START, }; } return $$res; }); }, this.$scope$SCOPE_START$memo, ); } public matchSCOPE_END($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:END)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:OF)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:STORY)`, "", $$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.SCOPE_END, }; } return $$res; }); }, this.$scope$SCOPE_END$memo, ); } public matchPROGRAM_END($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.run($$dpth, () => { let $$res: Nullable = null; if (true && this.regexAccept(String.raw`(?:PLEASE)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:LIKE)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:AND)`, "", $$dpth + 1, $$cr) !== null && this.match_($$dpth + 1, $$cr) !== null && this.regexAccept(String.raw`(?:SUBSCRIBE)`, "", $$dpth + 1, $$cr) !== null ) { $$res = {kind: ASTKinds.PROGRAM_END, }; } return $$res; }); }, this.$scope$PROGRAM_END$memo, ); } public matchPASCAL_CASE($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:[A-Z][\w\d]*)`, "", $$dpth + 1, $$cr); }, this.$scope$PASCAL_CASE$memo, ); } public matchCAMEL_CASE($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:[a-z][\w\d]*)`, "", $$dpth + 1, $$cr); }, this.$scope$CAMEL_CASE$memo, ); } public matchLPAREN($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:\()`, "", $$dpth + 1, $$cr); }, this.$scope$LPAREN$memo, ); } public matchRPAREN($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:\))`, "", $$dpth + 1, $$cr); }, this.$scope$RPAREN$memo, ); } public matchLBRACKET($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:\[)`, "", $$dpth + 1, $$cr); }, this.$scope$LBRACKET$memo, ); } public matchRBRACKET($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:\])`, "", $$dpth + 1, $$cr); }, this.$scope$RBRACKET$memo, ); } public matchCOMMA($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:,)`, "", $$dpth + 1, $$cr); }, this.$scope$COMMA$memo, ); } public matchPOSITIVE_INT($$dpth: number, $$cr?: ErrorTracker): Nullable { return this.memoise( () => { return this.regexAccept(String.raw`(?:^[1-9][0-9]*$)`, "", $$dpth + 1, $$cr); }, this.$scope$POSITIVE_INT$memo, ); } public match_($$dpth: number, $$cr?: ErrorTracker): Nullable<_> { return this.memoise( () => { return this.regexAccept(String.raw`(?:\s)`, "", $$dpth + 1, $$cr); }, this.$scope$_$memo, ); } public test(): boolean { const mrk = this.mark(); const res = this.matchProgram(0); const ans = res !== null; this.reset(mrk); return ans; } public parse(): ParseResult { const mrk = this.mark(); const res = this.matchProgram(0); if (res) return {ast: res, errs: []}; this.reset(mrk); const rec = new ErrorTracker(); this.clearMemos(); this.matchProgram(0, rec); const err = rec.getErr() return {ast: res, errs: err !== null ? [err] : []} } public mark(): PosInfo { return this.pos; } // @ts-ignore: loopPlus may not be called private loopPlus(func: $$RuleType): Nullable<[T, ...T[]]> { return this.loop(func, 1, -1) as Nullable<[T, ...T[]]>; } private loop(func: $$RuleType, lb: number, ub: number): Nullable { const mrk = this.mark(); const res: T[] = []; while (ub === -1 || res.length < ub) { const preMrk = this.mark(); const t = func(); if (t === null || this.pos.overallPos === preMrk.overallPos) { break; } res.push(t); } if (res.length >= lb) { return res; } this.reset(mrk); return null; } private run($$dpth: number, fn: $$RuleType): Nullable { const mrk = this.mark(); const res = fn() if (res !== null) return res; this.reset(mrk); return null; } // @ts-ignore: choice may not be called private choice(fns: Array<$$RuleType>): Nullable { for (const f of fns) { const res = f(); if (res !== null) { return res; } } return null; } private regexAccept(match: string, mods: string, dpth: number, cr?: ErrorTracker): Nullable { return this.run(dpth, () => { const reg = new RegExp(match, "y" + mods); const mrk = this.mark(); reg.lastIndex = mrk.overallPos; const res = this.tryConsume(reg); if(cr) { cr.record(mrk, res, { kind: "RegexMatch", // We substring from 3 to len - 1 to strip off the // non-capture group syntax added as a WebKit workaround literal: match.substring(3, match.length - 1), negated: this.negating, }); } return res; }); } private tryConsume(reg: RegExp): Nullable { const res = reg.exec(this.input); if (res) { let lineJmp = 0; let lind = -1; for (let i = 0; i < res[0].length; ++i) { if (res[0][i] === "\n") { ++lineJmp; lind = i; } } this.pos = { overallPos: reg.lastIndex, line: this.pos.line + lineJmp, offset: lind === -1 ? this.pos.offset + res[0].length : (res[0].length - lind - 1) }; return res[0]; } return null; } // @ts-ignore: noConsume may not be called private noConsume(fn: $$RuleType): Nullable { const mrk = this.mark(); const res = fn(); this.reset(mrk); return res; } // @ts-ignore: negate may not be called private negate(fn: $$RuleType): Nullable { const mrk = this.mark(); const oneg = this.negating; this.negating = !oneg; const res = fn(); this.negating = oneg; this.reset(mrk); return res === null ? true : null; } // @ts-ignore: Memoise may not be used private memoise(rule: $$RuleType, memo: Map, PosInfo]>): Nullable { const $scope$pos = this.mark(); const $scope$memoRes = memo.get($scope$pos.overallPos); if(this.memoSafe && $scope$memoRes !== undefined) { this.reset($scope$memoRes[1]); return $scope$memoRes[0]; } const $scope$result = rule(); if(this.memoSafe) memo.set($scope$pos.overallPos, [$scope$result, this.mark()]); return $scope$result; } } export function parse(s: string): ParseResult { const p = new Parser(s); return p.parse(); } export interface ParseResult { ast: Nullable; errs: SyntaxErr[]; } export interface PosInfo { readonly overallPos: number; readonly line: number; readonly offset: number; } export interface RegexMatch { readonly kind: "RegexMatch"; readonly negated: boolean; readonly literal: string; } export type EOFMatch = { kind: "EOF"; negated: boolean }; export type MatchAttempt = RegexMatch | EOFMatch; export class SyntaxErr { public pos: PosInfo; public expmatches: MatchAttempt[]; constructor(pos: PosInfo, expmatches: MatchAttempt[]) { this.pos = pos; this.expmatches = [...expmatches]; } public toString(): string { return `Syntax Error at line ${this.pos.line}:${this.pos.offset}. Expected one of ${this.expmatches.map(x => x.kind === "EOF" ? " EOF" : ` ${x.negated ? 'not ': ''}'${x.literal}'`)}`; } } class ErrorTracker { private mxpos: PosInfo = {overallPos: -1, line: -1, offset: -1}; private regexset: Set = new Set(); private pmatches: MatchAttempt[] = []; public record(pos: PosInfo, result: any, att: MatchAttempt) { if ((result === null) === att.negated) return; if (pos.overallPos > this.mxpos.overallPos) { this.mxpos = pos; this.pmatches = []; this.regexset.clear() } if (this.mxpos.overallPos === pos.overallPos) { if(att.kind === "RegexMatch") { if(!this.regexset.has(att.literal)) this.pmatches.push(att); this.regexset.add(att.literal); } else { this.pmatches.push(att); } } } public getErr(): SyntaxErr | null { if (this.mxpos.overallPos !== -1) return new SyntaxErr(this.mxpos, this.pmatches); return null; } }