A templating language that looks like Lisp and compiles to HTML
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

evaluator.js 1.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. const AST = require('./ast')
  2. const Env = require('./env')
  3. module.exports = class Evaluator {
  4. eval(tree, env) {
  5. let evaluatedTree = []
  6. tree.forEach(node => {
  7. evaluatedTree.push(this.evalNode(node, env))
  8. })
  9. return evaluatedTree
  10. }
  11. evalNode(node, env) {
  12. switch (node.constructor) {
  13. case AST.Boolean:
  14. case AST.Number:
  15. case AST.String:
  16. return node
  17. case AST.Identifier:
  18. return env.get(node.name)
  19. case AST.Application:
  20. switch (node.function.constructor) {
  21. case AST.Identifier:
  22. return this.evalNode(
  23. new AST.Application({
  24. function: env.get(node.function.name),
  25. args: node.args,
  26. }),
  27. env
  28. )
  29. case AST.Lambda:
  30. let innerEnv = new Env()
  31. node.function.parameters.forEach((param, index) => {
  32. innerEnv.set(param.name, node.args[index])
  33. })
  34. return this.evalNode(node.function.body, innerEnv)
  35. case Function:
  36. let args = node.args.map(arg => {
  37. return this.evalNode(arg, env)
  38. })
  39. args.unshift(this)
  40. return node.function.call(...args)
  41. }
  42. }
  43. return node
  44. }
  45. }