loxxy 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +7 -0
- data/README.md +39 -3
- data/lib/loxxy/datatype/builtin_datatype.rb +3 -4
- data/lib/loxxy/datatype/false.rb +3 -3
- data/lib/loxxy/datatype/lx_string.rb +4 -9
- data/lib/loxxy/datatype/nil.rb +3 -3
- data/lib/loxxy/datatype/number.rb +2 -10
- data/lib/loxxy/datatype/true.rb +4 -4
- data/lib/loxxy/front_end/grammar.rb +4 -5
- data/lib/loxxy/front_end/literal.rb +1 -1
- data/lib/loxxy/front_end/raw_parser.rb +2 -3
- data/lib/loxxy/front_end/scanner.rb +4 -6
- data/lib/loxxy/version.rb +1 -1
- data/loxxy.gemspec +2 -2
- data/spec/datatype/lx_string_spec.rb +35 -35
- data/spec/front_end/raw_parser_spec.rb +3 -1
- data/spec/front_end/scanner_spec.rb +2 -2
- data/spec/loxxy_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5db00fee0e8e7ef89a48cacc4e9ad0baf7ae5ee2cb419ba76964199bd7552199
|
4
|
+
data.tar.gz: ddb8e9c7ac267f32bed3f77ada05a6af38a872b5f892452a496b17522b608977
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44e0049b0bc01e5d35bed7b91c32a7a3b977e6ba4e806439958bad2dc8aae7ead017a310c8523bd4cb628c14951946981bee42f4001d68b701159fcdaff53419
|
7
|
+
data.tar.gz: c90236a82f0a4872b209b8462d5f13377815fd4fc41babf256ff4894ea6900e343c6f192194e1b713cb9f8a8d2bffc326e7ea4f00726193e0a792dc9e1457e41
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
AllCops:
|
2
2
|
Exclude:
|
3
3
|
- 'exp/**/*'
|
4
|
+
- 'demo/**/*'
|
4
5
|
|
5
6
|
Layout/ArgumentAlignment:
|
6
7
|
Enabled: false
|
@@ -55,6 +56,9 @@ Layout/MultilineMethodCallBraceLayout:
|
|
55
56
|
|
56
57
|
Layout/SpaceAroundOperators:
|
57
58
|
Enabled: true
|
59
|
+
|
60
|
+
Layout/SpaceBeforeBrackets:
|
61
|
+
Enabled: true
|
58
62
|
|
59
63
|
Layout/SpaceInsideParens:
|
60
64
|
Enabled: true
|
@@ -70,6 +74,9 @@ Layout/TrailingEmptyLines:
|
|
70
74
|
|
71
75
|
Layout/TrailingWhitespace:
|
72
76
|
Enabled: true
|
77
|
+
|
78
|
+
Lint/AmbiguousAssignment:
|
79
|
+
Enabled: true
|
73
80
|
|
74
81
|
Lint/DuplicateBranch:
|
75
82
|
Enabled: true
|
@@ -226,6 +233,9 @@ Style/GuardClause:
|
|
226
233
|
|
227
234
|
Style/HashEachMethods:
|
228
235
|
Enabled: true
|
236
|
+
|
237
|
+
Style/HashExcept:
|
238
|
+
Enabled: true
|
229
239
|
|
230
240
|
Style/HashTransformKeys:
|
231
241
|
Enabled: true
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## [0.0.5] - 2021-01-02
|
2
|
+
- Improved example in `README.md`, code re-styling to please `Rubocop` 1.7
|
3
|
+
|
4
|
+
## Changed
|
5
|
+
- Code re-styling to please `Rubocop` 1.7
|
6
|
+
- File `README.md` Improved example with better parse tree visualization.
|
7
|
+
|
1
8
|
## [0.0.4] - 2021-01-01
|
2
9
|
- A first parser implementation able to parse Lox source code.
|
3
10
|
|
data/README.md
CHANGED
@@ -13,6 +13,8 @@ a simple language used in Bob Nystrom's online book [Crafting Interpreters](http
|
|
13
13
|
- [DONE] Scanner (tokenizer)
|
14
14
|
- [DONE] Raw parser. It parses Lox programs and generates a parse tree.
|
15
15
|
- [TODO] Tailored parser for generating AST (Abstract Syntax Tree)
|
16
|
+
- [TODO] Custom AST builder class
|
17
|
+
- [TODO] Hierarchy classes for representing Lox expressions in AST
|
16
18
|
- [TODO] Interpreter or transpiler
|
17
19
|
|
18
20
|
|
@@ -34,11 +36,45 @@ base_parser = Loxxy::FrontEnd::RawParser.new
|
|
34
36
|
# Now parse the input into a concrete parse tree...
|
35
37
|
ptree = base_parser.parse(lox_input)
|
36
38
|
|
37
|
-
#
|
38
|
-
|
39
|
+
# Display the parse tree thanks to Rley formatters...
|
40
|
+
visitor = Rley::ParseTreeVisitor.new(ptree)
|
41
|
+
tree_formatter = Rley::Formatter::Asciitree.new($stdout)
|
42
|
+
tree_formatter.render(visitor)
|
39
43
|
```
|
40
44
|
|
41
|
-
|
45
|
+
This is the output produced by the above example:
|
46
|
+
```
|
47
|
+
program
|
48
|
+
+-- declaration_star
|
49
|
+
| +-- declaration_star
|
50
|
+
| +-- declaration
|
51
|
+
| +-- statement
|
52
|
+
| +-- printStmt
|
53
|
+
| +-- PRINT: 'print'
|
54
|
+
| +-- expression
|
55
|
+
| | +-- assignment
|
56
|
+
| | +-- logic_or
|
57
|
+
| | +-- logic_and
|
58
|
+
| | | +-- equality
|
59
|
+
| | | | +-- comparison
|
60
|
+
| | | | | +-- term
|
61
|
+
| | | | | | +-- factor
|
62
|
+
| | | | | | | +-- unary
|
63
|
+
| | | | | | | | +-- call
|
64
|
+
| | | | | | | | +-- primary
|
65
|
+
| | | | | | | | | +-- STRING: '"Hello, world!"'
|
66
|
+
| | | | | | | | +-- refinement_star
|
67
|
+
| | | | | | | +-- multiplicative_star
|
68
|
+
| | | | | | +-- additive_star
|
69
|
+
| | | | | +-- comparisonTest_star
|
70
|
+
| | | | +-- equalityTest_star
|
71
|
+
| | | +-- conjunct_star
|
72
|
+
| | +-- disjunct_star
|
73
|
+
| +-- SEMICOLON: ';'
|
74
|
+
+-- EOF: ''
|
75
|
+
```
|
76
|
+
|
77
|
+
Soon, the `loxxy` will host another, tailored parser, that will generate
|
42
78
|
abstract syntax tree which much more convenient for further processing
|
43
79
|
(like implementing an interpreter).
|
44
80
|
|
@@ -8,15 +8,14 @@ module Loxxy
|
|
8
8
|
class BuiltinDatatype
|
9
9
|
# @return [Object] The Ruby representation
|
10
10
|
attr_reader :value
|
11
|
-
|
11
|
+
|
12
12
|
# Constructor. Initialize a Lox value from one of its built-in data type.
|
13
13
|
def initialize(aValue)
|
14
14
|
@value = validated_value(aValue)
|
15
15
|
end
|
16
|
-
|
17
|
-
|
16
|
+
|
18
17
|
protected
|
19
|
-
|
18
|
+
|
20
19
|
def validated_value(aValue)
|
21
20
|
aValue
|
22
21
|
end
|
data/lib/loxxy/datatype/false.rb
CHANGED
@@ -8,13 +8,13 @@ module Loxxy
|
|
8
8
|
# Class for representing a Lox false value.
|
9
9
|
class False < Boolean
|
10
10
|
include Singleton # Make a singleton class
|
11
|
-
|
11
|
+
|
12
12
|
# Build the sole instance
|
13
13
|
def initialize
|
14
14
|
super(false)
|
15
15
|
end
|
16
16
|
end # class
|
17
|
-
|
18
|
-
False.instance.freeze
|
17
|
+
|
18
|
+
False.instance.freeze # Make the sole instance immutable
|
19
19
|
end # module
|
20
20
|
end # module
|
@@ -6,12 +6,6 @@ module Loxxy
|
|
6
6
|
module Datatype
|
7
7
|
# Class for representing a Lox string of characters value.
|
8
8
|
class LXString < BuiltinDatatype
|
9
|
-
|
10
|
-
# Build the sole instance
|
11
|
-
def initialize(aValue)
|
12
|
-
super(aValue)
|
13
|
-
end
|
14
|
-
|
15
9
|
# Compare a Lox String with another Lox (or genuine Ruby) String
|
16
10
|
# @param other [Datatype::LxString, String]
|
17
11
|
# @return [Boolean]
|
@@ -22,7 +16,8 @@ module Loxxy
|
|
22
16
|
when String
|
23
17
|
value == other
|
24
18
|
else
|
25
|
-
|
19
|
+
err_msg = "Cannot compare a #{self.class} with #{other.class}"
|
20
|
+
raise StandardError, err_msg
|
26
21
|
end
|
27
22
|
end
|
28
23
|
|
@@ -34,8 +29,8 @@ module Loxxy
|
|
34
29
|
end
|
35
30
|
|
36
31
|
# Remove double quotes delimiter
|
37
|
-
aValue.gsub(/(^")|("$)/, '')
|
32
|
+
aValue.gsub(/(^")|("$)/, '')
|
38
33
|
end
|
39
34
|
end # class
|
40
35
|
end # module
|
41
|
-
end # module
|
36
|
+
end # module
|
data/lib/loxxy/datatype/nil.rb
CHANGED
@@ -8,13 +8,13 @@ module Loxxy
|
|
8
8
|
# Class for representing a Lox nil "value".
|
9
9
|
class Nil < BuiltinDatatype
|
10
10
|
include Singleton # Make a singleton class
|
11
|
-
|
11
|
+
|
12
12
|
# Build the sole instance
|
13
13
|
def initialize
|
14
14
|
super(nil)
|
15
15
|
end
|
16
16
|
end # class
|
17
|
-
|
18
|
-
Nil.instance.freeze
|
17
|
+
|
18
|
+
Nil.instance.freeze # Make the sole instance immutable
|
19
19
|
end # module
|
20
20
|
end # module
|
@@ -6,19 +6,11 @@ module Loxxy
|
|
6
6
|
module Datatype
|
7
7
|
# Class for representing a Lox numeric value.
|
8
8
|
class Number < BuiltinDatatype
|
9
|
-
|
10
|
-
# Build the sole instance
|
11
|
-
def initialize(aValue)
|
12
|
-
super(aValue)
|
13
|
-
end
|
14
|
-
|
15
9
|
protected
|
16
10
|
|
17
11
|
def validated_value(aValue)
|
18
12
|
case aValue
|
19
|
-
when Integer
|
20
|
-
result = aValue
|
21
|
-
when Numeric
|
13
|
+
when Integer, Numeric
|
22
14
|
result = aValue
|
23
15
|
when /^-?\d+$/
|
24
16
|
result = aValue.to_i
|
@@ -32,4 +24,4 @@ module Loxxy
|
|
32
24
|
end
|
33
25
|
end # class
|
34
26
|
end # module
|
35
|
-
end # module
|
27
|
+
end # module
|
data/lib/loxxy/datatype/true.rb
CHANGED
@@ -8,13 +8,13 @@ module Loxxy
|
|
8
8
|
# Class for representing a Lox true value.
|
9
9
|
class True < Boolean
|
10
10
|
include Singleton # Make a singleton class
|
11
|
-
|
11
|
+
|
12
12
|
# Build the sole instance
|
13
13
|
def initialize
|
14
14
|
super(true)
|
15
|
-
end
|
15
|
+
end
|
16
16
|
end # class
|
17
|
-
|
18
|
-
True.instance.freeze
|
17
|
+
|
18
|
+
True.instance.freeze # Make the sole instance immutable
|
19
19
|
end # module
|
20
20
|
end # module
|
@@ -131,7 +131,7 @@ module Loxxy
|
|
131
131
|
rule('primary' => 'IDENTIFIER')
|
132
132
|
rule('primary' => 'LEFT_PAREN expression RIGHT_PAREN')
|
133
133
|
rule('primary' => 'SUPER DOT IDENTIFIER')
|
134
|
-
|
134
|
+
|
135
135
|
# Utility rules
|
136
136
|
rule('function' => 'IDENTIFIER LEFT_PAREN params_opt RIGHT_PAREN block')
|
137
137
|
rule('params_opt' => 'parameters')
|
@@ -142,11 +142,10 @@ module Loxxy
|
|
142
142
|
rule('arguments_opt' => [])
|
143
143
|
rule('arguments' => 'arguments COMMA expression')
|
144
144
|
rule('arguments' => 'expression')
|
145
|
-
|
146
145
|
end
|
147
146
|
|
148
|
-
|
149
|
-
|
150
|
-
|
147
|
+
# And now build the grammar and make it accessible via a constant
|
148
|
+
# @return [Rley::Syntax::Grammar]
|
149
|
+
Grammar = builder.grammar
|
151
150
|
end # module
|
152
151
|
end # module
|
@@ -14,7 +14,7 @@ module Loxxy
|
|
14
14
|
# @param theLexeme [String] the lexeme (= piece of text from input)
|
15
15
|
# @param aTerminal [Rley::Syntax::Terminal, String]
|
16
16
|
# The terminal symbol corresponding to the lexeme.
|
17
|
-
# @param aPosition [Rley::Lexical::Position] The position of lexeme
|
17
|
+
# @param aPosition [Rley::Lexical::Position] The position of lexeme
|
18
18
|
# in input text.
|
19
19
|
def initialize(aValue, aLexeme, aTerminal, aPosition)
|
20
20
|
super(aLexeme, aTerminal, aPosition)
|
@@ -15,7 +15,7 @@ module Loxxy
|
|
15
15
|
# A TerminalNode is leaf node, that is, it has no child node.
|
16
16
|
# While concrete parse tree nodes can be generated out of the box,
|
17
17
|
# they have the following drawbacks:
|
18
|
-
# - Generic node classes that aren't always suited for the needs of
|
18
|
+
# - Generic node classes that aren't always suited for the needs of
|
19
19
|
# the language being processing.
|
20
20
|
# - Concrete parse tree tend to be deeply nested, which may complicate
|
21
21
|
# further processing.
|
@@ -27,7 +27,6 @@ module Loxxy
|
|
27
27
|
# Create a Rley facade object
|
28
28
|
@engine = Rley::Engine.new do |cfg|
|
29
29
|
cfg.diagnose = true
|
30
|
-
# cfg.repr_builder = SkmBuilder
|
31
30
|
end
|
32
31
|
|
33
32
|
# Step 1. Load Lox grammar
|
@@ -52,4 +51,4 @@ module Loxxy
|
|
52
51
|
end
|
53
52
|
end # class
|
54
53
|
end # module
|
55
|
-
end # module
|
54
|
+
end # module
|
@@ -50,7 +50,7 @@ module Loxxy
|
|
50
50
|
'>' => 'GREATER',
|
51
51
|
'>=' => 'GREATER_EQUAL',
|
52
52
|
'<' => 'LESS',
|
53
|
-
'<=' => 'LESS_EQUAL'
|
53
|
+
'<=' => 'LESS_EQUAL'
|
54
54
|
}.freeze
|
55
55
|
|
56
56
|
# Here are all the implemented Lox keywords (in uppercase)
|
@@ -99,7 +99,7 @@ module Loxxy
|
|
99
99
|
|
100
100
|
token = nil
|
101
101
|
|
102
|
-
if
|
102
|
+
if '(){},.;/*'.include? curr_ch
|
103
103
|
# Single delimiter or separator character
|
104
104
|
token = build_token(@@lexeme2name[curr_ch], scanner.getch)
|
105
105
|
elsif (lexeme = scanner.scan(/[+\-](?!\d)/))
|
@@ -150,7 +150,7 @@ module Loxxy
|
|
150
150
|
when 'FALSE'
|
151
151
|
value = Datatype::False.instance
|
152
152
|
when 'NIL'
|
153
|
-
value = Datatype::Nil.instance
|
153
|
+
value = Datatype::Nil.instance
|
154
154
|
when 'NUMBER'
|
155
155
|
value = Datatype::Number.new(aLexeme)
|
156
156
|
when 'STRING'
|
@@ -167,8 +167,6 @@ module Loxxy
|
|
167
167
|
# Skip non-significant whitespaces and comments.
|
168
168
|
# Advance the scanner until something significant is found.
|
169
169
|
def skip_intertoken_spaces
|
170
|
-
pre_pos = scanner.pos
|
171
|
-
|
172
170
|
loop do
|
173
171
|
ws_found = scanner.skip(/[ \t\f]+/) ? true : false
|
174
172
|
nl_found = scanner.skip(/(?:\r\n)|\r|\n/)
|
@@ -191,7 +189,7 @@ module Loxxy
|
|
191
189
|
break unless ws_found || cmt_found
|
192
190
|
end
|
193
191
|
|
194
|
-
|
192
|
+
scanner.pos
|
195
193
|
end
|
196
194
|
|
197
195
|
def skip_block_comment
|
data/lib/loxxy/version.rb
CHANGED
data/loxxy.gemspec
CHANGED
@@ -40,8 +40,8 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.version = Loxxy::VERSION
|
41
41
|
spec.authors = ['Dimitri Geshef']
|
42
42
|
spec.email = ['famished.tiger@yahoo.com']
|
43
|
-
spec.summary =
|
44
|
-
spec.description =
|
43
|
+
spec.summary = 'An implementation of the Lox programming language. WIP'
|
44
|
+
spec.description = 'An implementation of the Lox programming language. WIP'
|
45
45
|
spec.homepage = 'https://github.com/famished-tiger/loxxy'
|
46
46
|
spec.license = 'MIT'
|
47
47
|
spec.required_ruby_version = '~> 2.4'
|
@@ -1,35 +1,35 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
-
|
5
|
-
# Load the class under test
|
6
|
-
require_relative '../../lib/loxxy/datatype/lx_string'
|
7
|
-
|
8
|
-
module Loxxy
|
9
|
-
module Datatype
|
10
|
-
describe LXString do
|
11
|
-
let(:sample_text) { 'some_text' }
|
12
|
-
subject { LXString.new(sample_text) }
|
13
|
-
|
14
|
-
context 'Initialization:' do
|
15
|
-
it 'should accept a String value at initialization' do
|
16
|
-
expect { LXString.new(sample_text) }.not_to raise_error
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should know its value' do
|
20
|
-
expect(subject.value).to eq(sample_text)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'Provided services:' do
|
25
|
-
it 'compares with another string' do
|
26
|
-
expect(subject).to eq(sample_text)
|
27
|
-
expect(subject).to eq(LXString.new(sample_text.dup))
|
28
|
-
|
29
|
-
expect(subject).not_to eq('')
|
30
|
-
expect(subject).not_to eq('other-text')
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end # describe
|
34
|
-
end # module
|
35
|
-
end # module
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load the class under test
|
6
|
+
require_relative '../../lib/loxxy/datatype/lx_string'
|
7
|
+
|
8
|
+
module Loxxy
|
9
|
+
module Datatype
|
10
|
+
describe LXString do
|
11
|
+
let(:sample_text) { 'some_text' }
|
12
|
+
subject { LXString.new(sample_text) }
|
13
|
+
|
14
|
+
context 'Initialization:' do
|
15
|
+
it 'should accept a String value at initialization' do
|
16
|
+
expect { LXString.new(sample_text) }.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should know its value' do
|
20
|
+
expect(subject.value).to eq(sample_text)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'Provided services:' do
|
25
|
+
it 'compares with another string' do
|
26
|
+
expect(subject).to eq(sample_text)
|
27
|
+
expect(subject).to eq(LXString.new(sample_text.dup))
|
28
|
+
|
29
|
+
expect(subject).not_to eq('')
|
30
|
+
expect(subject).not_to eq('other-text')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end # describe
|
34
|
+
end # module
|
35
|
+
end # module
|
@@ -92,8 +92,10 @@ LOX_END
|
|
92
92
|
expect(leaf_node.token.value).to eq('Hello, world!')
|
93
93
|
expect(prnt_stmt.subnodes[2]).to be_kind_of(Rley::PTree::TerminalNode)
|
94
94
|
expect(prnt_stmt.subnodes[2].symbol.name).to eq('SEMICOLON')
|
95
|
+
expect(eof).to be_kind_of(Rley::PTree::TerminalNode)
|
96
|
+
expect(eof.symbol.name).to eq('EOF')
|
95
97
|
end
|
96
98
|
end
|
97
99
|
end # describe
|
98
100
|
end # module
|
99
|
-
end # module
|
101
|
+
end # module
|
@@ -78,7 +78,7 @@ module Loxxy
|
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'should recognize non-datatype keywords' do
|
81
|
-
keywords
|
81
|
+
keywords = <<-LOX_END
|
82
82
|
and class else fun for if or
|
83
83
|
print return super this var while
|
84
84
|
LOX_END
|
@@ -167,7 +167,7 @@ LOX_END
|
|
167
167
|
end
|
168
168
|
|
169
169
|
it 'should recognize string values' do
|
170
|
-
input
|
170
|
+
input = <<-LOX_END
|
171
171
|
""
|
172
172
|
"string"
|
173
173
|
"123"
|
data/spec/loxxy_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'loxxy'
|
3
5
|
|
4
6
|
RSpec.configure do |config|
|
5
7
|
# Enable flags like --only-failures and --next-failure
|
6
|
-
config.example_status_persistence_file_path =
|
8
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
7
9
|
|
8
10
|
config.expect_with :rspec do |c|
|
9
11
|
# Disable the `should` syntax
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loxxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- ".rspec"
|
78
78
|
- ".rubocop.yml"
|
79
79
|
- ".travis.yml"
|
80
|
+
- ".yardopts"
|
80
81
|
- CHANGELOG.md
|
81
82
|
- Gemfile
|
82
83
|
- LICENSE.txt
|