I have a PEG -based parser, processing text input. In addition to regular macros, it supports nesting - macro within a macro.
My code peg processor function - async macroBuilder()
wraps every visit()
- method used to process a specific type macro in a Promise
as:
dateMath(obj) {
const dateAttribs = { format: obj.format };
switch (dateAttribs.format) {
...
default:
fragments.push(
new Promise((resolve, reject) => {
resolve(moment(now).format(dateAttribs.format));
});
);
break;
}
}
To process nested macros, I do:
nestedSnippet(obj) {
fragments.push(
processSingleShortcut(constants.SHORTCUT_PREFIX.concat(obj.name), true)
.then(res => {
let result = macroBuilder(res, { retainWhitespace: true, nestedLevel: nestedLevel+1 }, clipboard, window.now);
return result;
})
.catch(() => {
console.log(`couldn't find match for nested snippet: ${obj.name}`);
})
);
}
At the end, I do Promise.all()
and join all the pieces into a string.
However, it appears that the nested part is not working, like I want to. The idea is to push into fragments
a Promise
that when being resolved will:
- call
processSingleShortcut()
- use result of the previous call as an argument for an async function
macroBuilder()
- return the result of
macroBuilder()
I need this because in addition to returning strings as a result, macro processing may have side-effects and I need those from all previous macros to correctly process the next one in the fragments
array.
Hence, I need nested already processed before the macro following it is being evaluated. It does not seem to wrap a promise around nested macros, I need to.