Browse Source

Implement quoted values

master
Dylan Baker 5 years ago
parent
commit
1e1f64a141
6 changed files with 53 additions and 4 deletions
  1. 1
    0
      lib/chervil/ast.rb
  2. 21
    0
      lib/chervil/ast/quotation.rb
  3. 4
    1
      lib/chervil/lexer.rb
  4. 8
    0
      lib/chervil/parser.rb
  5. 5
    3
      spec/lexer_spec.rb
  6. 14
    0
      spec/parser_spec.rb

+ 1
- 0
lib/chervil/ast.rb View File

@@ -9,6 +9,7 @@ module Chervil
9 9
     require "chervil/ast/identifier"
10 10
     require "chervil/ast/list"
11 11
     require "chervil/ast/number"
12
+    require "chervil/ast/quotation"
12 13
     require "chervil/ast/string"
13 14
   end
14 15
 end

+ 21
- 0
lib/chervil/ast/quotation.rb View File

@@ -0,0 +1,21 @@
1
+module Chervil::AST
2
+  class Quotation
3
+    attr_reader :value
4
+
5
+    def initialize(value)
6
+      @value = value
7
+    end
8
+
9
+    def evaluate(env)
10
+      if @value.is_a?(List)
11
+        @value.elements
12
+      else
13
+        @value.evaluate(env)
14
+      end
15
+    end
16
+
17
+    def ==(other)
18
+      @value == other.value
19
+    end
20
+  end
21
+end

+ 4
- 1
lib/chervil/lexer.rb View File

@@ -38,7 +38,10 @@ module Chervil
38 38
         else
39 39
           raise "Unexpected character #{current_char}"
40 40
         end
41
-      when '"', '\''
41
+      when '\''
42
+        advance
43
+        Token.new(:quote, '\'')
44
+      when '"'
42 45
         delimiter = current_char
43 46
         advance
44 47
         string = String.new

+ 8
- 0
lib/chervil/parser.rb View File

@@ -22,11 +22,19 @@ module Chervil
22 22
         identifier
23 23
       elsif @current_token.type == :lparen
24 24
         list
25
+      elsif @current_token.type == :quote
26
+        quotation
25 27
       else
26 28
         @error = Error.new("Unexpected token #{@current_token.type}: #{@current_token.value}")
27 29
       end
28 30
     end
29 31
 
32
+    def quotation
33
+      eat(:quote)
34
+      value = expr
35
+      AST::Quotation.new(value)
36
+    end
37
+
30 38
     def list
31 39
       eat(:lparen)
32 40
 

+ 5
- 3
spec/lexer_spec.rb View File

@@ -39,9 +39,6 @@ module Chervil
39 39
       expect(Lexer.new('"hello"').get_next_token).to eq(
40 40
         Token.new(:string, 'hello')
41 41
       )
42
-      expect(Lexer.new("'world'").get_next_token).to eq(
43
-        Token.new(:string, 'world')
44
-      )
45 42
     end
46 43
 
47 44
     it 'lexes booleans' do
@@ -54,5 +51,10 @@ module Chervil
54 51
       lexer = Lexer.new('"hello world')
55 52
       expect(lexer.get_next_token).to eq(Error.new("Unterminated string"))
56 53
     end
54
+
55
+    it 'lexes quotes' do
56
+      lexer = Lexer.new('\'')
57
+      expect(lexer.get_next_token).to eq(Token.new(:quote, '\''))
58
+    end
57 59
   end
58 60
 end

+ 14
- 0
spec/parser_spec.rb View File

@@ -97,5 +97,19 @@ module Chervil
97 97
         )
98 98
       )
99 99
     end
100
+
101
+    it 'parses a quoted value' do
102
+      expect(parse('\'(1 2 3)').first).to eq(
103
+        AST::Quotation.new(
104
+          AST::List.new(
105
+            [
106
+              AST::Number.new(1.0),
107
+              AST::Number.new(2.0),
108
+              AST::Number.new(3.0),
109
+            ]
110
+          )
111
+        )
112
+      )
113
+    end
100 114
   end
101 115
 end

Loading…
Cancel
Save