UNPKG

@artemis-lang/parser

Version:

The artemis language parser

1,121 lines (1,076 loc) 36.3 kB
// src/node/node-types.ts var NodeTypes = { Program: "Program", Binary: "Binary", Hex: "Hex", Number: "Number", String: "String", Boolean: "Boolean", List: "List", Map: "Map", Set: "Set", BinaryLiteral: "BinaryLiteral", HexLiteral: "HexLiteral", NumberLiteral: "NumberLiteral", StringLiteral: "StringLiteral", BooleanLiteral: "BooleanLiteral", ListLiteral: "ListLiteral", MapLiteral: "MapLiteral", SetLiteral: "SetLiteral", Fn: "Fn", FnCall: "FnCall", NativeFnCall: "NativeFnCall", Result: "Result", NativeFnResult: "NativeFnResult", Reference: "Reference", If: "If", While: "While", For: "For", Match: "Match", BinaryExpression: "BinaryExpression", UnaryExpression: "UnaryExpression", BinaryExpressionLiteral: "BinaryExpressionLiteral", UnaryExpressionLiteral: "UnaryExpressionLiteral", JsCode: "JsCode", Return: "Return" }; var node_types_default = NodeTypes; // src/error/index.ts var debug = true; function error(message, token, input) { const lines = input.split("\n"); const line = lines[token.line - 1]; const col = token.col; const arrow = " ".repeat(col - 1) + "^"; if (debug) { throw new Error( `Artemis Parser Error: ${message} at line ${token.line} column ${token.col} ${line} ${arrow}` ); } console.error( `Artemis Parser Error: ${message} at line ${token.line} column ${token.col} ${line} ${arrow}` ); process.exit(1); } var error_default = error; // src/parser-plugin/index.ts var ParserPlugin = class { matcher; handler; constructor(matcher, handler, _options) { this.matcher = matcher; this.handler = handler; } }; var parser_plugin_default = ParserPlugin; // src/plugins/binary-operations/bin-op-plugin.ts var binaryExpressionPlugin = new parser_plugin_default( (parser) => { const binopSyms = [ "+", "-", "*", "**", "/", "%", "^", ">", "<", ">=", "<=", "==", "!=", "&&", "||", "??", ">>", "<<", ">>>" ]; return parser.peek().type === "lp" && parser.nextByType(1) === "operator" && binopSyms.includes(parser.nextBy(1).text); }, (parser) => { parser.consume("lp", "Expected left parenthesis"); const operator = parser.consume("operator", "Expected operator"); const left = parser.parseExpression(); const right = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.BinaryExpressionLiteral, operator: operator.value, left, right }; } ); var bin_op_plugin_default = binaryExpressionPlugin; // src/plugins/binary/binary-plugin.ts var binaryPlugin = new parser_plugin_default( (parser) => { return parser.match("binary"); }, (parser) => { const left = parser.consume("binary", "Expected binary").value; return { type: node_types_default.BinaryLiteral, value: left }; } ); var binary_plugin_default = binaryPlugin; // src/plugins/booleans/boolean-plugin.ts var booleanPlugin = new parser_plugin_default( (parser) => { return parser.match("boolean"); }, (parser) => { return { type: node_types_default.BooleanLiteral, value: parser.consume("boolean", "Expected boolean").value === "true" }; } ); var boolean_plugin_default = booleanPlugin; // src/plugins/definitions/binary-def-plugin.ts var binaryDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "binary"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const value = parser.consume("binary", "Expected binary"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Binary, name: name.value, value: value.value }; } ); var binary_def_plugin_default = binaryDefPlugin; // src/plugins/definitions/binop-def-plugin.ts var binaryExpressionDefPlugin = new parser_plugin_default( (parser) => { const binopSyms = [ "+", "-", "*", "/", "%", "^", ">", "<", ">=", "<=", "==", "!=", "&&", "||", "??", "=>", ">>", "<<", ">>>" ]; return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lp" && parser.nextByType(4) === "operator" && binopSyms.includes(parser.nextBy(4).text); }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lp", "Expected left parenthesis"); const operator = parser.consume("operator", "Expected operator"); const left = parser.parseExpression(); const right = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.BinaryExpression, name: name.value, operator: operator.value, left, right }; } ); var binop_def_plugin_default = binaryExpressionDefPlugin; // src/plugins/definitions/boolean-def-plugin.ts var booleanDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "boolean"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const value = parser.consume("boolean", "Expected boolean"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Boolean, name: name.value, value: value.value === "true" }; } ); var boolean_def_plugin_default = booleanDefPlugin; // src/plugins/definitions/float-def-plugin.ts var floatDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "number" && parser.nextByType(4) === "dot" && parser.nextByType(5) === "number"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const left = parser.consume("number", "Expected number").value; parser.consume("dot", "Expected dot"); const right = parser.consume("number", "Expected number").value; parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Number, name: name.value, value: left + "." + right }; } ); var float_def_plugin_default = floatDefPlugin; // src/plugins/definitions/function-def-plugin.ts var functionDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "fn" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lbk"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lbk", "Expected left bracket"); const args = []; while (parser.peek().type !== "rbk" && !parser.isAtEnd()) { args.push(parser.consume("identifier", "Expected identifier").value); } parser.consume("rbk", "Expected right bracket"); parser.consume("lp", "Expected left parenthesis"); const body = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { body.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Fn, name: name.value, args, body }; } ); var function_def_plugin_default = functionDefPlugin; // src/plugins/definitions/hex-def-plugin.ts var hexDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "hex"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const value = parser.consume("hex", "Expected hex"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Hex, name: name.value, value: value.value }; } ); var hex_def_plugin_default = hexDefPlugin; // src/plugins/definitions/list-def-plugin.ts var listDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lbk"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lbk", "Expected left bracket"); const value = []; while (parser.peek().type !== "rbk" && !parser.isAtEnd()) { value.push(parser.parseExpression()); if (parser.peek().type === "comma") parser.consume("comma", "Expected comma"); } parser.consume("rbk", "Expected right bracket"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.List, name: name.value, value }; } ); var list_def_plugin_default = listDefPlugin; // src/plugins/definitions/map-def-plugin.ts var mapDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lb"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lb", "Expected left brace"); const value = /* @__PURE__ */ new Map(); while (parser.peek().type !== "rb" && !parser.isAtEnd()) { const key = parser.consume("identifier", "Expected identifier"); parser.consume("colon", "Expected colon"); const val = parser.parseExpression(); value.set(key.value, val); if (parser.peek().type === "comma") parser.consume("comma", "Expected comma"); } parser.consume("rb", "Expected right brace"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Map, name: name.value, value }; } ); var map_def_plugin_default = mapDefPlugin; // src/plugins/definitions/number-def-plugin.ts var numberDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "number"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const value = parser.consume("number", "Expected number"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Number, name: name.value, value: value.value }; } ); var number_def_plugin_default = numberDefPlugin; // src/plugins/definitions/set-def-plugin.ts var setDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "hash"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("hash", "Expected hash"); parser.consume("lbk", "Expected left bracket"); const value = /* @__PURE__ */ new Set(); while (parser.peek().type !== "rbk" && !parser.isAtEnd()) { value.add(parser.parseExpression()); if (parser.peek().type === "comma") parser.consume("comma", "Expected comma"); } parser.consume("rbk", "Expected right bracket"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Set, name: name.value, value }; } ); var set_def_plugin_default = setDefPlugin; // src/plugins/definitions/signed-float-plugin.ts var signedFloatDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && (parser.nextByType(3) === "operator" || parser.nextByType(3) === "operator") && parser.nextByType(4) === "number" && parser.nextByType(5) === "dot" && parser.nextByType(6) === "number"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const op = parser.consume("operator", "Expected operator"); const left = parser.consume("number", "Expected number").value; parser.consume("dot", "Expected dot"); const right = parser.consume("number", "Expected number").value; parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Number, name: name.value, value: op.value + left + "." + right }; } ); var signed_float_plugin_default = signedFloatDefPlugin; // src/plugins/definitions/signed-number-def-plugin.ts var signedNumberDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "operator" && parser.nextByType(4) === "number"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const op = parser.consume("operator", "Expected operator"); const value = parser.consume("number", "Expected number"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Number, name: name.value, value: op.value + value.value }; } ); var signed_number_def_plugin_default = signedNumberDefPlugin; // src/plugins/definitions/string-def-plugin.ts var stringDefPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "string"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); const value = parser.consume("string", "Expected string"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.String, name: name.value, value: value.value }; } ); var string_def_plugin_default = stringDefPlugin; // src/plugins/definitions/uniop-def-plugin.ts var unaryExpressionDefPlugin = new parser_plugin_default( (parser) => { const uniopSyms = ["!", "~", "++", "--"]; return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lp" && parser.nextByType(4) === "operator" && uniopSyms.includes(parser.nextBy(4).text); }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lp", "Expected left parenthesis"); const operator = parser.consume("operator", "Expected operator"); const operand = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.UnaryExpression, name: name.value, operator: operator.value, operand }; } ); var uniop_def_plugin_default = unaryExpressionDefPlugin; // src/plugins/for-statement/for-plugin.ts var forPlugin = new parser_plugin_default( (parser) => { return parser.match("lp") && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "for" && parser.nextByType(2) === "lbk"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); parser.consume("lbk", "Expected left bracket"); const index = parser.consume("identifier", "Expected identifier"); const start = parser.parseExpression(); const end = parser.parseExpression(); const step = parser.peek().type !== "rbk" ? parser.parseExpression() : null; parser.consume("rbk", "Expected right bracket"); parser.consume("lp", "Expected left parenthesis"); const body = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { body.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.For, index: index.value, start, end, step: step ? step : null, body }; } ); var for_plugin_default = forPlugin; // src/plugins/functions/function-call-plugin.ts var functionCallPlugin = new parser_plugin_default( (parser) => { return parser.match("lp") && parser.nextByType(1) === "identifier" && parser.nextByType(2) !== "dot"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); const name = parser.consume("identifier", "Expected identifier"); const params = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { params.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.FnCall, name: name.value, params }; } ); var function_call_plugin_default = functionCallPlugin; // src/plugins/functions/function-plugin.ts var functionPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "fn" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lbk"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lbk", "Expected left bracket"); const args = []; while (parser.peek().type !== "rb" && !parser.isAtEnd()) { args.push(parser.consume("identifier", "Expected identifier").value); } parser.consume("rbk", "Expected right bracket"); parser.consume("lp", "Expected left parenthesis"); const body = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { body.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Fn, name: name.value, args, body }; } ); var function_plugin_default = functionPlugin; // src/plugins/functions/native-function-plugin.ts var nativeFunctionCallPlugin = new parser_plugin_default( (parser) => { return parser.match("lp") && parser.nextByType(1) === "nativeFn" && parser.nextByType(2) !== "dot"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); const name = parser.consume("nativeFn", "Expected native function call"); const params = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { params.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.NativeFnCall, name: name.value, params }; } ); var native_function_plugin_default = nativeFunctionCallPlugin; // src/plugins/hex/hex-plugin.ts var hexPlugin = new parser_plugin_default( (parser) => { return parser.match("hex"); }, (parser) => { const left = parser.consume("hex", "Expected hex").value; return { type: node_types_default.HexLiteral, value: left }; } ); var hex_plugin_default = hexPlugin; // src/plugins/if-statement/if-plugin.ts var ifPlugin = new parser_plugin_default( (parser) => { return parser.match("lp") && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "if"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); parser.consume("lp", "Expected left parenthesis"); const condition = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); parser.consume("lp", "Expected left parenthesis"); const thenBranch = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); if (parser.match("lp")) { parser.consume("lp", "Expected left parenthesis"); const elseBranch = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.If, condition, thenBranch, elseBranch }; } parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.If, condition, thenBranch, elseBranch: null }; } ); var if_plugin_default = ifPlugin; // src/plugins/lists/list-plugin.ts var listPlugin = new parser_plugin_default( (parser) => { return parser.match("lbk"); }, (parser) => { parser.consume("lbk", "Expected left bracket"); const value = []; while (parser.peek().type !== "rbk" && !parser.isAtEnd()) { value.push(parser.parseExpression()); if (parser.peek().type === "comma") parser.consume("comma", "Expected comma"); } parser.consume("rbk", "Expected right bracket"); return { type: node_types_default.ListLiteral, value }; } ); var list_plugin_default = listPlugin; // src/plugins/maps/map-plugin.ts var mapPlugin = new parser_plugin_default( (parser) => { return parser.match("lb"); }, (parser) => { parser.consume("lb", "Expected left brace"); const value = /* @__PURE__ */ new Map(); while (parser.peek().type !== "rb" && !parser.isAtEnd()) { const key = parser.consume("identifier", "Expected identifier"); parser.consume("colon", "Expected colon"); const val = parser.parseExpression(); value.set(key.value, val); if (parser.peek().type === "comma") parser.consume("comma", "Expected comma"); } parser.consume("rb", "Expected right brace"); return { type: node_types_default.MapLiteral, value }; } ); var map_plugin_default = mapPlugin; // src/plugins/match/match-plugin.ts var matchPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "match"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const condition = parser.parseExpression(); parser.consume("lb", "Expected left brace"); const value = /* @__PURE__ */ new Map(); while (parser.peek().type !== "rb" && !parser.isAtEnd()) { const key = parser.parseExpression(); parser.consume("colon", "Expected colon"); const val = parser.parseExpression(); value.set(key, val); if (parser.peek().type === "comma") parser.consume("comma", "Expected comma"); } parser.consume("rb", "Expected right brace"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Match, value, condition }; } ); var match_plugin_default = matchPlugin; // src/plugins/numbers/float-plugin.ts var floatPlugin = new parser_plugin_default( (parser) => { return parser.match("number") && parser.nextBy(1).type === "dot" && parser.nextBy(2).type === "number"; }, (parser) => { const left = parser.consume("number", "Expected number").value; parser.consume("dot", "Expected dot"); const right = parser.consume("number", "Expected number").value; return { type: node_types_default.NumberLiteral, value: left + "." + right }; } ); var float_plugin_default = floatPlugin; // src/plugins/numbers/number-plugin.ts var numberPlugin = new parser_plugin_default( (parser) => { return parser.match("number"); }, (parser) => { return { type: node_types_default.NumberLiteral, value: parser.consume("number", "Expected number").value }; } ); var number_plugin_default = numberPlugin; // src/plugins/numbers/signed-float-plugin.ts var signedFloatPlugin = new parser_plugin_default( (parser) => { return (parser.match("operator", "+") || parser.match("operator", "-")) && parser.nextBy(1).type === "number" && parser.nextBy(2).type === "dot"; }, (parser) => { const op = parser.consume("operator", "Expected operator"); const left = parser.consume("number", "Expected number").value; parser.consume("dot", "Expected dot"); const right = parser.consume("number", "Expected number").value; return { type: node_types_default.NumberLiteral, value: op.value + left + "." + right }; } ); var signed_float_plugin_default2 = signedFloatPlugin; // src/plugins/numbers/signed-number-plugin.ts var signedNumberPlugin = new parser_plugin_default( (parser) => { return (parser.match("operator", "+") || parser.match("operator", "-")) && parser.nextBy(1).type === "number"; }, (parser) => { const op = parser.consume("operator", "Expected operator"); return { type: node_types_default.NumberLiteral, value: op.value + parser.consume("number", "Expected number").value }; } ); var signed_number_plugin_default = signedNumberPlugin; // src/plugins/reference/ref-plugin.ts var referencePlugin = new parser_plugin_default( (parser) => { return parser.match("identifier"); }, (parser) => { return { type: node_types_default.Reference, value: parser.consume("identifier", "Expected identifier").value }; } ); var ref_plugin_default = referencePlugin; // src/plugins/result/function-result-plugin.ts var functionResultPlugin = new parser_plugin_default( (parser) => { return parser.match("lp") && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "def" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lp" && parser.nextByType(4) === "identifier"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lp", "Expected left parenthesis"); const fnName = parser.consume("identifier", "Expected identifier"); const params = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { params.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Result, name: name.value, fnName: fnName.value, params }; } ); var function_result_plugin_default = functionResultPlugin; // src/plugins/result/native-function-result-plugin.ts var nativeFnRsultPlugin = new parser_plugin_default( (parser) => { return parser.match("lp") && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "def" && parser.nextByType(2) === "identifier" && parser.nextByType(3) === "lp" && parser.nextByType(4) === "nativeFn"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const name = parser.consume("identifier", "Expected identifier"); parser.consume("lp", "Expected left parenthesis"); const fnName = parser.consume("nativeFn", "Expected native function call"); const params = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { params.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.NativeFnResult, name: name.value, nativeFn: fnName.value, params }; } ); var native_function_result_plugin_default = nativeFnRsultPlugin; // src/plugins/sets/set-plugin.ts var setPlugin = new parser_plugin_default( (parser) => { return parser.match("hash"); }, (parser) => { parser.consume("hash", "Expected hash"); parser.consume("lbk", "Expected left bracket"); const value = /* @__PURE__ */ new Set(); while (parser.peek().type !== "rbk" && !parser.isAtEnd()) { value.add(parser.parseExpression()); if (parser.peek().type === "comma") parser.consume("comma", "Expected comma"); } parser.consume("rbk", "Expected right bracket"); return { type: node_types_default.SetLiteral, value }; } ); var set_plugin_default = setPlugin; // src/plugins/strings/string-plugin.ts var stringPlugin = new parser_plugin_default( (parser) => { return parser.match("string"); }, (parser) => { return { type: node_types_default.StringLiteral, value: parser.consume("string", "Expected string").value }; } ); var string_plugin_default = stringPlugin; // src/plugins/unary-operations/unary-expression-plugin.ts var unaryExpressionPlugin = new parser_plugin_default( (parser) => { const uniopSyms = ["!", "~", "++", "--"]; return parser.peek().type === "lp" && parser.nextByType(1) === "operator" && uniopSyms.includes(parser.nextBy(1).text); }, (parser) => { parser.consume("lp", "Expected left parenthesis"); const operator = parser.consume("operator", "Expected operator"); const operand = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.UnaryExpressionLiteral, operator: operator.value, operand }; } ); var unary_expression_plugin_default = unaryExpressionPlugin; // src/plugins/while-statement/while-plugin.ts var whilePlugin = new parser_plugin_default( (parser) => { return parser.match("lp") && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "while"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); parser.consume("lp", "Expected left parenthesis"); const condition = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); parser.consume("lp", "Expected left parenthesis"); const body = []; while (parser.peek().type !== "rp" && !parser.isAtEnd()) { body.push(parser.parseExpression()); } parser.consume("rp", "Expected right parenthesis"); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.While, condition, body }; } ); var while_plugin_default = whilePlugin; // src/plugins/js/js-code.ts var jsCodePlugin = new parser_plugin_default( (parser) => { return parser.match("jsCode"); }, (parser) => { const code = parser.consume("jsCode", "Expected js code"); return { type: node_types_default.JsCode, value: code.value.slice(1, -1) }; } ); var js_code_default = jsCodePlugin; // src/plugins/functions/function-return-plugin.ts var functionReturnPlugin = new parser_plugin_default( (parser) => { return parser.peek().type === "lp" && parser.nextByType(1) === "keyword" && parser.nextBy(1).value === "return"; }, (parser) => { parser.consume("lp", "Expected left parenthesis"); parser.consume("keyword", "Expected keyword"); const value = parser.parseExpression(); parser.consume("rp", "Expected right parenthesis"); return { type: node_types_default.Return, value }; } ); var function_return_plugin_default = functionReturnPlugin; // src/plugins/index.ts var plugins = [ js_code_default, function_def_plugin_default, function_plugin_default, function_return_plugin_default, native_function_plugin_default, function_call_plugin_default, match_plugin_default, if_plugin_default, while_plugin_default, for_plugin_default, native_function_result_plugin_default, function_result_plugin_default, signed_float_plugin_default, signed_float_plugin_default2, float_def_plugin_default, float_plugin_default, signed_number_def_plugin_default, signed_number_plugin_default, number_def_plugin_default, number_plugin_default, string_def_plugin_default, string_plugin_default, boolean_def_plugin_default, boolean_plugin_default, hex_plugin_default, hex_def_plugin_default, binary_plugin_default, binary_def_plugin_default, list_def_plugin_default, list_plugin_default, set_def_plugin_default, set_plugin_default, map_def_plugin_default, map_plugin_default, uniop_def_plugin_default, binop_def_plugin_default, unary_expression_plugin_default, bin_op_plugin_default, ref_plugin_default ]; var plugins_default = plugins; // src/lib/parser.ts var Parser = class { tokens; current; plugins; input; constructor(lexer) { this.tokens = this.init(lexer.tokenize().tokens); this.input = lexer.code; this.current = 0; this.plugins = plugins_default; } init(tokens) { return tokens.filter( (v) => v.type !== "ws" && v.type !== "nl" && v.type !== "multilineComment" && v.type !== "singlelineComment" ); } isAtEnd() { return this.current >= this.tokens.length; } isAtStart() { return this.current <= 0; } peek() { return this.tokens[this.current]; } previous() { return this.tokens[this.current - 1]; } advance() { if (!this.isAtEnd()) this.current++; return this.previous(); } match(type, value) { if (this.isAtEnd()) return false; if (value) return this.peek().type === type && this.peek().value === value; return this.peek().type === type; } consume(type, message) { if (this.match(type)) return this.advance(); throw error_default(message, this.peek(), this.input); } plugin(plugin) { this.plugins.push(plugin); } add(...plugins2) { this.plugins.push(...plugins2); } next() { if (!this.isAtEnd()) return this.tokens[this.current++]; return this.tokens[this.current]; } nextBy(n) { if (!this.isAtEnd()) return this.tokens[this.current + n]; return this.tokens[this.current]; } nextByType(n) { return this.nextBy(n).type; } parse() { const program = { type: node_types_default.Program, body: [] }; while (!this.isAtEnd()) { program.body.push(this.parseExpression()); } return program; } parseExpression() { for (const plugin of this.plugins) { if (plugin.matcher(this)) return plugin.handler(this); } throw error_default("Unexpected token", this.peek(), this.input); } }; var parser_default = Parser; // src/index.ts var src_default = parser_default; export { src_default as default };