1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- const AST = require('./ast')
- const Env = require('./env')
-
- module.exports = class Evaluator {
- eval(tree, env) {
- this.env = env
-
- let evaluatedTree = []
-
- tree.forEach(node => {
- let evaluatedNode = this.evalNode(node)
-
- if (evaluatedNode) {
- evaluatedTree.push(evaluatedNode)
- }
- })
-
- return evaluatedTree
- }
-
- evalNode(node, env) {
- if (!env) env = this.env
-
- switch (node.constructor) {
- case AST.Boolean:
- case AST.Number:
- case AST.String:
- return node
- case AST.Identifier:
- return env.get(node.name)
- case AST.Definition:
- this.env.set(node.symbol.name, node.value)
- return false
- case AST.Application:
- switch (node.function.constructor) {
- case AST.Identifier:
- return this.evalNode(
- new AST.Application({
- function: env.get(node.function.name),
- args: node.args,
- }),
- )
- case AST.Lambda:
- let innerEnv = new Env(env)
-
- node.function.parameters.forEach((param, index) => {
- innerEnv.set(param.name, node.args[index])
- })
-
- return this.evalNode(node.function.body, innerEnv)
- case Function:
- let args = node.args.map(arg => {
- return this.evalNode(arg)
- })
- args.unshift(this)
- return node.function.call(...args)
- }
- }
-
- return node
- }
- }
|