@neuledge/states-parser
Version:
A parser for the Neuledge States language
1 lines • 62.4 kB
Source Map (JSON)
{"version":3,"sources":["../src/nodes/identifier.ts","../src/nodes/argument.ts","../src/nodes/literal.ts","../src/nodes/decorator.ts","../src/nodes/description.ts","../src/nodes/either.ts","../src/nodes/expressions/binary.ts","../src/nodes/expressions/identifier.ts","../src/nodes/expressions/logical.ts","../src/nodes/expressions/member.ts","../src/nodes/expressions/unary.ts","../src/nodes/expressions/expression.ts","../src/nodes/expressions/call.ts","../src/nodes/type.ts","../src/nodes/parameter.ts","../src/nodes/property.ts","../src/nodes/mutation.ts","../src/error.ts","../src/nodes/state-field.ts","../src/nodes/state.ts","../src/nodes/document.ts","../src/tokens/tokenize.ts","../src/tokens/cursor.ts","../src/parser.ts"],"sourcesContent":["import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\n\nexport interface IdentifierNode extends AbstractNode<'Identifier'> {\n name: string;\n}\n\nexport const parseIdentifierNode = (cursor: TokenCursor): IdentifierNode => ({\n type: 'Identifier',\n path: cursor.path,\n start: cursor.start,\n name: cursor.consume('Word', null, `identifier name`).value,\n end: cursor.end,\n});\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\n\nexport interface ArgumentNode<Value> extends AbstractNode<'Argument'> {\n key: IdentifierNode;\n value: Value;\n}\n\nexport const parseMaybeArgumentNodes = <Value>(\n cursor: TokenCursor,\n parseValue: (cursor: TokenCursor) => Value,\n allowImplicit?: boolean,\n): ArgumentNode<Value>[] => {\n if (!cursor.pickPunctuation('(')) {\n return [];\n }\n\n return parseArgumentNodes(cursor, parseValue, allowImplicit);\n};\n\nexport const parseArgumentNodes = <Value>(\n cursor: TokenCursor,\n parseValue: (cursor: TokenCursor) => Value,\n allowImplicit?: boolean,\n): ArgumentNode<Value>[] => {\n const { index: position } = cursor;\n\n cursor.consumePunctuation('(');\n\n try {\n const args: ArgumentNode<Value>[] = [];\n do {\n if (cursor.maybeConsumePunctuation(')')) {\n return args;\n }\n\n args.push(parseArgumentNode(cursor, parseValue, allowImplicit));\n } while (cursor.maybeConsumePunctuation(','));\n\n cursor.consumePunctuation(')');\n return args;\n } catch (error) {\n cursor.index = position;\n throw error;\n }\n};\n\nconst parseArgumentNode = <Value>(\n cursor: TokenCursor,\n parseValue: (cursor: TokenCursor) => Value,\n allowImplicit?: boolean,\n): ArgumentNode<Value> => {\n const start = cursor.start;\n const path = cursor.path;\n\n const key = parseIdentifierNode(cursor);\n\n const explicit = allowImplicit\n ? cursor.maybeConsumePunctuation(':')\n : cursor.consumePunctuation(':');\n\n const value = explicit ? parseValue(cursor) : (key as Value);\n\n return {\n type: 'Argument',\n path,\n start,\n end: cursor.end,\n key,\n value,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\n\nexport interface LiteralNode<T extends LiteralValue = LiteralValue>\n extends AbstractNode<'Literal'> {\n value: T;\n}\n\nexport type LiteralValue =\n | string\n | number\n | boolean\n | null\n | LiteralValue[]\n | { [K in string]?: LiteralValue };\n\nconst LiteralValues: Partial<Record<string, LiteralNode['value']>> = {\n true: true,\n false: false,\n null: null,\n NaN: NaN,\n Infinity: Infinity,\n};\n\nexport const parseLiteralNode = <Value extends LiteralValue>(\n cursor: TokenCursor,\n parseValue: (cursor: TokenCursor) => Value = parseLiteralValue as never,\n): LiteralNode<Value> => ({\n type: 'Literal',\n path: cursor.path,\n start: cursor.start,\n value: parseValue(cursor),\n end: cursor.end,\n});\n\nexport const parseUInt8LiteralNode = (\n cursor: TokenCursor,\n): LiteralNode<number> => ({\n type: 'Literal',\n path: cursor.path,\n start: cursor.start,\n value: parseUInt8(cursor),\n end: cursor.end,\n});\n\n// value parsers\n\nconst parseUInt8 = (cursor: TokenCursor): number =>\n cursor.consume(\n 'Number',\n ({ value }) => value > 0 && Number.isInteger(value) && value <= 255,\n `positive unsigned integer between 1 and 255`,\n ).value;\n\nconst parseLiteralValue = (cursor: TokenCursor): LiteralValue => {\n const token = cursor.current;\n\n switch (token?.type) {\n case 'String':\n case 'Number': {\n cursor.index += 1;\n return token.value;\n }\n\n case 'Word': {\n const value = LiteralValues[token.value] as LiteralNode['value'];\n if (value === undefined) {\n throw cursor.createError(`literal value`);\n }\n\n cursor.index += 1;\n return value;\n }\n\n case 'Punctuation': {\n return parseLiteralPunctuationValue(cursor, token.value);\n }\n\n default: {\n throw cursor.createError(`literal value`);\n }\n }\n};\n\nconst parseLiteralPunctuationValue = (\n cursor: TokenCursor,\n value: string,\n): LiteralValue => {\n switch (value) {\n case '-':\n case '+': {\n cursor.index += 1;\n\n const { index: position } = cursor;\n const num = parseLiteralValue(cursor);\n\n if (typeof num === 'number') {\n return value === '-' ? -num : num;\n }\n\n // rollback position before throw\n cursor.index = position;\n throw cursor.createError(`literal number`);\n }\n\n case '[': {\n cursor.index += 1;\n const values = parseLiteralArrayValues(cursor);\n\n cursor.consumePunctuation(']');\n return values;\n }\n\n case '{': {\n cursor.index += 1;\n const entries = parseObjectEntries(cursor);\n\n cursor.consumePunctuation('}');\n return Object.fromEntries(entries);\n }\n\n default: {\n throw cursor.createError(`literal value`);\n }\n }\n};\n\nconst parseLiteralArrayValues = (cursor: TokenCursor): LiteralValue[] => {\n const values: LiteralValue[] = [];\n\n while (!cursor.pickPunctuation(']')) {\n values.push(parseLiteralValue(cursor));\n\n if (!cursor.maybeConsumePunctuation(',')) {\n break;\n }\n }\n\n return values;\n};\n\nconst parseObjectEntries = (cursor: TokenCursor): [string, LiteralValue][] => {\n const entries: [string, LiteralValue][] = [];\n\n while (!cursor.pickPunctuation('}')) {\n const key = (\n cursor.maybeConsume('String') ||\n cursor.consume('Word', undefined, `object key`)\n ).value;\n\n cursor.consumePunctuation(':');\n const value = parseLiteralValue(cursor);\n\n entries.push([key, value]);\n\n if (!cursor.maybeConsumePunctuation(',')) {\n break;\n }\n }\n\n return entries;\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\nimport { ArgumentNode, parseMaybeArgumentNodes } from './argument';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\nimport { LiteralNode, parseLiteralNode } from './literal';\n\nexport interface DecoratorNode extends AbstractNode<'Decorator'> {\n callee: IdentifierNode;\n arguments: ArgumentNode<LiteralNode>[];\n}\n\nexport const parseDecoratorNodes = (cursor: TokenCursor): DecoratorNode[] => {\n const decorators: DecoratorNode[] = [];\n\n for (let decorator; (decorator = parseMaybeDecoratorNode(cursor)); ) {\n decorators.push(decorator);\n }\n\n return decorators;\n};\n\nconst parseMaybeDecoratorNode = (\n cursor: TokenCursor,\n): DecoratorNode | undefined => {\n const start = cursor.start;\n const path = cursor.path;\n\n const decoratorToken = cursor.maybeConsumePunctuation('@');\n if (!decoratorToken) return undefined;\n\n if (!decoratorToken.adjacent) {\n cursor.index -= 1;\n throw cursor.createError('decorator name');\n }\n\n const callee = parseIdentifierNode(cursor);\n const args = parseMaybeArgumentNodes(cursor, parseLiteralNode);\n\n return {\n type: 'Decorator',\n path,\n start,\n end: cursor.end,\n callee,\n arguments: args,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\n\nexport interface DescriptionNode extends AbstractNode<'Description'> {\n value: string;\n}\n\nexport const parseMaybeDescriptionNode = (\n cursor: TokenCursor,\n): DescriptionNode | undefined => {\n const start = cursor.start;\n const path = cursor.path;\n\n const strToken = cursor.maybeConsume(\n 'String',\n (token) => token.kind === '\"' || token.kind === '\"\"\"',\n );\n\n return (\n strToken && {\n type: 'Description',\n path,\n start,\n end: cursor.end,\n value: strToken.value,\n }\n );\n};\n","import { TokenCursor } from '@/tokens';\nimport { DecoratorNode } from './decorator';\nimport { DescriptionNode } from './description';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\nimport { NamedNode } from './named';\n\nexport const EITHER_KEYWORD = 'either';\n\nexport interface EitherNode extends NamedNode<'Either'> {\n states: IdentifierNode[];\n}\n\nexport const parseEitherNode = (\n cursor: TokenCursor,\n description?: DescriptionNode,\n decorators: DecoratorNode[] = [],\n): EitherNode => {\n const start = cursor.start;\n\n cursor.consumeKeyword(EITHER_KEYWORD);\n const id = parseIdentifierNode(cursor);\n\n cursor.consumePunctuation('=');\n const states = parseEitherStateNodes(cursor);\n\n return {\n type: 'Either',\n path: cursor.path,\n start,\n end: cursor.end,\n id,\n description,\n decorators,\n states,\n };\n};\n\nconst parseEitherStateNodes = (cursor: TokenCursor): IdentifierNode[] => {\n const states: IdentifierNode[] = [];\n\n do {\n const state = parseIdentifierNode(cursor);\n states.push(state);\n } while (cursor.maybeConsumePunctuation('|'));\n\n return states;\n};\n","import { AbstractNode } from '../abstract';\nimport { ExpressionNode } from './expression';\n\nconst BinaryExpressionNodeOperators = {\n '+': 1,\n '-': 1,\n '*': 1,\n '/': 1,\n '%': 1,\n '**': 1,\n '==': 1,\n '!=': 1,\n '===': 1,\n '!==': 1,\n '<': 1,\n '<=': 1,\n '>': 1,\n '>=': 1,\n} as const;\n\nexport const isBinaryExpressionNodeOperator = (\n operator: string,\n): operator is keyof typeof BinaryExpressionNodeOperators =>\n operator in BinaryExpressionNodeOperators;\n\nexport interface BinaryExpressionNode extends AbstractNode<'BinaryExpression'> {\n operator: keyof typeof BinaryExpressionNodeOperators;\n left: ExpressionNode;\n right: ExpressionNode;\n}\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from '../abstract';\nimport { IdentifierNode, parseIdentifierNode } from '../identifier';\n\nexport type IdentifierExpressionNode =\n | ThisExpressionNode\n | NullLiteralNode\n | IdentifierNode;\n\nexport interface ThisExpressionNode extends AbstractNode<'ThisExpression'> {\n name: 'this';\n}\n\nexport interface NullLiteralNode extends AbstractNode<'NullLiteral'> {\n value: null;\n}\n\nexport const parseIdentifierExpressionNode = (\n cursor: TokenCursor,\n): IdentifierExpressionNode => {\n const start = cursor.start;\n const value = cursor.pickKeyword('this', 'null')?.value;\n\n switch (value) {\n case 'this': {\n cursor.consumeKeyword('this');\n\n return {\n type: 'ThisExpression',\n path: cursor.path,\n start,\n end: cursor.end,\n name: 'this',\n };\n }\n\n case 'null': {\n cursor.consumeKeyword('null');\n\n return {\n type: 'NullLiteral',\n path: cursor.path,\n start,\n end: cursor.end,\n value: null,\n };\n }\n\n default: {\n return parseIdentifierNode(cursor);\n }\n }\n};\n","import { AbstractNode } from '../abstract';\nimport { ExpressionNode } from './expression';\n\nconst LogicalExpressionNodeOperators = {\n '&&': 1,\n '||': 1,\n '??': 1,\n} as const;\n\nexport const isLogicalExpressionNodeOperator = (\n operator: string,\n): operator is keyof typeof LogicalExpressionNodeOperators =>\n operator in LogicalExpressionNodeOperators;\n\nexport interface LogicalExpressionNode\n extends AbstractNode<'LogicalExpression'> {\n operator: keyof typeof LogicalExpressionNodeOperators;\n left: ExpressionNode;\n right: ExpressionNode;\n}\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from '../abstract';\nimport { IdentifierNode, parseIdentifierNode } from '../identifier';\nimport {\n IdentifierExpressionNode,\n NullLiteralNode,\n parseIdentifierExpressionNode,\n} from './identifier';\n\nexport interface MemberExpressionNode extends AbstractNode<'MemberExpression'> {\n object:\n | Exclude<IdentifierExpressionNode, NullLiteralNode>\n | MemberExpressionNode;\n property: IdentifierNode;\n}\n\nexport const parseMemberExpressionNode = (\n cursor: TokenCursor,\n): MemberExpressionNode => {\n const start = cursor.start;\n\n let object: IdentifierExpressionNode | MemberExpressionNode =\n parseIdentifierExpressionNode(cursor);\n if (object.type === 'NullLiteral') {\n throw cursor.createError(`Unexpected null literal`);\n }\n\n cursor.consumePunctuation('.');\n\n do {\n const property = parseIdentifierNode(cursor);\n\n object = {\n type: 'MemberExpression',\n path: cursor.path,\n start,\n end: cursor.end,\n object,\n property,\n };\n } while (cursor.maybeConsumePunctuation('.'));\n\n return object;\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from '../abstract';\nimport { ExpressionNode, parseExpressionNode } from './expression';\n\nconst UnaryExpressionNodeOperators = {\n '!': 1,\n '-': 1,\n '+': 1,\n '~': 1,\n} as const;\n\nexport interface UnaryExpressionNode extends AbstractNode<'UnaryExpression'> {\n operator: keyof typeof UnaryExpressionNodeOperators;\n argument: ExpressionNode;\n}\n\nconst UnaryExpressionNodeOperatorsArray = Object.keys(\n UnaryExpressionNodeOperators,\n) as (keyof typeof UnaryExpressionNodeOperators)[];\n\nexport const isUnaryExpressionNodeOperator = (\n operator: string,\n): operator is keyof typeof UnaryExpressionNodeOperators =>\n operator in UnaryExpressionNodeOperators;\n\nexport const parseUnaryExpressionNode = (\n cursor: TokenCursor,\n): UnaryExpressionNode => {\n const start = cursor.start;\n\n const operator = cursor.consumePunctuation(\n ...UnaryExpressionNodeOperatorsArray,\n ).value;\n const argument = parseExpressionNode(cursor);\n\n return {\n type: 'UnaryExpression',\n path: cursor.path,\n start,\n end: cursor.end,\n operator,\n argument,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { LiteralNode, parseLiteralNode } from '../literal';\nimport { BinaryExpressionNode, isBinaryExpressionNodeOperator } from './binary';\nimport { CallExpressionNode, parseCallExpressionNode } from './call';\nimport {\n IdentifierExpressionNode,\n parseIdentifierExpressionNode,\n} from './identifier';\nimport {\n isLogicalExpressionNodeOperator,\n LogicalExpressionNode,\n} from './logical';\nimport { MemberExpressionNode, parseMemberExpressionNode } from './member';\nimport {\n isUnaryExpressionNodeOperator,\n parseUnaryExpressionNode,\n UnaryExpressionNode,\n} from './unary';\n\nexport type ExpressionNode =\n | MemberExpressionNode\n | CallExpressionNode\n | BinaryExpressionNode\n | LogicalExpressionNode\n | UnaryExpressionNode\n | LiteralNode\n | IdentifierExpressionNode;\n\nexport const parseExpressionNode = (cursor: TokenCursor): ExpressionNode => {\n const start = cursor.start;\n const node = parseCoreExpressionNode(cursor);\n\n const current = cursor.current;\n if (current?.type !== 'Punctuation') {\n return node;\n }\n\n if (isLogicalExpressionNodeOperator(current.value)) {\n cursor.consume('Punctuation');\n const right = parseExpressionNode(cursor);\n\n return {\n type: 'LogicalExpression',\n path: cursor.path,\n start,\n end: cursor.end,\n operator: current.value,\n left: node,\n right,\n };\n }\n\n if (isBinaryExpressionNodeOperator(current.value)) {\n cursor.consume('Punctuation');\n const right = parseExpressionNode(cursor);\n\n return {\n type: 'BinaryExpression',\n path: cursor.path,\n start,\n end: cursor.end,\n operator: current.value,\n left: node,\n right,\n };\n }\n\n return node;\n};\n\nconst parseCoreExpressionNode = (cursor: TokenCursor): ExpressionNode => {\n const { current, next } = cursor;\n\n if (current?.type === 'Punctuation') {\n if (current.value === '(') {\n cursor.consumePunctuation('(');\n\n const node = parseExpressionNode(cursor);\n cursor.consumePunctuation(')');\n\n return node;\n }\n\n if (isUnaryExpressionNodeOperator(current.value)) {\n return parseUnaryExpressionNode(cursor);\n }\n\n return parseLiteralNode(cursor);\n }\n\n if (current?.type !== 'Word') {\n return parseLiteralNode(cursor);\n }\n\n switch (next?.value) {\n case '(': {\n return parseCallExpressionNode(cursor);\n }\n\n case '.': {\n return parseMemberExpressionNode(cursor);\n }\n\n default: {\n return parseIdentifierExpressionNode(cursor);\n }\n }\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from '../abstract';\nimport { ArgumentNode, parseArgumentNodes } from '../argument';\nimport { IdentifierNode, parseIdentifierNode } from '../identifier';\nimport { ExpressionNode, parseExpressionNode } from './expression';\n\nexport interface CallExpressionNode extends AbstractNode<'CallExpression'> {\n callee: IdentifierNode;\n arguments: ArgumentNode<ExpressionNode>[];\n}\n\nexport const parseCallExpressionNode = (\n cursor: TokenCursor,\n): CallExpressionNode => {\n const start = cursor.start;\n\n const callee = parseIdentifierNode(cursor);\n const args = parseArgumentNodes(cursor, parseExpressionNode, true);\n\n return {\n type: 'CallExpression',\n path: cursor.path,\n start,\n end: cursor.end,\n callee,\n arguments: args,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\nimport { ArgumentNode, parseMaybeArgumentNodes } from './argument';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\nimport { LiteralNode, parseLiteralNode } from './literal';\n\nexport type TypeNode = TypeGeneratorNode | TypeExpressionNode;\n\nexport interface TypeGeneratorNode extends AbstractNode<'TypeGenerator'> {\n identifier: IdentifierNode;\n arguments: ArgumentNode<LiteralNode>[];\n}\n\nexport interface TypeExpressionNode extends AbstractNode<'TypeExpression'> {\n identifier: IdentifierNode;\n list: boolean;\n}\n\nexport const parseTypeNode = (cursor: TokenCursor): TypeNode => {\n const start = cursor.start;\n const path = cursor.path;\n\n const identifier = parseIdentifierNode(cursor);\n const args = parseMaybeArgumentNodes(cursor, parseLiteralNode);\n\n if (args.length) {\n return {\n type: 'TypeGenerator',\n path,\n start,\n end: cursor.end,\n identifier,\n arguments: args,\n };\n }\n\n const list = !!cursor.maybeConsumePunctuation('[');\n if (list) {\n cursor.consumePunctuation(']');\n }\n\n return {\n type: 'TypeExpression',\n path,\n start,\n end: cursor.end,\n identifier,\n list,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\nimport { DecoratorNode, parseDecoratorNodes } from './decorator';\nimport { DescriptionNode, parseMaybeDescriptionNode } from './description';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\nimport { parseTypeNode, TypeNode } from './type';\n\nexport interface ParameterNode extends AbstractNode<'Parameter'> {\n key: IdentifierNode;\n description?: DescriptionNode;\n decorators: DecoratorNode[];\n as: TypeNode;\n nullable: boolean;\n}\n\nexport const parseParameterNodes = (cursor: TokenCursor): ParameterNode[] => {\n const parameters: ParameterNode[] = [];\n\n cursor.consumePunctuation('(');\n\n while (!cursor.maybeConsumePunctuation(')')) {\n const parameter = parseParameterNode(cursor);\n parameters.push(parameter);\n\n cursor.maybeConsumePunctuation(',');\n }\n\n return parameters;\n};\n\nconst parseParameterNode = (cursor: TokenCursor): ParameterNode => {\n const start = cursor.start;\n\n const description = parseMaybeDescriptionNode(cursor);\n const decorators = parseDecoratorNodes(cursor);\n const key = parseIdentifierNode(cursor);\n const nullable = !!cursor.maybeConsumePunctuation('?');\n\n cursor.consumePunctuation(':');\n const as = parseTypeNode(cursor);\n\n return {\n type: 'Parameter',\n path: cursor.path,\n start,\n end: cursor.end,\n key,\n as,\n nullable,\n description,\n decorators,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\nimport {\n ExpressionNode,\n // MemberExpressionNode,\n parseExpressionNode,\n} from './expressions';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\n\nexport type ReturnBodyNode = PropertyNode; /* | SpreadElementNode; */\n\nexport interface PropertyNode extends AbstractNode<'Property'> {\n key: IdentifierNode;\n value: ExpressionNode;\n}\n\n// export interface SpreadElementNode extends AbstractNode<'SpreadElement'> {\n// argument: MemberExpressionNode['object'];\n// }\n\nexport const parseReturnBodyNodes = (cursor: TokenCursor): ReturnBodyNode[] => {\n const body: ReturnBodyNode[] = [];\n\n cursor.consumePunctuation('{');\n\n do {\n if (cursor.maybeConsumePunctuation('}')) {\n return body;\n }\n\n body.push(parseReturnBodyNode(cursor));\n } while (cursor.maybeConsumePunctuation(','));\n\n cursor.consumePunctuation('}');\n return body;\n};\n\nconst parseReturnBodyNode = (cursor: TokenCursor): ReturnBodyNode => {\n const start = cursor.start;\n\n const key = parseIdentifierNode(cursor);\n\n const explicit = cursor.maybeConsumePunctuation(':');\n const value = explicit ? parseExpressionNode(cursor) : key;\n\n return {\n type: 'Property',\n path: cursor.path,\n start,\n end: cursor.end,\n key,\n value,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\nimport { DecoratorNode } from './decorator';\nimport { DescriptionNode } from './description';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\nimport { ParameterNode, parseParameterNodes } from './parameter';\nimport { parseReturnBodyNodes, ReturnBodyNode } from './property';\n\nexport interface MutationNode extends AbstractNode<'Mutation'> {\n key: IdentifierNode;\n description?: DescriptionNode;\n decorators: DecoratorNode[];\n from?: IdentifierNode;\n parameters: ParameterNode[];\n returns: IdentifierNode;\n body: ReturnBodyNode[];\n}\n\nexport const parseMutationNode = (\n cursor: TokenCursor,\n description?: DescriptionNode,\n decorators: DecoratorNode[] = [],\n): MutationNode => {\n const start = cursor.start;\n\n const firstId = parseIdentifierNode(cursor);\n const secondId = cursor.maybeConsumePunctuation('.')\n ? parseIdentifierNode(cursor)\n : undefined;\n\n const parameters = parseParameterNodes(cursor);\n\n cursor.consumePunctuation(':');\n const returns = parseIdentifierNode(cursor);\n\n const hasBody = cursor.maybeConsumePunctuation('=>');\n const body = hasBody ? parseReturnBodyNodes(cursor) : [];\n\n return {\n type: 'Mutation',\n path: cursor.path,\n start,\n end: cursor.end,\n key: secondId || firstId,\n description,\n decorators,\n from: secondId ? firstId : undefined,\n parameters,\n returns,\n body,\n };\n};\n","export class ParsingError extends SyntaxError {\n public readonly name = 'ParsingError';\n\n public readonly start: number;\n public readonly end: number;\n public readonly path?: string;\n\n constructor(\n position: { start: number; end: number; path?: string },\n message: string,\n ) {\n super(message);\n\n // because we are extending a built-in class\n Object.setPrototypeOf(this, ParsingError.prototype);\n\n this.start = position.start;\n this.end = position.end;\n this.path = position.path;\n\n this.stack = `${this.name}: ${this.message}\\r\\n\\tat ${\n this.path ?? `character ${this.start}`\n }`;\n }\n}\n","import { TokenCursor } from '@/tokens';\nimport { parseDecoratorNodes } from './decorator';\nimport { parseMaybeDescriptionNode } from './description';\nimport { ExcludedFieldNode } from './excluded-field';\nimport { ReferenceFieldNode } from './reference-field';\nimport { FieldNode } from './field';\nimport { parseIdentifierNode } from './identifier';\nimport { LiteralNode, parseUInt8LiteralNode } from './literal';\nimport { parseTypeNode } from './type';\nimport { ParsingError } from '@/error';\n\nexport const STATE_FIELD_INDEX_MAX_INPUT_VALUE = 255;\n\nexport type StateFieldNode = FieldNode | ReferenceFieldNode | ExcludedFieldNode;\n\nexport const parseStateFieldNodes = (\n cursor: TokenCursor,\n hasParent?: boolean,\n): StateFieldNode[] => {\n const fieldMap: Record<string, StateFieldNode> = {};\n const indexMap: Record<number, StateFieldNode> = {};\n\n cursor.consumePunctuation('{');\n\n while (!cursor.maybeConsumePunctuation('}')) {\n const field = parseStateFieldNode(cursor);\n\n if (fieldMap[field.key.name]) {\n throw new ParsingError(\n field.key,\n `Duplicate field name '${field.key.name}'`,\n );\n }\n\n if (!hasParent && field.type === 'ExcludedField') {\n throw new ParsingError(\n field,\n `Unexpected excluded field on state without a parent state`,\n );\n }\n\n if ('index' in field) {\n if (indexMap[field.index.value]) {\n throw new ParsingError(\n field.index,\n `Duplicate index for field name '${\n indexMap[field.index.value].key.name\n }'`,\n );\n }\n\n indexMap[field.index.value] = field;\n }\n\n fieldMap[field.key.name] = field;\n\n cursor.maybeConsumePunctuation(',');\n }\n\n return Object.values(fieldMap);\n};\n\nconst parseStateFieldNode = (cursor: TokenCursor): StateFieldNode => {\n const description = parseMaybeDescriptionNode(cursor);\n const decorators = parseDecoratorNodes(cursor);\n\n const maybeRef = !description && !decorators.length;\n const start = cursor.start;\n const path = cursor.path;\n\n const substractSign = maybeRef\n ? cursor.maybeConsumePunctuation('-')\n : undefined;\n\n const firstId = parseIdentifierNode(cursor);\n if (substractSign) {\n return {\n type: 'ExcludedField',\n key: firstId,\n path,\n start,\n end: cursor.end,\n };\n }\n\n const dotSign = maybeRef ? cursor.maybeConsumePunctuation('.') : undefined;\n\n if (!dotSign) {\n return parseFieldNode(cursor, {\n path,\n start,\n key: firstId,\n description,\n decorators,\n });\n }\n\n const secId = parseIdentifierNode(cursor);\n\n return parseReferenceFieldNode(cursor, {\n path,\n start,\n state: firstId,\n key: secId,\n });\n};\n\nconst parseFieldNode = (\n cursor: TokenCursor,\n base: Pick<\n FieldNode,\n 'key' | 'description' | 'decorators' | 'path' | 'start'\n >,\n): FieldNode => {\n const nullSign = cursor.maybeConsumePunctuation('?');\n\n cursor.maybeConsumePunctuation(':');\n const as = parseTypeNode(cursor);\n const index = parseIndex(cursor);\n\n return {\n type: 'Field',\n ...base,\n end: cursor.end,\n as,\n index,\n nullable: !!nullSign,\n };\n};\n\nconst parseReferenceFieldNode = (\n cursor: TokenCursor,\n base: Pick<ReferenceFieldNode, 'state' | 'key' | 'path' | 'start'>,\n): ReferenceFieldNode => {\n const index = parseIndex(cursor);\n\n return {\n type: 'ReferenceField',\n ...base,\n end: cursor.end,\n index,\n };\n};\n\nconst parseIndex = (cursor: TokenCursor): LiteralNode<number> => {\n cursor.consumePunctuation('=');\n return parseUInt8LiteralNode(cursor);\n};\n","import { TokenCursor } from '@/tokens';\nimport { DecoratorNode } from './decorator';\nimport { DescriptionNode } from './description';\nimport { IdentifierNode, parseIdentifierNode } from './identifier';\nimport { NamedNode } from './named';\nimport { parseStateFieldNodes, StateFieldNode } from './state-field';\n\nexport const STATE_KEYWORD = 'state';\n\nexport interface StateNode extends NamedNode<'State'> {\n from?: IdentifierNode;\n fields: StateFieldNode[];\n}\n\nexport const parseStateNode = (\n cursor: TokenCursor,\n description?: DescriptionNode,\n decorators: DecoratorNode[] = [],\n): StateNode => {\n const start = cursor.start;\n\n cursor.consumeKeyword(STATE_KEYWORD);\n const id = parseIdentifierNode(cursor);\n\n const fromKeyword = cursor.maybeConsumeKeyword('from');\n let from;\n if (fromKeyword) {\n from = parseIdentifierNode(cursor);\n }\n\n const fields = parseStateFieldNodes(cursor, !!from);\n\n return {\n type: 'State',\n path: cursor.path,\n start,\n end: cursor.end,\n id,\n description,\n from,\n fields,\n decorators,\n };\n};\n","import { TokenCursor } from '@/tokens';\nimport { AbstractNode } from './abstract';\nimport { parseDecoratorNodes } from './decorator';\nimport { parseMaybeDescriptionNode } from './description';\nimport { EITHER_KEYWORD, parseEitherNode } from './either';\nimport { EntityNode } from './entity';\nimport { MigrationNode } from './migration';\nimport { MutationNode, parseMutationNode } from './mutation';\nimport { parseStateNode, STATE_KEYWORD } from './state';\n\nexport interface DocumentNode extends AbstractNode<'Root'> {\n body: DocumentBodyNode[];\n}\n\nexport type DocumentBodyNode = EntityNode | MigrationNode | MutationNode;\n\nexport const parseDocumentNode = (cursor: TokenCursor): DocumentNode => ({\n type: 'Root',\n path: cursor.path,\n start: cursor.start,\n body: parseDocumentBodyNodes(cursor),\n end: cursor.end,\n});\n\nconst parseDocumentBodyNodes = (cursor: TokenCursor): DocumentBodyNode[] => {\n const body: DocumentBodyNode[] = [];\n\n while (cursor.current) {\n const description = parseMaybeDescriptionNode(cursor);\n const decorators = parseDecoratorNodes(cursor);\n\n const keyword = cursor.pickKeyword();\n const nodeKeyword =\n keyword && cursor.next?.type === 'Word' ? keyword.value : null;\n\n let node: DocumentBodyNode;\n\n switch (nodeKeyword) {\n case STATE_KEYWORD: {\n node = parseStateNode(cursor, description, decorators);\n break;\n }\n\n case EITHER_KEYWORD: {\n node = parseEitherNode(cursor, description, decorators);\n break;\n }\n\n default: {\n if (!keyword) {\n // TODO parse migration\n throw cursor.createError();\n }\n\n node = parseMutationNode(cursor, description, decorators);\n }\n }\n\n body.push(node);\n }\n\n return body;\n};\n","import { PunctuationToken, StringToken, Token } from '@/tokens';\n\nconst TokenCharMap: Record<string, Token['type'] | 0 | -1> = {\n '\"': 'String',\n \"'\": 'String',\n '': -1,\n ' ': -1,\n '\\t': -1,\n '\\r': -1,\n '\\n': -1,\n};\nfor (const char of '$_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {\n TokenCharMap[char] = 'Word';\n}\nfor (const char of '0123456789') {\n TokenCharMap[char] = 'Number';\n}\n\nexport const tokenize = (content: string, path?: string): Token[] => {\n const values = splitTokenValues(content);\n\n const tokens: Token[] = [];\n let position = 0;\n let line = 1;\n let column = 1;\n let isComment = false;\n let lastPunctuation: PunctuationToken | null = null;\n\n for (const value of values) {\n if (!isComment) {\n const token = parseToken(\n value,\n position,\n path && `${path}:${line}:${column}`,\n );\n if (token) {\n if (lastPunctuation) {\n lastPunctuation.adjacent = true;\n }\n\n tokens.push(token);\n lastPunctuation = token.type === 'Punctuation' ? token : null;\n } else {\n lastPunctuation = null;\n if (value === '#') isComment = true;\n }\n }\n\n const lines = value.split(/\\r*\\n/g);\n if (lines.length > 1) {\n line += lines.length - 1;\n column = 1;\n }\n\n column += lines.at(-1)?.length ?? 0;\n position += value.length;\n\n if (isComment && value.includes('\\n')) {\n isComment = false;\n }\n }\n\n return tokens;\n};\n\nconst splitTokenValues = (content: string): string[] =>\n content.match(\n /([$_a-z]\\w*|(?:\\d*\\.\\d+|\\d+)|\\s+|\"\"\"(?:[^\"]+|\"[^\"]|\"\"[^\"])*\"\"\"|\"(?:[^\\n\"\\\\]+|\\\\.)*\"|'(?:[^\\n'\\\\]+|\\\\.)*'|[<=>]=|=>|[!=]==|&&|!!|\\|\\||\\?\\?|\\*\\*|\\.\\.\\.|.)/gi,\n ) || [];\n\nconst parseToken = (\n value: string,\n position: number,\n path?: string,\n): Token | null => {\n const kind = value[0];\n const type = TokenCharMap[kind] || 'Punctuation';\n const start = position;\n const end = position + value.length;\n\n switch (type) {\n case 'Number': {\n return { type, path, start, end, value: Number(value) };\n }\n\n case 'String': {\n return {\n type,\n start,\n end,\n ...parseStringToken(kind, value),\n };\n }\n\n case 'Punctuation': {\n if (value.length > 1 && /^[+-]?(?:\\d*\\.\\d+|\\d+)$/.test(value)) {\n return {\n type: 'Number',\n path,\n start,\n end,\n value: Number(value),\n };\n }\n\n if (value === '#') {\n return null;\n }\n\n return { type, path, start, end, value, adjacent: false };\n }\n\n case 'Word': {\n return { type, path, start, end, value };\n }\n\n case -1: {\n return null;\n }\n }\n};\n\nconst parseStringToken = (\n kind: string,\n raw: string,\n): Pick<StringToken, 'value' | 'kind'> => {\n if (kind === '\"' && raw[1] === '\"' && raw[2] === '\"') {\n return {\n kind: '\"\"\"',\n value: raw\n .slice(3, -3)\n .trim()\n .replaceAll(/[\\t ]*\\r?\\n[\\t ]*/g, '\\n'),\n };\n }\n\n return {\n kind: kind as '\"' | \"'\",\n value: raw.slice(1, -1).replaceAll(/\\\\(.)/g, '$1'),\n };\n};\n","import { tokenize } from './tokenize';\nimport { ParsingError } from '@/error';\nimport { PunctuationToken, Token, WordToken } from './index';\nimport { AbstractToken } from './abstract';\n\nexport class TokenCursor {\n public readonly tokens: Token[];\n\n constructor(\n public readonly content: string,\n path?: string,\n public index = 0,\n ) {\n this.tokens = tokenize(content, path);\n }\n\n get current(): Token | undefined {\n return this.tokens[this.index];\n }\n\n get next(): Token | undefined {\n return this.tokens[this.index + 1];\n }\n\n get path(): string | undefined {\n return this.tokens[this.index]?.path;\n }\n\n get start(): number {\n return this.tokens[this.index]?.start ?? this.content.length;\n }\n\n get end(): number {\n return this.tokens[this.index - 1]?.end ?? 0;\n }\n\n static isMatch<T extends Token['type']>(\n token: Token | null | undefined,\n type: T,\n test?: ((token: Token & AbstractToken<T>) => boolean) | null,\n ): token is Token & AbstractToken<T> {\n if (token?.type !== type) {\n return false;\n }\n\n if (test == null) {\n return true;\n }\n\n try {\n return test(token as Token & AbstractToken<T>);\n } catch {\n return false;\n }\n }\n\n pickKeyword<V extends string>(\n ...values: V[]\n ): (WordToken & { value: V }) | null {\n return this.pick(\n 'Word',\n values.length ? (token) => values.includes(token.value as V) : undefined,\n ) as (WordToken & { value: V }) | null;\n }\n\n consumeKeyword<V extends string>(...values: V[]): WordToken & { value: V } {\n return this.consume(\n 'Word',\n (token) => values.includes(token.value as V),\n `'${values[0]}' keyword`,\n ) as WordToken & { value: V };\n }\n\n pickPunctuation<V extends string>(\n ...values: V[]\n ): PunctuationToken & { value: V } {\n return this.pick('Punctuation', (token) =>\n values.includes(token.value as V),\n ) as PunctuationToken & { value: V };\n }\n\n consumePunctuation<V extends string>(\n ...values: V[]\n ): PunctuationToken & { value: V } {\n return this.consume(\n 'Punctuation',\n (token) => values.includes(token.value as V),\n `'${values[0]}' token`,\n ) as PunctuationToken & { value: V };\n }\n\n pick<T extends Token['type']>(\n type: T,\n test?: ((token: Token & AbstractToken<T>) => boolean) | null,\n ): (Token & AbstractToken<T>) | null {\n const token = this.current;\n\n if (!TokenCursor.isMatch<T>(token, type, test)) {\n return null;\n }\n\n return token as Token & AbstractToken<T>;\n }\n\n consume<T extends Token['type']>(\n type: T,\n test?: ((token: Token & AbstractToken<T>) => boolean) | null,\n expected?: string,\n ): Token & AbstractToken<T> {\n const token = this.pick<T>(type, test);\n\n if (!token) {\n throw this.createError(expected);\n }\n\n this.index += 1;\n return token;\n }\n\n createError(expected?: string): ParsingError {\n const token = this.current ?? null;\n\n return new ParsingError(\n token ?? { start: this.content.length - 1, end: this.content.length },\n expected\n ? `Expect ${expected}`\n : token\n ? `Unexpected token '${this.content.slice(token.start, token.end)}'`\n : `Unexpected EOF`,\n );\n }\n\n maybeConsumeKeyword<V extends string>(\n value: V,\n ): (WordToken & { value: V }) | undefined {\n const token = this.current;\n\n if (\n !token ||\n (token as WordToken).value !== value ||\n token.type !== 'Word'\n ) {\n return undefined;\n }\n\n this.index += 1;\n return token as WordToken & { value: V };\n }\n\n maybeConsumePunctuation<V extends string>(\n value: V,\n ): (PunctuationToken & { value: V }) | undefined {\n const token = this.current;\n\n if (\n !token ||\n (token as PunctuationToken).value !== value ||\n token.type !== 'Punctuation'\n ) {\n return undefined;\n }\n\n this.index += 1;\n return token as PunctuationToken & { value: V };\n }\n\n maybeConsume<T extends Token['type']>(\n type: T,\n test?: ((token: Token & AbstractToken<T>) => boolean) | null,\n ): (Token & AbstractToken<T>) | undefined {\n const token = this.current;\n\n if (!TokenCursor.isMatch<T>(token, type, test)) {\n return undefined;\n }\n\n this.index += 1;\n return token as Token & AbstractToken<T>;\n }\n\n transaction<T>(fn: () => T): T {\n const { index: position } = this;\n\n try {\n return fn();\n } catch (error) {\n this.index = position;\n throw error;\n }\n }\n}\n","import { DocumentNode, parseDocumentNode } from './nodes';\nimport { TokenCursor } from './tokens';\n\nexport const parseStates = (\n source: string,\n filepath?: string,\n): DocumentNode => {\n const cursor = new TokenCursor(source, filepath);\n return parseDocumentNode(cursor);\n};\n"],"mappings":"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