cordbuilder
Version:
Simple dsl to create discord builders simple.
112 lines (111 loc) • 4.79 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Expressions_1 = require("../structs/Expressions");
const Statements_1 = require("../structs/Statements");
const Token_1 = __importDefault(require("../structs/Token"));
const ast_1 = require("../types/ast");
const Lexer_1 = __importDefault(require("./Lexer"));
class Parser {
constructor(code) {
this.code = code;
const lexer = new Lexer_1.default(code);
this.tokens = lexer.lex();
this.cursor = 0;
}
parse() {
const statements = [];
while (this.current.kind !== ast_1.TokenKind.Eof)
statements.push(this.parsePropertyDeclaration());
const program = new Statements_1.Program(statements);
return program;
}
parsePropertyDeclaration() {
const at = this.expect(ast_1.TokenKind.At);
const identifier = this.parseIdentifier();
const expression = this.parseExpression();
return new Statements_1.PropertyDeclaration(identifier, expression, at);
}
parseSubPropertyDeclaration() {
const colon = this.expect(ast_1.TokenKind.Colon);
const identifier = this.parseIdentifier();
const expression = this.parseExpression();
return new Expressions_1.SubPropertyDeclaration(identifier, expression, colon);
}
parseExpression() {
switch (this.current.kind) {
case ast_1.TokenKind.String:
return this.parseStringExpresison();
case ast_1.TokenKind.Boolean:
return this.parseBooleanExpresison();
case ast_1.TokenKind.Identifier:
return this.parseIdentifier();
case ast_1.TokenKind.OpenParen:
return this.parseParenthesizedExpression();
case ast_1.TokenKind.OpenBracket:
return this.parseArgumentsExpression();
default:
throw new Error(`parser (l:${this.current.line}, c:${this.current.col}): Invalid token found during parsing: "${this.current.text}"`);
}
}
parseStringExpresison() {
const token = this.expect(ast_1.TokenKind.String);
const value = token.text;
return new Expressions_1.StringExpression(value);
}
parseBooleanExpresison() {
const token = this.expect(ast_1.TokenKind.Boolean);
const value = Boolean(token.text);
return new Expressions_1.BooleanExpression(value);
}
parseParenthesizedExpression() {
const open = this.expect(ast_1.TokenKind.OpenParen);
const expression = this.parseExpression();
const close = this.expect(ast_1.TokenKind.CloseParen);
const parens = [open, close];
return expression;
}
parseArgumentsExpression() {
const open = this.expect(ast_1.TokenKind.OpenBracket);
const expressions = [];
const firstExpression = this.parseSubPropertyDeclaration();
expressions.push(firstExpression);
while (this.current.kind !== ast_1.TokenKind.CloseBracket && this.current.kind !== ast_1.TokenKind.Eof) {
this.expect(ast_1.TokenKind.Comma);
const expression = this.parseSubPropertyDeclaration();
expressions.push(expression);
}
const close = this.expect(ast_1.TokenKind.CloseBracket);
const brackets = [open, close];
return new Expressions_1.ArgumentsExpression(brackets, expressions);
}
parseIdentifier() {
const token = this.expect(ast_1.TokenKind.Identifier);
const name = token.text;
return new Expressions_1.Identifier(name, token);
}
get current() {
return this.tokens[this.cursor];
}
peek(offset = 0) {
if (this.cursor + offset > this.tokens.length)
return this.tokens[this.tokens.length - 1];
if (this.cursor + offset < 0)
return this.tokens[0];
return this.tokens[this.cursor + offset];
}
expect(kind) {
if (this.current.kind == ast_1.TokenKind.Eof)
throw new Error(`parser (l:${this.current.line}, c:${this.current.col}): Unexpected end of input expected: "${Token_1.default.getLexemeByKind(kind)}" (${kind})`);
else if (this.current.kind !== kind)
throw new Error(`parser (l:${this.current.line}, c:${this.current.col}): Unexpected token has found during parsing "${this.current.text}" (${this.current.kind}), expected "${Token_1.default.getLexemeByKind(kind)}" (${kind})`);
else {
const token = this.current;
this.cursor++;
return token;
}
}
}
exports.default = Parser;