@artemis-lang/parser
Version:
The artemis language parser
1,121 lines (1,076 loc) • 36.3 kB
JavaScript
// 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
};