浏览代码

Parse application

master
Dylan Baker 6 年前
父节点
当前提交
2dfba579de
共有 5 个文件被更改,包括 46 次插入4 次删除
  1. 1
    0
      lib/chervil/ast.rb
  2. 15
    0
      lib/chervil/ast/application.rb
  3. 5
    4
      lib/chervil/lexer.rb
  4. 16
    0
      lib/chervil/parser.rb
  5. 9
    0
      spec/parser_spec.rb

+ 1
- 0
lib/chervil/ast.rb 查看文件

@@ -1,4 +1,5 @@
1 1
 module Chervil::AST
2
+  require "chervil/ast/application"
2 3
   require "chervil/ast/identifier"
3 4
   require "chervil/ast/number"
4 5
 end

+ 15
- 0
lib/chervil/ast/application.rb 查看文件

@@ -0,0 +1,15 @@
1
+module Chervil::AST
2
+  class Application
3
+    attr_reader :expr
4
+    attr_reader :arguments
5
+
6
+    def initialize(expr, arguments)
7
+      @expr = expr
8
+      @arguments = arguments
9
+    end
10
+
11
+    def ==(other)
12
+      @expr == other.expr && @arguments == other.arguments
13
+    end
14
+  end
15
+end

+ 5
- 4
lib/chervil/lexer.rb 查看文件

@@ -23,11 +23,13 @@ module Chervil
23 23
       when ')'
24 24
         advance
25 25
         Token.new(:rparen, ")")
26
-      when ' '
27
-        advance
28
-        nil
29 26
       else
30 27
         source = @source.slice(@position..-1)
28
+        while source.match(/^\s/)
29
+          advance
30
+          source = @source.slice(@position..-1)
31
+        end
32
+
31 33
         if match = source.match(/^[0-9]+(\.[0-9]+)?/)
32 34
           advance(match[0].size)
33 35
           Token.new(:number, match[0])
@@ -42,7 +44,6 @@ module Chervil
42 44
       tokens = Array.new
43 45
       loop do
44 46
         token = get_next_token
45
-        next if token.nil?
46 47
         tokens << token
47 48
         break if token.type == :eof
48 49
       end

+ 16
- 0
lib/chervil/parser.rb 查看文件

@@ -18,9 +18,25 @@ module Chervil
18 18
         constant
19 19
       elsif @current_token.type == :identifier
20 20
         identifier
21
+      elsif @current_token.type == :lparen
22
+        application
21 23
       end
22 24
     end
23 25
 
26
+    def application
27
+      eat(:lparen)
28
+      expression = expr
29
+
30
+      args = Array.new
31
+      until @current_token.type == :rparen
32
+        args << expr
33
+      end
34
+
35
+      eat(:rparen)
36
+
37
+      AST::Application.new(expression, args)
38
+    end
39
+
24 40
     def identifier
25 41
       identifier = eat(:identifier)
26 42
       AST::Identifier.new(identifier.value)

+ 9
- 0
spec/parser_spec.rb 查看文件

@@ -13,5 +13,14 @@ module Chervil
13 13
     it 'parses an identifier' do
14 14
       expect(parse('+').first).to eq(AST::Identifier.new('+'))
15 15
     end
16
+
17
+    it 'parses an application' do
18
+      expect(parse('(+ 1 2)').first).to eq(
19
+        AST::Application.new(
20
+          AST::Identifier.new('+'),
21
+          [AST::Number.new(1.0), AST::Number.new(2.0)]
22
+        )
23
+      )
24
+    end
16 25
   end
17 26
 end

正在加载...
取消
保存