Created
April 5, 2021 14:20
-
-
Save thomasvrgn/cffc3720bee1ac7478d45d36473058bf to your computer and use it in GitHub Desktop.
Simple Lisp parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const code = '(print "test" (+ 5 (- 4 2)) (print "bruh" (t "test")))'; | |
| const tokens = tokenize(code); | |
| console.log(parse(tokens)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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