subtle-lang 0.0.2 → 0.0.3

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.
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - ruby-head
5
+ - jruby-19mode
6
+ - rbx-19mode
7
+ script: bundle exec rspec spec
data/README.md CHANGED
@@ -1,29 +1,37 @@
1
- # Subtle
1
+ # Subtle [![Build Status](https://travis-ci.org/utkarshkukreti/subtle-lang.png)](https://travis-ci.org/utkarshkukreti/subtle-lang)
2
2
 
3
- TODO: Write a gem description
3
+ Subtle is a Terse, Array based Programming Language, heavily inspired by the K
4
+ Programming Language, and partly by APL and J.
4
5
 
5
6
  ## Installation
6
7
 
7
- Add this line to your application's Gemfile:
8
+ ### Using Git (Recommended)
8
9
 
9
- gem 'subtle'
10
+ git clone https://github.com/utkarshkukreti/subtle-lang.git
11
+ cd subtle-lang
12
+ bundle install
13
+ rake install
10
14
 
11
- And then execute:
15
+ ### From RubyGems
12
16
 
13
- $ bundle
17
+ gem install subtle-lang
14
18
 
15
- Or install it yourself as:
19
+ ## Usage
16
20
 
17
- $ gem install subtle
21
+ Run
18
22
 
19
- ## Usage
23
+ subtle
24
+
25
+ to start the interactive REPL.
26
+
27
+ ## Documentation
28
+
29
+ No docs yet, but the language is **heavily** tested.
30
+
31
+ Best way to learn more is to read the specs in `spec/`.
20
32
 
21
- TODO: Write usage instructions here
33
+ ## License
22
34
 
23
- ## Contributing
35
+ The MIT License
24
36
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
37
+ Copyright (c) 2012 Utkarsh Kukreti
@@ -1,6 +1,7 @@
1
1
  module Subtle
2
2
  class Evaluator
3
3
  def initialize
4
+ @state = {}
4
5
  @parser = Parser.new
5
6
  @transform = Transform.new
6
7
  end
@@ -15,7 +16,45 @@ module Subtle
15
16
 
16
17
  if Hash === t
17
18
  type = t[:type]
19
+
18
20
  case type
21
+ when :assignment
22
+ identifier = t[:identifier]
23
+ right = try_eval t[:right]
24
+ @state[identifier] = right
25
+ when :deassignment
26
+ identifier = t[:identifier]
27
+ @state[identifier]
28
+ when :function
29
+ t[:function]
30
+ when :function_call
31
+ function = t[:function]
32
+ adverb = t[:adverb]
33
+ right = try_eval t[:right]
34
+ if adverb
35
+ case adverb
36
+ when "/:"
37
+ right = [right] unless Array === right
38
+ right.map do |r|
39
+ eval type: :function_call, function: function, right: r
40
+ end
41
+ else
42
+ ae! t, "Invalid adverb #{adverb.inspect} for :function_call."
43
+ end
44
+ else
45
+ _x = @state["x"]
46
+ @state["x"] = right
47
+ eval(function).tap do
48
+ @state["x"] = _x
49
+ end
50
+ end
51
+ when :variable_call
52
+ identifier = t[:identifier]
53
+ adverb = t[:adverb]
54
+ arguments = t[:arguments]
55
+ function = @state[identifier]
56
+ eval type: :function_call, function: function, adverb: adverb,
57
+ right: arguments
19
58
  when :monad
20
59
  verb = t[:verb]
21
60
  adverb = t[:adverb]
@@ -35,6 +74,10 @@ module Subtle
35
74
  " You passed in #{right.class}."
36
75
  end
37
76
  case adverb
77
+ when "//:"
78
+ right.map do |r|
79
+ eval type: :monad, verb: verb, adverb: "/", right: r
80
+ end
38
81
  when "/"
39
82
  right.reduce do |fold, r|
40
83
  eval type: :dyad, verb: verb, left: fold, right: r
@@ -76,21 +119,16 @@ module Subtle
76
119
  end
77
120
  end
78
121
  when :dyad
122
+ # Evaluate right first.
123
+ right = try_eval t[:right]
79
124
  left = try_eval t[:left]
80
125
  verb = t[:verb]
81
126
  adverb = t[:adverb]
82
- right = try_eval t[:right]
83
127
 
84
128
  # `^` in Subtle is `**` in Ruby.
85
129
  verb = "**" if verb == "^"
86
130
 
87
131
  if adverb
88
- if Array === left && Array === right
89
- else
90
- ae! t, "Adverb `#{adverb}` must have arrays on both left and" +
91
- " right. You passed in #{left.class} and #{right.class}."
92
- end
93
-
94
132
  case adverb
95
133
  when "/:" # Map each over right
96
134
  right.map do |r|
@@ -125,34 +163,31 @@ module Subtle
125
163
  end
126
164
  else
127
165
  left.zip(right).map do |l, r|
128
- l.send(verb, r)
166
+ (try_eval l).send(verb, try_eval(r))
129
167
  end
130
168
  end
131
169
 
132
170
  elsif Array === left && Numeric === right
133
- # Multi-dimensional arrays
134
- if Array === left.first
135
- left.map do |l|
171
+ left.map do |l|
172
+ # Multi-dimensional arrays
173
+ if Array === l
136
174
  eval type: :dyad, verb: verb, left: l, right: right
137
- end
138
- else
139
- left.map do |l|
140
- l.send(verb, right)
175
+ else
176
+ (try_eval l).send(verb, right)
141
177
  end
142
178
  end
143
179
  elsif Numeric === left && Array === right
144
- # Multi-dimensional arrays
145
- if Array === right.first
146
- right.map do |r|
180
+ right.map do |r|
181
+ # Multi-dimensional arrays
182
+ if Array === r
147
183
  eval type: :dyad, verb: verb, left: left, right: r
148
- end
149
- else
150
- right.map do |r|
184
+ else
151
185
  left.send(verb, r)
152
186
  end
153
187
  end
154
188
  else
155
- nie! t
189
+ nie! t, "Left and Array must be Numeric or Arrays." +
190
+ " You passed in #{left.class} and #{right.class}."
156
191
  end
157
192
  when "&", "|"
158
193
  verb = "min" if verb == "&"
@@ -197,10 +232,11 @@ module Subtle
197
232
  if Numeric === last
198
233
  (0...last.floor).to_a
199
234
  else
200
- nie! t
235
+ nie! t, "`last` must be Numeric for type: :enumerate. You passed" +
236
+ " in #{last.class}."
201
237
  end
202
238
  else
203
- nie! t
239
+ nie! t, "Type #{t[:type].inspect} not implemented."
204
240
  end
205
241
  else
206
242
  t
data/lib/subtle/parser.rb CHANGED
@@ -2,9 +2,10 @@ module Subtle
2
2
  class Parser < Parslet::Parser
3
3
  def initialize
4
4
  @monadic_verbs = %w{+ - * / % ^ | & ~}
5
- @monadic_adverbs = %w{/: /}
5
+ @monadic_adverbs = %w{//: /: /}
6
6
  @dyadic_verbs = %w{+ - * / % ^ | & !}
7
7
  @dyadic_adverbs = %w{/: \:}
8
+ @function_adverbs = %w{/:}
8
9
  end
9
10
 
10
11
  rule(:spaces) { match["\\s"].repeat(1) }
@@ -12,10 +13,39 @@ module Subtle
12
13
  rule(:digits) { match["0-9"].repeat(1) }
13
14
  rule(:minus) { str("-") }
14
15
 
15
- rule(:integer) { (minus.maybe >> digits).as(:integer) >> spaces? }
16
- rule(:float) { (minus.maybe >> digits >> str(".") >> digits).as(:float) >>
17
- spaces? }
18
- rule(:atom) { float | integer }
16
+ rule(:integer) { (minus.maybe >> digits).as(:integer) >> spaces? }
17
+ rule(:float) { (minus.maybe >> digits >> str(".") >> digits).
18
+ as(:float) >> spaces? }
19
+ rule(:identifier) { (match["a-zA-Z"] >> match["a-zA-Z0-9_"].repeat).
20
+ as(:identifier) }
21
+ rule(:assignment) { (identifier >> spaces? >> str(":") >> spaces? >>
22
+ word.as(:right)).as(:assignment) >> spaces? }
23
+ rule(:deassignment) { identifier.as(:deassignment) >> spaces? }
24
+
25
+ rule(:function) do
26
+ str("{") >> spaces? >> word.as(:function) >> spaces? >> str("}") >>
27
+ spaces?
28
+ end
29
+
30
+ rule :function_adverb do
31
+ @function_adverbs.map { |adverb| str(adverb) }.reduce(:|).as(:adverb) >>
32
+ spaces?
33
+ end
34
+
35
+ rule(:function_call) do
36
+ (function >> function_adverb.maybe >> word.as(:right)).
37
+ as(:function_call) >> spaces?
38
+ end
39
+
40
+ rule(:variable_call) do
41
+ (identifier >> spaces? >> function_adverb.maybe >>
42
+ (assignment | dyad | noun).as(:arguments)).as(:variable_call)
43
+ end
44
+
45
+ rule(:atom) do
46
+ variable_call | function_call | function | float | integer | pword |
47
+ deassignment
48
+ end
19
49
 
20
50
  rule :array do
21
51
  atom_or_array = (array | (atom >> spaces?).repeat.as(:array)) >> spaces?
@@ -27,7 +57,7 @@ module Subtle
27
57
  end
28
58
 
29
59
  rule :enumerate do
30
- (str("!") >> spaces? >> (float | integer).as(:last)).as(:enumerate)
60
+ (str("!") >> spaces? >> (word).as(:last)).as(:enumerate)
31
61
  end
32
62
 
33
63
  rule(:noun) { enumerate | array | atom }
@@ -60,7 +90,12 @@ module Subtle
60
90
  end
61
91
 
62
92
  rule :word do
63
- dyad | noun | monad
93
+ assignment | dyad | noun | monad
94
+ end
95
+
96
+ # This is the last option of rule(:atom) above ^
97
+ rule :pword do
98
+ str("(") >> spaces? >> word >> spaces? >> str(")") >> spaces?
64
99
  end
65
100
 
66
101
  rule :sentence do
@@ -1,8 +1,8 @@
1
1
  module Subtle
2
2
  class Transform < Parslet::Transform
3
- rule(integer: simple(:x)) { x.to_i }
4
- rule(float: simple(:x)) { x.to_f }
5
- rule(array: subtree(:x)) { x }
3
+ rule(integer: simple(:x)) { x.to_i }
4
+ rule(float: simple(:x)) { x.to_f }
5
+ rule(array: subtree(:x)) { x.size == 1 ? x.first : x }
6
6
 
7
7
  rule monad: { verb: simple(:verb), right: subtree(:right) } do
8
8
  { type: :monad, verb: verb.to_s, right: right }
@@ -20,11 +20,49 @@ module Subtle
20
20
 
21
21
  rule dyad: { left: subtree(:left), verb: simple(:verb),
22
22
  adverb: simple(:adverb), right: subtree(:right) } do
23
- { type: :dyad, left: left, verb: verb.to_s, adverb: adverb, right: right }
23
+ { type: :dyad, left: left, verb: verb.to_s, adverb: adverb.to_s,
24
+ right: right }
24
25
  end
25
26
 
26
27
  rule enumerate: { last: subtree(:last) } do
27
28
  { type: :enumerate, last: last }
28
29
  end
30
+
31
+ rule assignment: { identifier: simple(:identifier),
32
+ right: subtree(:right) } do
33
+ { type: :assignment, identifier: identifier.to_s, right: right }
34
+ end
35
+
36
+ rule deassignment: { identifier: simple(:identifier) } do
37
+ { type: :deassignment, identifier: identifier.to_s }
38
+ end
39
+
40
+ rule function: subtree(:function) do
41
+ { type: :function, function: function }
42
+ end
43
+
44
+ rule function_call: { function: subtree(:function),
45
+ right: subtree(:right) } do
46
+ { type: :function_call, function: function, right: right }
47
+ end
48
+
49
+ rule function_call: { function: subtree(:function), adverb: simple(:adverb),
50
+ right: subtree(:right) } do
51
+ { type: :function_call, function: function, adverb: adverb.to_s,
52
+ right: right }
53
+ end
54
+
55
+ rule variable_call: { identifier: simple(:identifier),
56
+ arguments: subtree(:arguments) } do
57
+ { type: :variable_call, identifier: identifier.to_s,
58
+ arguments: arguments }
59
+ end
60
+
61
+ rule variable_call: { identifier: simple(:identifier),
62
+ adverb: simple(:adverb),
63
+ arguments: subtree(:arguments) } do
64
+ { type: :variable_call, identifier: identifier.to_s, adverb: adverb.to_s,
65
+ arguments: arguments }
66
+ end
29
67
  end
30
68
  end
@@ -1,3 +1,3 @@
1
1
  module Subtle
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -5,7 +5,13 @@ describe Subtle do
5
5
  describe "Project Euler" do
6
6
  describe "Problem 1:" +
7
7
  " Find the sum of all the multiples of 3 or 5 below 1000." do
8
- e "+/&~&/!1000%/:3 5", 233168
8
+ e "+/&~&/(!1000)%/:3 5", 233168
9
+ end
10
+
11
+ describe "Problem 6:" +
12
+ " Find the difference between the sum of the squares of the first" +
13
+ " one hundred natural numbers and the square of the sum." do
14
+ e "((+/!101)^2)-+/(!101)^2", 25164150
9
15
  end
10
16
  end
11
17
  end
data/spec/spec_helper.rb CHANGED
@@ -8,10 +8,13 @@ end
8
8
  require "subtle"
9
9
 
10
10
  RSpec.configure do |config|
11
- def e(input, output)
11
+ def e(input, output, evaluator = nil)
12
12
  it "should evaluate #{input.inspect} to #{output.inspect}" do
13
- evaluator = Subtle::Evaluator.new
14
- evaluator.eval(input).should eq output
13
+ evaluator ||= Subtle::Evaluator.new
14
+ evaluated = evaluator.eval(input)
15
+ if output
16
+ evaluated.should eq output
17
+ end
15
18
  end
16
19
  end
17
20
 
@@ -37,17 +37,17 @@ describe Subtle::Evaluator do
37
37
  describe "Rotate (`!`) (on left: Integer, right: Array)" do
38
38
  e "2 ! 1 2 3", [3, 1, 2]
39
39
  e "2 ! (1 2)", [1, 2]
40
- e "2 ! (2 3; 4 5; 8)", [[8], [2, 3], [4, 5]]
40
+ e "2 ! (2 3; 4 5; 8)", [8, [2, 3], [4, 5]]
41
41
  e "-2 ! 1 2 3", [2, 3, 1]
42
42
  e "-2 ! (1 2)", [1, 2]
43
- e "-2 ! (2 3; 4 5; 8)", [[4, 5], [8], [2, 3]]
43
+ e "-2 ! (2 3; 4 5; 8)", [[4, 5], 8, [2, 3]]
44
44
  end
45
45
  end
46
46
 
47
47
  describe "Enumerate (`!`)" do
48
48
  describe "Precedence" do
49
49
  e "!4", [0, 1, 2, 3]
50
- e "1 - !2 + 2", [-1, -2]
50
+ e "5 - !2 + 2", [5, 4, 3, 2]
51
51
  end
52
52
 
53
53
  describe "on Floats" do
@@ -63,6 +63,7 @@ describe Subtle::Evaluator do
63
63
  e "3 2 3 ^/: 2 3", [[9, 4, 9], [27, 8, 27]]
64
64
  e "3 2 3 &/: 2 3", [[2, 2, 2], [3, 2, 3]]
65
65
  e "1 2 3 |/: 0 3", [[1, 2, 3], [3, 3, 3]]
66
+ e "2 !/: (1 2 3; 2 3 4; 4 5 6)", [[3, 1, 2], [4, 2, 3], [6, 4, 5]]
66
67
  end
67
68
 
68
69
  describe "Map over each left (`\:`)" do
@@ -91,6 +92,11 @@ describe Subtle::Evaluator do
91
92
  e "+/: ((1 2; 3 4); (5 6; 7 8))", [[[1, 3], [2, 4]], [[5, 7], [6, 8]]]
92
93
  e "|/: (0 1; 0 2)", [[1, 0], [2, 0]]
93
94
  end
95
+
96
+ describe "Map over and fold (`//:`)" do
97
+ e "+//: (2 4; 3 1)", [6, 4]
98
+ e "+//:+(2 4; 3 1)", [5, 5]
99
+ end
94
100
  end
95
101
  end
96
102
 
@@ -111,7 +117,7 @@ describe Subtle::Evaluator do
111
117
 
112
118
  describe "Reverse (`|`)" do
113
119
  e "|1 2", [2, 1]
114
- e "|(1 2; 3; (6 7; 8))", [[[6, 7], [8]], [3], [1, 2]]
120
+ e "|(1 2; 3; (6 7; 8))", [[[6, 7], 8], 3, [1, 2]]
115
121
  end
116
122
  end
117
123
 
@@ -120,12 +126,13 @@ describe Subtle::Evaluator do
120
126
  e "(1 2; 3 4; 5 6.6 7)", [[1, 2], [3, 4], [5, 6.6, 7]]
121
127
  e "(;;;)", [[], [], [], []]
122
128
  e "(;;3 8;)", [[], [], [3, 8], []]
123
- e "(1;2.2 3.3;(;;3 8;);)", [[1], [2.2, 3.3], [[], [], [3, 8], []], []]
129
+ e "(1;2.2 3.3;(;;3 8;);)", [1, [2.2, 3.3], [[], [], [3, 8], []], []]
124
130
  end
125
131
 
126
132
  describe "Dyads" do
127
133
  describe "on Atoms and 2D/3D Arrays" do
128
134
  e "1 + (;1 2; 3 4)", [[], [2, 3], [4, 5]]
135
+ e "(1; 2 3) + 1", [2, [3, 4]]
129
136
  e "2 ^ ((5 6; 0 1);1 2; 3 4)", [[[32, 64], [1, 2]], [2, 4], [8, 16]]
130
137
  e "(;1 2; 3 4) - 1", [[], [0, 1], [2, 3]]
131
138
  e "((5 6; 0 1);1 2; 3 4) ^ 2", [[[25, 36], [0, 1]], [1, 4], [9, 16]]
@@ -134,6 +141,7 @@ describe Subtle::Evaluator do
134
141
  describe "on 1D/2D/3D Arrays with 2D/3D Arrays" do
135
142
  e "(1 2; 3 4) + (2 3; 4 5)", [[3, 5], [7, 9]]
136
143
  e "(1 2; 3 4) % (2 3; 4 5)", [[1, 2], [3, 4]]
144
+ e "(1 2; 3) + (1; 2 3)", [[2, 3], [5, 6]]
137
145
  e "((1 2); 5 6) + (3 1)", [[4, 5], [6, 7]]
138
146
  e "(((2 4); (6 8)); ((2 4); (6 8))) + 1 2", [[[3, 5], [7, 9]],
139
147
  [[4, 6], [8, 10]]]
@@ -141,10 +149,63 @@ describe Subtle::Evaluator do
141
149
  [[[4, 16], [36, 64]], [[4, 16], [36, 64]]]
142
150
  e "1 2 + (((2 4); (6 8)); ((2 4); (6 8)))", [[[3, 5], [7, 9]],
143
151
  [[4, 6], [8, 10]]]
152
+ e "1 2 + ((2; (6 8)); ((2 4 3); 6))", [[3, [7, 9]],
153
+ [[4, 6, 5], 8]]
144
154
  end
145
155
  end
146
156
  end
147
157
 
158
+ describe "Parentheses" do
159
+ e "(1 + 1) * 2", 4
160
+ e "3 + (1 + 1) * 2", 7
161
+ e "(1 + 2) * 3", 9
162
+ e "(((((1 + 1) * 2) + 2) * 3) + 3) * 4", 84
163
+ end
164
+
165
+ describe "Variables" do
166
+ @e = Subtle::Evaluator.new
167
+ e "a: 10", 10, @e
168
+ e "a", 10, @e
169
+ e "b", nil, @e
170
+ e "a: 1 + 2", 3, @e
171
+ e "b: a + 2", 5, @e
172
+ # Tests whether dyads are evaluated from right to left.
173
+ e "a: 1", 1, @e
174
+ e "(a: 10) + (b: 6) * a * (a: 3) + a", 82, @e
175
+ end
176
+
177
+ describe "Functions" do
178
+ describe "Map" do
179
+ e "{x * 2 - x} 4", -8
180
+ e "{x * 2 - x} 4 6 8", [-8, -24, -48]
181
+ e "{x + 1} {x * 2 - x} 4 6 8", [-7, -23, -47]
182
+ e "{x + {x + x} x} 1 2 3", [3, 6, 9]
183
+ e "{!x} 2", [0, 1]
184
+ e "{!x + 1} 2", [0, 1, 2]
185
+ end
186
+
187
+ describe "Map over each right (`/:`)" do
188
+ e "{!x}/:1 2 3", [[0], [0, 1], [0, 1, 2]]
189
+ e "{!x + 1}/:!3", [[0], [0, 1], [0, 1, 2]]
190
+ e "{+x}/:((1 2; 3 4); (4 5; 6 7))", [[[1, 3], [2, 4]], [[4, 6], [5, 7]]]
191
+ end
192
+
193
+ describe "Storing in variables" do
194
+ @e = Subtle::Evaluator.new
195
+ e "a: {x + !x}", nil, @e
196
+ e "a 3", [3, 4, 5], @e
197
+ e "a /: 1 2 3", [[1], [2, 3], [3, 4, 5]], @e
198
+ e "b: {x + 1}", nil, @e
199
+ e "c: 4", 4, @e
200
+ e "c: b b b c", 7, @e
201
+
202
+ e "d: {x * 2}", nil, @e
203
+ e "e: {2 * d x}", nil, @e
204
+ e "f: {(d x) + e x}", nil, @e
205
+ e "d e f f d e 6", 13824, @e
206
+ end
207
+ end
208
+
148
209
  describe "Errors" do
149
210
  describe "on Arrays" do
150
211
  ae! "1 2 + 2 3 4"
data/subtle.gemspec CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |gem|
23
23
 
24
24
  gem.add_dependency "parslet"
25
25
 
26
- %w{rspec guard-rspec simplecov pry pry-debugger}.each do |name|
26
+ %w{rspec guard-rspec simplecov pry}.each do |name|
27
27
  gem.add_development_dependency name
28
28
  end
29
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subtle-lang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-09 00:00:00.000000000 Z
12
+ date: 2012-12-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parslet
@@ -91,22 +91,6 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
- - !ruby/object:Gem::Dependency
95
- name: pry-debugger
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ! '>='
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ! '>='
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
94
  description: ! "Subtle is a Terse, Array based Programming Language,\n heavily
111
95
  inspired by the K Programming Language, and\n partly by
112
96
  APL and J."
@@ -119,6 +103,7 @@ extra_rdoc_files: []
119
103
  files:
120
104
  - .gitignore
121
105
  - .rspec
106
+ - .travis.yml
122
107
  - Gemfile
123
108
  - Guardfile
124
109
  - LICENSE.txt