UNPKG

cordbuilder

Version:

Simple dsl to create discord builders simple.

112 lines (111 loc) 4.79 kB
"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;