@kpi4me/golden-layout
Version:
A multi-screen javascript Layout manager https://golden-layout.com
329 lines (328 loc) • 9.84 kB
JavaScript
// Generated by CoffeeScript 2.0.0-beta8
var DEDENT, INDENT, pointToErrorLocation, Preprocessor, StringScanner, TERM, ws;
pointToErrorLocation = require('./helpers').pointToErrorLocation;
StringScanner = require('StringScanner');
this.Preprocessor = Preprocessor = function () {
ws = '\\t\\x0B\\f\\r \\xA0\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000\\uFEFF';
INDENT = '\uefef';
DEDENT = '\ueffe';
TERM = '\uefff';
function Preprocessor(param$) {
if (null == param$)
param$ = {};
this.options = param$;
this.preprocessed = '';
this.base = null;
this.indents = [];
this.context = [];
}
Preprocessor.process = function (input, options) {
if (null == options)
options = {};
return new Preprocessor(options).process(input);
};
Preprocessor.prototype.err = function (c) {
var columns, context, lines, token;
token = function () {
switch (c) {
case INDENT:
return 'INDENT';
case DEDENT:
return 'DEDENT';
case TERM:
return 'TERM';
default:
return '"' + c.replace(/"/g, '\\"') + '"';
}
}.call(this);
lines = this.ss.str.substr(0, this.ss.pos).split(/\n/) || [''];
columns = null != lines[lines.length - 1] ? lines[lines.length - 1].length : 0;
context = pointToErrorLocation(this.ss.str, lines.length, columns);
throw new Error('Unexpected ' + token + '\n' + context);
};
Preprocessor.prototype.peek = function () {
if (this.context.length) {
return this.context[this.context.length - 1];
} else {
return null;
}
};
Preprocessor.prototype.observe = function (c) {
var top;
top = this.peek();
switch (c) {
case '"""':
case "'''":
case '"':
case "'":
case '###':
case '`':
case '///':
case '/':
if (top === c) {
this.context.pop();
} else {
this.context.push(c);
}
break;
case INDENT:
case '#':
case '#{':
case '[':
case '(':
case '{':
case '\\':
case 'regexp-[':
case 'regexp-(':
case 'regexp-{':
case 'heregexp-#':
case 'heregexp-[':
case 'heregexp-(':
case 'heregexp-{':
this.context.push(c);
break;
case DEDENT:
if (!(top === INDENT))
this.err(c);
this.indents.pop();
this.context.pop();
break;
case '\n':
if (!(top === '#' || top === 'heregexp-#'))
this.err(c);
this.context.pop();
break;
case ']':
if (!(top === '[' || top === 'regexp-[' || top === 'heregexp-['))
this.err(c);
this.context.pop();
break;
case ')':
if (!(top === '(' || top === 'regexp-(' || top === 'heregexp-('))
this.err(c);
this.context.pop();
break;
case '}':
if (!(top === '#{' || top === '{' || top === 'regexp-{' || top === 'heregexp-{'))
this.err(c);
this.context.pop();
break;
case 'end-\\':
if (!(top === '\\'))
this.err(c);
this.context.pop();
break;
default:
throw new Error('undefined token observed: ' + c);
}
return this.context;
};
Preprocessor.prototype.p = function (s) {
if (null != s)
this.preprocessed = '' + this.preprocessed + s;
return s;
};
Preprocessor.prototype.scan = function (r) {
return this.p(this.ss.scan(r));
};
Preprocessor.prototype.consumeIndentation = function () {
var context, indent, indentIndex, lineLen, lines, message;
if (this.ss.bol() || this.scan(new RegExp('(?:[' + ws + ']*\\n)+'))) {
this.scan(new RegExp('(?:[' + ws + ']*(\\#\\#?(?!\\#)[^\\n]*)?\\n)+'));
if (null != this.base) {
if (!(this.ss.eos() || null != this.scan(this.base))) {
throw new Error('inconsistent base indentation');
}
} else {
this.base = new RegExp('' + this.scan(new RegExp('[' + ws + ']*')) + '');
}
indentIndex = 0;
while (indentIndex < this.indents.length) {
indent = this.indents[indentIndex];
if (this.ss.check(new RegExp('' + indent + ''))) {
this.scan(new RegExp('' + indent + ''));
} else if (this.ss.eos() || this.ss.check(new RegExp('[^' + ws + ']'))) {
--indentIndex;
this.p('' + DEDENT + TERM);
this.observe(DEDENT);
} else {
lines = this.ss.str.substr(0, this.ss.pos).split(/\n/) || [''];
message = 'Syntax error on line ' + lines.length + ': indentation is ambiguous';
lineLen = this.indents.reduce(function (l, r) {
return l + r.length;
}, 0);
context = pointToErrorLocation(this.ss.str, lines.length, lineLen);
throw new Error('' + message + '\n' + context);
}
++indentIndex;
}
if (this.ss.check(new RegExp('[' + ws + ']+[^' + ws + '#]'))) {
this.indents.push(this.scan(new RegExp('[' + ws + ']+')));
this.p(INDENT);
return this.observe(INDENT);
}
}
};
Preprocessor.prototype.introduceContext = function () {
var impliedRegexp, lastChar, pos, spaceBefore, tok;
if (tok = this.scan(/"""|'''|\/\/\/|###|["'`#[({\\]/)) {
return this.observe(tok);
} else if (tok = this.scan(/\//)) {
pos = this.ss.position();
if (pos > 1) {
lastChar = this.ss.string()[pos - 2];
spaceBefore = new RegExp('[' + ws + ']').test(lastChar);
impliedRegexp = /[;,=><*%^&|[(+!~-]/.test(lastChar);
}
if (pos === 1 || impliedRegexp || spaceBefore && !this.ss.check(new RegExp('[' + ws + '=]')) && this.ss.check(/[^\r\n]*\//))
return this.observe('/');
}
};
Preprocessor.prototype.process = function (input) {
var tok;
if (this.options.literate)
input = input.replace(/^( {0,3}\S)/gm, ' #$1');
this.ss = new StringScanner(input);
while (!this.ss.eos()) {
switch (this.peek()) {
case null:
case INDENT:
this.consumeIndentation();
this.scan(/[^\n'"\\\/#`[(){}\]]+/);
if (this.ss.check(/[})\]]/)) {
while (this.peek() === INDENT) {
this.p('' + DEDENT + TERM);
this.observe(DEDENT);
}
this.observe(this.scan(/[})\]]/));
} else {
this.introduceContext();
}
break;
case '#{':
case '{':
this.scan(/[^\n'"\\\/#`[({}]+/);
if (tok = this.scan(/\}/)) {
this.observe(tok);
} else {
this.consumeIndentation();
this.introduceContext();
}
break;
case '[':
this.scan(/[^\n'"\\\/#`[({\]]+/);
if (tok = this.scan(/\]/)) {
this.observe(tok);
} else {
this.consumeIndentation();
this.introduceContext();
}
break;
case '(':
this.scan(/[^\n'"\\\/#`[({)]+/);
if (tok = this.scan(/\)/)) {
this.observe(tok);
} else {
this.consumeIndentation();
this.introduceContext();
}
break;
case '\\':
if (this.scan(/[\s\S]/))
this.observe('end-\\');
break;
case '"""':
this.scan(/(?:[^"#\\]+|""?(?!")|#(?!{)|\\.)+/);
this.ss.scan(/\\\n/);
if (tok = this.scan(/#{|"""/)) {
this.observe(tok);
} else if (tok = this.scan(/#{|"""/)) {
this.observe(tok);
}
break;
case '"':
this.scan(/(?:[^"#\\]+|#(?!{)|\\.)+/);
this.ss.scan(/\\\n/);
if (tok = this.scan(/#{|"/))
this.observe(tok);
break;
case "'''":
this.scan(/(?:[^'\\]+|''?(?!')|\\.)+/);
this.ss.scan(/\\\n/);
if (tok = this.scan(/'''/))
this.observe(tok);
break;
case "'":
this.scan(/(?:[^'\\]+|\\.)+/);
this.ss.scan(/\\\n/);
if (tok = this.scan(/'/))
this.observe(tok);
break;
case '###':
this.scan(/(?:[^#]+|##?(?!#))+/);
if (tok = this.scan(/###/))
this.observe(tok);
break;
case '#':
this.scan(/[^\n]+/);
if (tok = this.scan(/\n/))
this.observe(tok);
break;
case '`':
this.scan(/[^`]+/);
if (tok = this.scan(/`/))
this.observe(tok);
break;
case '///':
this.scan(/(?:[^[/#\\]+|\/\/?(?!\/)|\\.)+/);
if (tok = this.scan(/#{|\/\/\/|\\/)) {
this.observe(tok);
} else if (this.ss.scan(/#/)) {
this.observe('heregexp-#');
} else if (tok = this.scan(/[\[]/)) {
this.observe('heregexp-' + tok);
}
break;
case 'heregexp-[':
this.scan(/(?:[^\]\/\\]+|\/\/?(?!\/))+/);
if (tok = this.scan(/[\]\\]|#{|\/\/\//))
this.observe(tok);
break;
case 'heregexp-#':
this.ss.scan(/(?:[^\n/]+|\/\/?(?!\/))+/);
if (tok = this.scan(/\n|\/\/\//))
this.observe(tok);
break;
case '/':
this.scan(/[^[/\\]+/);
if (tok = this.scan(/[\/\\]/)) {
this.observe(tok);
} else if (tok = this.scan(/\[/)) {
this.observe('regexp-' + tok);
}
break;
case 'regexp-[':
this.scan(/[^\]\\]+/);
if (tok = this.scan(/[\]\\]/))
this.observe(tok);
}
}
this.scan(new RegExp('[' + ws + '\\n]*$'));
while (this.context.length) {
switch (this.peek()) {
case INDENT:
this.p('' + DEDENT + TERM);
this.observe(DEDENT);
break;
case '#':
this.p('\n');
this.observe('\n');
break;
default:
throw new Error('Unclosed "' + this.peek().replace(/"/g, '\\"') + '" at EOF');
}
}
return this.preprocessed;
};
return Preprocessor;
}();