UNPKG

@neuledge/states-parser

Version:

A parser for the Neuledge States language

1,023 lines (998 loc) 28.9 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { EITHER_KEYWORD: () => EITHER_KEYWORD, ParsingError: () => ParsingError, STATE_FIELD_INDEX_MAX_INPUT_VALUE: () => STATE_FIELD_INDEX_MAX_INPUT_VALUE, STATE_KEYWORD: () => STATE_KEYWORD, TokenCursor: () => TokenCursor, isBinaryExpressionNodeOperator: () => isBinaryExpressionNodeOperator, isLogicalExpressionNodeOperator: () => isLogicalExpressionNodeOperator, isUnaryExpressionNodeOperator: () => isUnaryExpressionNodeOperator, parseArgumentNodes: () => parseArgumentNodes, parseCallExpressionNode: () => parseCallExpressionNode, parseDecoratorNodes: () => parseDecoratorNodes, parseDocumentNode: () => parseDocumentNode, parseEitherNode: () => parseEitherNode, parseExpressionNode: () => parseExpressionNode, parseIdentifierExpressionNode: () => parseIdentifierExpressionNode, parseIdentifierNode: () => parseIdentifierNode, parseLiteralNode: () => parseLiteralNode, parseMaybeArgumentNodes: () => parseMaybeArgumentNodes, parseMaybeDescriptionNode: () => parseMaybeDescriptionNode, parseMemberExpressionNode: () => parseMemberExpressionNode, parseMutationNode: () => parseMutationNode, parseParameterNodes: () => parseParameterNodes, parseReturnBodyNodes: () => parseReturnBodyNodes, parseStateFieldNodes: () => parseStateFieldNodes, parseStateNode: () => parseStateNode, parseStates: () => parseStates, parseTypeNode: () => parseTypeNode, parseUInt8LiteralNode: () => parseUInt8LiteralNode, parseUnaryExpressionNode: () => parseUnaryExpressionNode }); module.exports = __toCommonJS(src_exports); // src/nodes/identifier.ts var parseIdentifierNode = /* @__PURE__ */ __name((cursor) => ({ type: "Identifier", path: cursor.path, start: cursor.start, name: cursor.consume("Word", null, `identifier name`).value, end: cursor.end }), "parseIdentifierNode"); // src/nodes/argument.ts var parseMaybeArgumentNodes = /* @__PURE__ */ __name((cursor, parseValue, allowImplicit) => { if (!cursor.pickPunctuation("(")) { return []; } return parseArgumentNodes(cursor, parseValue, allowImplicit); }, "parseMaybeArgumentNodes"); var parseArgumentNodes = /* @__PURE__ */ __name((cursor, parseValue, allowImplicit) => { const { index: position } = cursor; cursor.consumePunctuation("("); try { const args = []; do { if (cursor.maybeConsumePunctuation(")")) { return args; } args.push(parseArgumentNode(cursor, parseValue, allowImplicit)); } while (cursor.maybeConsumePunctuation(",")); cursor.consumePunctuation(")"); return args; } catch (error) { cursor.index = position; throw error; } }, "parseArgumentNodes"); var parseArgumentNode = /* @__PURE__ */ __name((cursor, parseValue, allowImplicit) => { const start = cursor.start; const path = cursor.path; const key = parseIdentifierNode(cursor); const explicit = allowImplicit ? cursor.maybeConsumePunctuation(":") : cursor.consumePunctuation(":"); const value = explicit ? parseValue(cursor) : key; return { type: "Argument", path, start, end: cursor.end, key, value }; }, "parseArgumentNode"); // src/nodes/literal.ts var LiteralValues = { true: true, false: false, null: null, NaN: NaN, Infinity: Infinity }; var parseLiteralNode = /* @__PURE__ */ __name((cursor, parseValue = parseLiteralValue) => ({ type: "Literal", path: cursor.path, start: cursor.start, value: parseValue(cursor), end: cursor.end }), "parseLiteralNode"); var parseUInt8LiteralNode = /* @__PURE__ */ __name((cursor) => ({ type: "Literal", path: cursor.path, start: cursor.start, value: parseUInt8(cursor), end: cursor.end }), "parseUInt8LiteralNode"); var parseUInt8 = /* @__PURE__ */ __name((cursor) => cursor.consume("Number", ({ value }) => value > 0 && Number.isInteger(value) && value <= 255, `positive unsigned integer between 1 and 255`).value, "parseUInt8"); var parseLiteralValue = /* @__PURE__ */ __name((cursor) => { const token = cursor.current; switch (token?.type) { case "String": case "Number": { cursor.index += 1; return token.value; } case "Word": { const value = LiteralValues[token.value]; if (value === void 0) { throw cursor.createError(`literal value`); } cursor.index += 1; return value; } case "Punctuation": { return parseLiteralPunctuationValue(cursor, token.value); } default: { throw cursor.createError(`literal value`); } } }, "parseLiteralValue"); var parseLiteralPunctuationValue = /* @__PURE__ */ __name((cursor, value) => { switch (value) { case "-": case "+": { cursor.index += 1; const { index: position } = cursor; const num = parseLiteralValue(cursor); if (typeof num === "number") { return value === "-" ? -num : num; } cursor.index = position; throw cursor.createError(`literal number`); } case "[": { cursor.index += 1; const values = parseLiteralArrayValues(cursor); cursor.consumePunctuation("]"); return values; } case "{": { cursor.index += 1; const entries = parseObjectEntries(cursor); cursor.consumePunctuation("}"); return Object.fromEntries(entries); } default: { throw cursor.createError(`literal value`); } } }, "parseLiteralPunctuationValue"); var parseLiteralArrayValues = /* @__PURE__ */ __name((cursor) => { const values = []; while (!cursor.pickPunctuation("]")) { values.push(parseLiteralValue(cursor)); if (!cursor.maybeConsumePunctuation(",")) { break; } } return values; }, "parseLiteralArrayValues"); var parseObjectEntries = /* @__PURE__ */ __name((cursor) => { const entries = []; while (!cursor.pickPunctuation("}")) { const key = (cursor.maybeConsume("String") || cursor.consume("Word", void 0, `object key`)).value; cursor.consumePunctuation(":"); const value = parseLiteralValue(cursor); entries.push([ key, value ]); if (!cursor.maybeConsumePunctuation(",")) { break; } } return entries; }, "parseObjectEntries"); // src/nodes/decorator.ts var parseDecoratorNodes = /* @__PURE__ */ __name((cursor) => { const decorators = []; for (let decorator; decorator = parseMaybeDecoratorNode(cursor); ) { decorators.push(decorator); } return decorators; }, "parseDecoratorNodes"); var parseMaybeDecoratorNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const path = cursor.path; const decoratorToken = cursor.maybeConsumePunctuation("@"); if (!decoratorToken) return void 0; if (!decoratorToken.adjacent) { cursor.index -= 1; throw cursor.createError("decorator name"); } const callee = parseIdentifierNode(cursor); const args = parseMaybeArgumentNodes(cursor, parseLiteralNode); return { type: "Decorator", path, start, end: cursor.end, callee, arguments: args }; }, "parseMaybeDecoratorNode"); // src/nodes/description.ts var parseMaybeDescriptionNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const path = cursor.path; const strToken = cursor.maybeConsume("String", (token) => token.kind === '"' || token.kind === '"""'); return strToken && { type: "Description", path, start, end: cursor.end, value: strToken.value }; }, "parseMaybeDescriptionNode"); // src/nodes/either.ts var EITHER_KEYWORD = "either"; var parseEitherNode = /* @__PURE__ */ __name((cursor, description, decorators = []) => { const start = cursor.start; cursor.consumeKeyword(EITHER_KEYWORD); const id = parseIdentifierNode(cursor); cursor.consumePunctuation("="); const states = parseEitherStateNodes(cursor); return { type: "Either", path: cursor.path, start, end: cursor.end, id, description, decorators, states }; }, "parseEitherNode"); var parseEitherStateNodes = /* @__PURE__ */ __name((cursor) => { const states = []; do { const state = parseIdentifierNode(cursor); states.push(state); } while (cursor.maybeConsumePunctuation("|")); return states; }, "parseEitherStateNodes"); // src/nodes/expressions/binary.ts var BinaryExpressionNodeOperators = { "+": 1, "-": 1, "*": 1, "/": 1, "%": 1, "**": 1, "==": 1, "!=": 1, "===": 1, "!==": 1, "<": 1, "<=": 1, ">": 1, ">=": 1 }; var isBinaryExpressionNodeOperator = /* @__PURE__ */ __name((operator) => operator in BinaryExpressionNodeOperators, "isBinaryExpressionNodeOperator"); // src/nodes/expressions/identifier.ts var parseIdentifierExpressionNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const value = cursor.pickKeyword("this", "null")?.value; switch (value) { case "this": { cursor.consumeKeyword("this"); return { type: "ThisExpression", path: cursor.path, start, end: cursor.end, name: "this" }; } case "null": { cursor.consumeKeyword("null"); return { type: "NullLiteral", path: cursor.path, start, end: cursor.end, value: null }; } default: { return parseIdentifierNode(cursor); } } }, "parseIdentifierExpressionNode"); // src/nodes/expressions/logical.ts var LogicalExpressionNodeOperators = { "&&": 1, "||": 1, "??": 1 }; var isLogicalExpressionNodeOperator = /* @__PURE__ */ __name((operator) => operator in LogicalExpressionNodeOperators, "isLogicalExpressionNodeOperator"); // src/nodes/expressions/member.ts var parseMemberExpressionNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; let object = parseIdentifierExpressionNode(cursor); if (object.type === "NullLiteral") { throw cursor.createError(`Unexpected null literal`); } cursor.consumePunctuation("."); do { const property = parseIdentifierNode(cursor); object = { type: "MemberExpression", path: cursor.path, start, end: cursor.end, object, property }; } while (cursor.maybeConsumePunctuation(".")); return object; }, "parseMemberExpressionNode"); // src/nodes/expressions/unary.ts var UnaryExpressionNodeOperators = { "!": 1, "-": 1, "+": 1, "~": 1 }; var UnaryExpressionNodeOperatorsArray = Object.keys(UnaryExpressionNodeOperators); var isUnaryExpressionNodeOperator = /* @__PURE__ */ __name((operator) => operator in UnaryExpressionNodeOperators, "isUnaryExpressionNodeOperator"); var parseUnaryExpressionNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const operator = cursor.consumePunctuation(...UnaryExpressionNodeOperatorsArray).value; const argument = parseExpressionNode(cursor); return { type: "UnaryExpression", path: cursor.path, start, end: cursor.end, operator, argument }; }, "parseUnaryExpressionNode"); // src/nodes/expressions/expression.ts var parseExpressionNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const node = parseCoreExpressionNode(cursor); const current = cursor.current; if (current?.type !== "Punctuation") { return node; } if (isLogicalExpressionNodeOperator(current.value)) { cursor.consume("Punctuation"); const right = parseExpressionNode(cursor); return { type: "LogicalExpression", path: cursor.path, start, end: cursor.end, operator: current.value, left: node, right }; } if (isBinaryExpressionNodeOperator(current.value)) { cursor.consume("Punctuation"); const right = parseExpressionNode(cursor); return { type: "BinaryExpression", path: cursor.path, start, end: cursor.end, operator: current.value, left: node, right }; } return node; }, "parseExpressionNode"); var parseCoreExpressionNode = /* @__PURE__ */ __name((cursor) => { const { current, next } = cursor; if (current?.type === "Punctuation") { if (current.value === "(") { cursor.consumePunctuation("("); const node = parseExpressionNode(cursor); cursor.consumePunctuation(")"); return node; } if (isUnaryExpressionNodeOperator(current.value)) { return parseUnaryExpressionNode(cursor); } return parseLiteralNode(cursor); } if (current?.type !== "Word") { return parseLiteralNode(cursor); } switch (next?.value) { case "(": { return parseCallExpressionNode(cursor); } case ".": { return parseMemberExpressionNode(cursor); } default: { return parseIdentifierExpressionNode(cursor); } } }, "parseCoreExpressionNode"); // src/nodes/expressions/call.ts var parseCallExpressionNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const callee = parseIdentifierNode(cursor); const args = parseArgumentNodes(cursor, parseExpressionNode, true); return { type: "CallExpression", path: cursor.path, start, end: cursor.end, callee, arguments: args }; }, "parseCallExpressionNode"); // src/nodes/type.ts var parseTypeNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const path = cursor.path; const identifier = parseIdentifierNode(cursor); const args = parseMaybeArgumentNodes(cursor, parseLiteralNode); if (args.length) { return { type: "TypeGenerator", path, start, end: cursor.end, identifier, arguments: args }; } const list = !!cursor.maybeConsumePunctuation("["); if (list) { cursor.consumePunctuation("]"); } return { type: "TypeExpression", path, start, end: cursor.end, identifier, list }; }, "parseTypeNode"); // src/nodes/parameter.ts var parseParameterNodes = /* @__PURE__ */ __name((cursor) => { const parameters = []; cursor.consumePunctuation("("); while (!cursor.maybeConsumePunctuation(")")) { const parameter = parseParameterNode(cursor); parameters.push(parameter); cursor.maybeConsumePunctuation(","); } return parameters; }, "parseParameterNodes"); var parseParameterNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const description = parseMaybeDescriptionNode(cursor); const decorators = parseDecoratorNodes(cursor); const key = parseIdentifierNode(cursor); const nullable = !!cursor.maybeConsumePunctuation("?"); cursor.consumePunctuation(":"); const as = parseTypeNode(cursor); return { type: "Parameter", path: cursor.path, start, end: cursor.end, key, as, nullable, description, decorators }; }, "parseParameterNode"); // src/nodes/property.ts var parseReturnBodyNodes = /* @__PURE__ */ __name((cursor) => { const body = []; cursor.consumePunctuation("{"); do { if (cursor.maybeConsumePunctuation("}")) { return body; } body.push(parseReturnBodyNode(cursor)); } while (cursor.maybeConsumePunctuation(",")); cursor.consumePunctuation("}"); return body; }, "parseReturnBodyNodes"); var parseReturnBodyNode = /* @__PURE__ */ __name((cursor) => { const start = cursor.start; const key = parseIdentifierNode(cursor); const explicit = cursor.maybeConsumePunctuation(":"); const value = explicit ? parseExpressionNode(cursor) : key; return { type: "Property", path: cursor.path, start, end: cursor.end, key, value }; }, "parseReturnBodyNode"); // src/nodes/mutation.ts var parseMutationNode = /* @__PURE__ */ __name((cursor, description, decorators = []) => { const start = cursor.start; const firstId = parseIdentifierNode(cursor); const secondId = cursor.maybeConsumePunctuation(".") ? parseIdentifierNode(cursor) : void 0; const parameters = parseParameterNodes(cursor); cursor.consumePunctuation(":"); const returns = parseIdentifierNode(cursor); const hasBody = cursor.maybeConsumePunctuation("=>"); const body = hasBody ? parseReturnBodyNodes(cursor) : []; return { type: "Mutation", path: cursor.path, start, end: cursor.end, key: secondId || firstId, description, decorators, from: secondId ? firstId : void 0, parameters, returns, body }; }, "parseMutationNode"); // src/error.ts var ParsingError = class _ParsingError extends SyntaxError { static { __name(this, "ParsingError"); } name = "ParsingError"; start; end; path; constructor(position, message) { super(message); Object.setPrototypeOf(this, _ParsingError.prototype); this.start = position.start; this.end = position.end; this.path = position.path; this.stack = `${this.name}: ${this.message}\r at ${this.path ?? `character ${this.start}`}`; } }; // src/nodes/state-field.ts var STATE_FIELD_INDEX_MAX_INPUT_VALUE = 255; var parseStateFieldNodes = /* @__PURE__ */ __name((cursor, hasParent) => { const fieldMap = {}; const indexMap = {}; cursor.consumePunctuation("{"); while (!cursor.maybeConsumePunctuation("}")) { const field = parseStateFieldNode(cursor); if (fieldMap[field.key.name]) { throw new ParsingError(field.key, `Duplicate field name '${field.key.name}'`); } if (!hasParent && field.type === "ExcludedField") { throw new ParsingError(field, `Unexpected excluded field on state without a parent state`); } if ("index" in field) { if (indexMap[field.index.value]) { throw new ParsingError(field.index, `Duplicate index for field name '${indexMap[field.index.value].key.name}'`); } indexMap[field.index.value] = field; } fieldMap[field.key.name] = field; cursor.maybeConsumePunctuation(","); } return Object.values(fieldMap); }, "parseStateFieldNodes"); var parseStateFieldNode = /* @__PURE__ */ __name((cursor) => { const description = parseMaybeDescriptionNode(cursor); const decorators = parseDecoratorNodes(cursor); const maybeRef = !description && !decorators.length; const start = cursor.start; const path = cursor.path; const substractSign = maybeRef ? cursor.maybeConsumePunctuation("-") : void 0; const firstId = parseIdentifierNode(cursor); if (substractSign) { return { type: "ExcludedField", key: firstId, path, start, end: cursor.end }; } const dotSign = maybeRef ? cursor.maybeConsumePunctuation(".") : void 0; if (!dotSign) { return parseFieldNode(cursor, { path, start, key: firstId, description, decorators }); } const secId = parseIdentifierNode(cursor); return parseReferenceFieldNode(cursor, { path, start, state: firstId, key: secId }); }, "parseStateFieldNode"); var parseFieldNode = /* @__PURE__ */ __name((cursor, base) => { const nullSign = cursor.maybeConsumePunctuation("?"); cursor.maybeConsumePunctuation(":"); const as = parseTypeNode(cursor); const index = parseIndex(cursor); return { type: "Field", ...base, end: cursor.end, as, index, nullable: !!nullSign }; }, "parseFieldNode"); var parseReferenceFieldNode = /* @__PURE__ */ __name((cursor, base) => { const index = parseIndex(cursor); return { type: "ReferenceField", ...base, end: cursor.end, index }; }, "parseReferenceFieldNode"); var parseIndex = /* @__PURE__ */ __name((cursor) => { cursor.consumePunctuation("="); return parseUInt8LiteralNode(cursor); }, "parseIndex"); // src/nodes/state.ts var STATE_KEYWORD = "state"; var parseStateNode = /* @__PURE__ */ __name((cursor, description, decorators = []) => { const start = cursor.start; cursor.consumeKeyword(STATE_KEYWORD); const id = parseIdentifierNode(cursor); const fromKeyword = cursor.maybeConsumeKeyword("from"); let from; if (fromKeyword) { from = parseIdentifierNode(cursor); } const fields = parseStateFieldNodes(cursor, !!from); return { type: "State", path: cursor.path, start, end: cursor.end, id, description, from, fields, decorators }; }, "parseStateNode"); // src/nodes/document.ts var parseDocumentNode = /* @__PURE__ */ __name((cursor) => ({ type: "Root", path: cursor.path, start: cursor.start, body: parseDocumentBodyNodes(cursor), end: cursor.end }), "parseDocumentNode"); var parseDocumentBodyNodes = /* @__PURE__ */ __name((cursor) => { const body = []; while (cursor.current) { const description = parseMaybeDescriptionNode(cursor); const decorators = parseDecoratorNodes(cursor); const keyword = cursor.pickKeyword(); const nodeKeyword = keyword && cursor.next?.type === "Word" ? keyword.value : null; let node; switch (nodeKeyword) { case STATE_KEYWORD: { node = parseStateNode(cursor, description, decorators); break; } case EITHER_KEYWORD: { node = parseEitherNode(cursor, description, decorators); break; } default: { if (!keyword) { throw cursor.createError(); } node = parseMutationNode(cursor, description, decorators); } } body.push(node); } return body; }, "parseDocumentBodyNodes"); // src/tokens/tokenize.ts var TokenCharMap = { '"': "String", "'": "String", "": -1, " ": -1, " ": -1, "\r": -1, "\n": -1 }; for (const char of "$_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") { TokenCharMap[char] = "Word"; } for (const char of "0123456789") { TokenCharMap[char] = "Number"; } var tokenize = /* @__PURE__ */ __name((content, path) => { const values = splitTokenValues(content); const tokens = []; let position = 0; let line = 1; let column = 1; let isComment = false; let lastPunctuation = null; for (const value of values) { if (!isComment) { const token = parseToken(value, position, path && `${path}:${line}:${column}`); if (token) { if (lastPunctuation) { lastPunctuation.adjacent = true; } tokens.push(token); lastPunctuation = token.type === "Punctuation" ? token : null; } else { lastPunctuation = null; if (value === "#") isComment = true; } } const lines = value.split(/\r*\n/g); if (lines.length > 1) { line += lines.length - 1; column = 1; } column += lines.at(-1)?.length ?? 0; position += value.length; if (isComment && value.includes("\n")) { isComment = false; } } return tokens; }, "tokenize"); var splitTokenValues = /* @__PURE__ */ __name((content) => content.match(/([$_a-z]\w*|(?:\d*\.\d+|\d+)|\s+|"""(?:[^"]+|"[^"]|""[^"])*"""|"(?:[^\n"\\]+|\\.)*"|'(?:[^\n'\\]+|\\.)*'|[<=>]=|=>|[!=]==|&&|!!|\|\||\?\?|\*\*|\.\.\.|.)/gi) || [], "splitTokenValues"); var parseToken = /* @__PURE__ */ __name((value, position, path) => { const kind = value[0]; const type = TokenCharMap[kind] || "Punctuation"; const start = position; const end = position + value.length; switch (type) { case "Number": { return { type, path, start, end, value: Number(value) }; } case "String": { return { type, start, end, ...parseStringToken(kind, value) }; } case "Punctuation": { if (value.length > 1 && /^[+-]?(?:\d*\.\d+|\d+)$/.test(value)) { return { type: "Number", path, start, end, value: Number(value) }; } if (value === "#") { return null; } return { type, path, start, end, value, adjacent: false }; } case "Word": { return { type, path, start, end, value }; } case -1: { return null; } } }, "parseToken"); var parseStringToken = /* @__PURE__ */ __name((kind, raw) => { if (kind === '"' && raw[1] === '"' && raw[2] === '"') { return { kind: '"""', value: raw.slice(3, -3).trim().replaceAll(/[\t ]*\r?\n[\t ]*/g, "\n") }; } return { kind, value: raw.slice(1, -1).replaceAll(/\\(.)/g, "$1") }; }, "parseStringToken"); // src/tokens/cursor.ts var TokenCursor = class _TokenCursor { static { __name(this, "TokenCursor"); } content; index; tokens; constructor(content, path, index = 0) { this.content = content; this.index = index; this.tokens = tokenize(content, path); } get current() { return this.tokens[this.index]; } get next() { return this.tokens[this.index + 1]; } get path() { return this.tokens[this.index]?.path; } get start() { return this.tokens[this.index]?.start ?? this.content.length; } get end() { return this.tokens[this.index - 1]?.end ?? 0; } static isMatch(token, type, test) { if (token?.type !== type) { return false; } if (test == null) { return true; } try { return test(token); } catch { return false; } } pickKeyword(...values) { return this.pick("Word", values.length ? (token) => values.includes(token.value) : void 0); } consumeKeyword(...values) { return this.consume("Word", (token) => values.includes(token.value), `'${values[0]}' keyword`); } pickPunctuation(...values) { return this.pick("Punctuation", (token) => values.includes(token.value)); } consumePunctuation(...values) { return this.consume("Punctuation", (token) => values.includes(token.value), `'${values[0]}' token`); } pick(type, test) { const token = this.current; if (!_TokenCursor.isMatch(token, type, test)) { return null; } return token; } consume(type, test, expected) { const token = this.pick(type, test); if (!token) { throw this.createError(expected); } this.index += 1; return token; } createError(expected) { const token = this.current ?? null; return new ParsingError(token ?? { start: this.content.length - 1, end: this.content.length }, expected ? `Expect ${expected}` : token ? `Unexpected token '${this.content.slice(token.start, token.end)}'` : `Unexpected EOF`); } maybeConsumeKeyword(value) { const token = this.current; if (!token || token.value !== value || token.type !== "Word") { return void 0; } this.index += 1; return token; } maybeConsumePunctuation(value) { const token = this.current; if (!token || token.value !== value || token.type !== "Punctuation") { return void 0; } this.index += 1; return token; } maybeConsume(type, test) { const token = this.current; if (!_TokenCursor.isMatch(token, type, test)) { return void 0; } this.index += 1; return token; } transaction(fn) { const { index: position } = this; try { return fn(); } catch (error) { this.index = position; throw error; } } }; // src/parser.ts var parseStates = /* @__PURE__ */ __name((source, filepath) => { const cursor = new TokenCursor(source, filepath); return parseDocumentNode(cursor); }, "parseStates"); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { EITHER_KEYWORD, ParsingError, STATE_FIELD_INDEX_MAX_INPUT_VALUE, STATE_KEYWORD, TokenCursor, isBinaryExpressionNodeOperator, isLogicalExpressionNodeOperator, isUnaryExpressionNodeOperator, parseArgumentNodes, parseCallExpressionNode, parseDecoratorNodes, parseDocumentNode, parseEitherNode, parseExpressionNode, parseIdentifierExpressionNode, parseIdentifierNode, parseLiteralNode, parseMaybeArgumentNodes, parseMaybeDescriptionNode, parseMemberExpressionNode, parseMutationNode, parseParameterNodes, parseReturnBodyNodes, parseStateFieldNodes, parseStateNode, parseStates, parseTypeNode, parseUInt8LiteralNode, parseUnaryExpressionNode }); //# sourceMappingURL=index.js.map