From a92b3d5f35255b6eb8d131ca2dd74d1428fd900a Mon Sep 17 00:00:00 2001 From: Eugene Yakhnenko Date: Mon, 4 Dec 2023 12:41:08 -0800 Subject: [PATCH] Project upgrades (#13) * build: dependency upgrade * feat: added tailwind styling * chore: fix build * chore: min build * chore: fix ci node version --- .github/workflows/node.js.yml | 24 +- dist/kasper.js | 4279 ++++++++++++++++----------------- dist/kasper.min.js | 3 +- live/index.html | 118 +- package.json | 14 +- src/interpreter.ts | 2 +- src/scanner.ts | 2 +- src/scope.ts | 2 +- src/types/demo.ts | 11 +- src/utils.ts | 4 +- tsconfig.json | 3 +- webpack.prod.js | 9 +- yarn.lock | 2888 ++++++---------------- 13 files changed, 2932 insertions(+), 4427 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 98e533a..74b0c14 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -5,23 +5,23 @@ name: Node.js CI on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] jobs: build: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: [18.x] steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm install - - run: npm run build - - run: npm run testprod + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - run: npm install + - run: npm run build + - run: npm run testprod diff --git a/dist/kasper.js b/dist/kasper.js index 525b135..282c0cf 100644 --- a/dist/kasper.js +++ b/dist/kasper.js @@ -1,454 +1,370 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = "./src/kasper.ts"); -/******/ }) -/************************************************************************/ -/******/ ({ +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ /***/ "./src/expression-parser.ts": /*!**********************************!*\ !*** ./src/expression-parser.ts ***! \**********************************/ -/*! exports provided: ExpressionParser */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpressionParser", function() { return ExpressionParser; }); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ExpressionParser: () => (/* binding */ ExpressionParser) +/* harmony export */ }); /* harmony import */ var _types_error__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./types/error */ "./src/types/error.ts"); /* harmony import */ var _types_expressions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./types/expressions */ "./src/types/expressions.ts"); /* harmony import */ var _types_token__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./types/token */ "./src/types/token.ts"); - - - -class ExpressionParser { - constructor() { - this.errorLevel = 1; - } - parse(tokens) { - this.current = 0; - this.tokens = tokens; - this.errors = []; - const expressions = []; - while (!this.eof()) { - try { - expressions.push(this.expression()); - } - catch (e) { - if (e instanceof _types_error__WEBPACK_IMPORTED_MODULE_0__["KasperError"]) { - this.errors.push(`Parse Error (${e.line}:${e.col}) => ${e.value}`); - } - else { - this.errors.push(`${e}`); - if (this.errors.length > 100) { - this.errors.push("Parse Error limit exceeded"); - return expressions; - } - } - this.synchronize(); - } - } - return expressions; - } - match(...types) { - for (const type of types) { - if (this.check(type)) { - this.advance(); - return true; - } - } - return false; - } - advance() { - if (!this.eof()) { - this.current++; - } - return this.previous(); - } - peek() { - return this.tokens[this.current]; - } - previous() { - return this.tokens[this.current - 1]; - } - check(type) { - return this.peek().type === type; - } - eof() { - return this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Eof); - } - consume(type, message) { - if (this.check(type)) { - return this.advance(); - } - return this.error(this.peek(), message + `, unexpected token "${this.peek().lexeme}"`); - } - error(token, message) { - throw new _types_error__WEBPACK_IMPORTED_MODULE_0__["KasperError"](message, token.line, token.col); - } - synchronize() { - do { - if (this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Semicolon) || this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightBrace)) { - this.advance(); - return; - } - this.advance(); - } while (!this.eof()); - } - foreach(tokens) { - this.current = 0; - this.tokens = tokens; - this.errors = []; - this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Const, `Expected const definition starting "each" statement`); - const name = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Identifier, `Expected an identifier inside "each" statement`); - let key = null; - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].With)) { - key = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Identifier, `Expected a "key" identifier after "with" keyword in foreach statement`); - } - this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Of, `Expected "of" keyword inside foreach statement`); - const iterable = this.expression(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Each"](name, key, iterable, name.line); - } - expression() { - const expression = this.assignment(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Semicolon)) { - // consume all semicolons - // tslint:disable-next-line - while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Semicolon)) { } - } - return expression; - } - assignment() { - const expr = this.ternary(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Equal, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].PlusEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].MinusEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].StarEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].SlashEqual)) { - const operator = this.previous(); - let value = this.assignment(); - if (expr instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Variable"]) { - const name = expr.name; - if (operator.type !== _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Equal) { - value = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Binary"](new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Variable"](name, name.line), operator, value, operator.line); - } - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Assign"](name, value, name.line); - } - else if (expr instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Get"]) { - if (operator.type !== _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Equal) { - value = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Binary"](new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Get"](expr.entity, expr.key, expr.type, expr.line), operator, value, operator.line); - } - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Set"](expr.entity, expr.key, value, expr.line); - } - this.error(operator, `Invalid l-value, is not an assigning target.`); - } - return expr; - } - ternary() { - const expr = this.nullCoalescing(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Question)) { - const thenExpr = this.ternary(); - this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Colon, `Expected ":" after ternary ? expression`); - const elseExpr = this.ternary(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Ternary"](expr, thenExpr, elseExpr, expr.line); - } - return expr; - } - nullCoalescing() { - const expr = this.logicalOr(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].QuestionQuestion)) { - const rightExpr = this.nullCoalescing(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["NullCoalescing"](expr, rightExpr, expr.line); - } - return expr; - } - logicalOr() { - let expr = this.logicalAnd(); - while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Or)) { - const operator = this.previous(); - const right = this.logicalAnd(); - expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Logical"](expr, operator, right, operator.line); - } - return expr; - } - logicalAnd() { - let expr = this.equality(); - while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].And)) { - const operator = this.previous(); - const right = this.equality(); - expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Logical"](expr, operator, right, operator.line); - } - return expr; - } - equality() { - let expr = this.addition(); - while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].BangEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].EqualEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Greater, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].GreaterEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Less, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].LessEqual)) { - const operator = this.previous(); - const right = this.addition(); - expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Binary"](expr, operator, right, operator.line); - } - return expr; - } - addition() { - let expr = this.modulus(); - while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Minus, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Plus)) { - const operator = this.previous(); - const right = this.modulus(); - expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Binary"](expr, operator, right, operator.line); - } - return expr; - } - modulus() { - let expr = this.multiplication(); - while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Percent)) { - const operator = this.previous(); - const right = this.multiplication(); - expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Binary"](expr, operator, right, operator.line); - } - return expr; - } - multiplication() { - let expr = this.typeof(); - while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Slash, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Star)) { - const operator = this.previous(); - const right = this.typeof(); - expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Binary"](expr, operator, right, operator.line); - } - return expr; - } - typeof() { - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Typeof)) { - const operator = this.previous(); - const value = this.typeof(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Typeof"](value, operator.line); - } - return this.unary(); - } - unary() { - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Minus, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Bang, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Dollar, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].PlusPlus, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].MinusMinus)) { - const operator = this.previous(); - const right = this.unary(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Unary"](operator, right, operator.line); - } - return this.newKeyword(); - } - newKeyword() { - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].New)) { - const keyword = this.previous(); - const construct = this.call(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["New"](construct, keyword.line); - } - return this.call(); - } - call() { - let expr = this.primary(); - let consumed = true; - do { - consumed = false; - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].LeftParen)) { - consumed = true; - do { - const args = []; - if (!this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightParen)) { - do { - args.push(this.expression()); - } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Comma)); - } - const paren = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightParen, `Expected ")" after arguments`); - expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Call"](expr, paren, args, paren.line); - } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].LeftParen)); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Dot, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].QuestionDot)) { - consumed = true; - expr = this.dotGet(expr, this.previous()); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].LeftBracket)) { - consumed = true; - expr = this.bracketGet(expr, this.previous()); - } - } while (consumed); - return expr; - } - dotGet(expr, operator) { - const name = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Identifier, `Expect property name after '.'`); - const key = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Key"](name, name.line); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Get"](expr, key, operator.type, name.line); - } - bracketGet(expr, operator) { - let key = null; - if (!this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightBracket)) { - key = this.expression(); - } - this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightBracket, `Expected "]" after an index`); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Get"](expr, key, operator.type, operator.line); - } - primary() { - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].False)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Literal"](false, this.previous().line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].True)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Literal"](true, this.previous().line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Null)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Literal"](null, this.previous().line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Undefined)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Literal"](undefined, this.previous().line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Number) || this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].String)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Literal"](this.previous().literal, this.previous().line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Template)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Template"](this.previous().literal, this.previous().line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Identifier)) { - const identifier = this.previous(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].PlusPlus)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Postfix"](identifier, 1, identifier.line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].MinusMinus)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Postfix"](identifier, -1, identifier.line); - } - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Variable"](identifier, identifier.line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].LeftParen)) { - const expr = this.expression(); - this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightParen, `Expected ")" after expression`); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Grouping"](expr, expr.line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].LeftBrace)) { - return this.dictionary(); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].LeftBracket)) { - return this.list(); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Void)) { - const expr = this.expression(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Void"](expr, this.previous().line); - } - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Debug)) { - const expr = this.expression(); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Debug"](expr, this.previous().line); - } - throw this.error(this.peek(), `Expected expression, unexpected token "${this.peek().lexeme}"`); - // unreacheable code - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Literal"](null, 0); - } - dictionary() { - const leftBrace = this.previous(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightBrace)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Dictionary"]([], this.previous().line); - } - const properties = []; - do { - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].String, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Identifier, _types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Number)) { - const key = this.previous(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Colon)) { - const value = this.expression(); - properties.push(new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Set"](null, new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Key"](key, key.line), value, key.line)); - } - else { - const value = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Variable"](key, key.line); - properties.push(new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Set"](null, new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Key"](key, key.line), value, key.line)); - } - } - else { - this.error(this.peek(), `String, Number or Identifier expected as a Key of Dictionary {, unexpected token ${this.peek().lexeme}`); - } - } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Comma)); - this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightBrace, `Expected "}" after object literal`); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["Dictionary"](properties, leftBrace.line); - } - list() { - const values = []; - const leftBracket = this.previous(); - if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightBracket)) { - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["List"]([], this.previous().line); - } - do { - values.push(this.expression()); - } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].Comma)); - this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__["TokenType"].RightBracket, `Expected "]" after array declaration`); - return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__["List"](values, leftBracket.line); - } -} + + + +class ExpressionParser { + constructor() { + this.errorLevel = 1; + } + parse(tokens) { + this.current = 0; + this.tokens = tokens; + this.errors = []; + const expressions = []; + while (!this.eof()) { + try { + expressions.push(this.expression()); + } + catch (e) { + if (e instanceof _types_error__WEBPACK_IMPORTED_MODULE_0__.KasperError) { + this.errors.push(`Parse Error (${e.line}:${e.col}) => ${e.value}`); + } + else { + this.errors.push(`${e}`); + if (this.errors.length > 100) { + this.errors.push("Parse Error limit exceeded"); + return expressions; + } + } + this.synchronize(); + } + } + return expressions; + } + match(...types) { + for (const type of types) { + if (this.check(type)) { + this.advance(); + return true; + } + } + return false; + } + advance() { + if (!this.eof()) { + this.current++; + } + return this.previous(); + } + peek() { + return this.tokens[this.current]; + } + previous() { + return this.tokens[this.current - 1]; + } + check(type) { + return this.peek().type === type; + } + eof() { + return this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Eof); + } + consume(type, message) { + if (this.check(type)) { + return this.advance(); + } + return this.error(this.peek(), message + `, unexpected token "${this.peek().lexeme}"`); + } + error(token, message) { + throw new _types_error__WEBPACK_IMPORTED_MODULE_0__.KasperError(message, token.line, token.col); + } + synchronize() { + do { + if (this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Semicolon) || this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightBrace)) { + this.advance(); + return; + } + this.advance(); + } while (!this.eof()); + } + foreach(tokens) { + this.current = 0; + this.tokens = tokens; + this.errors = []; + this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Const, `Expected const definition starting "each" statement`); + const name = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Identifier, `Expected an identifier inside "each" statement`); + let key = null; + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.With)) { + key = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Identifier, `Expected a "key" identifier after "with" keyword in foreach statement`); + } + this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Of, `Expected "of" keyword inside foreach statement`); + const iterable = this.expression(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Each(name, key, iterable, name.line); + } + expression() { + const expression = this.assignment(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Semicolon)) { + // consume all semicolons + // tslint:disable-next-line + while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Semicolon)) { } + } + return expression; + } + assignment() { + const expr = this.ternary(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Equal, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.PlusEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.MinusEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.StarEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.SlashEqual)) { + const operator = this.previous(); + let value = this.assignment(); + if (expr instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Variable) { + const name = expr.name; + if (operator.type !== _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Equal) { + value = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Binary(new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Variable(name, name.line), operator, value, operator.line); + } + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Assign(name, value, name.line); + } + else if (expr instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Get) { + if (operator.type !== _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Equal) { + value = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Binary(new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Get(expr.entity, expr.key, expr.type, expr.line), operator, value, operator.line); + } + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Set(expr.entity, expr.key, value, expr.line); + } + this.error(operator, `Invalid l-value, is not an assigning target.`); + } + return expr; + } + ternary() { + const expr = this.nullCoalescing(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Question)) { + const thenExpr = this.ternary(); + this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Colon, `Expected ":" after ternary ? expression`); + const elseExpr = this.ternary(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Ternary(expr, thenExpr, elseExpr, expr.line); + } + return expr; + } + nullCoalescing() { + const expr = this.logicalOr(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.QuestionQuestion)) { + const rightExpr = this.nullCoalescing(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.NullCoalescing(expr, rightExpr, expr.line); + } + return expr; + } + logicalOr() { + let expr = this.logicalAnd(); + while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Or)) { + const operator = this.previous(); + const right = this.logicalAnd(); + expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Logical(expr, operator, right, operator.line); + } + return expr; + } + logicalAnd() { + let expr = this.equality(); + while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.And)) { + const operator = this.previous(); + const right = this.equality(); + expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Logical(expr, operator, right, operator.line); + } + return expr; + } + equality() { + let expr = this.addition(); + while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.BangEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.EqualEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Greater, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.GreaterEqual, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Less, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.LessEqual)) { + const operator = this.previous(); + const right = this.addition(); + expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Binary(expr, operator, right, operator.line); + } + return expr; + } + addition() { + let expr = this.modulus(); + while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Minus, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Plus)) { + const operator = this.previous(); + const right = this.modulus(); + expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Binary(expr, operator, right, operator.line); + } + return expr; + } + modulus() { + let expr = this.multiplication(); + while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Percent)) { + const operator = this.previous(); + const right = this.multiplication(); + expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Binary(expr, operator, right, operator.line); + } + return expr; + } + multiplication() { + let expr = this.typeof(); + while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Slash, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Star)) { + const operator = this.previous(); + const right = this.typeof(); + expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Binary(expr, operator, right, operator.line); + } + return expr; + } + typeof() { + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Typeof)) { + const operator = this.previous(); + const value = this.typeof(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Typeof(value, operator.line); + } + return this.unary(); + } + unary() { + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Minus, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Bang, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Dollar, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.PlusPlus, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.MinusMinus)) { + const operator = this.previous(); + const right = this.unary(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Unary(operator, right, operator.line); + } + return this.newKeyword(); + } + newKeyword() { + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.New)) { + const keyword = this.previous(); + const construct = this.call(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.New(construct, keyword.line); + } + return this.call(); + } + call() { + let expr = this.primary(); + let consumed = true; + do { + consumed = false; + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.LeftParen)) { + consumed = true; + do { + const args = []; + if (!this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightParen)) { + do { + args.push(this.expression()); + } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Comma)); + } + const paren = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightParen, `Expected ")" after arguments`); + expr = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Call(expr, paren, args, paren.line); + } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.LeftParen)); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Dot, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.QuestionDot)) { + consumed = true; + expr = this.dotGet(expr, this.previous()); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.LeftBracket)) { + consumed = true; + expr = this.bracketGet(expr, this.previous()); + } + } while (consumed); + return expr; + } + dotGet(expr, operator) { + const name = this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Identifier, `Expect property name after '.'`); + const key = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Key(name, name.line); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Get(expr, key, operator.type, name.line); + } + bracketGet(expr, operator) { + let key = null; + if (!this.check(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightBracket)) { + key = this.expression(); + } + this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightBracket, `Expected "]" after an index`); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Get(expr, key, operator.type, operator.line); + } + primary() { + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.False)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Literal(false, this.previous().line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.True)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Literal(true, this.previous().line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Null)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Literal(null, this.previous().line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Undefined)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Literal(undefined, this.previous().line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Number) || this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.String)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Literal(this.previous().literal, this.previous().line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Template)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Template(this.previous().literal, this.previous().line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Identifier)) { + const identifier = this.previous(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.PlusPlus)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Postfix(identifier, 1, identifier.line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.MinusMinus)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Postfix(identifier, -1, identifier.line); + } + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Variable(identifier, identifier.line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.LeftParen)) { + const expr = this.expression(); + this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightParen, `Expected ")" after expression`); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Grouping(expr, expr.line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.LeftBrace)) { + return this.dictionary(); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.LeftBracket)) { + return this.list(); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Void)) { + const expr = this.expression(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Void(expr, this.previous().line); + } + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Debug)) { + const expr = this.expression(); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Debug(expr, this.previous().line); + } + throw this.error(this.peek(), `Expected expression, unexpected token "${this.peek().lexeme}"`); + // unreacheable code + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Literal(null, 0); + } + dictionary() { + const leftBrace = this.previous(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightBrace)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Dictionary([], this.previous().line); + } + const properties = []; + do { + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.String, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Identifier, _types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Number)) { + const key = this.previous(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Colon)) { + const value = this.expression(); + properties.push(new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Set(null, new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Key(key, key.line), value, key.line)); + } + else { + const value = new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Variable(key, key.line); + properties.push(new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Set(null, new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Key(key, key.line), value, key.line)); + } + } + else { + this.error(this.peek(), `String, Number or Identifier expected as a Key of Dictionary {, unexpected token ${this.peek().lexeme}`); + } + } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Comma)); + this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightBrace, `Expected "}" after object literal`); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.Dictionary(properties, leftBrace.line); + } + list() { + const values = []; + const leftBracket = this.previous(); + if (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightBracket)) { + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.List([], this.previous().line); + } + do { + values.push(this.expression()); + } while (this.match(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.Comma)); + this.consume(_types_token__WEBPACK_IMPORTED_MODULE_2__.TokenType.RightBracket, `Expected "]" after array declaration`); + return new _types_expressions__WEBPACK_IMPORTED_MODULE_1__.List(values, leftBracket.line); + } +} /***/ }), @@ -457,315 +373,254 @@ class ExpressionParser { /*!****************************!*\ !*** ./src/interpreter.ts ***! \****************************/ -/*! exports provided: Interpreter */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Interpreter", function() { return Interpreter; }); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Interpreter: () => (/* binding */ Interpreter) +/* harmony export */ }); /* harmony import */ var _types_expressions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./types/expressions */ "./src/types/expressions.ts"); /* harmony import */ var _scanner__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./scanner */ "./src/scanner.ts"); /* harmony import */ var _expression_parser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./expression-parser */ "./src/expression-parser.ts"); /* harmony import */ var _scope__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./scope */ "./src/scope.ts"); /* harmony import */ var _types_token__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./types/token */ "./src/types/token.ts"); - - - - - -class Interpreter { - constructor() { - this.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__["Scope"](); - this.errors = []; - this.scanner = new _scanner__WEBPACK_IMPORTED_MODULE_1__["Scanner"](); - this.parser = new _expression_parser__WEBPACK_IMPORTED_MODULE_2__["ExpressionParser"](); - } - evaluate(expr) { - return (expr.result = expr.accept(this)); - } - error(message) { - throw new Error(`Runtime Error => ${message}`); - } - visitVariableExpr(expr) { - return this.scope.get(expr.name.lexeme); - } - visitAssignExpr(expr) { - const value = this.evaluate(expr.value); - this.scope.set(expr.name.lexeme, value); - return value; - } - visitKeyExpr(expr) { - return expr.name.literal; - } - visitGetExpr(expr) { - const entity = this.evaluate(expr.entity); - const key = this.evaluate(expr.key); - if (!entity && expr.type === _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].QuestionDot) { - return undefined; - } - return entity[key]; - } - visitSetExpr(expr) { - const entity = this.evaluate(expr.entity); - const key = this.evaluate(expr.key); - const value = this.evaluate(expr.value); - entity[key] = value; - return value; - } - visitPostfixExpr(expr) { - const value = this.scope.get(expr.name.lexeme); - const newValue = value + expr.increment; - this.scope.set(expr.name.lexeme, newValue); - return value; - } - visitListExpr(expr) { - const values = []; - for (const expression of expr.value) { - const value = this.evaluate(expression); - values.push(value); - } - return values; - } - templateParse(source) { - const tokens = this.scanner.scan(source); - const expressions = this.parser.parse(tokens); - if (this.parser.errors.length) { - this.error(`Template string error: ${this.parser.errors[0]}`); - } - let result = ""; - for (const expression of expressions) { - result += this.evaluate(expression).toString(); - } - return result; - } - visitTemplateExpr(expr) { - const result = expr.value.replace(/\{\{([\s\S]+?)\}\}/g, (m, placeholder) => { - return this.templateParse(placeholder); - }); - return result; - } - visitBinaryExpr(expr) { - const left = this.evaluate(expr.left); - const right = this.evaluate(expr.right); - switch (expr.operator.type) { - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Minus: - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].MinusEqual: - return left - right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Slash: - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].SlashEqual: - return left / right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Star: - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].StarEqual: - return left * right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Percent: - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].PercentEqual: - return left % right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Plus: - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].PlusEqual: - return left + right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Pipe: - return left | right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Caret: - return left ^ right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Greater: - return left > right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].GreaterEqual: - return left >= right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Less: - return left < right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].LessEqual: - return left <= right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].EqualEqual: - return left === right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].BangEqual: - return left !== right; - default: - this.error("Unknown binary operator " + expr.operator); - return null; // unreachable - } - } - visitLogicalExpr(expr) { - const left = this.evaluate(expr.left); - if (expr.operator.type === _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Or) { - if (left) { - return left; - } - } - else { - if (!left) { - return left; - } - } - return this.evaluate(expr.right); - } - visitTernaryExpr(expr) { - return this.evaluate(expr.condition).isTruthy() - ? this.evaluate(expr.thenExpr) - : this.evaluate(expr.elseExpr); - } - visitNullCoalescingExpr(expr) { - const left = this.evaluate(expr.left); - if (!left) { - return this.evaluate(expr.right); - } - return left; - } - visitGroupingExpr(expr) { - return this.evaluate(expr.expression); - } - visitLiteralExpr(expr) { - return expr.value; - } - visitUnaryExpr(expr) { - const right = this.evaluate(expr.right); - switch (expr.operator.type) { - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Minus: - return -right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].Bang: - return !right; - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].PlusPlus: - case _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].MinusMinus: - const newValue = Number(right) + (expr.operator.type === _types_token__WEBPACK_IMPORTED_MODULE_4__["TokenType"].PlusPlus ? 1 : -1); - if (expr.right instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__["Variable"]) { - this.scope.set(expr.right.name.lexeme, newValue); - } - else if (expr.right instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__["Get"]) { - const assign = new _types_expressions__WEBPACK_IMPORTED_MODULE_0__["Set"](expr.right.entity, expr.right.key, new _types_expressions__WEBPACK_IMPORTED_MODULE_0__["Literal"](newValue, expr.line), expr.line); - this.evaluate(assign); - } - else { - this.error(`Invalid right-hand side expression in prefix operation: ${expr.right}`); - } - return newValue; - default: - this.error(`Unknown unary operator ' + expr.operator`); - return null; // should be unreachable - } - } - visitCallExpr(expr) { - // verify callee is a function - const callee = this.evaluate(expr.callee); - if (typeof callee !== "function") { - this.error(`${callee} is not a function`); - } - // evaluate function arguments - const args = []; - for (const argument of expr.args) { - args.push(this.evaluate(argument)); - } - // execute function - if (expr.callee instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__["Get"] && - (expr.callee.entity instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__["Variable"] || - expr.callee.entity instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__["Grouping"])) { - return callee.apply(expr.callee.entity.result, args); - } - else { - return callee(...args); - } - } - visitNewExpr(expr) { - const newCall = expr.clazz; - // internal class definition instance - const clazz = this.evaluate(newCall.callee); - if (typeof clazz !== "function") { - this.error(`'${clazz}' is not a class. 'new' statement must be used with classes.`); - } - const args = []; - for (const arg of newCall.args) { - args.push(this.evaluate(arg)); - } - return new clazz(...args); - } - visitDictionaryExpr(expr) { - const dict = {}; - for (const property of expr.properties) { - const key = this.evaluate(property.key); - const value = this.evaluate(property.value); - dict[key] = value; - } - return dict; - } - visitTypeofExpr(expr) { - return typeof this.evaluate(expr.value); - } - visitEachExpr(expr) { - return [ - expr.name.lexeme, - expr.key ? expr.key.lexeme : null, - this.evaluate(expr.iterable), - ]; - } - visitVoidExpr(expr) { - this.evaluate(expr.value); - return ""; - } - visitDebugExpr(expr) { - const result = this.evaluate(expr.value); - console.log(result); - return ""; - } -} -/***/ }), -/***/ "./src/kasper.ts": -/*!***********************!*\ - !*** ./src/kasper.ts ***! - \***********************/ -/*! no exports provided */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _template_parser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./template-parser */ "./src/template-parser.ts"); -/* harmony import */ var _expression_parser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./expression-parser */ "./src/expression-parser.ts"); -/* harmony import */ var _interpreter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./interpreter */ "./src/interpreter.ts"); -/* harmony import */ var _transpiler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./transpiler */ "./src/transpiler.ts"); -/* harmony import */ var _types_demo__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./types/demo */ "./src/types/demo.ts"); -/* harmony import */ var _viewer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./viewer */ "./src/viewer.ts"); -/* harmony import */ var _scanner__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./scanner */ "./src/scanner.ts"); - - - - - - - -function execute(source) { - const parser = new _template_parser__WEBPACK_IMPORTED_MODULE_0__["TemplateParser"](); - const nodes = parser.parse(source); - if (parser.errors.length) { - return JSON.stringify(parser.errors); - } - const result = JSON.stringify(nodes); - return result; -} -function transpile(source, entries) { - const parser = new _template_parser__WEBPACK_IMPORTED_MODULE_0__["TemplateParser"](); - const nodes = parser.parse(source); - const transpiler = new _transpiler__WEBPACK_IMPORTED_MODULE_3__["Transpiler"](); - const result = transpiler.transpile(nodes, entries); - return result; -} -if (typeof window !== "undefined") { - (window || {}).kasper = { - demoJson: _types_demo__WEBPACK_IMPORTED_MODULE_4__["DemoJson"], - demoSourceCode: _types_demo__WEBPACK_IMPORTED_MODULE_4__["DemoSource"], - execute, - transpile, - }; -} -else if (typeof exports !== "undefined") { - exports.kasper = { - ExpressionParser: _expression_parser__WEBPACK_IMPORTED_MODULE_1__["ExpressionParser"], - Interpreter: _interpreter__WEBPACK_IMPORTED_MODULE_2__["Interpreter"], - Scanner: _scanner__WEBPACK_IMPORTED_MODULE_6__["Scanner"], - TemplateParser: _template_parser__WEBPACK_IMPORTED_MODULE_0__["TemplateParser"], - Transpiler: _transpiler__WEBPACK_IMPORTED_MODULE_3__["Transpiler"], - Viewer: _viewer__WEBPACK_IMPORTED_MODULE_5__["Viewer"], - }; -} + +class Interpreter { + constructor() { + this.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__.Scope(); + this.errors = []; + this.scanner = new _scanner__WEBPACK_IMPORTED_MODULE_1__.Scanner(); + this.parser = new _expression_parser__WEBPACK_IMPORTED_MODULE_2__.ExpressionParser(); + } + evaluate(expr) { + return (expr.result = expr.accept(this)); + } + error(message) { + throw new Error(`Runtime Error => ${message}`); + } + visitVariableExpr(expr) { + return this.scope.get(expr.name.lexeme); + } + visitAssignExpr(expr) { + const value = this.evaluate(expr.value); + this.scope.set(expr.name.lexeme, value); + return value; + } + visitKeyExpr(expr) { + return expr.name.literal; + } + visitGetExpr(expr) { + const entity = this.evaluate(expr.entity); + const key = this.evaluate(expr.key); + if (!entity && expr.type === _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.QuestionDot) { + return undefined; + } + return entity[key]; + } + visitSetExpr(expr) { + const entity = this.evaluate(expr.entity); + const key = this.evaluate(expr.key); + const value = this.evaluate(expr.value); + entity[key] = value; + return value; + } + visitPostfixExpr(expr) { + const value = this.scope.get(expr.name.lexeme); + const newValue = value + expr.increment; + this.scope.set(expr.name.lexeme, newValue); + return value; + } + visitListExpr(expr) { + const values = []; + for (const expression of expr.value) { + const value = this.evaluate(expression); + values.push(value); + } + return values; + } + templateParse(source) { + const tokens = this.scanner.scan(source); + const expressions = this.parser.parse(tokens); + if (this.parser.errors.length) { + this.error(`Template string error: ${this.parser.errors[0]}`); + } + let result = ""; + for (const expression of expressions) { + result += this.evaluate(expression).toString(); + } + return result; + } + visitTemplateExpr(expr) { + const result = expr.value.replace(/\{\{([\s\S]+?)\}\}/g, (m, placeholder) => { + return this.templateParse(placeholder); + }); + return result; + } + visitBinaryExpr(expr) { + const left = this.evaluate(expr.left); + const right = this.evaluate(expr.right); + switch (expr.operator.type) { + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Minus: + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.MinusEqual: + return left - right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Slash: + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.SlashEqual: + return left / right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Star: + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.StarEqual: + return left * right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Percent: + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.PercentEqual: + return left % right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Plus: + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.PlusEqual: + return left + right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Pipe: + return left | right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Caret: + return left ^ right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Greater: + return left > right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.GreaterEqual: + return left >= right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Less: + return left < right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.LessEqual: + return left <= right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.EqualEqual: + return left === right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.BangEqual: + return left !== right; + default: + this.error("Unknown binary operator " + expr.operator); + return null; // unreachable + } + } + visitLogicalExpr(expr) { + const left = this.evaluate(expr.left); + if (expr.operator.type === _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Or) { + if (left) { + return left; + } + } + else { + if (!left) { + return left; + } + } + return this.evaluate(expr.right); + } + visitTernaryExpr(expr) { + return this.evaluate(expr.condition).isTruthy() + ? this.evaluate(expr.thenExpr) + : this.evaluate(expr.elseExpr); + } + visitNullCoalescingExpr(expr) { + const left = this.evaluate(expr.left); + if (!left) { + return this.evaluate(expr.right); + } + return left; + } + visitGroupingExpr(expr) { + return this.evaluate(expr.expression); + } + visitLiteralExpr(expr) { + return expr.value; + } + visitUnaryExpr(expr) { + const right = this.evaluate(expr.right); + switch (expr.operator.type) { + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Minus: + return -right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.Bang: + return !right; + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.PlusPlus: + case _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.MinusMinus: + const newValue = Number(right) + (expr.operator.type === _types_token__WEBPACK_IMPORTED_MODULE_4__.TokenType.PlusPlus ? 1 : -1); + if (expr.right instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__.Variable) { + this.scope.set(expr.right.name.lexeme, newValue); + } + else if (expr.right instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__.Get) { + const assign = new _types_expressions__WEBPACK_IMPORTED_MODULE_0__.Set(expr.right.entity, expr.right.key, new _types_expressions__WEBPACK_IMPORTED_MODULE_0__.Literal(newValue, expr.line), expr.line); + this.evaluate(assign); + } + else { + this.error(`Invalid right-hand side expression in prefix operation: ${expr.right}`); + } + return newValue; + default: + this.error(`Unknown unary operator ' + expr.operator`); + return null; // should be unreachable + } + } + visitCallExpr(expr) { + // verify callee is a function + const callee = this.evaluate(expr.callee); + if (typeof callee !== "function") { + this.error(`${callee} is not a function`); + } + // evaluate function arguments + const args = []; + for (const argument of expr.args) { + args.push(this.evaluate(argument)); + } + // execute function + if (expr.callee instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__.Get && + (expr.callee.entity instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__.Variable || + expr.callee.entity instanceof _types_expressions__WEBPACK_IMPORTED_MODULE_0__.Grouping)) { + return callee.apply(expr.callee.entity.result, args); + } + else { + return callee(...args); + } + } + visitNewExpr(expr) { + const newCall = expr.clazz; + // internal class definition instance + const clazz = this.evaluate(newCall.callee); + if (typeof clazz !== "function") { + this.error(`'${clazz}' is not a class. 'new' statement must be used with classes.`); + } + const args = []; + for (const arg of newCall.args) { + args.push(this.evaluate(arg)); + } + return new clazz(...args); + } + visitDictionaryExpr(expr) { + const dict = {}; + for (const property of expr.properties) { + const key = this.evaluate(property.key); + const value = this.evaluate(property.value); + dict[key] = value; + } + return dict; + } + visitTypeofExpr(expr) { + return typeof this.evaluate(expr.value); + } + visitEachExpr(expr) { + return [ + expr.name.lexeme, + expr.key ? expr.key.lexeme : null, + this.evaluate(expr.iterable), + ]; + } + visitVoidExpr(expr) { + this.evaluate(expr.value); + return ""; + } + visitDebugExpr(expr) { + const result = this.evaluate(expr.value); + console.log(result); + return ""; + } +} /***/ }), @@ -774,296 +629,296 @@ else if (typeof exports !== "undefined") { /*!************************!*\ !*** ./src/scanner.ts ***! \************************/ -/*! exports provided: Scanner */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scanner", function() { return Scanner; }); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Scanner: () => (/* binding */ Scanner) +/* harmony export */ }); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils */ "./src/utils.ts"); /* harmony import */ var _types_token__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./types/token */ "./src/types/token.ts"); - - -class Scanner { - scan(source) { - this.source = source; - this.tokens = []; - this.errors = []; - this.current = 0; - this.start = 0; - this.line = 1; - this.col = 1; - while (!this.eof()) { - this.start = this.current; - try { - this.getToken(); - } - catch (e) { - this.errors.push(`${e}`); - if (this.errors.length > 100) { - this.errors.push("Error limit exceeded"); - return this.tokens; - } - } - } - this.tokens.push(new _types_token__WEBPACK_IMPORTED_MODULE_1__["Token"](_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Eof, "", null, this.line, 0)); - return this.tokens; - } - eof() { - return this.current >= this.source.length; - } - advance() { - if (this.peek() === "\n") { - this.line++; - this.col = 0; - } - this.current++; - this.col++; - return this.source.charAt(this.current - 1); - } - addToken(tokenType, literal) { - const text = this.source.substring(this.start, this.current); - this.tokens.push(new _types_token__WEBPACK_IMPORTED_MODULE_1__["Token"](tokenType, text, literal, this.line, this.col)); - } - match(expected) { - if (this.eof()) { - return false; - } - if (this.source.charAt(this.current) !== expected) { - return false; - } - this.current++; - return true; - } - peek() { - if (this.eof()) { - return "\0"; - } - return this.source.charAt(this.current); - } - peekNext() { - if (this.current + 1 >= this.source.length) { - return "\0"; - } - return this.source.charAt(this.current + 1); - } - comment() { - while (this.peek() !== "\n" && !this.eof()) { - this.advance(); - } - } - multilineComment() { - while (!this.eof() && !(this.peek() === "*" && this.peekNext() === "/")) { - this.advance(); - } - if (this.eof()) { - this.error('Unterminated comment, expecting closing "*/"'); - } - else { - // the closing slash '*/' - this.advance(); - this.advance(); - } - } - string(quote) { - while (this.peek() !== quote && !this.eof()) { - this.advance(); - } - // Unterminated string. - if (this.eof()) { - this.error(`Unterminated string, expecting closing ${quote}`); - return; - } - // The closing ". - this.advance(); - // Trim the surrounding quotes. - const value = this.source.substring(this.start + 1, this.current - 1); - this.addToken(quote !== "`" ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].String : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Template, value); - } - number() { - // gets integer part - while (_utils__WEBPACK_IMPORTED_MODULE_0__["isDigit"](this.peek())) { - this.advance(); - } - // checks for fraction - if (this.peek() === "." && _utils__WEBPACK_IMPORTED_MODULE_0__["isDigit"](this.peekNext())) { - this.advance(); - } - // gets fraction part - while (_utils__WEBPACK_IMPORTED_MODULE_0__["isDigit"](this.peek())) { - this.advance(); - } - // checks for exponent - if (this.peek().toLowerCase() === "e") { - this.advance(); - if (this.peek() === "-" || this.peek() === "+") { - this.advance(); - } - } - while (_utils__WEBPACK_IMPORTED_MODULE_0__["isDigit"](this.peek())) { - this.advance(); - } - const value = this.source.substring(this.start, this.current); - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Number, Number(value)); - } - identifier() { - while (_utils__WEBPACK_IMPORTED_MODULE_0__["isAlphaNumeric"](this.peek())) { - this.advance(); - } - const value = this.source.substring(this.start, this.current); - const capitalized = _utils__WEBPACK_IMPORTED_MODULE_0__["capitalize"](value); - if (_utils__WEBPACK_IMPORTED_MODULE_0__["isKeyword"](capitalized)) { - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"][capitalized], value); - } - else { - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Identifier, value); - } - } - getToken() { - const char = this.advance(); - switch (char) { - case "(": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].LeftParen, null); - break; - case ")": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].RightParen, null); - break; - case "[": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].LeftBracket, null); - break; - case "]": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].RightBracket, null); - break; - case "{": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].LeftBrace, null); - break; - case "}": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].RightBrace, null); - break; - case ",": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Comma, null); - break; - case ";": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Semicolon, null); - break; - case "^": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Caret, null); - break; - case "$": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Dollar, null); - break; - case "#": - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Hash, null); - break; - case ":": - this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Arrow : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Colon, null); - break; - case "*": - this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].StarEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Star, null); - break; - case "%": - this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].PercentEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Percent, null); - break; - case "|": - this.addToken(this.match("|") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Or : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Pipe, null); - break; - case "&": - this.addToken(this.match("&") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].And : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Ampersand, null); - break; - case ">": - this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].GreaterEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Greater, null); - break; - case "!": - this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].BangEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Bang, null); - break; - case "?": - this.addToken(this.match("?") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].QuestionQuestion - : this.match(".") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].QuestionDot - : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Question, null); - break; - case "=": - this.addToken(this.match("=") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].EqualEqual - : this.match(">") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Arrow - : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Equal, null); - break; - case "+": - this.addToken(this.match("+") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].PlusPlus - : this.match("=") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].PlusEqual - : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Plus, null); - break; - case "-": - this.addToken(this.match("-") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].MinusMinus - : this.match("=") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].MinusEqual - : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Minus, null); - break; - case "<": - this.addToken(this.match("=") - ? this.match(">") - ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].LessEqualGreater - : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].LessEqual - : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Less, null); - break; - case ".": - if (this.match(".")) { - if (this.match(".")) { - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].DotDotDot, null); - } - else { - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].DotDot, null); - } - } - else { - this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Dot, null); - } - break; - case "/": - if (this.match("/")) { - this.comment(); - } - else if (this.match("*")) { - this.multilineComment(); - } - else { - this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].SlashEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__["TokenType"].Slash, null); - } - break; - case `'`: - case `"`: - case "`": - this.string(char); - break; - // ignore cases - case "\n": - case " ": - case "\r": - case "\t": - break; - // complex cases - default: - if (_utils__WEBPACK_IMPORTED_MODULE_0__["isDigit"](char)) { - this.number(); - } - else if (_utils__WEBPACK_IMPORTED_MODULE_0__["isAlpha"](char)) { - this.identifier(); - } - else { - this.error(`Unexpected character '${char}'`); - } - break; - } - } - error(message) { - throw new Error(`Scan Error (${this.line}:${this.col}) => ${message}`); - } -} + + +class Scanner { + scan(source) { + this.source = source; + this.tokens = []; + this.errors = []; + this.current = 0; + this.start = 0; + this.line = 1; + this.col = 1; + while (!this.eof()) { + this.start = this.current; + try { + this.getToken(); + } + catch (e) { + this.errors.push(`${e}`); + if (this.errors.length > 100) { + this.errors.push("Error limit exceeded"); + return this.tokens; + } + } + } + this.tokens.push(new _types_token__WEBPACK_IMPORTED_MODULE_1__.Token(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Eof, "", null, this.line, 0)); + return this.tokens; + } + eof() { + return this.current >= this.source.length; + } + advance() { + if (this.peek() === "\n") { + this.line++; + this.col = 0; + } + this.current++; + this.col++; + return this.source.charAt(this.current - 1); + } + addToken(tokenType, literal) { + const text = this.source.substring(this.start, this.current); + this.tokens.push(new _types_token__WEBPACK_IMPORTED_MODULE_1__.Token(tokenType, text, literal, this.line, this.col)); + } + match(expected) { + if (this.eof()) { + return false; + } + if (this.source.charAt(this.current) !== expected) { + return false; + } + this.current++; + return true; + } + peek() { + if (this.eof()) { + return "\0"; + } + return this.source.charAt(this.current); + } + peekNext() { + if (this.current + 1 >= this.source.length) { + return "\0"; + } + return this.source.charAt(this.current + 1); + } + comment() { + while (this.peek() !== "\n" && !this.eof()) { + this.advance(); + } + } + multilineComment() { + while (!this.eof() && !(this.peek() === "*" && this.peekNext() === "/")) { + this.advance(); + } + if (this.eof()) { + this.error('Unterminated comment, expecting closing "*/"'); + } + else { + // the closing slash '*/' + this.advance(); + this.advance(); + } + } + string(quote) { + while (this.peek() !== quote && !this.eof()) { + this.advance(); + } + // Unterminated string. + if (this.eof()) { + this.error(`Unterminated string, expecting closing ${quote}`); + return; + } + // The closing ". + this.advance(); + // Trim the surrounding quotes. + const value = this.source.substring(this.start + 1, this.current - 1); + this.addToken(quote !== "`" ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.String : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Template, value); + } + number() { + // gets integer part + while (_utils__WEBPACK_IMPORTED_MODULE_0__.isDigit(this.peek())) { + this.advance(); + } + // checks for fraction + if (this.peek() === "." && _utils__WEBPACK_IMPORTED_MODULE_0__.isDigit(this.peekNext())) { + this.advance(); + } + // gets fraction part + while (_utils__WEBPACK_IMPORTED_MODULE_0__.isDigit(this.peek())) { + this.advance(); + } + // checks for exponent + if (this.peek().toLowerCase() === "e") { + this.advance(); + if (this.peek() === "-" || this.peek() === "+") { + this.advance(); + } + } + while (_utils__WEBPACK_IMPORTED_MODULE_0__.isDigit(this.peek())) { + this.advance(); + } + const value = this.source.substring(this.start, this.current); + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Number, Number(value)); + } + identifier() { + while (_utils__WEBPACK_IMPORTED_MODULE_0__.isAlphaNumeric(this.peek())) { + this.advance(); + } + const value = this.source.substring(this.start, this.current); + const capitalized = _utils__WEBPACK_IMPORTED_MODULE_0__.capitalize(value); + if (_utils__WEBPACK_IMPORTED_MODULE_0__.isKeyword(capitalized)) { + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType[capitalized], value); + } + else { + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Identifier, value); + } + } + getToken() { + const char = this.advance(); + switch (char) { + case "(": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.LeftParen, null); + break; + case ")": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.RightParen, null); + break; + case "[": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.LeftBracket, null); + break; + case "]": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.RightBracket, null); + break; + case "{": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.LeftBrace, null); + break; + case "}": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.RightBrace, null); + break; + case ",": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Comma, null); + break; + case ";": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Semicolon, null); + break; + case "^": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Caret, null); + break; + case "$": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Dollar, null); + break; + case "#": + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Hash, null); + break; + case ":": + this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Arrow : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Colon, null); + break; + case "*": + this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.StarEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Star, null); + break; + case "%": + this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.PercentEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Percent, null); + break; + case "|": + this.addToken(this.match("|") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Or : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Pipe, null); + break; + case "&": + this.addToken(this.match("&") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.And : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Ampersand, null); + break; + case ">": + this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.GreaterEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Greater, null); + break; + case "!": + this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.BangEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Bang, null); + break; + case "?": + this.addToken(this.match("?") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.QuestionQuestion + : this.match(".") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.QuestionDot + : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Question, null); + break; + case "=": + this.addToken(this.match("=") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.EqualEqual + : this.match(">") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Arrow + : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Equal, null); + break; + case "+": + this.addToken(this.match("+") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.PlusPlus + : this.match("=") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.PlusEqual + : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Plus, null); + break; + case "-": + this.addToken(this.match("-") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.MinusMinus + : this.match("=") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.MinusEqual + : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Minus, null); + break; + case "<": + this.addToken(this.match("=") + ? this.match(">") + ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.LessEqualGreater + : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.LessEqual + : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Less, null); + break; + case ".": + if (this.match(".")) { + if (this.match(".")) { + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.DotDotDot, null); + } + else { + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.DotDot, null); + } + } + else { + this.addToken(_types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Dot, null); + } + break; + case "/": + if (this.match("/")) { + this.comment(); + } + else if (this.match("*")) { + this.multilineComment(); + } + else { + this.addToken(this.match("=") ? _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.SlashEqual : _types_token__WEBPACK_IMPORTED_MODULE_1__.TokenType.Slash, null); + } + break; + case `'`: + case `"`: + case "`": + this.string(char); + break; + // ignore cases + case "\n": + case " ": + case "\r": + case "\t": + break; + // complex cases + default: + if (_utils__WEBPACK_IMPORTED_MODULE_0__.isDigit(char)) { + this.number(); + } + else if (_utils__WEBPACK_IMPORTED_MODULE_0__.isAlpha(char)) { + this.identifier(); + } + else { + this.error(`Unexpected character '${char}'`); + } + break; + } + } + error(message) { + throw new Error(`Scan Error (${this.line}:${this.col}) => ${message}`); + } +} /***/ }), @@ -1072,38 +927,38 @@ class Scanner { /*!**********************!*\ !*** ./src/scope.ts ***! \**********************/ -/*! exports provided: Scope */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scope", function() { return Scope; }); -class Scope { - constructor(parent, entries) { - this.parent = parent ? parent : null; - this.init(entries); - } - init(entries) { - if (entries) { - this.values = new Map(Object.entries(entries)); - } - else { - this.values = new Map(); - } - } - set(name, value) { - this.values.set(name, value); - } - get(key) { - if (this.values.has(key)) { - return this.values.get(key); - } - if (this.parent !== null) { - return this.parent.get(key); - } - return window[key]; - } -} +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Scope: () => (/* binding */ Scope) +/* harmony export */ }); +class Scope { + constructor(parent, entries) { + this.parent = parent ? parent : null; + this.init(entries); + } + init(entries) { + if (entries) { + this.values = new Map(Object.entries(entries)); + } + else { + this.values = new Map(); + } + } + set(name, value) { + this.values.set(name, value); + } + get(key) { + if (this.values.has(key)) { + return this.values.get(key); + } + if (this.parent !== null) { + return this.parent.get(key); + } + return window[key]; + } +} /***/ }), @@ -1112,241 +967,241 @@ class Scope { /*!********************************!*\ !*** ./src/template-parser.ts ***! \********************************/ -/*! exports provided: TemplateParser */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TemplateParser", function() { return TemplateParser; }); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ TemplateParser: () => (/* binding */ TemplateParser) +/* harmony export */ }); /* harmony import */ var _types_error__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./types/error */ "./src/types/error.ts"); /* harmony import */ var _types_nodes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./types/nodes */ "./src/types/nodes.ts"); /* harmony import */ var _types_token__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./types/token */ "./src/types/token.ts"); - - - -class TemplateParser { - parse(source) { - this.current = 0; - this.line = 1; - this.col = 1; - this.source = source; - this.errors = []; - this.nodes = []; - while (!this.eof()) { - try { - const node = this.node(); - if (node === null) { - continue; - } - this.nodes.push(node); - } - catch (e) { - if (e instanceof _types_error__WEBPACK_IMPORTED_MODULE_0__["KasperError"]) { - this.errors.push(`Parse Error (${e.line}:${e.col}) => ${e.value}`); - } - else { - this.errors.push(`${e}`); - if (this.errors.length > 10) { - this.errors.push("Parse Error limit exceeded"); - return this.nodes; - } - } - break; - } - } - this.source = ""; - return this.nodes; - } - match(...chars) { - for (const char of chars) { - if (this.check(char)) { - this.current += char.length; - return true; - } - } - return false; - } - advance(eofError = "") { - if (!this.eof()) { - if (this.check("\n")) { - this.line += 1; - this.col = 0; - } - this.col += 1; - this.current++; - } - else { - this.error(`Unexpected end of file. ${eofError}`); - } - } - peek(...chars) { - for (const char of chars) { - if (this.check(char)) { - return true; - } - } - return false; - } - check(char) { - return this.source.slice(this.current, this.current + char.length) === char; - } - eof() { - return this.current > this.source.length; - } - error(message) { - throw new _types_error__WEBPACK_IMPORTED_MODULE_0__["KasperError"](message, this.line, this.col); - } - node() { - this.whitespace(); - let node; - if (this.match("'"); - } while (!this.match(`-->`)); - const comment = this.source.slice(start, this.current - 3); - return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__["Comment"](comment, this.line); - } - doctype() { - const start = this.current; - do { - this.advance("Expected closing doctype"); - } while (!this.match(`>`)); - const doctype = this.source.slice(start, this.current - 1).trim(); - return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__["Doctype"](doctype, this.line); - } - element() { - const line = this.line; - const name = this.identifier("/", ">"); - if (!name) { - this.error("Expected a tag name"); - } - const attributes = this.attributes(); - if (this.match("/>") || - (_types_token__WEBPACK_IMPORTED_MODULE_2__["SelfClosingTags"].includes(name) && this.match(">"))) { - return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__["Element"](name, attributes, [], true, this.line); - } - if (!this.match(">")) { - this.error("Expected closing tag"); - } - let children = []; - this.whitespace(); - if (!this.peek("`); - } - if (!this.match(`${name}`)) { - this.error(`Expected `); - } - this.whitespace(); - if (!this.match(">")) { - this.error(`Expected `); - } - } - children(parent) { - const children = []; - do { - if (this.eof()) { - this.error(`Expected `); - } - const node = this.node(); - if (node === null) { - continue; - } - children.push(node); - } while (!this.peek(`", "/>") && !this.eof()) { - this.whitespace(); - const line = this.line; - const name = this.identifier("=", ">", "/>"); - if (!name) { - this.error("Blank attribute name"); - } - this.whitespace(); - let value = ""; - if (this.match("=")) { - this.whitespace(); - if (this.match("'")) { - value = this.string("'"); - } - else if (this.match('"')) { - value = this.string('"'); - } - else { - value = this.identifier(">", "/>"); - } - } - this.whitespace(); - attributes.push(new _types_nodes__WEBPACK_IMPORTED_MODULE_1__["Attribute"](name, value, line)); - } - return attributes; - } - text() { - const start = this.current; - const line = this.line; - while (!this.peek("<") && !this.eof()) { - this.advance(); - } - const text = this.source.slice(start, this.current).trim(); - if (!text) { - return null; - } - return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__["Text"](text, line); - } - whitespace() { - let count = 0; - while (this.peek(..._types_token__WEBPACK_IMPORTED_MODULE_2__["WhiteSpaces"]) && !this.eof()) { - count += 1; - this.advance(); - } - return count; - } - identifier(...closing) { - this.whitespace(); - const start = this.current; - while (!this.peek(..._types_token__WEBPACK_IMPORTED_MODULE_2__["WhiteSpaces"], ...closing)) { - this.advance(`Expected closing ${closing}`); - } - const end = this.current; - this.whitespace(); - return this.source.slice(start, end).trim(); - } - string(closing) { - const start = this.current; - while (!this.match(closing)) { - this.advance(`Expected closing ${closing}`); - } - return this.source.slice(start, this.current - 1); - } -} + + + +class TemplateParser { + parse(source) { + this.current = 0; + this.line = 1; + this.col = 1; + this.source = source; + this.errors = []; + this.nodes = []; + while (!this.eof()) { + try { + const node = this.node(); + if (node === null) { + continue; + } + this.nodes.push(node); + } + catch (e) { + if (e instanceof _types_error__WEBPACK_IMPORTED_MODULE_0__.KasperError) { + this.errors.push(`Parse Error (${e.line}:${e.col}) => ${e.value}`); + } + else { + this.errors.push(`${e}`); + if (this.errors.length > 10) { + this.errors.push("Parse Error limit exceeded"); + return this.nodes; + } + } + break; + } + } + this.source = ""; + return this.nodes; + } + match(...chars) { + for (const char of chars) { + if (this.check(char)) { + this.current += char.length; + return true; + } + } + return false; + } + advance(eofError = "") { + if (!this.eof()) { + if (this.check("\n")) { + this.line += 1; + this.col = 0; + } + this.col += 1; + this.current++; + } + else { + this.error(`Unexpected end of file. ${eofError}`); + } + } + peek(...chars) { + for (const char of chars) { + if (this.check(char)) { + return true; + } + } + return false; + } + check(char) { + return this.source.slice(this.current, this.current + char.length) === char; + } + eof() { + return this.current > this.source.length; + } + error(message) { + throw new _types_error__WEBPACK_IMPORTED_MODULE_0__.KasperError(message, this.line, this.col); + } + node() { + this.whitespace(); + let node; + if (this.match("'"); + } while (!this.match(`-->`)); + const comment = this.source.slice(start, this.current - 3); + return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__.Comment(comment, this.line); + } + doctype() { + const start = this.current; + do { + this.advance("Expected closing doctype"); + } while (!this.match(`>`)); + const doctype = this.source.slice(start, this.current - 1).trim(); + return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__.Doctype(doctype, this.line); + } + element() { + const line = this.line; + const name = this.identifier("/", ">"); + if (!name) { + this.error("Expected a tag name"); + } + const attributes = this.attributes(); + if (this.match("/>") || + (_types_token__WEBPACK_IMPORTED_MODULE_2__.SelfClosingTags.includes(name) && this.match(">"))) { + return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__.Element(name, attributes, [], true, this.line); + } + if (!this.match(">")) { + this.error("Expected closing tag"); + } + let children = []; + this.whitespace(); + if (!this.peek("`); + } + if (!this.match(`${name}`)) { + this.error(`Expected `); + } + this.whitespace(); + if (!this.match(">")) { + this.error(`Expected `); + } + } + children(parent) { + const children = []; + do { + if (this.eof()) { + this.error(`Expected `); + } + const node = this.node(); + if (node === null) { + continue; + } + children.push(node); + } while (!this.peek(`", "/>") && !this.eof()) { + this.whitespace(); + const line = this.line; + const name = this.identifier("=", ">", "/>"); + if (!name) { + this.error("Blank attribute name"); + } + this.whitespace(); + let value = ""; + if (this.match("=")) { + this.whitespace(); + if (this.match("'")) { + value = this.string("'"); + } + else if (this.match('"')) { + value = this.string('"'); + } + else { + value = this.identifier(">", "/>"); + } + } + this.whitespace(); + attributes.push(new _types_nodes__WEBPACK_IMPORTED_MODULE_1__.Attribute(name, value, line)); + } + return attributes; + } + text() { + const start = this.current; + const line = this.line; + while (!this.peek("<") && !this.eof()) { + this.advance(); + } + const text = this.source.slice(start, this.current).trim(); + if (!text) { + return null; + } + return new _types_nodes__WEBPACK_IMPORTED_MODULE_1__.Text(text, line); + } + whitespace() { + let count = 0; + while (this.peek(..._types_token__WEBPACK_IMPORTED_MODULE_2__.WhiteSpaces) && !this.eof()) { + count += 1; + this.advance(); + } + return count; + } + identifier(...closing) { + this.whitespace(); + const start = this.current; + while (!this.peek(..._types_token__WEBPACK_IMPORTED_MODULE_2__.WhiteSpaces, ...closing)) { + this.advance(`Expected closing ${closing}`); + } + const end = this.current; + this.whitespace(); + return this.source.slice(start, end).trim(); + } + string(closing) { + const start = this.current; + while (!this.match(closing)) { + this.advance(`Expected closing ${closing}`); + } + return this.source.slice(start, this.current - 1); + } +} /***/ }), @@ -1355,243 +1210,243 @@ class TemplateParser { /*!***************************!*\ !*** ./src/transpiler.ts ***! \***************************/ -/*! exports provided: Transpiler */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Transpiler", function() { return Transpiler; }); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Transpiler: () => (/* binding */ Transpiler) +/* harmony export */ }); /* harmony import */ var _expression_parser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./expression-parser */ "./src/expression-parser.ts"); /* harmony import */ var _interpreter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./interpreter */ "./src/interpreter.ts"); /* harmony import */ var _scanner__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./scanner */ "./src/scanner.ts"); /* harmony import */ var _scope__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./scope */ "./src/scope.ts"); - - - - -class Transpiler { - constructor() { - this.scanner = new _scanner__WEBPACK_IMPORTED_MODULE_2__["Scanner"](); - this.parser = new _expression_parser__WEBPACK_IMPORTED_MODULE_0__["ExpressionParser"](); - this.interpreter = new _interpreter__WEBPACK_IMPORTED_MODULE_1__["Interpreter"](); - this.errors = []; - } - evaluate(node, parent) { - node.accept(this, parent); - } - // evaluates expressions and returns the result of the first evaluation - execute(source) { - const tokens = this.scanner.scan(source); - const expressions = this.parser.parse(tokens); - const result = expressions.map((expression) => this.interpreter.evaluate(expression)); - return result && result.length ? result[0] : undefined; - } - transpile(nodes, entries) { - const container = document.createElement("kasper"); - this.interpreter.scope.init(entries); - this.errors = []; - try { - this.createSiblings(nodes, container); - } - catch (e) { - console.error(`${e}`); - } - return container; - } - visitElementKNode(node, parent) { - this.createElement(node, parent); - } - visitTextKNode(node, parent) { - const regex = /\{\{.+\}\}/ms; - let text; - if (regex.test(node.value)) { - const result = node.value.replace(/\{\{([\s\S]+?)\}\}/g, (m, placeholder) => { - return this.templateParse(placeholder); - }); - text = document.createTextNode(result); - } - else { - text = document.createTextNode(node.value); - } - if (parent) { - parent.appendChild(text); - } - } - visitAttributeKNode(node, parent) { - const attr = document.createAttribute(node.name); - if (node.value) { - attr.value = node.value; - } - if (parent) { - parent.setAttributeNode(attr); - } - } - visitCommentKNode(node, parent) { - const result = new Comment(node.value); - if (parent) { - parent.appendChild(result); - } - } - findAttr(node, name) { - if (!node || !node.attributes || !node.attributes.length) { - return null; - } - const attrib = node.attributes.find((attr) => name.includes(attr.name)); - if (attrib) { - return attrib; - } - return null; - } - doIf(expressions, parent) { - const $if = this.execute(expressions[0][1].value); - if ($if) { - this.createElement(expressions[0][0], parent); - return; - } - for (const expression of expressions.slice(1, expressions.length)) { - if (this.findAttr(expression[0], ["@elseif"])) { - const $elseif = this.execute(expression[1].value); - if ($elseif) { - this.createElement(expression[0], parent); - return; - } - else { - continue; - } - } - if (this.findAttr(expression[0], ["@else"])) { - this.createElement(expression[0], parent); - return; - } - } - } - doEach(each, node, parent) { - const tokens = this.scanner.scan(each.value); - const [name, key, iterable] = this.interpreter.evaluate(this.parser.foreach(tokens)); - const originalScope = this.interpreter.scope; - let index = 0; - for (const item of iterable) { - const scope = { [name]: item }; - if (key) { - scope[key] = index; - } - this.interpreter.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__["Scope"](originalScope, scope); - this.createElement(node, parent); - index += 1; - } - this.interpreter.scope = originalScope; - } - doWhile($while, node, parent) { - const originalScope = this.interpreter.scope; - this.interpreter.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__["Scope"](originalScope); - while (this.execute($while.value)) { - this.createElement(node, parent); - } - this.interpreter.scope = originalScope; - } - doInit(init, node, parent) { - const originalScope = this.interpreter.scope; - this.interpreter.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__["Scope"](originalScope); - this.execute(init.value); - this.createElement(node, parent); - this.interpreter.scope = originalScope; - } - createSiblings(nodes, parent) { - let current = 0; - while (current < nodes.length) { - const node = nodes[current++]; - if (node.type === "element") { - const $each = this.findAttr(node, ["@each"]); - if ($each) { - this.doEach($each, node, parent); - continue; - } - const $if = this.findAttr(node, ["@if"]); - if ($if) { - const expressions = [[node, $if]]; - const tag = node.name; - let found = true; - while (found) { - if (current >= nodes.length) { - break; - } - const attr = this.findAttr(nodes[current], [ - "@else", - "@elseif", - ]); - if (nodes[current].name === tag && attr) { - expressions.push([nodes[current], attr]); - current += 1; - } - else { - found = false; - } - } - this.doIf(expressions, parent); - continue; - } - const $while = this.findAttr(node, ["@while"]); - if ($while) { - this.doWhile($while, node, parent); - continue; - } - const $init = this.findAttr(node, ["@init"]); - if ($init) { - this.doInit($init, node, parent); - continue; - } - } - this.evaluate(node, parent); - } - } - createElement(node, parent) { - const isTemplate = node.name === "kvoid"; - const element = isTemplate ? parent : document.createElement(node.name); - if (!isTemplate) { - // event binding - const events = node.attributes.filter((attr) => attr.name.startsWith("@on:")); - for (const event of events) { - this.createEventListener(element, event); - } - // attributes - node.attributes - .filter((attr) => !attr.name.startsWith("@")) - .map((attr) => this.evaluate(attr, element)); - } - if (node.self) { - return; - } - this.createSiblings(node.children, element); - if (!isTemplate && parent) { - parent.appendChild(element); - } - } - createEventListener(element, attr) { - const type = attr.name.split(":")[1]; - element.addEventListener(type, () => { - this.execute(attr.value); - }); - } - templateParse(source) { - const tokens = this.scanner.scan(source); - const expressions = this.parser.parse(tokens); - if (this.parser.errors.length) { - this.error(`Template string error: ${this.parser.errors[0]}`); - } - let result = ""; - for (const expression of expressions) { - result += `${this.interpreter.evaluate(expression)}`; - } - return result; - } - visitDoctypeKNode(node) { - return; - // return document.implementation.createDocumentType("html", "", ""); - } - error(message) { - throw new Error(`Runtime Error => ${message}`); - } -} + + + + +class Transpiler { + constructor() { + this.scanner = new _scanner__WEBPACK_IMPORTED_MODULE_2__.Scanner(); + this.parser = new _expression_parser__WEBPACK_IMPORTED_MODULE_0__.ExpressionParser(); + this.interpreter = new _interpreter__WEBPACK_IMPORTED_MODULE_1__.Interpreter(); + this.errors = []; + } + evaluate(node, parent) { + node.accept(this, parent); + } + // evaluates expressions and returns the result of the first evaluation + execute(source) { + const tokens = this.scanner.scan(source); + const expressions = this.parser.parse(tokens); + const result = expressions.map((expression) => this.interpreter.evaluate(expression)); + return result && result.length ? result[0] : undefined; + } + transpile(nodes, entries) { + const container = document.createElement("kasper"); + this.interpreter.scope.init(entries); + this.errors = []; + try { + this.createSiblings(nodes, container); + } + catch (e) { + console.error(`${e}`); + } + return container; + } + visitElementKNode(node, parent) { + this.createElement(node, parent); + } + visitTextKNode(node, parent) { + const regex = /\{\{.+\}\}/ms; + let text; + if (regex.test(node.value)) { + const result = node.value.replace(/\{\{([\s\S]+?)\}\}/g, (m, placeholder) => { + return this.templateParse(placeholder); + }); + text = document.createTextNode(result); + } + else { + text = document.createTextNode(node.value); + } + if (parent) { + parent.appendChild(text); + } + } + visitAttributeKNode(node, parent) { + const attr = document.createAttribute(node.name); + if (node.value) { + attr.value = node.value; + } + if (parent) { + parent.setAttributeNode(attr); + } + } + visitCommentKNode(node, parent) { + const result = new Comment(node.value); + if (parent) { + parent.appendChild(result); + } + } + findAttr(node, name) { + if (!node || !node.attributes || !node.attributes.length) { + return null; + } + const attrib = node.attributes.find((attr) => name.includes(attr.name)); + if (attrib) { + return attrib; + } + return null; + } + doIf(expressions, parent) { + const $if = this.execute(expressions[0][1].value); + if ($if) { + this.createElement(expressions[0][0], parent); + return; + } + for (const expression of expressions.slice(1, expressions.length)) { + if (this.findAttr(expression[0], ["@elseif"])) { + const $elseif = this.execute(expression[1].value); + if ($elseif) { + this.createElement(expression[0], parent); + return; + } + else { + continue; + } + } + if (this.findAttr(expression[0], ["@else"])) { + this.createElement(expression[0], parent); + return; + } + } + } + doEach(each, node, parent) { + const tokens = this.scanner.scan(each.value); + const [name, key, iterable] = this.interpreter.evaluate(this.parser.foreach(tokens)); + const originalScope = this.interpreter.scope; + let index = 0; + for (const item of iterable) { + const scope = { [name]: item }; + if (key) { + scope[key] = index; + } + this.interpreter.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__.Scope(originalScope, scope); + this.createElement(node, parent); + index += 1; + } + this.interpreter.scope = originalScope; + } + doWhile($while, node, parent) { + const originalScope = this.interpreter.scope; + this.interpreter.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__.Scope(originalScope); + while (this.execute($while.value)) { + this.createElement(node, parent); + } + this.interpreter.scope = originalScope; + } + doInit(init, node, parent) { + const originalScope = this.interpreter.scope; + this.interpreter.scope = new _scope__WEBPACK_IMPORTED_MODULE_3__.Scope(originalScope); + this.execute(init.value); + this.createElement(node, parent); + this.interpreter.scope = originalScope; + } + createSiblings(nodes, parent) { + let current = 0; + while (current < nodes.length) { + const node = nodes[current++]; + if (node.type === "element") { + const $each = this.findAttr(node, ["@each"]); + if ($each) { + this.doEach($each, node, parent); + continue; + } + const $if = this.findAttr(node, ["@if"]); + if ($if) { + const expressions = [[node, $if]]; + const tag = node.name; + let found = true; + while (found) { + if (current >= nodes.length) { + break; + } + const attr = this.findAttr(nodes[current], [ + "@else", + "@elseif", + ]); + if (nodes[current].name === tag && attr) { + expressions.push([nodes[current], attr]); + current += 1; + } + else { + found = false; + } + } + this.doIf(expressions, parent); + continue; + } + const $while = this.findAttr(node, ["@while"]); + if ($while) { + this.doWhile($while, node, parent); + continue; + } + const $init = this.findAttr(node, ["@init"]); + if ($init) { + this.doInit($init, node, parent); + continue; + } + } + this.evaluate(node, parent); + } + } + createElement(node, parent) { + const isTemplate = node.name === "kvoid"; + const element = isTemplate ? parent : document.createElement(node.name); + if (!isTemplate) { + // event binding + const events = node.attributes.filter((attr) => attr.name.startsWith("@on:")); + for (const event of events) { + this.createEventListener(element, event); + } + // attributes + node.attributes + .filter((attr) => !attr.name.startsWith("@")) + .map((attr) => this.evaluate(attr, element)); + } + if (node.self) { + return; + } + this.createSiblings(node.children, element); + if (!isTemplate && parent) { + parent.appendChild(element); + } + } + createEventListener(element, attr) { + const type = attr.name.split(":")[1]; + element.addEventListener(type, () => { + this.execute(attr.value); + }); + } + templateParse(source) { + const tokens = this.scanner.scan(source); + const expressions = this.parser.parse(tokens); + if (this.parser.errors.length) { + this.error(`Template string error: ${this.parser.errors[0]}`); + } + let result = ""; + for (const expression of expressions) { + result += `${this.interpreter.evaluate(expression)}`; + } + return result; + } + visitDoctypeKNode(node) { + return; + // return document.implementation.createDocumentType("html", "", ""); + } + error(message) { + throw new Error(`Runtime Error => ${message}`); + } +} /***/ }), @@ -1600,15 +1455,14 @@ class Transpiler { /*!***************************!*\ !*** ./src/types/demo.ts ***! \***************************/ -/*! exports provided: DemoSource, DemoJson */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DemoSource", function() { return DemoSource; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DemoJson", function() { return DemoJson; }); -const DemoSource = ` - +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ DemoJson: () => (/* binding */ DemoJson), +/* harmony export */ DemoSource: () => (/* binding */ DemoSource) +/* harmony export */ }); +const DemoSource = `

{{person.name}}

{{person.profession}}

@@ -1620,15 +1474,16 @@ const DemoSource = `

Hobbies ({{person.hobbies.length}}):

-