Namespace Notcl

This commit is contained in:
Tangent Wantwight 2023-07-29 00:37:25 -04:00
parent 71581253d5
commit 64c2d1c35d
2 changed files with 74 additions and 70 deletions

2
3x5.js
View file

@ -24,7 +24,7 @@
* @returns {string} Markup to render / output
*/
function renderCard(state, code) {
const script = parseNotcl(code);
const script = Notcl.parse(code);
state.output = JSON.stringify(script, null, 2);
return state.output;
}

142
notcl.js
View file

@ -1,84 +1,88 @@
/**
* @typedef {Command[]} Script
* @typedef {Word[]} Command
* @typedef {object} Word
* @typedef {Notcl.Command[]} Notcl.Script
* @typedef {Notcl.Word[]} Notcl.Command
* @typedef {object} Notcl.Word
* @property {string} text
*/
const InterCommandWhitespace = Peg.Regex(/[^\S\n;]*/y);
var Notcl = (() => {
const InterCommandWhitespace = Peg.Regex(/[^\S\n;]*/y);
const CommentPattern = Peg.Regex(/#.*\n/y);
const Comment = Peg.Regex(/#.*\n/y);
const PreWordWhitespace = Peg.Regex(/[^\S\n;]*/y);
const PreWordWhitespace = Peg.Regex(/[^\S\n;]*/y);
const BasicWord = Peg.Map(Peg.Regex(/[^\s;]+/y), ([word]) => ({
text: word,
}));
const BasicWord = Peg.Map(Peg.Regex(/[^\s;]+/y), ([word]) => ({
text: word,
}));
const WordPattern = Peg.Map(
Peg.Sequence(PreWordWhitespace, BasicWord),
([_, word]) => word
);
const Word = Peg.Map(
Peg.Sequence(PreWordWhitespace, BasicWord),
([_, word]) => word
);
/**
* 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");
return {
/**
* Parse out a Notcl script into an easier-to-interpret representation.
* No script is actually executed yet.
*
* @param {string} code
* @returns Script
*/
parse(code) {
/* Preprocess */
// fold line endings
code = code.replace(/(?<!\\)((\\\\)*)\\\n/g, "$1");
/* Parse */
function nextWord(/* TODO: null/]/" terminator */) {
// TODO: handle all kinds of brace/substitution stuff
const [word, nextIndex] = WordPattern(code, 0) ?? [null, 0];
if (word) {
code = code.substring(nextIndex);
return word;
} 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;
/* Parse */
function nextWord(/* TODO: null/]/" terminator */) {
// TODO: handle all kinds of brace/substitution stuff
const [word, nextIndex] = Word(code, 0) ?? [null, 0];
if (word) {
code = code.substring(nextIndex);
return word;
} else {
return null;
}
}
// Strip semicolons
if (code[0] == ";") {
code = code.substring(1);
continue;
function nextCommand(/* TODO: null/]/" terminator */) {
const command = /** @type {Notcl.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;
}
break;
}
while (true) {
const word = nextWord();
if (word) {
command.push(word);
continue;
/* Loop through commands, with safety check */
const script = /** @type {Notcl.Command[]} */ ([]);
for (let i = 0; i < 1000 && code != ""; i++) {
script.push(nextCommand());
}
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;
}
return script;
},
};
})();