Last active
February 14, 2025 21:55
-
-
Save sbrow/1459a040966c21e2b901b380299e163d to your computer and use it in GitHub Desktop.
Simple lisp parser in Javascript
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
// Simple Lisp Parser | |
// ========================== | |
// | |
// Accepts expressions like "(* 2 (+ 3 4))" and computes their value. | |
{ | |
// This initializer block allows us to define a variables object | |
//const variables = options; | |
const variables = { | |
users: 2, | |
people: 80, | |
...options.variables, | |
} | |
const functions = { | |
'*': (...args) => args.reduce((acc, item) => acc * item, 1), | |
'/': (...args) => args.reduce((acc, item) => acc / item, 1), | |
'+': (...args) => args.reduce((acc, item) => acc + item, 0), | |
'-': (...args) => args.reduce((acc, item) => acc - item, 0), | |
// Not perfect, doesn't handle non-lists correctly | |
'append': (...args) => args.reduce((acc, item) => acc.concat(item), []), | |
'list': (...args) => args, | |
...options.functions, | |
} | |
} | |
Expression | |
= FunctionCall | |
/ Integer | |
/ Variable | |
FunctionCall | |
= "(" fn:FunctionName args:(_ Expression)* ")" { | |
if (fn in functions) { | |
return functions[fn](...args.map(x => x[1])); | |
} else { | |
return error(`Unknown function '${fn}' called`); | |
} | |
} | |
FunctionName | |
= [a-zA-Z_][a-zA-Z0-9_]+ { return text(); } | |
/ [\*\+\-\/] | |
Integer "integer" | |
= _ "-"? [0-9]+ { return parseInt(text(), 10); } | |
Variable "variable" | |
= _ [a-zA-Z_][a-zA-Z0-9_]* { | |
const varName = text().trim(); | |
if (varName in variables) { | |
return variables[varName]; | |
} else { | |
return 0 | |
} | |
} | |
_ "whitespace" | |
= [ \t\n\r]* |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment