Browse Source

Parse conditionals

master
Dylan Baker 5 years ago
parent
commit
b3735912f5
4 changed files with 43 additions and 2 deletions
  1. 1
    0
      lib/chervil/ast.rb
  2. 17
    0
      lib/chervil/ast/conditional.rb
  3. 15
    2
      lib/chervil/parser.rb
  4. 10
    0
      spec/parser_spec.rb

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

@@ -4,6 +4,7 @@ module Chervil
4 4
   module AST
5 5
     require "chervil/ast/application"
6 6
     require "chervil/ast/boolean"
7
+    require "chervil/ast/conditional"
7 8
     require "chervil/ast/definition"
8 9
     require "chervil/ast/function"
9 10
     require "chervil/ast/identifier"

+ 17
- 0
lib/chervil/ast/conditional.rb View File

@@ -0,0 +1,17 @@
1
+module Chervil::AST
2
+  class Conditional
3
+    attr_reader :predicate
4
+    attr_reader :true_branch
5
+    attr_reader :false_branch
6
+
7
+    def initialize(predicate, true_branch, false_branch)
8
+      @predicate = predicate
9
+      @true_branch = true_branch
10
+      @false_branch = false_branch
11
+    end
12
+
13
+    def ==(other)
14
+      @predicate == other.predicate && @true_branch == other.true_branch && @false_branch == other.false_branch
15
+    end
16
+  end
17
+end

+ 15
- 2
lib/chervil/parser.rb View File

@@ -30,8 +30,12 @@ module Chervil
30 30
     def application
31 31
       eat(:lparen)
32 32
 
33
-      if @current_token.type == :identifier && @current_token.value == 'define'
34
-        return definition
33
+      if @current_token.type == :identifier
34
+        if @current_token.value == 'define'
35
+          return definition
36
+        elsif @current_token.value == 'if'
37
+          return conditional
38
+        end
35 39
       end
36 40
 
37 41
       expression = expr
@@ -73,6 +77,15 @@ module Chervil
73 77
       end
74 78
     end
75 79
 
80
+    def conditional
81
+      eat(:identifier) # the `if`
82
+      predicate = expr
83
+      true_branch = expr
84
+      false_branch = expr
85
+      eat(:rparen)
86
+      AST::Conditional.new(predicate, true_branch, false_branch)
87
+    end
88
+
76 89
     def identifier
77 90
       identifier = eat(:identifier)
78 91
       AST::Identifier.new(identifier.value)

+ 10
- 0
spec/parser_spec.rb View File

@@ -93,5 +93,15 @@ module Chervil
93 93
       expect(parse('(+ 1')).to eq(Error.new("Expected rparen but got eof"))
94 94
       expect(parse('1)')).to eq(Error.new("Unexpected token rparen: )"))
95 95
     end
96
+
97
+    it 'parses a conditional' do
98
+      expect(parse('(if #t 1 0)').first).to eq(
99
+        AST::Conditional.new(
100
+          AST::Boolean.new(true),
101
+          AST::Number.new(1.0),
102
+          AST::Number.new(0.0),
103
+        )
104
+      )
105
+    end
96 106
   end
97 107
 end

Loading…
Cancel
Save