templural
Version:
Template function for plural-sensitive formatting
89 lines • 2.68 kB
JavaScript
export var Token;
(function (Token) {
let Type;
(function (Type) {
Type["String"] = "String";
Type["Integer"] = "Integer";
Type["LCurly"] = "{";
Type["RCurly"] = "}";
Type["SColon"] = ";";
Type["Dollar"] = "$";
Type["Colon"] = ":";
})(Type = Token.Type || (Token.Type = {}));
function isSpecialChar(char) {
return char === Token.Type.LCurly || char === Token.Type.RCurly || char === Token.Type.SColon || char === Token.Type.Dollar || char === Token.Type.Colon;
}
Token.isSpecialChar = isSpecialChar;
function string(value) {
return [Type.String, value];
}
Token.string = string;
function isString(token) {
return Array.isArray(token) && token[0] === Type.String;
}
Token.isString = isString;
function integer(value) {
return [Type.Integer, value];
}
Token.integer = integer;
function isInteger(token) {
return Array.isArray(token) && token[0] === Type.Integer;
}
Token.isInteger = isInteger;
function toString(token) {
if (isString(token))
return token[1];
if (isInteger(token))
return token[1].toString();
return token;
}
Token.toString = toString;
})(Token || (Token = {}));
export function lex(source) {
return [...new Lexer(source)];
}
class Lexer {
constructor(source) {
this.pos = 0;
this.source = source;
}
next() {
if (this.ch === undefined)
return { done: true, value: null };
if (Token.isSpecialChar(this.ch)) {
const value = this.ch;
this.nextPos();
return { value };
}
if (this.ch >= '1' && this.ch <= '9')
return { value: this.readInteger() };
return { value: this.readString() };
}
readInteger() {
const { pos } = this;
do {
this.nextPos();
} while (this.ch !== undefined && this.ch >= '0' && this.ch <= '9');
if (!Token.isSpecialChar(this.ch))
return this.readString(pos);
return Token.integer(this.source.slice(pos, this.pos));
}
readString(pos = this.pos) {
do {
if (this.ch === '\\')
this.nextPos();
this.nextPos();
} while (this.ch !== undefined && !Token.isSpecialChar(this.ch));
return Token.string(this.source.slice(pos, this.pos).replace(/\\(.)/g, '$1'));
}
nextPos() {
this.pos++;
}
get ch() {
return this.source[this.pos];
}
[Symbol.iterator]() {
return this;
}
}
//# sourceMappingURL=lex.js.map