Skip to content

Commit f42c27e

Browse files
authored
Merge pull request #13 from daigaku-ruby/feature/implement-end_begin-less-ranges
Implement handling of endless & beginless ranges
2 parents 03b846f + fe9678b commit f42c27e

4 files changed

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

0 commit comments

Comments
 (0)