Skip to content

Instantly share code, notes, and snippets.

@sbrow
Last active February 14, 2025 21:55
Show Gist options
  • Save sbrow/1459a040966c21e2b901b380299e163d to your computer and use it in GitHub Desktop.
Save sbrow/1459a040966c21e2b901b380299e163d to your computer and use it in GitHub Desktop.
Simple lisp parser in Javascript
// 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