Skip to content

Instantly share code, notes, and snippets.

@superMDguy
Created December 18, 2017 20:40
Show Gist options
  • Select an option

  • Save superMDguy/1873330ebc0b04c6eed6290f4cb3918e to your computer and use it in GitHub Desktop.

Select an option

Save superMDguy/1873330ebc0b04c6eed6290f4cb3918e to your computer and use it in GitHub Desktop.
<script>
const code = '(print (+ 1 (* 2 3) 3))'
const parsed = parse(code)
console.debug('Parsed AST', parsed)
evaluate(parsed[0])
function parse(phrase) {
let seek = 0
const parsed = []
let nextToken = ""
while (seek < phrase.length) {
const nextChar = phrase[seek]
if (nextChar == '(') {
const matchingParen = phrase.length - phrase.split("").reverse().join("").indexOf(')') - 1
parsed.push(parse(phrase.slice(seek + 1, matchingParen)))
seek = matchingParen + 1
} else if (/\s/.test(nextChar)) {
if (nextToken) parsed.push(nextToken)
nextToken = ""
} else {
nextToken += nextChar
}
seek++
}
if (nextToken) parsed.push(nextToken)
return parsed
}
function evaluate(ast) {
const functions = {
'+': function () { return Array.from(arguments).reduce((a, b) => a + b) },
'-': function () { return Array.from(arguments).reduce((a, b) => a - b) },
'*': function () { return Array.from(arguments).reduce((a, b) => a * b) },
'/': function () { return Array.from(arguments).reduce((a, b) => a / b) },
'print': console.log,
}
const op = functions[ast[0]]
const args = ast.slice(1).map(x => (x instanceof Array) ? evaluate(x) : parseFloat(x))
result = op(...args)
return result
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment