Browse Source

Evaluate lambda functions

master
Dylan Baker 5 years ago
parent
commit
63d4d4b735
2 changed files with 36 additions and 13 deletions
  1. 25
    2
      src/evaluator.js
  2. 11
    11
      test/evaluatorTest.js

+ 25
- 2
src/evaluator.js View File

@@ -14,11 +14,34 @@ module.exports = class Evaluator {
14 14
 
15 15
   evalNode(node, env) {
16 16
     switch (node.constructor) {
17
+      case AST.Number:
18
+        return node
19
+      case AST.Identifier:
20
+        return env.get(node.name)
17 21
       case AST.Application:
18 22
         switch (node.function.constructor) {
19 23
           case AST.Identifier:
20
-            node.function = env.get(node.function.name)
21
-            break
24
+            return this.evalNode(
25
+              new AST.Application({
26
+                function: env.get(node.function.name),
27
+                args: node.args,
28
+              }),
29
+              env
30
+            )
31
+          case AST.Lambda:
32
+            let innerEnv = new Env()
33
+
34
+            node.function.parameters.forEach((param, index) => {
35
+              innerEnv.set(param.name, node.args[index])
36
+            })
37
+
38
+            return this.evalNode(node.function.body, innerEnv)
39
+          case Function:
40
+            let args = node.args.map(arg => {
41
+              return this.evalNode(arg, env)
42
+            })
43
+            args.unshift(this)
44
+            return node.function.call(...args)
22 45
         }
23 46
     }
24 47
 

+ 11
- 11
test/evaluatorTest.js View File

@@ -4,18 +4,18 @@ const helpers = require('./helpers')
4 4
 const AST = require('../src/ast')
5 5
 const Evaluator = require('../src/evaluator')
6 6
 
7
-test('looks up and injects the function to which a symbol refers', t => {
8
-  t.plan(2)
7
+test('applies functions from core library', t => {
8
+  t.plan(1)
9 9
 
10 10
   const tree = helpers.evaluate('(+ 1 2)')
11 11
 
12
-  t.deepEqual(tree[0].function.constructor, Function)
13
-  t.deepEqual(
14
-    tree[0].function.call(
15
-      this,
16
-      new AST.Number({ value: 4 }),
17
-      new AST.Number({ value: 5 })
18
-    ),
19
-    new AST.Number({ value: 9 })
20
-  )
12
+  t.deepEqual(tree[0], new AST.Number({ value: 3 }))
13
+})
14
+
15
+test('applies lambda functions', t => {
16
+  t.plan(1)
17
+
18
+  const tree = helpers.evaluate('((lambda (x y) (+ x y)) 1 2)')
19
+
20
+  t.deepEqual(tree[0], new AST.Number({ value: 3 }))
21 21
 })

Loading…
Cancel
Save