apricot 0.0.1

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.
Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/.rspec +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +26 -0
  7. data/README.md +90 -0
  8. data/Rakefile +9 -0
  9. data/apricot.gemspec +22 -0
  10. data/bin/apricot +58 -0
  11. data/examples/bot.apr +23 -0
  12. data/examples/cinch-bot.apr +12 -0
  13. data/examples/hanoi.apr +10 -0
  14. data/examples/hello.apr +1 -0
  15. data/examples/plot.apr +28 -0
  16. data/examples/quine.apr +1 -0
  17. data/kernel/core.apr +928 -0
  18. data/lib/apricot/ast/identifier.rb +111 -0
  19. data/lib/apricot/ast/list.rb +99 -0
  20. data/lib/apricot/ast/literals.rb +240 -0
  21. data/lib/apricot/ast/node.rb +45 -0
  22. data/lib/apricot/ast/scopes.rb +147 -0
  23. data/lib/apricot/ast/toplevel.rb +66 -0
  24. data/lib/apricot/ast/variables.rb +64 -0
  25. data/lib/apricot/ast.rb +3 -0
  26. data/lib/apricot/compiler.rb +55 -0
  27. data/lib/apricot/cons.rb +27 -0
  28. data/lib/apricot/errors.rb +38 -0
  29. data/lib/apricot/generator.rb +15 -0
  30. data/lib/apricot/identifier.rb +91 -0
  31. data/lib/apricot/list.rb +96 -0
  32. data/lib/apricot/macroexpand.rb +47 -0
  33. data/lib/apricot/misc.rb +11 -0
  34. data/lib/apricot/namespace.rb +59 -0
  35. data/lib/apricot/parser.rb +541 -0
  36. data/lib/apricot/printers.rb +12 -0
  37. data/lib/apricot/repl.rb +254 -0
  38. data/lib/apricot/ruby_ext.rb +254 -0
  39. data/lib/apricot/seq.rb +44 -0
  40. data/lib/apricot/special_forms.rb +735 -0
  41. data/lib/apricot/stages.rb +60 -0
  42. data/lib/apricot/version.rb +3 -0
  43. data/lib/apricot.rb +30 -0
  44. data/spec/compiler_spec.rb +499 -0
  45. data/spec/identifier_spec.rb +58 -0
  46. data/spec/list_spec.rb +96 -0
  47. data/spec/parser_spec.rb +312 -0
  48. data/spec/spec_helper.rb +10 -0
  49. metadata +188 -0
data/spec/list_spec.rb ADDED
@@ -0,0 +1,96 @@
1
+ describe Apricot::List do
2
+ def new_list(*args)
3
+ described_class[*args]
4
+ end
5
+
6
+ def empty_list
7
+ described_class::EmptyList
8
+ end
9
+
10
+ it 'has a single instance of the empty list' do
11
+ new_list.object_id.should == empty_list.object_id
12
+ new_list(1,2).tail.tail.object_id.should == empty_list.object_id
13
+ end
14
+
15
+ it 'can be built up with cons' do
16
+ list = empty_list.cons(3).cons(2).cons(1)
17
+ list.head.should == 1
18
+ list.tail.head.should == 2
19
+ list.tail.tail.head.should == 3
20
+ end
21
+
22
+ it 'supports the == operator' do
23
+ empty_list.should == new_list
24
+ new_list.should == empty_list
25
+
26
+ list123 = new_list(1,2,3)
27
+ list23 = new_list(2,3)
28
+
29
+ list123.should == list23.cons(1)
30
+ list23.cons(1).should == list123
31
+
32
+ list23.tail.tail.should == empty_list
33
+ empty_list.should == list23.tail.tail
34
+
35
+ list123.should_not == empty_list
36
+ empty_list.should_not == list123
37
+
38
+ empty_list.should_not == 42
39
+ list123.should_not == 42
40
+ end
41
+
42
+ it 'responds to #empty?' do
43
+ new_list.should be_empty
44
+ empty_list.should be_empty
45
+ end
46
+
47
+ it 'supports Enumerable methods' do
48
+ list = new_list(1,2,3)
49
+
50
+ foo = []
51
+ list.each {|x| foo << x }
52
+ foo.should == [1,2,3]
53
+
54
+ list.to_a.should == [1,2,3]
55
+ list.count.should == 3
56
+ list.map {|x| x + x }.should == [2,4,6]
57
+ end
58
+
59
+ it 'can be inspected' do
60
+ list = new_list(1,2,3)
61
+ list.inspect.should == "(1 2 3)"
62
+ list.tail.tail.inspect.should == "(3)"
63
+ empty_list.inspect.should == "()"
64
+ end
65
+
66
+ it 'copies its tail when copied' do
67
+ list1 = new_list(1,2)
68
+ list2 = list1.dup
69
+
70
+ list1.object_id.should_not == list2.object_id
71
+ list1.tail.object_id.should_not == list2.tail.object_id
72
+ end
73
+
74
+ it 'does not copy the empty list in its tail when copied' do
75
+ list = new_list(1).dup
76
+
77
+ list.tail.object_id.should == empty_list.object_id
78
+ end
79
+
80
+ it 'can be used as a key in Hashes' do
81
+ list1 = new_list(1,2)
82
+ list2 = new_list(1,2)
83
+ list3 = new_list(1,2,3)
84
+ h = {}
85
+
86
+ h[list1] = 1
87
+ h[list2] = 2
88
+ h[list3] = 3
89
+ h[new_list] = 4
90
+
91
+ h[list1].should == 2
92
+ h[list2].should == 2
93
+ h[list3].should == 3
94
+ h[empty_list].should == 4
95
+ end
96
+ end
@@ -0,0 +1,312 @@
1
+ describe Apricot::Parser do
2
+ def parse(s)
3
+ @ast = described_class.parse_string(s, "(spec)")
4
+ @first = @ast.elements.first
5
+ @ast.elements
6
+ end
7
+
8
+ def parse_one(s, klass)
9
+ parse(s).length.should == 1
10
+ @first.should be_a(klass)
11
+ @first
12
+ end
13
+
14
+ def expect_syntax_error(s)
15
+ expect { parse(s) }.to raise_error(Apricot::SyntaxError)
16
+ end
17
+
18
+ it 'parses nothing' do
19
+ parse('').should be_empty
20
+ end
21
+
22
+ it 'skips whitespace' do
23
+ parse(" \n\t,").should be_empty
24
+ end
25
+
26
+ it 'skips comments' do
27
+ parse('; example').should be_empty
28
+ parse('#!/usr/bin/env apricot').should be_empty
29
+ end
30
+
31
+ it 'discards commented forms' do
32
+ parse('#_form').should be_empty
33
+ end
34
+
35
+ it 'parses identifiers' do
36
+ parse_one('example', AST::Identifier)
37
+ @first.name.should == :example
38
+ end
39
+
40
+ it 'parses pipe identifiers' do
41
+ parse_one('#|example|', AST::Identifier).name.should == :example
42
+ parse_one('#|foo bar|', AST::Identifier).name.should == :"foo bar"
43
+ parse_one('#|foo\nbar|', AST::Identifier).name.should == :"foo\nbar"
44
+ parse_one('#|foo\|bar|', AST::Identifier).name.should == :"foo|bar"
45
+ parse_one('#|foo"bar|', AST::Identifier).name.should == :'foo"bar'
46
+ end
47
+
48
+ it 'parses constants' do
49
+ parse_one('Example', AST::Identifier)
50
+ @first.constant?.should be_true
51
+ @first.const_names.should == [:Example]
52
+ end
53
+
54
+ it 'parses invalid constants as identifiers' do
55
+ parse_one('Fo$o', AST::Identifier)
56
+ @first.constant?.should be_false
57
+ end
58
+
59
+ it 'parses scoped constants' do
60
+ parse_one('Foo::Bar::Baz', AST::Identifier)
61
+ @first.constant?.should be_true
62
+ @first.const_names.should == [:Foo, :Bar, :Baz]
63
+ end
64
+
65
+ it 'parses invalid scoped constants as identifiers' do
66
+ parse_one('Foo::', AST::Identifier)
67
+ @first.constant?.should be_false
68
+ parse_one('Foo:', AST::Identifier)
69
+ @first.constant?.should be_false
70
+ parse_one('Foo::a', AST::Identifier)
71
+ @first.constant?.should be_false
72
+ parse_one('Foo::::Bar', AST::Identifier)
73
+ @first.constant?.should be_false
74
+ end
75
+
76
+ it 'parses true, false, nil, and self' do
77
+ parse('true false nil self').length.should == 4
78
+ @ast[0].should be_a(AST::Literal)
79
+ @ast[0].value.should == :true
80
+ @ast[1].should be_a(AST::Literal)
81
+ @ast[1].value.should == :false
82
+ @ast[2].should be_a(AST::Literal)
83
+ @ast[2].value.should == :nil
84
+ @ast[3].should be_a(AST::Identifier)
85
+ @ast[3].name.should == :self
86
+ end
87
+
88
+ it 'parses fixnums' do
89
+ parse_one('123', AST::Literal)
90
+ @first.value.should == 123
91
+ end
92
+
93
+ it 'parses bignums' do
94
+ parse_one('12345678901234567890', AST::BignumLiteral)
95
+ @first.value.should == 12345678901234567890
96
+ end
97
+
98
+ it 'parses radix integers' do
99
+ parse_one('2r10', AST::Literal)
100
+ @first.value.should == 2
101
+ end
102
+
103
+ it 'parses floats' do
104
+ parse_one('1.23', AST::FloatLiteral)
105
+ @first.value.should == 1.23
106
+ end
107
+
108
+ it 'parses rationals' do
109
+ parse_one('12/34', AST::RationalLiteral)
110
+ @first.numerator.should == 12
111
+ @first.denominator.should == 34
112
+ end
113
+
114
+ it 'does not parse invalid numbers' do
115
+ expect_syntax_error '12abc'
116
+ end
117
+
118
+ it 'parses empty strings' do
119
+ parse_one('""', AST::StringLiteral)
120
+ @first.value.should == ''
121
+ end
122
+
123
+ it 'parses strings' do
124
+ parse_one('"Hello, world!"', AST::StringLiteral)
125
+ @first.value.should == 'Hello, world!'
126
+ end
127
+
128
+ it 'parses multiline strings' do
129
+ parse_one(%{"This is\na test"}, AST::StringLiteral)
130
+ @first.value.should == "This is\na test"
131
+ end
132
+
133
+ it 'does not parse unfinished strings' do
134
+ expect_syntax_error '"'
135
+ end
136
+
137
+ it 'parses strings with character escapes' do
138
+ parse_one('"\\a\\b\\t\\n\\v\\f\\r\\e\\"\\\\"', AST::StringLiteral)
139
+ @first.value.should == "\a\b\t\n\v\f\r\e\"\\"
140
+ end
141
+
142
+ it 'parses strings with octal escapes' do
143
+ parse_one('"\\1\\01\\001"', AST::StringLiteral)
144
+ @first.value.should == "\001\001\001"
145
+ end
146
+
147
+ it 'parses strings with hex escapes' do
148
+ parse_one('"\\x1\\x01"', AST::StringLiteral)
149
+ @first.value.should == "\001\001"
150
+ end
151
+
152
+ it 'does not parse strings with invalid hex escapes' do
153
+ expect_syntax_error '"\\x"'
154
+ end
155
+
156
+ it 'stops parsing hex/octal escapes in strings at non-hex/octal digits' do
157
+ parse_one('"\xAZ\082"', AST::StringLiteral)
158
+ @first.value.should == "\x0AZ\00082"
159
+ end
160
+
161
+ it 'parses regexes' do
162
+ parse_one('#r!!', AST::RegexLiteral).pattern.should == ''
163
+ parse_one('#r!egex!', AST::RegexLiteral).pattern.should == 'egex'
164
+ parse_one('#r(egex)', AST::RegexLiteral).pattern.should == 'egex'
165
+ parse_one('#r[egex]', AST::RegexLiteral).pattern.should == 'egex'
166
+ parse_one('#r{egex}', AST::RegexLiteral).pattern.should == 'egex'
167
+ parse_one('#r<egex>', AST::RegexLiteral).pattern.should == 'egex'
168
+ parse_one('#r!\!!', AST::RegexLiteral).pattern.should == '!'
169
+ parse_one('#r!foo\bar!', AST::RegexLiteral).pattern.should == 'foo\bar'
170
+ parse_one('#r!\\\\!', AST::RegexLiteral).pattern.should == "\\\\"
171
+ end
172
+
173
+ it 'parses regexes with trailing options' do
174
+ parse_one('#r//i', AST::RegexLiteral)
175
+ @first.options.should == Regexp::IGNORECASE
176
+ parse_one('#r/foo/x', AST::RegexLiteral)
177
+ @first.options.should == Regexp::EXTENDED
178
+ parse_one('#r//im', AST::RegexLiteral)
179
+ @first.options.should == Regexp::IGNORECASE | Regexp::MULTILINE
180
+ end
181
+
182
+ it 'does not parse regexes with unknown trailing options' do
183
+ expect_syntax_error '#r/foo/asdf'
184
+ end
185
+
186
+ it 'parses symbols' do
187
+ parse_one(':example', AST::SymbolLiteral)
188
+ @first.value.should == :example
189
+ end
190
+
191
+ it 'parses quoted symbols' do
192
+ parse_one(':"\x01()"', AST::SymbolLiteral)
193
+ @first.value.should == :"\x01()"
194
+ end
195
+
196
+ it 'does not parse unfinished quoted symbols' do
197
+ expect_syntax_error ':"'
198
+ end
199
+
200
+ it 'does not parse empty symbols' do
201
+ expect_syntax_error ':'
202
+ end
203
+
204
+ it 'does parse empty quoted symbols' do
205
+ parse_one(':""', AST::SymbolLiteral)
206
+ @first.value.should == :""
207
+ end
208
+
209
+ it 'parses empty lists' do
210
+ parse_one('()', AST::List)
211
+ @first.elements.should be_empty
212
+ end
213
+
214
+ it 'parses lists' do
215
+ parse_one('(1 two)', AST::List)
216
+ @first[0].should be_a(AST::Literal)
217
+ @first[1].should be_a(AST::Identifier)
218
+ end
219
+
220
+ it 'parses empty arrays' do
221
+ parse_one('[]', AST::ArrayLiteral)
222
+ @first.elements.should be_empty
223
+ end
224
+
225
+ it 'parses arrays' do
226
+ parse_one('[1 two]', AST::ArrayLiteral)
227
+ @first[0].should be_a(AST::Literal)
228
+ @first[1].should be_a(AST::Identifier)
229
+ end
230
+
231
+ it 'parses empty hashes' do
232
+ parse_one('{}', AST::HashLiteral)
233
+ @first.elements.should be_empty
234
+ end
235
+
236
+ it 'parses hashes' do
237
+ parse_one('{:example 1}', AST::HashLiteral)
238
+ @first[0].should be_a(AST::SymbolLiteral)
239
+ @first[1].should be_a(AST::Literal)
240
+ end
241
+
242
+ it 'does not parse invalid hashes' do
243
+ expect_syntax_error '{:foo 1 :bar}'
244
+ end
245
+
246
+ it 'parses empty sets' do
247
+ parse_one('#{}', AST::SetLiteral)
248
+ @first.elements.should be_empty
249
+ end
250
+
251
+ it 'parses sets' do
252
+ parse_one('#{1 two}', AST::SetLiteral)
253
+ @first[0].should be_a(AST::Literal)
254
+ @first[1].should be_a(AST::Identifier)
255
+ end
256
+
257
+ it 'parses multiple forms' do
258
+ parse('foo bar').length.should == 2
259
+ @ast[0].should be_a(AST::Identifier)
260
+ @ast[1].should be_a(AST::Identifier)
261
+ end
262
+
263
+ it 'parses quoted forms' do
264
+ parse_one("'test", AST::List)
265
+ @first.elements.length.should == 2
266
+ @first[0].should be_a(AST::Identifier)
267
+ @first[0].name.should == :quote
268
+ @first[1].should be_a(AST::Identifier)
269
+ @first[1].name.should == :test
270
+ end
271
+
272
+ it 'parses syntax quoted forms' do
273
+ begin
274
+ old_gensym = Apricot.instance_variable_get :@gensym
275
+ Apricot.instance_variable_set :@gensym, 41
276
+
277
+ parse_one("`(foo ~bar ~@baz quux#)", AST::List)
278
+ @first.should == AST::Node.from_value(
279
+ List[Identifier.intern(:concat),
280
+ List[Identifier.intern(:list),
281
+ List[Identifier.intern(:quote),
282
+ Identifier.intern(:foo)]],
283
+ List[Identifier.intern(:list),
284
+ Identifier.intern(:bar)],
285
+ Identifier.intern(:baz),
286
+ List[Identifier.intern(:list),
287
+ List[Identifier.intern(:quote),
288
+ Identifier.intern(:'quux#__42')]]])
289
+ ensure
290
+ Apricot.instance_variable_set :@gensym, old_gensym
291
+ end
292
+ end
293
+
294
+ it 'parses #() shorthand' do
295
+ Apricot.stub(:gensym).and_return(*:a..:z)
296
+
297
+ parse("#()").should == parse("(fn [] ())")
298
+ parse("#(foo)").should == parse("(fn [] (foo))")
299
+ parse("#(%)").should == parse("(fn [a] (a))")
300
+ parse("#(% %2)").should == parse("(fn [b c] (b c))")
301
+ parse("#(%1 %2)").should == parse("(fn [d e] (d e))")
302
+ parse("#(%2)").should == parse("(fn [g f] (f))")
303
+ parse("#(%&)").should == parse("(fn [& h] (h))")
304
+ parse("#(% %&)").should == parse("(fn [i & j] (i j))")
305
+
306
+ expect_syntax_error("#(%0)")
307
+ expect_syntax_error("#(%-1)")
308
+ expect_syntax_error("#(%x)")
309
+ expect_syntax_error("#(%1.1)")
310
+ expect_syntax_error("#(%1asdf)")
311
+ end
312
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'rspec'
3
+
4
+ unless Rubinius.ruby19?
5
+ puts "Error: Apricot must be run in Ruby 1.9 mode"
6
+ exit 1
7
+ end
8
+
9
+ require 'apricot'
10
+ include Apricot
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: apricot
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Curtis McEnroe
9
+ - Scott Olson
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-04-13 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ prerelease: false
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 10.0.3
22
+ none: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 10.0.3
28
+ none: false
29
+ name: rake
30
+ type: :development
31
+ - !ruby/object:Gem::Dependency
32
+ prerelease: false
33
+ requirement: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.13.0
38
+ none: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.13.0
44
+ none: false
45
+ name: rspec
46
+ type: :development
47
+ description: A compiler for a Clojure-like programming language on the Rubinius VM
48
+ email:
49
+ - programble@gmail.com
50
+ - scott@scott-olson.org
51
+ executables:
52
+ - !binary |-
53
+ YXByaWNvdA==
54
+ extensions: []
55
+ extra_rdoc_files: []
56
+ files:
57
+ - !binary |-
58
+ LmdpdGlnbm9yZQ==
59
+ - !binary |-
60
+ LnJzcGVj
61
+ - !binary |-
62
+ LnJ1YnktdmVyc2lvbg==
63
+ - !binary |-
64
+ LnRyYXZpcy55bWw=
65
+ - !binary |-
66
+ R2VtZmlsZQ==
67
+ - !binary |-
68
+ R2VtZmlsZS5sb2Nr
69
+ - !binary |-
70
+ UkVBRE1FLm1k
71
+ - !binary |-
72
+ UmFrZWZpbGU=
73
+ - !binary |-
74
+ YXByaWNvdC5nZW1zcGVj
75
+ - !binary |-
76
+ YmluL2Fwcmljb3Q=
77
+ - !binary |-
78
+ ZXhhbXBsZXMvYm90LmFwcg==
79
+ - !binary |-
80
+ ZXhhbXBsZXMvY2luY2gtYm90LmFwcg==
81
+ - !binary |-
82
+ ZXhhbXBsZXMvaGFub2kuYXBy
83
+ - !binary |-
84
+ ZXhhbXBsZXMvaGVsbG8uYXBy
85
+ - !binary |-
86
+ ZXhhbXBsZXMvcGxvdC5hcHI=
87
+ - !binary |-
88
+ ZXhhbXBsZXMvcXVpbmUuYXBy
89
+ - !binary |-
90
+ a2VybmVsL2NvcmUuYXBy
91
+ - !binary |-
92
+ bGliL2Fwcmljb3QucmI=
93
+ - !binary |-
94
+ bGliL2Fwcmljb3QvYXN0LnJi
95
+ - !binary |-
96
+ bGliL2Fwcmljb3QvYXN0L2lkZW50aWZpZXIucmI=
97
+ - !binary |-
98
+ bGliL2Fwcmljb3QvYXN0L2xpc3QucmI=
99
+ - !binary |-
100
+ bGliL2Fwcmljb3QvYXN0L2xpdGVyYWxzLnJi
101
+ - !binary |-
102
+ bGliL2Fwcmljb3QvYXN0L25vZGUucmI=
103
+ - !binary |-
104
+ bGliL2Fwcmljb3QvYXN0L3Njb3Blcy5yYg==
105
+ - !binary |-
106
+ bGliL2Fwcmljb3QvYXN0L3RvcGxldmVsLnJi
107
+ - !binary |-
108
+ bGliL2Fwcmljb3QvYXN0L3ZhcmlhYmxlcy5yYg==
109
+ - !binary |-
110
+ bGliL2Fwcmljb3QvY29tcGlsZXIucmI=
111
+ - !binary |-
112
+ bGliL2Fwcmljb3QvY29ucy5yYg==
113
+ - !binary |-
114
+ bGliL2Fwcmljb3QvZXJyb3JzLnJi
115
+ - !binary |-
116
+ bGliL2Fwcmljb3QvZ2VuZXJhdG9yLnJi
117
+ - !binary |-
118
+ bGliL2Fwcmljb3QvaWRlbnRpZmllci5yYg==
119
+ - !binary |-
120
+ bGliL2Fwcmljb3QvbGlzdC5yYg==
121
+ - !binary |-
122
+ bGliL2Fwcmljb3QvbWFjcm9leHBhbmQucmI=
123
+ - !binary |-
124
+ bGliL2Fwcmljb3QvbWlzYy5yYg==
125
+ - !binary |-
126
+ bGliL2Fwcmljb3QvbmFtZXNwYWNlLnJi
127
+ - !binary |-
128
+ bGliL2Fwcmljb3QvcGFyc2VyLnJi
129
+ - !binary |-
130
+ bGliL2Fwcmljb3QvcHJpbnRlcnMucmI=
131
+ - !binary |-
132
+ bGliL2Fwcmljb3QvcmVwbC5yYg==
133
+ - !binary |-
134
+ bGliL2Fwcmljb3QvcnVieV9leHQucmI=
135
+ - !binary |-
136
+ bGliL2Fwcmljb3Qvc2VxLnJi
137
+ - !binary |-
138
+ bGliL2Fwcmljb3Qvc3BlY2lhbF9mb3Jtcy5yYg==
139
+ - !binary |-
140
+ bGliL2Fwcmljb3Qvc3RhZ2VzLnJi
141
+ - !binary |-
142
+ bGliL2Fwcmljb3QvdmVyc2lvbi5yYg==
143
+ - !binary |-
144
+ c3BlYy9jb21waWxlcl9zcGVjLnJi
145
+ - !binary |-
146
+ c3BlYy9pZGVudGlmaWVyX3NwZWMucmI=
147
+ - !binary |-
148
+ c3BlYy9saXN0X3NwZWMucmI=
149
+ - !binary |-
150
+ c3BlYy9wYXJzZXJfc3BlYy5yYg==
151
+ - !binary |-
152
+ c3BlYy9zcGVjX2hlbHBlci5yYg==
153
+ homepage: https://github.com/programble/apricot
154
+ licenses:
155
+ - ISC
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ none: false
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ! '>='
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ none: false
172
+ requirements: []
173
+ rubyforge_project:
174
+ rubygems_version: 1.8.25
175
+ signing_key:
176
+ specification_version: 3
177
+ summary: A Clojure-like programming language on Rubinius
178
+ test_files:
179
+ - !binary |-
180
+ c3BlYy9jb21waWxlcl9zcGVjLnJi
181
+ - !binary |-
182
+ c3BlYy9pZGVudGlmaWVyX3NwZWMucmI=
183
+ - !binary |-
184
+ c3BlYy9saXN0X3NwZWMucmI=
185
+ - !binary |-
186
+ c3BlYy9wYXJzZXJfc3BlYy5yYg==
187
+ - !binary |-
188
+ c3BlYy9zcGVjX2hlbHBlci5yYg==