Skip to content

Instantly share code, notes, and snippets.

@tail-call
Created February 17, 2022 03:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tail-call/7f8fd5ae78d2d4dfefc7515f6f983ea0 to your computer and use it in GitHub Desktop.
Save tail-call/7f8fd5ae78d2d4dfefc7515f6f983ea0 to your computer and use it in GitHub Desktop.
//@ts-check
class PushbackIterator {
/**
* @param {Iterator<string, string, string>} stringIter
*/
constructor(stringIter) {
/** @type {Iterator<string, string, string>} */
this.stringIter = stringIter;
/** @type {Array<string>} */
this.backBuffer = [];
}
/**
* @param {string} char
*/
pushBack(char) {
this.backBuffer.push(char);
}
next() {
if (this.backBuffer.length) {
return { value: this.backBuffer.pop(), done: false };
} else {
return this.stringIter.next();
}
}
[Symbol.iterator]() {
return this;
}
}
/**
* @param {PushbackIterator} stringIter
* @param {string} stopChar
* @returns {string}
*/
function copyString(stringIter, stopChar) {
let result = "";
for (const char of stringIter) {
if (char === stopChar) break;
result += char;
}
return result;
}
/**
* @param {PushbackIterator} stringIter
* @returns {string}
*/
function readName(stringIter) {
let result = "";
for (const char of stringIter) {
if (!char.match(/[a-z0-9_]/i)) {
stringIter.pushBack(char);
break;
}
result += char;
}
return result;
}
/**
* @param {PushbackIterator} jsonString
* @param {string=} propertyName
* @param {string=} stopChar
* @returns {string}
*/
function untag(jsonString, stopChar = "", propertyName = "type") {
let result = "";
for (const char of jsonString) {
if (char === `"`) {
result += `"${copyString(jsonString, `"`)}"`;
} else if (char.match(/[a-z]/i)) {
const name = char + readName(jsonString);
result += copyString(jsonString, "{") + "{";
result += (` "type": "${name}",` + untag(jsonString, "}", propertyName)).replace(/,\s*$/, " ");
result += "}";
} else if (char === stopChar) {
return result;
} else {
result += char;
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment