apricot 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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==