Skip to content

Instantly share code, notes, and snippets.

@thomasvrgn
Created April 5, 2021 14:20
Show Gist options
  • Select an option

  • Save thomasvrgn/cffc3720bee1ac7478d45d36473058bf to your computer and use it in GitHub Desktop.

Select an option

Save thomasvrgn/cffc3720bee1ac7478d45d36473058bf to your computer and use it in GitHub Desktop.
Simple Lisp parser
const code = '(print "test" (+ 5 (- 4 2)) (print "bruh" (t "test")))';
const tokens = tokenize(code);
console.log(parse(tokens));
const tokenize = (code) => code
.split(/(\(|\)|".*?"|\w+)/g)
.map((acc) => acc.trim())
.filter((acc) => acc.length > 0);
const ast = [];
function findParent(node, root) {
let found = null;
for (const child of root) {
if (child === node) return root;
if (!Array.isArray(child)) continue;
found = this.findParent(node, child);
if (found !== null) return found;
}
return null;
}
function parse(tokens, index = 0, _ast = ast) {
const token = tokens[index];
if (!token) return ast;
if (token === '(') {
_ast.push([]);
return parse(tokens, index + 1, _ast.slice(-1)[0]);
}
if (token === ')') {
return parse(tokens, index + 1, findParent(_ast, ast));
}
if (isNaN(Number(token))) {
_ast.push(token)
} else _ast.push(Number(token))
return parse(tokens, index + 1, _ast);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment