Skip to content

Instantly share code, notes, and snippets.

@BRonen
Created March 27, 2023 07:03
Show Gist options
  • Save BRonen/5a8d2dfd4ec14a752520174c871979a1 to your computer and use it in GitHub Desktop.
Save BRonen/5a8d2dfd4ec14a752520174c871979a1 to your computer and use it in GitHub Desktop.
const code1 = '((7 1 +) 5 +) ((8 ((8 ((8 3 +) 1 +) +) 1 +) +) 1 +) +';
const code2 = '4 3 -';
const code3 = '(2 3 +) (23 21 +) +';
const operators = {
'+': (args) => args[0] + args[1],
'-': (args) => args[0] - args[1],
'*': (args) => args[0] * args[1],
'/': (args) => args[0] / args[1],
};
let counter = 0;
const parse = (source) => {
console.log(counter++, `${' '.repeat(counter*4)}${source}`);
const re = /\(.*?\)/;
let hasNestedScope = re.test(source);
while (hasNestedScope) {
let nestedCounter = 0;
const parentesisIndexes = [0, 0];
for(let i = 0; i < source.length; i++) {
const char = source[i];
if(char === '(') {
nestedCounter++;
if(nestedCounter === 1) parentesisIndexes[0] = i+1;
}
if(char === ')') {
nestedCounter--;
if(nestedCounter === 0) parentesisIndexes[1] = i;
}
}
const scopeCode = source.slice(...parentesisIndexes);
const scopeResult = parse(scopeCode);
source = source.replace(`(${scopeCode})`, scopeResult);
hasNestedScope = re.test(source);
}
const tokens = source.split(' ');
let stack = [];
for (const token of tokens) {
if (token in operators) break;
stack.push(Number(token));
}
const op = tokens.pop();
const result = operators[op](stack);
return result;
};
console.log( 'Result:', parse(code1), '\n' );
counter = 0;
console.log( 'Result:', parse(code2), '\n' );
counter = 0;
console.log( 'Result:', parse(code3), '\n' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment