ivi
Version:
Lightweight Embeddable Web UI Library.
136 lines • 3.49 kB
JavaScript
export class TemplateParserError extends Error {
staticsOffset;
textOffset;
constructor(message, staticsOffset, textOffset) {
super(message);
this.staticsOffset = staticsOffset;
this.textOffset = textOffset;
}
}
export class TemplateScanner {
statics;
exprCount;
text;
i;
e;
constructor(statics) {
if (statics.length === 0) {
throw new TemplateParserError("Template is empty.", 0, 0);
}
this.statics = statics;
this.exprCount = statics.length - 1;
this.text = statics[0];
this.i = 0;
this.e = 0;
}
isEnd() {
return (this.i === this.text.length &&
this.e === this.exprCount);
}
peekCharCode(i = 0) {
i += this.i;
return i < this.text.length
? this.text.charCodeAt(i)
: -1;
}
charCode(c) {
if (this.i < this.text.length && this.text.charCodeAt(this.i) === c) {
this.i++;
return true;
}
return false;
}
peekExpr() {
const e = this.e;
return (e < this.exprCount && this.i === this.text.length)
? e
: -1;
}
expr() {
const e = this.e;
if (e < this.exprCount && this.i === this.text.length) {
this.i = 0;
this.text = this.statics[++this.e];
return e;
}
return -1;
}
peekString(s) {
const text = this.text;
const end = this.i + s.length;
return (end <= text.length &&
text.substring(this.i, end) === s);
}
string(s) {
const r = this.peekString(s);
if (r) {
this.i += s.length;
}
return r;
}
peekRegExp(re) {
if (!re.sticky) {
throw Error("RegExp should have a sticky flag.");
}
re.lastIndex = this.i;
const match = re.exec(this.text);
if (match !== null) {
return match[0];
}
}
regExp(re) {
const r = this.peekRegExp(re);
if (r !== void 0) {
this.i += r.length;
}
return r;
}
}
/**
* Formats error message.
*
* @param errorMsg Error message.
* @param errorCol Line column.
*/
const formatErrorMsg = (errorMsg, errorCol) => {
let msg = "";
while (--errorCol >= 0) {
msg += " ";
}
msg += "^\nError: " + errorMsg + "\n";
return msg;
};
/**
* Formats compiler errors.
*
* @param statics Statics.
* @param errorMsg Error message.
* @param staticsOffset Expression offset.
* @param textOffset Text offset.
* @returns Formatted error message.
*/
export const formatError = (statics, errorMsg, staticsOffset, textOffset) => {
for (let i = 0; i < staticsOffset; i++) {
if (i > 0) {
textOffset += 4 + (Math.log10(i) | 0); // ${i}
}
textOffset += statics[i].length;
}
let msg = "\n";
let text = statics[0];
for (let i = 1; i < statics.length; i++) {
text += "${" + (i - 1) + "}" + statics[i];
}
for (const line of text.split("\n")) {
msg += line + "\n";
if (textOffset >= 0 && textOffset < line.length) {
msg += formatErrorMsg(errorMsg, textOffset);
}
textOffset -= (line.length + 1);
}
if (textOffset >= 0) {
msg += formatErrorMsg(errorMsg, textOffset);
}
return msg;
};
//# sourceMappingURL=parser.js.map