zignet
Version:
MCP server for Zig — AI-powered code analysis, validation, and documentation with fine-tuned LLM
839 lines (836 loc) • 24.7 kB
JavaScript
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
//#region src/lexer.js
var require_lexer = /* @__PURE__ */ __commonJS({ "src/lexer.js": ((exports, module) => {
/**
* ZigNet Lexer
* Tokenizes Zig source code
*/
const TokenType$1 = {
FN: "FN",
CONST: "CONST",
VAR: "VAR",
STRUCT: "STRUCT",
UNION: "UNION",
ENUM: "ENUM",
IF: "IF",
ELSE: "ELSE",
WHILE: "WHILE",
FOR: "FOR",
RETURN: "RETURN",
BREAK: "BREAK",
CONTINUE: "CONTINUE",
COMPTIME: "COMPTIME",
INLINE: "INLINE",
I32: "I32",
I64: "I64",
U32: "U32",
F32: "F32",
F64: "F64",
BOOL: "BOOL",
VOID: "VOID",
NUMBER: "NUMBER",
STRING: "STRING",
IDENT: "IDENT",
TRUE: "TRUE",
FALSE: "FALSE",
PLUS: "PLUS",
MINUS: "MINUS",
STAR: "STAR",
SLASH: "SLASH",
PERCENT: "PERCENT",
EQ: "EQ",
NEQ: "NEQ",
LT: "LT",
GT: "GT",
LTE: "LTE",
GTE: "GTE",
ASSIGN: "ASSIGN",
PLUS_ASSIGN: "PLUS_ASSIGN",
AND: "AND",
OR: "OR",
NOT: "NOT",
LPAREN: "LPAREN",
RPAREN: "RPAREN",
LBRACE: "LBRACE",
RBRACE: "RBRACE",
LBRACKET: "LBRACKET",
RBRACKET: "RBRACKET",
COLON: "COLON",
SEMICOLON: "SEMICOLON",
COMMA: "COMMA",
DOT: "DOT",
ARROW: "ARROW",
FAT_ARROW: "FAT_ARROW",
EOF: "EOF",
ERROR: "ERROR"
};
var Token = class {
constructor(type, value, line, column) {
this.type = type;
this.value = value;
this.line = line;
this.column = column;
}
toString() {
return `Token(${this.type}, "${this.value}", ${this.line}:${this.column})`;
}
};
var Lexer = class {
constructor(source) {
this.source = source;
this.position = 0;
this.line = 1;
this.column = 1;
this.tokens = [];
}
error(message) {
return new Token(TokenType$1.ERROR, message, this.line, this.column);
}
peek(offset = 0) {
const pos = this.position + offset;
if (pos >= this.source.length) return "\0";
return this.source[pos];
}
advance() {
const char = this.source[this.position];
this.position++;
if (char === "\n") {
this.line++;
this.column = 1;
} else this.column++;
return char;
}
skipWhitespace() {
while (this.position < this.source.length && /\s/.test(this.peek())) this.advance();
}
skipComment() {
if (this.peek() === "/" && this.peek(1) === "/") {
while (this.peek() !== "\n" && this.peek() !== "\0") this.advance();
return true;
}
return false;
}
readIdentifier() {
let value = "";
while (/[a-zA-Z0-9_]/.test(this.peek())) value += this.advance();
return value;
}
readNumber() {
let value = "";
while (/[0-9]/.test(this.peek())) value += this.advance();
if (this.peek() === "." && /[0-9]/.test(this.peek(1))) {
value += this.advance();
while (/[0-9]/.test(this.peek())) value += this.advance();
}
return value;
}
readString(quote) {
let value = "";
this.advance();
while (this.peek() !== quote && this.peek() !== "\0") if (this.peek() === "\\") {
this.advance();
const escaped = this.advance();
value += this.getEscapeSequence(escaped);
} else value += this.advance();
if (this.peek() === quote) this.advance();
else return this.error("Unterminated string");
return value;
}
getEscapeSequence(char) {
return {
"n": "\n",
"t": " ",
"r": "\r",
"\\": "\\",
"\"": "\"",
"'": "'"
}[char] || char;
}
tokenize() {
const keywords = {
"fn": TokenType$1.FN,
"const": TokenType$1.CONST,
"var": TokenType$1.VAR,
"struct": TokenType$1.STRUCT,
"union": TokenType$1.UNION,
"enum": TokenType$1.ENUM,
"if": TokenType$1.IF,
"else": TokenType$1.ELSE,
"while": TokenType$1.WHILE,
"for": TokenType$1.FOR,
"return": TokenType$1.RETURN,
"break": TokenType$1.BREAK,
"continue": TokenType$1.CONTINUE,
"comptime": TokenType$1.COMPTIME,
"inline": TokenType$1.INLINE,
"i32": TokenType$1.I32,
"i64": TokenType$1.I64,
"u32": TokenType$1.U32,
"f32": TokenType$1.F32,
"f64": TokenType$1.F64,
"bool": TokenType$1.BOOL,
"void": TokenType$1.VOID,
"true": TokenType$1.TRUE,
"false": TokenType$1.FALSE
};
while (this.position < this.source.length) {
this.skipWhitespace();
if (this.skipComment()) continue;
const char = this.peek();
const line = this.line;
const column = this.column;
if (char === "\0") break;
if (/[0-9]/.test(char)) {
const value = this.readNumber();
this.tokens.push(new Token(TokenType$1.NUMBER, value, line, column));
continue;
}
if (char === "\"" || char === "'") {
const value = this.readString(char);
if (value instanceof Token) this.tokens.push(value);
else this.tokens.push(new Token(TokenType$1.STRING, value, line, column));
continue;
}
if (/[a-zA-Z_]/.test(char)) {
const value = this.readIdentifier();
const type = keywords[value] || TokenType$1.IDENT;
this.tokens.push(new Token(type, value, line, column));
continue;
}
this.advance();
if (char === "+") if (this.peek() === "=") {
this.advance();
this.tokens.push(new Token(TokenType$1.PLUS_ASSIGN, "+=", line, column));
} else this.tokens.push(new Token(TokenType$1.PLUS, "+", line, column));
else if (char === "-") if (this.peek() === ">") {
this.advance();
this.tokens.push(new Token(TokenType$1.ARROW, "->", line, column));
} else this.tokens.push(new Token(TokenType$1.MINUS, "-", line, column));
else if (char === "*") this.tokens.push(new Token(TokenType$1.STAR, "*", line, column));
else if (char === "/") this.tokens.push(new Token(TokenType$1.SLASH, "/", line, column));
else if (char === "%") this.tokens.push(new Token(TokenType$1.PERCENT, "%", line, column));
else if (char === "=") if (this.peek() === "=") {
this.advance();
this.tokens.push(new Token(TokenType$1.EQ, "==", line, column));
} else if (this.peek() === ">") {
this.advance();
this.tokens.push(new Token(TokenType$1.FAT_ARROW, "=>", line, column));
} else this.tokens.push(new Token(TokenType$1.ASSIGN, "=", line, column));
else if (char === "!") if (this.peek() === "=") {
this.advance();
this.tokens.push(new Token(TokenType$1.NEQ, "!=", line, column));
} else this.tokens.push(new Token(TokenType$1.NOT, "!", line, column));
else if (char === "<") if (this.peek() === "=") {
this.advance();
this.tokens.push(new Token(TokenType$1.LTE, "<=", line, column));
} else this.tokens.push(new Token(TokenType$1.LT, "<", line, column));
else if (char === ">") if (this.peek() === "=") {
this.advance();
this.tokens.push(new Token(TokenType$1.GTE, ">=", line, column));
} else this.tokens.push(new Token(TokenType$1.GT, ">", line, column));
else if (char === "&") if (this.peek() === "&") {
this.advance();
this.tokens.push(new Token(TokenType$1.AND, "&&", line, column));
} else this.tokens.push(new Token(TokenType$1.ERROR, `Unexpected char: &`, line, column));
else if (char === "|") if (this.peek() === "|") {
this.advance();
this.tokens.push(new Token(TokenType$1.OR, "||", line, column));
} else this.tokens.push(new Token(TokenType$1.ERROR, `Unexpected char: |`, line, column));
else if (char === "(") this.tokens.push(new Token(TokenType$1.LPAREN, "(", line, column));
else if (char === ")") this.tokens.push(new Token(TokenType$1.RPAREN, ")", line, column));
else if (char === "{") this.tokens.push(new Token(TokenType$1.LBRACE, "{", line, column));
else if (char === "}") this.tokens.push(new Token(TokenType$1.RBRACE, "}", line, column));
else if (char === "[") this.tokens.push(new Token(TokenType$1.LBRACKET, "[", line, column));
else if (char === "]") this.tokens.push(new Token(TokenType$1.RBRACKET, "]", line, column));
else if (char === ":") this.tokens.push(new Token(TokenType$1.COLON, ":", line, column));
else if (char === ";") this.tokens.push(new Token(TokenType$1.SEMICOLON, ";", line, column));
else if (char === ",") this.tokens.push(new Token(TokenType$1.COMMA, ",", line, column));
else if (char === ".") this.tokens.push(new Token(TokenType$1.DOT, ".", line, column));
else this.tokens.push(new Token(TokenType$1.ERROR, `Unexpected char: ${char}`, line, column));
}
this.tokens.push(new Token(TokenType$1.EOF, "", this.line, this.column));
return this.tokens;
}
};
module.exports = {
Lexer,
Token,
TokenType: TokenType$1
};
}) });
//#endregion
//#region src/parser.ts
var import_lexer = /* @__PURE__ */ __toESM(require_lexer(), 1);
/**
* Parser error class
*/
var ParseError = class extends Error {
constructor(message, token) {
super(message);
this.token = token;
this.name = "ParseError";
}
toString() {
return `${this.name} at ${this.token.line}:${this.token.column}: ${this.message}`;
}
};
/**
* Parser class
*/
var Parser = class {
position = 0;
constructor(tokens) {
this.tokens = tokens;
}
/**
* Parse the entire program
*/
parse() {
const body = [];
while (!this.isAtEnd()) body.push(this.parseDeclaration());
return {
type: "Program",
body
};
}
/**
* Parse a top-level declaration
*/
parseDeclaration() {
const isInline = this.match(import_lexer.TokenType.INLINE);
const isComptime = this.match(import_lexer.TokenType.COMPTIME);
if (this.check(import_lexer.TokenType.FN)) return this.parseFunctionDeclaration(isInline, isComptime);
if (this.check(import_lexer.TokenType.CONST) || this.check(import_lexer.TokenType.VAR)) {
const decl = this.parseVariableDeclaration();
if (decl.initializer && decl.initializer.type === "Identifier" && (this.previous().type === import_lexer.TokenType.STRUCT || this.previous().type === import_lexer.TokenType.UNION || this.previous().type === import_lexer.TokenType.ENUM)) return decl;
return decl;
}
throw this.error("Expected declaration");
}
/**
* Parse function declaration
*/
parseFunctionDeclaration(isInline = false, isComptime = false) {
const fnToken = this.consume(import_lexer.TokenType.FN, "Expected 'fn'");
const name = this.consume(import_lexer.TokenType.IDENT, "Expected function name").value;
this.consume(import_lexer.TokenType.LPAREN, "Expected '(' after function name");
const parameters = this.parseParameters();
this.consume(import_lexer.TokenType.RPAREN, "Expected ')' after parameters");
const errorUnion = this.match(import_lexer.TokenType.NOT);
return {
type: "FunctionDeclaration",
name,
parameters,
returnType: this.parseTypeAnnotation(),
body: this.parseBlockStatement(),
isInline,
isComptime,
errorUnion,
line: fnToken.line,
column: fnToken.column
};
}
/**
* Parse function parameters
*/
parseParameters() {
const parameters = [];
if (!this.check(import_lexer.TokenType.RPAREN)) do {
const isComptime = this.match(import_lexer.TokenType.COMPTIME);
const paramToken = this.consume(import_lexer.TokenType.IDENT, "Expected parameter name");
const name = paramToken.value;
this.consume(import_lexer.TokenType.COLON, "Expected ':' after parameter name");
const typeAnnotation = this.parseTypeAnnotation();
parameters.push({
type: "Parameter",
name,
typeAnnotation,
isComptime,
line: paramToken.line,
column: paramToken.column
});
} while (this.match(import_lexer.TokenType.COMMA));
return parameters;
}
/**
* Parse variable declaration
*/
parseVariableDeclaration() {
const isConst = this.match(import_lexer.TokenType.CONST);
if (!isConst) this.consume(import_lexer.TokenType.VAR, "Expected 'const' or 'var'");
const nameToken = this.consume(import_lexer.TokenType.IDENT, "Expected variable name");
const name = nameToken.value;
let typeAnnotation;
if (this.match(import_lexer.TokenType.COLON)) typeAnnotation = this.parseTypeAnnotation();
let initializer;
if (this.match(import_lexer.TokenType.ASSIGN)) initializer = this.parseExpression();
this.consume(import_lexer.TokenType.SEMICOLON, "Expected ';' after variable declaration");
return {
type: "VariableDeclaration",
isConst,
name,
typeAnnotation,
initializer,
line: nameToken.line,
column: nameToken.column
};
}
/**
* Parse type annotation
*/
parseTypeAnnotation() {
const token = this.current();
if (this.check(import_lexer.TokenType.I32) || this.check(import_lexer.TokenType.I64) || this.check(import_lexer.TokenType.U32) || this.check(import_lexer.TokenType.F32) || this.check(import_lexer.TokenType.F64) || this.check(import_lexer.TokenType.BOOL) || this.check(import_lexer.TokenType.VOID)) {
this.advance();
return {
type: "PrimitiveType",
name: token.value,
line: token.line,
column: token.column
};
}
if (this.check(import_lexer.TokenType.IDENT)) return {
type: "IdentifierType",
name: this.advance().value,
line: token.line,
column: token.column
};
throw this.error("Expected type annotation");
}
/**
* Parse block statement
*/
parseBlockStatement() {
const lbrace = this.consume(import_lexer.TokenType.LBRACE, "Expected '{'");
const statements = [];
while (!this.check(import_lexer.TokenType.RBRACE) && !this.isAtEnd()) statements.push(this.parseStatement());
this.consume(import_lexer.TokenType.RBRACE, "Expected '}'");
return {
type: "BlockStatement",
statements,
line: lbrace.line,
column: lbrace.column
};
}
/**
* Parse statement
*/
parseStatement() {
if (this.check(import_lexer.TokenType.RETURN)) return this.parseReturnStatement();
if (this.check(import_lexer.TokenType.IF)) return this.parseIfStatement();
if (this.check(import_lexer.TokenType.WHILE)) return this.parseWhileStatement();
if (this.check(import_lexer.TokenType.BREAK)) {
const token = this.advance();
this.consume(import_lexer.TokenType.SEMICOLON, "Expected ';' after 'break'");
return {
type: "BreakStatement",
line: token.line,
column: token.column
};
}
if (this.check(import_lexer.TokenType.CONTINUE)) {
const token = this.advance();
this.consume(import_lexer.TokenType.SEMICOLON, "Expected ';' after 'continue'");
return {
type: "ContinueStatement",
line: token.line,
column: token.column
};
}
if (this.check(import_lexer.TokenType.COMPTIME)) return this.parseComptimeStatement();
if (this.check(import_lexer.TokenType.CONST) || this.check(import_lexer.TokenType.VAR)) return this.parseVariableDeclaration();
if (this.check(import_lexer.TokenType.LBRACE)) return this.parseBlockStatement();
return this.parseExpressionStatement();
}
/**
* Parse return statement
*/
parseReturnStatement() {
const returnToken = this.consume(import_lexer.TokenType.RETURN, "Expected 'return'");
let value;
if (!this.check(import_lexer.TokenType.SEMICOLON)) value = this.parseExpression();
this.consume(import_lexer.TokenType.SEMICOLON, "Expected ';' after return statement");
return {
type: "ReturnStatement",
value,
line: returnToken.line,
column: returnToken.column
};
}
/**
* Parse if statement
*/
parseIfStatement() {
const ifToken = this.consume(import_lexer.TokenType.IF, "Expected 'if'");
this.consume(import_lexer.TokenType.LPAREN, "Expected '(' after 'if'");
const condition = this.parseExpression();
this.consume(import_lexer.TokenType.RPAREN, "Expected ')' after condition");
const consequent = this.parseStatement();
let alternate;
if (this.match(import_lexer.TokenType.ELSE)) alternate = this.parseStatement();
return {
type: "IfStatement",
condition,
consequent,
alternate,
line: ifToken.line,
column: ifToken.column
};
}
/**
* Parse while statement
*/
parseWhileStatement() {
const whileToken = this.consume(import_lexer.TokenType.WHILE, "Expected 'while'");
this.consume(import_lexer.TokenType.LPAREN, "Expected '(' after 'while'");
const condition = this.parseExpression();
this.consume(import_lexer.TokenType.RPAREN, "Expected ')' after condition");
return {
type: "WhileStatement",
condition,
body: this.parseStatement(),
line: whileToken.line,
column: whileToken.column
};
}
/**
* Parse comptime statement
*/
parseComptimeStatement() {
const comptimeToken = this.consume(import_lexer.TokenType.COMPTIME, "Expected 'comptime'");
return {
type: "ComptimeStatement",
body: this.parseBlockStatement(),
line: comptimeToken.line,
column: comptimeToken.column
};
}
/**
* Parse expression statement
*/
parseExpressionStatement() {
const expr = this.parseExpression();
this.consume(import_lexer.TokenType.SEMICOLON, "Expected ';' after expression");
return {
type: "ExpressionStatement",
expression: expr,
line: expr.line,
column: expr.column
};
}
/**
* Parse expression (starting point for precedence climbing)
*/
parseExpression() {
return this.parseAssignment();
}
/**
* Parse assignment expression
*/
parseAssignment() {
const expr = this.parseLogicalOr();
if (this.match(import_lexer.TokenType.ASSIGN, import_lexer.TokenType.PLUS_ASSIGN)) return {
type: "AssignmentExpression",
operator: this.previous().value,
left: expr,
right: this.parseAssignment(),
line: expr.line,
column: expr.column
};
return expr;
}
/**
* Parse logical OR expression
*/
parseLogicalOr() {
let left = this.parseLogicalAnd();
while (this.match(import_lexer.TokenType.OR)) {
const operator = this.previous().value;
const right = this.parseLogicalAnd();
left = {
type: "BinaryExpression",
operator,
left,
right,
line: left.line,
column: left.column
};
}
return left;
}
/**
* Parse logical AND expression
*/
parseLogicalAnd() {
let left = this.parseEquality();
while (this.match(import_lexer.TokenType.AND)) {
const operator = this.previous().value;
const right = this.parseEquality();
left = {
type: "BinaryExpression",
operator,
left,
right,
line: left.line,
column: left.column
};
}
return left;
}
/**
* Parse equality expression (==, !=)
*/
parseEquality() {
let left = this.parseComparison();
while (this.match(import_lexer.TokenType.EQ, import_lexer.TokenType.NEQ)) {
const operator = this.previous().value;
const right = this.parseComparison();
left = {
type: "BinaryExpression",
operator,
left,
right,
line: left.line,
column: left.column
};
}
return left;
}
/**
* Parse comparison expression (<, >, <=, >=)
*/
parseComparison() {
let left = this.parseAddition();
while (this.match(import_lexer.TokenType.LT, import_lexer.TokenType.GT, import_lexer.TokenType.LTE, import_lexer.TokenType.GTE)) {
const operator = this.previous().value;
const right = this.parseAddition();
left = {
type: "BinaryExpression",
operator,
left,
right,
line: left.line,
column: left.column
};
}
return left;
}
/**
* Parse addition/subtraction expression
*/
parseAddition() {
let left = this.parseMultiplication();
while (this.match(import_lexer.TokenType.PLUS, import_lexer.TokenType.MINUS)) {
const operator = this.previous().value;
const right = this.parseMultiplication();
left = {
type: "BinaryExpression",
operator,
left,
right,
line: left.line,
column: left.column
};
}
return left;
}
/**
* Parse multiplication/division expression
*/
parseMultiplication() {
let left = this.parseUnary();
while (this.match(import_lexer.TokenType.STAR, import_lexer.TokenType.SLASH, import_lexer.TokenType.PERCENT)) {
const operator = this.previous().value;
const right = this.parseUnary();
left = {
type: "BinaryExpression",
operator,
left,
right,
line: left.line,
column: left.column
};
}
return left;
}
/**
* Parse unary expression (-, !)
*/
parseUnary() {
if (this.match(import_lexer.TokenType.MINUS, import_lexer.TokenType.NOT)) {
const operator = this.previous();
return {
type: "UnaryExpression",
operator: operator.value,
operand: this.parseUnary(),
line: operator.line,
column: operator.column
};
}
return this.parsePostfix();
}
/**
* Parse postfix expression (call, member access, index)
*/
parsePostfix() {
let expr = this.parsePrimary();
while (true) if (this.match(import_lexer.TokenType.LPAREN)) {
const args = [];
if (!this.check(import_lexer.TokenType.RPAREN)) do
args.push(this.parseExpression());
while (this.match(import_lexer.TokenType.COMMA));
this.consume(import_lexer.TokenType.RPAREN, "Expected ')' after arguments");
expr = {
type: "CallExpression",
callee: expr,
arguments: args,
line: expr.line,
column: expr.column
};
} else if (this.match(import_lexer.TokenType.DOT)) {
const property = this.consume(import_lexer.TokenType.IDENT, "Expected property name").value;
expr = {
type: "MemberExpression",
object: expr,
property,
line: expr.line,
column: expr.column
};
} else if (this.match(import_lexer.TokenType.LBRACKET)) {
const index = this.parseExpression();
this.consume(import_lexer.TokenType.RBRACKET, "Expected ']' after index");
expr = {
type: "IndexExpression",
object: expr,
index,
line: expr.line,
column: expr.column
};
} else break;
return expr;
}
/**
* Parse primary expression (literals, identifiers, grouped expressions)
*/
parsePrimary() {
const token = this.current();
if (this.match(import_lexer.TokenType.NUMBER)) return {
type: "NumberLiteral",
value: parseFloat(this.previous().value),
line: token.line,
column: token.column
};
if (this.match(import_lexer.TokenType.STRING)) return {
type: "StringLiteral",
value: this.previous().value,
line: token.line,
column: token.column
};
if (this.match(import_lexer.TokenType.TRUE)) return {
type: "BooleanLiteral",
value: true,
line: token.line,
column: token.column
};
if (this.match(import_lexer.TokenType.FALSE)) return {
type: "BooleanLiteral",
value: false,
line: token.line,
column: token.column
};
if (this.match(import_lexer.TokenType.IDENT)) return {
type: "Identifier",
name: this.previous().value,
line: token.line,
column: token.column
};
if (this.match(import_lexer.TokenType.LPAREN)) {
const expr = this.parseExpression();
this.consume(import_lexer.TokenType.RPAREN, "Expected ')' after expression");
return expr;
}
throw this.error("Expected expression");
}
/**
* Check if current token matches any of the given types
*/
match(...types) {
for (const type of types) if (this.check(type)) {
this.advance();
return true;
}
return false;
}
/**
* Check if current token is of given type
*/
check(type) {
if (this.isAtEnd()) return false;
return this.current().type === type;
}
/**
* Consume current token if it matches expected type, otherwise throw error
*/
consume(type, message) {
if (this.check(type)) return this.advance();
throw this.error(message);
}
/**
* Advance to next token
*/
advance() {
if (!this.isAtEnd()) this.position++;
return this.previous();
}
/**
* Check if at end of token stream
*/
isAtEnd() {
return this.current().type === import_lexer.TokenType.EOF;
}
/**
* Get current token
*/
current() {
return this.tokens[this.position];
}
/**
* Get previous token
*/
previous() {
return this.tokens[this.position - 1];
}
/**
* Create a parse error
*/
error(message) {
return new ParseError(message, this.current());
}
};
//#endregion
export { ParseError, Parser };
//# sourceMappingURL=parser.js.map