Stub parser for code

This commit is contained in:
Tangent Wantwight 2023-07-27 01:54:06 -04:00
parent 4eec6f8a2d
commit eca8c6218f
3 changed files with 77 additions and 6 deletions

9
3x5.js
View file

@ -24,12 +24,8 @@
* @returns {string} Markup to render / output
*/
function renderCard(state, code) {
/* Preprocess: fold line endings */
code = code.replace(/(?<!\\)(\\\\)*\\q/g, "$1");
/* Preprocess: escape HTML */
code = escapeHtml(code);
state.output = code;
const script = parseNotcl(code);
state.output = JSON.stringify(script, null, 2);
return state.output;
}
@ -59,6 +55,7 @@ let theCard = {
} {
Since we want escapes to work, these blocks [i will] be subject to substitutions.
}
# A comment
para {
line endings escaped\
one slash

View file

@ -6,6 +6,7 @@
</head>
<body>
<script src="helpers.js"></script>
<script src="notcl.js"></script>
<script src="3x5.js"></script>
</body>
</html>

73
notcl.js Normal file
View file

@ -0,0 +1,73 @@
/**
* @typedef {Command[]} Script
* @typedef {Word[]} Command
* @typedef {object} Word
* @property {string} text
*/
/**
* Parse out a Notcl script into an easier-to-interpret representation.
* No script is actually executed yet.
*
* @param {string} code
* @returns Script
*/
function parseNotcl(code) {
/* Preprocess */
// fold line endings
code = code.replace(/(?<!\\)(\\\\)*\\n/g, "$1");
// escape HTML
code = escapeHtml(code);
/* Parse */
function nextWord(/* TODO: null/] terminator */) {
// Strip whitespace
code = code.replace(/^[^\S\n;]*/, "");
// TODO: handle all kinds of brace/substitution stuff
const word = code.match(/^[^\s;]+/);
if (word) {
code = code.substring(word[0].length);
return { text: word[0] };
} else {
return null;
}
}
function nextCommand(/* TODO: null/] terminator */) {
const command = /** @type {Word[]} */ ([]);
while (true) {
// Strip whitespace
code = code.replace(/^\s*/, "");
// Strip comments
if (code[0] == "#") {
code = code.replace(/^.*\n/, "");
continue;
}
// Strip semicolons
if (code[0] == ";") {
code = code.substring(1);
continue;
}
break;
}
while (true) {
const word = nextWord();
if (word) {
command.push(word);
continue;
}
break;
}
return command;
}
/* Loop through commands, with safety check */
const script = /** @type {Command[]} */ ([]);
for (let i = 0; i < 1000 && code != ""; i++) {
script.push(nextCommand());
}
return script;
}