Dylan Baker 5 лет назад
Родитель
Сommit
03bc1d2184
7 измененных файлов: 57 добавлений и 1 удалений
  1. 1
    0
      lib/chervil/ast.rb
  2. 17
    0
      lib/chervil/ast/boolean.rb
  3. 11
    0
      lib/chervil/lexer.rb
  4. 6
    1
      lib/chervil/parser.rb
  5. 7
    0
      spec/ast/boolean_spec.rb
  6. 6
    0
      spec/lexer_spec.rb
  7. 9
    0
      spec/parser_spec.rb

+ 1
- 0
lib/chervil/ast.rb Просмотреть файл

3
 module Chervil
3
 module Chervil
4
   module AST
4
   module AST
5
     require "chervil/ast/application"
5
     require "chervil/ast/application"
6
+    require "chervil/ast/boolean"
6
     require "chervil/ast/definition"
7
     require "chervil/ast/definition"
7
     require "chervil/ast/identifier"
8
     require "chervil/ast/identifier"
8
     require "chervil/ast/number"
9
     require "chervil/ast/number"

+ 17
- 0
lib/chervil/ast/boolean.rb Просмотреть файл

1
+module Chervil::AST
2
+  class Boolean
3
+    attr_reader :value
4
+
5
+    def initialize(value)
6
+      @value = value
7
+    end
8
+
9
+    def ==(other)
10
+      @value == other.value
11
+    end
12
+
13
+    def evaluate(env)
14
+      @value
15
+    end
16
+  end
17
+end

+ 11
- 0
lib/chervil/lexer.rb Просмотреть файл

27
       when ')'
27
       when ')'
28
         advance
28
         advance
29
         Token.new(:rparen, ")")
29
         Token.new(:rparen, ")")
30
+      when '#'
31
+        advance
32
+        if current_char == 't'
33
+          advance
34
+          Token.new(:boolean, true)
35
+        elsif current_char == 'f'
36
+          advance
37
+          Token.new(:boolean, false)
38
+        else
39
+          raise "Unexpected character #{current_char}"
40
+        end
30
       when '"', '\''
41
       when '"', '\''
31
         delimiter = current_char
42
         delimiter = current_char
32
         advance
43
         advance

+ 6
- 1
lib/chervil/parser.rb Просмотреть файл

13
     end
13
     end
14
 
14
 
15
     def expr
15
     def expr
16
-      if [:string, :number].include?(@current_token.type)
16
+      if [:string, :number, :boolean].include?(@current_token.type)
17
         constant
17
         constant
18
       elsif @current_token.type == :identifier
18
       elsif @current_token.type == :identifier
19
         identifier
19
         identifier
20
       elsif @current_token.type == :lparen
20
       elsif @current_token.type == :lparen
21
         application
21
         application
22
+      else
23
+        raise "Unexpected token #{@current_token.type}: #{@current_token.value}"
22
       end
24
       end
23
     end
25
     end
24
 
26
 
58
       when :string
60
       when :string
59
         token = eat(:string)
61
         token = eat(:string)
60
         AST::String.new(token.value)
62
         AST::String.new(token.value)
63
+      when :boolean
64
+        token = eat(:boolean)
65
+        AST::Boolean.new(token.value)
61
       end
66
       end
62
     end
67
     end
63
 
68
 

+ 7
- 0
spec/ast/boolean_spec.rb Просмотреть файл

1
+module Chervil
2
+  RSpec.describe AST::String do
3
+    it 'evaluates' do
4
+      expect(AST::Boolean.new(true).evaluate(Env.new)).to eq(true)
5
+    end
6
+  end
7
+end

+ 6
- 0
spec/lexer_spec.rb Просмотреть файл

43
         Token.new(:string, 'world')
43
         Token.new(:string, 'world')
44
       )
44
       )
45
     end
45
     end
46
+
47
+    it 'lexes booleans' do
48
+      lexer = Lexer.new("#t #f")
49
+      expect(lexer.get_next_token).to eq(Token.new(:boolean, true))
50
+      expect(lexer.get_next_token).to eq(Token.new(:boolean, false))
51
+    end
46
   end
52
   end
47
 end
53
 end

+ 9
- 0
spec/parser_spec.rb Просмотреть файл

56
         )
56
         )
57
       )
57
       )
58
     end
58
     end
59
+
60
+    it 'parses booleans' do
61
+      expect(parse('#t #f')).to eq(
62
+        [
63
+          AST::Boolean.new(true),
64
+          AST::Boolean.new(false),
65
+        ]
66
+      )
67
+    end
59
   end
68
   end
60
 end
69
 end

Загрузка…
Отмена
Сохранить