Skip to content

Commit 0411bbc

Browse files
committed
Implement handling of endless & beginless ranges
This adds an else part for case statement to always be available. (Because we cannot distinguish between an "else nil end" and a not existing else clause for a case statement)
1 parent 03b846f commit 0411bbc

4 files changed

Lines changed: 52 additions & 12 deletions

File tree

lib/code_breaker/parsable/node.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@ module CodeBreaker
22
module Parsable
33
module Node
44
def parse(node)
5-
return if node.nil?
6-
75
if node.is_a?(Symbol)
86
node
7+
elsif node.nil?
8+
parse_nil_node(node)
99
else
1010
send("parse_#{node.type}_node", node)
1111
end
1212
end
1313

14-
def parse_children(node)
15-
node.children.each_with_object([]) do |child, nodes|
16-
nodes << parse(child) unless child.nil?
17-
nodes
14+
def parse_children(node, compact: true)
15+
children = node.children
16+
children = children.compact if compact
17+
18+
children.each_with_object([]) do |child, nodes|
19+
nodes << parse(child)
1820
end
1921
end
2022

@@ -31,7 +33,8 @@ def parse_as_node_type(node)
3133
end
3234

3335
def method_missing(method, *args, &block)
34-
node_type = method.to_s.match(/^parse_(.+)_node$/).captures.first
36+
matches = method.to_s.match(/^parse_(.+)_node$/)
37+
node_type = matches ? matches.captures.first : []
3538

3639
if node_type.empty?
3740
super

lib/code_breaker/parsable/ranges.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ module Parsable
33
module Ranges
44
include Parsable::Node
55

6-
# inclusive range a..b
7-
alias_method :parse_irange_node, :parse_as_hash
6+
# inclusive range a..b, a.., ..b
7+
def parse_irange_node(node)
8+
{ node.type => parse_children(node, compact: false) }
9+
end
810

9-
# exclusive range a...b
10-
alias_method :parse_erange_node, :parse_as_hash
11+
# exclusive range a...b, a..., ...b
12+
def parse_erange_node(node)
13+
{ node.type => parse_children(node, compact: false) }
14+
end
1115
end
1216
end
1317
end

spec/code_breaker/parser/keywords_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@
267267
case: [
268268
{ lvar: :state },
269269
{ when: Symbol, then: [fixnum_or_integer, :to_s] },
270-
{ when: Symbol, then: [fixnum_or_integer, :to_s] }
270+
{ when: Symbol, then: [fixnum_or_integer, :to_s] },
271+
{ else: NilClass }
271272
]
272273
}
273274
]

spec/code_breaker/parser/ranges_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,37 @@
1717
expect(input).to be_parsed_as output
1818
end
1919
end
20+
21+
context 'for a beginless inclusive range' do
22+
it 'returns a Hash with key :irange and the upper bounding type' do
23+
input = '..1.2'
24+
output = { irange: [NilClass, Float]}
25+
expect(input).to be_parsed_as output
26+
end
27+
end
28+
29+
context 'for a beginless exclusive range' do
30+
it 'returns a Hash with key :erange and the upper bounding type' do
31+
input = '...1.2'
32+
output = { erange: [NilClass, Float]}
33+
expect(input).to be_parsed_as output
34+
end
35+
end
36+
37+
context 'for a endless inclusive range' do
38+
it 'returns a Hash with key :irange and the lower bounding type' do
39+
input = '1.2..'
40+
output = { irange: [Float, NilClass]}
41+
expect(input).to be_parsed_as output
42+
end
43+
end
44+
45+
context 'for a endless exclusive range' do
46+
it 'returns a Hash with key :erange and the lower bounding type' do
47+
input = '1.2...'
48+
output = { erange: [Float, NilClass]}
49+
expect(input).to be_parsed_as output
50+
end
51+
end
2052
end
2153
end

0 commit comments

Comments
 (0)