Browse Source

Evaluate user-defined functions

master
Dylan Baker 5 years ago
parent
commit
616231a55b
2 changed files with 43 additions and 0 deletions
  1. 18
    0
      lib/chervil/ast/function.rb
  2. 25
    0
      spec/ast/function_spec.rb

+ 18
- 0
lib/chervil/ast/function.rb View File

@@ -11,5 +11,23 @@ module Chervil::AST
11 11
     def ==(other)
12 12
       @params == other.params && @body == other.body
13 13
     end
14
+
15
+    def call(args)
16
+      unless @params.size == args.size
17
+        raise "Expected #{params.size} arguments but received #{args.size}"
18
+      end
19
+
20
+      env = ::Chervil::Env.new
21
+      @params.zip(args).each do |key, value|
22
+        env.set(key.name, value)
23
+      end
24
+
25
+      current_expr = nil
26
+      @body.each do |expr|
27
+        current_expr = expr.evaluate(env)
28
+      end
29
+
30
+      current_expr
31
+    end
14 32
   end
15 33
 end

+ 25
- 0
spec/ast/function_spec.rb View File

@@ -0,0 +1,25 @@
1
+module Chervil
2
+  RSpec.describe AST::Definition do
3
+    it 'evaluates its body with its arguments when called' do
4
+      env = Env.new
5
+      expect(
6
+        AST::Function.new(
7
+          [
8
+            AST::Identifier.new("x")
9
+          ],
10
+          [
11
+            AST::Application.new(
12
+              AST::Identifier.new("*"),
13
+              [
14
+                AST::Identifier.new("x"),
15
+                AST::Identifier.new("x")
16
+              ]
17
+            )
18
+          ],
19
+        ).call(
20
+          [5.0]
21
+        )
22
+      ).to eq(25.0)
23
+    end
24
+  end
25
+end

Loading…
Cancel
Save