Browse Source

Return error for unbound variable/function

master
Dylan Baker 5 years ago
parent
commit
1cd0480079

+ 1
- 0
lib/chervil.rb View File

@@ -1,6 +1,7 @@
1 1
 require 'chervil/ast'
2 2
 require 'chervil/core'
3 3
 require 'chervil/env'
4
+require 'chervil/error'
4 5
 require 'chervil/interpreter'
5 6
 require 'chervil/lexer'
6 7
 require 'chervil/parser'

+ 6
- 1
lib/chervil/ast/application.rb View File

@@ -15,7 +15,12 @@ module Chervil::AST
15 15
     def evaluate(env)
16 16
       if @expr.class == Identifier
17 17
         function = env.get(@expr.name)
18
-        function.call(@arguments.map { |arg| arg.evaluate(env) })
18
+
19
+        if function.nil?
20
+          ::Chervil::Error.new("Unbound variable #{@expr.name}")
21
+        else
22
+          function.call(@arguments.map { |arg| arg.evaluate(env) })
23
+        end
19 24
       end
20 25
     end
21 26
   end

+ 6
- 1
lib/chervil/ast/identifier.rb View File

@@ -11,7 +11,12 @@ module Chervil::AST
11 11
     end
12 12
 
13 13
     def evaluate(env)
14
-      env.get(@name).evaluate(env)
14
+      value = env.get(@name)
15
+      if value.nil?
16
+        ::Chervil::Error.new("unbound variable #{@name}")
17
+      else
18
+        value.evaluate(env)
19
+      end
15 20
     end
16 21
   end
17 22
 end

+ 17
- 0
lib/chervil/error.rb View File

@@ -0,0 +1,17 @@
1
+module Chervil
2
+  class Error
3
+    attr_reader :message
4
+
5
+    def initialize(message)
6
+      @message = message
7
+    end
8
+
9
+    def ==(other)
10
+      @message == other.message
11
+    end
12
+
13
+    def to_s
14
+      "Error: #{@message}"
15
+    end
16
+  end
17
+end

+ 7
- 0
spec/ast/application_spec.rb View File

@@ -30,5 +30,12 @@ module Chervil
30 30
           .evaluate(env)
31 31
       ).to eq(10.0)
32 32
     end
33
+
34
+    it 'returns an error if the function is not defined' do
35
+      env = Env.new
36
+      expect(AST::Application.new(AST::Identifier.new("x"), []).evaluate(env)).to eq(
37
+        Error.new("Unbound variable x")
38
+      )
39
+    end
33 40
   end
34 41
 end

+ 6
- 0
spec/ast/identifier_spec.rb View File

@@ -8,5 +8,11 @@ module Chervil
8 8
       definition.evaluate(env)
9 9
       expect(identifier.evaluate(env)).to eq(5.0)
10 10
     end
11
+
12
+    it 'returns an error for an unbound identifier' do
13
+      env = Env.new
14
+      identifier = AST::Identifier.new("x")
15
+      expect(identifier.evaluate(env)).to eq(Error.new("unbound variable x"))
16
+    end
11 17
   end
12 18
 end

Loading…
Cancel
Save