Browse Source

Improve errors a little bit

master
Dylan Baker 5 years ago
parent
commit
3119c4b7d1
3 changed files with 18 additions and 4 deletions
  1. 6
    0
      bin/chervil
  2. 7
    4
      lib/chervil/parser.rb
  3. 5
    0
      spec/parser_spec.rb

+ 6
- 0
bin/chervil View File

@@ -9,6 +9,12 @@ def repl(env)
9 9
       break if line == "(exit)"
10 10
       lexer = Chervil::Lexer.new(line)
11 11
       tree = Chervil::Parser.new(lexer).parse
12
+
13
+      if tree.is_a? Chervil::Error
14
+        puts tree
15
+        next
16
+      end
17
+
12 18
       results = Chervil::Interpreter.new(tree, env).interpret
13 19
       results.each { |result| puts result unless result.nil? }
14 20
     end

+ 7
- 4
lib/chervil/parser.rb View File

@@ -1,13 +1,16 @@
1 1
 module Chervil
2
-  class Parser def initialize(lexer)
2
+  class Parser
3
+    def initialize(lexer)
3 4
       @lexer = lexer
4 5
       @tree = Array.new
5 6
       @current_token = @lexer.get_next_token
7
+      @error = nil
6 8
     end
7 9
 
8 10
     def parse
9 11
       until @current_token.type == :eof
10 12
         @tree << expr
13
+        return @error unless @error.nil?
11 14
       end
12 15
       @tree
13 16
     end
@@ -20,7 +23,7 @@ module Chervil
20 23
       elsif @current_token.type == :lparen
21 24
         application
22 25
       else
23
-        raise "Unexpected token #{@current_token.type}: #{@current_token.value}"
26
+        @error = Error.new("Unexpected token #{@current_token.type}: #{@current_token.value}")
24 27
       end
25 28
     end
26 29
 
@@ -34,7 +37,7 @@ module Chervil
34 37
       expression = expr
35 38
 
36 39
       args = Array.new
37
-      until @current_token.type == :rparen
40
+      until @current_token.type == :rparen || @current_token.type == :eof
38 41
         args << expr
39 42
       end
40 43
 
@@ -95,7 +98,7 @@ module Chervil
95 98
         @current_token = @lexer.get_next_token
96 99
         token
97 100
       else
98
-        raise "Expected #{type} but got #{@current_token.type}"
101
+        @error = Error.new("Expected #{type} but got #{@current_token.type}")
99 102
       end
100 103
     end
101 104
   end

+ 5
- 0
spec/parser_spec.rb View File

@@ -88,5 +88,10 @@ module Chervil
88 88
         )
89 89
       )
90 90
     end
91
+
92
+    it 'returns a syntax error object instead of raising' do
93
+      expect(parse('(+ 1')).to eq(Error.new("Expected rparen but got eof"))
94
+      expect(parse('1)')).to eq(Error.new("Unexpected token rparen: )"))
95
+    end
91 96
   end
92 97
 end

Loading…
Cancel
Save