Browse Source

Test function calls

master
Dylan Baker 5 years ago
parent
commit
0724802b86
1 changed files with 89 additions and 0 deletions
  1. 89
    0
      spec/ast/function_call_spec.rb

+ 89
- 0
spec/ast/function_call_spec.rb View File

@@ -0,0 +1,89 @@
1
+RSpec.describe AST::FunctionCall do
2
+  it 'evaluates built-in functions' do
3
+    expect {
4
+      AST::FunctionCall.new(
5
+        AST::Identifier.new('print'),
6
+        [AST::String.new('hello world')]
7
+      ).execute(Environment.new)
8
+    }.to output("hello world\n").to_stdout
9
+  end
10
+
11
+  it 'evaluates user-defined functions' do
12
+    env = Environment.new
13
+    AST::FunctionDefinition.new(
14
+      AST::Identifier.new('add_one'),
15
+      [AST::Identifier.new('n')],
16
+      AST::Block.new([
17
+        AST::Binary.new(
18
+          AST::Operators::ADD,
19
+          AST::Identifier.new('n'),
20
+          AST::Number.new(1.0)
21
+        )
22
+      ])
23
+    ).execute(env)
24
+    expect(
25
+      AST::FunctionCall.new(
26
+        AST::Identifier.new('add_one'),
27
+        [AST::Number.new(5.0)]
28
+      ).execute(env)
29
+    ).to eq(6.0)
30
+  end
31
+
32
+  # This corresponds to the program
33
+  # function factorial(n) {
34
+  #   if n == 0 {
35
+  #     1;
36
+  #   } else {
37
+  #     n * factorial(n - 1);
38
+  #   }
39
+  # }
40
+  # factorial(5);
41
+  it 'evaluates recursive functions' do
42
+    env = Environment.new
43
+    AST::FunctionDefinition.new(
44
+      AST::Identifier.new('factorial'),
45
+      [AST::Identifier.new('n')],
46
+      AST::Block.new([
47
+        AST::Conditional.new(
48
+          [
49
+            AST::Branch.new(
50
+              AST::Binary.new(
51
+                AST::Operators::DOUBLE_EQUALS,
52
+                AST::Identifier.new('n'),
53
+                AST::Number.new(0.0),
54
+              ),
55
+              AST::Block.new([
56
+                AST::Number.new(1.0),
57
+              ])
58
+            ),
59
+            AST::Branch.new(
60
+              AST::Boolean.new(true),
61
+              AST::Block.new([
62
+                AST::Binary.new(
63
+                  AST::Operators::MULTIPLY,
64
+                  AST::Identifier.new('n'),
65
+                  AST::FunctionCall.new(
66
+                    AST::Identifier.new('factorial'),
67
+                    [
68
+                      AST::Binary.new(
69
+                        AST::Operators::SUBTRACT,
70
+                        AST::Identifier.new('n'),
71
+                        AST::Number.new(1.0),
72
+                      )
73
+                    ]
74
+                  )
75
+                )
76
+              ])
77
+            ),
78
+          ]
79
+        )
80
+      ])
81
+    ).execute(env)
82
+    expect(
83
+      AST::FunctionCall.new(
84
+        AST::Identifier.new('factorial'),
85
+        [AST::Number.new(5.0)]
86
+      ).execute(env)
87
+    ).to eq(120.0)
88
+  end
89
+end

Loading…
Cancel
Save