92 lines
2.2 KiB
JavaScript
92 lines
2.2 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
var _types = require("../tokenizer/types");
|
||
|
|
||
|
var _index = require("./index");
|
||
|
|
||
|
var _index2 = _interopRequireDefault(_index);
|
||
|
|
||
|
var _whitespace = require("../util/whitespace");
|
||
|
|
||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
||
|
var pp = _index2.default.prototype;
|
||
|
|
||
|
// ## Parser utilities
|
||
|
|
||
|
// TODO
|
||
|
|
||
|
pp.addExtra = function (node, key, val) {
|
||
|
if (!node) return;
|
||
|
|
||
|
var extra = node.extra = node.extra || {};
|
||
|
extra[key] = val;
|
||
|
};
|
||
|
|
||
|
// TODO
|
||
|
|
||
|
pp.isRelational = function (op) {
|
||
|
return this.match(_types.types.relational) && this.state.value === op;
|
||
|
};
|
||
|
|
||
|
// TODO
|
||
|
|
||
|
pp.expectRelational = function (op) {
|
||
|
if (this.isRelational(op)) {
|
||
|
this.next();
|
||
|
} else {
|
||
|
this.unexpected();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Tests whether parsed token is a contextual keyword.
|
||
|
|
||
|
pp.isContextual = function (name) {
|
||
|
return this.match(_types.types.name) && this.state.value === name;
|
||
|
};
|
||
|
|
||
|
// Consumes contextual keyword if possible.
|
||
|
|
||
|
pp.eatContextual = function (name) {
|
||
|
return this.state.value === name && this.eat(_types.types.name);
|
||
|
};
|
||
|
|
||
|
// Asserts that following token is given contextual keyword.
|
||
|
|
||
|
pp.expectContextual = function (name, message) {
|
||
|
if (!this.eatContextual(name)) this.unexpected(null, message);
|
||
|
};
|
||
|
|
||
|
// Test whether a semicolon can be inserted at the current position.
|
||
|
|
||
|
pp.canInsertSemicolon = function () {
|
||
|
return this.match(_types.types.eof) || this.match(_types.types.braceR) || _whitespace.lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
|
||
|
};
|
||
|
|
||
|
// TODO
|
||
|
|
||
|
pp.isLineTerminator = function () {
|
||
|
return this.eat(_types.types.semi) || this.canInsertSemicolon();
|
||
|
};
|
||
|
|
||
|
// Consume a semicolon, or, failing that, see if we are allowed to
|
||
|
// pretend that there is a semicolon at this position.
|
||
|
|
||
|
pp.semicolon = function () {
|
||
|
if (!this.isLineTerminator()) this.unexpected();
|
||
|
};
|
||
|
|
||
|
// Expect a token of a given type. If found, consume it, otherwise,
|
||
|
// raise an unexpected token error at given pos.
|
||
|
|
||
|
pp.expect = function (type, pos) {
|
||
|
return this.eat(type) || this.unexpected(pos);
|
||
|
};
|
||
|
|
||
|
// Raise an unexpected token error.
|
||
|
|
||
|
pp.unexpected = function (pos) {
|
||
|
var message = arguments.length <= 1 || arguments[1] === undefined ? "Unexpected token" : arguments[1];
|
||
|
|
||
|
this.raise(pos != null ? pos : this.state.start, message);
|
||
|
};
|