sxp 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
data/lib/sxp.rb CHANGED
@@ -1,7 +1,73 @@
1
1
  require 'sxp/version'
2
2
  require 'sxp/extensions'
3
- require 'sxp/pair'
4
- require 'sxp/list'
5
- require 'sxp/reader'
6
3
  require 'sxp/writer'
7
- require 'sxp/generator'
4
+
5
+ module SXP
6
+ autoload :Pair, 'sxp/pair'
7
+ autoload :List, 'sxp/list'
8
+ autoload :Generator, 'sxp/generator'
9
+ autoload :Reader, 'sxp/reader'
10
+
11
+ ##
12
+ # Reads all S-expressions from a given input URI using the HTTP or FTP
13
+ # protocols.
14
+ #
15
+ # @param [String, #to_s] url
16
+ # @param [Hash{Symbol => Object}] options
17
+ # @return [Enumerable<Object>]
18
+ def self.read_url(url, options = {})
19
+ require 'openuri'
20
+ open(url.to_s, 'rb', nil, options) { |io| read_all(io, options) }
21
+ end
22
+
23
+ ##
24
+ # Reads all S-expressions from the given input files.
25
+ #
26
+ # @param [Enumerable<String>] filenames
27
+ # @param [Hash{Symbol => Object}] options
28
+ # @return [Enumerable<Object>]
29
+ def self.read_files(*filenames)
30
+ options = filenames.last.is_a?(Hash) ? filenames.pop : {}
31
+ filenames.map { |filename| read_file(filename, options) }.inject { |sxps, sxp| sxps + sxp }
32
+ end
33
+
34
+ ##
35
+ # Reads all S-expressions from a given input file.
36
+ #
37
+ # @param [String, #to_s] filename
38
+ # @param [Hash{Symbol => Object}] options
39
+ # @return [Enumerable<Object>]
40
+ def self.read_file(filename, options = {})
41
+ File.open(filename.to_s, 'rb') { |io| read_all(io, options) }
42
+ end
43
+
44
+ ##
45
+ # Reads all S-expressions from the given input stream.
46
+ #
47
+ # @param [IO, StringIO, String] input
48
+ # @param [Hash{Symbol => Object}] options
49
+ # @return [Enumerable<Object>]
50
+ def self.read_all(input, options = {})
51
+ Reader.new(input, options).read_all
52
+ end
53
+
54
+ ##
55
+ # Reads one S-expression from the given input stream.
56
+ #
57
+ # @param [IO, StringIO, String] input
58
+ # @param [Hash{Symbol => Object}] options
59
+ # @return [Object]
60
+ def self.read(input, options = {})
61
+ Reader.new(input, options).read
62
+ end
63
+
64
+ class << self
65
+ alias_method :parse, :read
66
+ alias_method :parse_all, :read_all
67
+ alias_method :parse_files, :read_files
68
+ alias_method :parse_file, :read_file
69
+ alias_method :parse_url, :read_url
70
+ alias_method :parse_uri, :read_url # @deprecated
71
+ alias_method :read_uri, :read_url # @deprecated
72
+ end
73
+ end # module SXP
@@ -1,6 +1,10 @@
1
+ ##
2
+ # Extensions for Ruby's `Symbol` class.
1
3
  class Symbol
2
4
  ##
3
- # Returns +true+ if this is a keyword symbol.
5
+ # Returns `true` if this is a keyword symbol.
6
+ #
7
+ # @return [Boolean]
4
8
  def keyword?
5
9
  to_s[-1] == ?:
6
10
  end
data/lib/sxp/generator.rb CHANGED
@@ -1,14 +1,26 @@
1
1
  module SXP
2
+ ##
3
+ # An S-expression generator.
2
4
  class Generator
5
+ ##
6
+ # @param [Array] sxps
7
+ # @return [Object]
3
8
  def self.string(*sxps)
4
9
  require 'stringio' unless defined?(StringIO)
5
10
  write(StringIO.new, *sxps).instance_variable_get('@buffer').string
6
11
  end
7
12
 
13
+ ##
14
+ # @param [Array] sxps
15
+ # @return [Object]
8
16
  def self.print(*sxps)
9
17
  write($stdout, *sxps)
10
18
  end
11
19
 
20
+ ##
21
+ # @param [Object] out
22
+ # @param [Array] sxps
23
+ # @return [Object]
12
24
  def self.write(out, *sxps)
13
25
  generator = self.new(out)
14
26
  sxps.each do |sxp|
@@ -17,6 +29,8 @@ module SXP
17
29
  generator
18
30
  end
19
31
 
32
+ ##
33
+ # @param [Object] buffer
20
34
  def initialize(buffer)
21
35
  @output = [@buffer = buffer]
22
36
  @indent = 0
@@ -24,39 +38,53 @@ module SXP
24
38
 
25
39
  protected
26
40
 
27
- def emit(text, options = {})
28
- if out = @output.last
29
- out.print(' ' * (indent * 2)) if options[:indent]
30
- out.print(text)
31
- end
41
+ ##
42
+ # @param [String] text
43
+ # @param [Hash{Symbol => Object}] options
44
+ # @return [void]
45
+ def emit(text, options = {})
46
+ if out = @output.last
47
+ out.print(' ' * (indent * 2)) if options[:indent]
48
+ out.print(text)
32
49
  end
50
+ end
33
51
 
34
- def captured(&block)
35
- require 'stringio' unless defined?(StringIO)
36
- begin
37
- @output.push(buffer = StringIO.new)
38
- block.call
39
- ensure
40
- @output.pop
41
- end
42
- buffer.string
52
+ ##
53
+ # @yield
54
+ # @return [String]
55
+ def captured(&block)
56
+ require 'stringio' unless defined?(StringIO)
57
+ begin
58
+ @output.push(buffer = StringIO.new)
59
+ block.call
60
+ ensure
61
+ @output.pop
43
62
  end
63
+ buffer.string
64
+ end
44
65
 
45
- def indented(&block)
46
- begin
47
- increase_indent!
48
- block.call
49
- ensure
50
- decrease_indent!
51
- end
66
+ ##
67
+ # @yield
68
+ # @return [Object]
69
+ def indented(&block)
70
+ begin
71
+ increase_indent!
72
+ block.call
73
+ ensure
74
+ decrease_indent!
52
75
  end
76
+ end
53
77
 
54
- def increase_indent!()
55
- @indent += 1
56
- end
78
+ ##
79
+ # @return [void]
80
+ def increase_indent!
81
+ @indent += 1
82
+ end
57
83
 
58
- def decrease_indent!()
59
- @indent -= 1
60
- end
61
- end
62
- end
84
+ ##
85
+ # @return [void]
86
+ def decrease_indent!
87
+ @indent -= 1
88
+ end
89
+ end # class Generator
90
+ end # module SXP
data/lib/sxp/list.rb CHANGED
@@ -1,62 +1,106 @@
1
1
  require 'sxp/pair'
2
2
 
3
3
  module SXP
4
+ ##
5
+ # A singly-linked list.
4
6
  class List < Pair
5
7
  include Enumerable
6
8
 
9
+ ##
10
+ # @param [Array] elements
11
+ # @return [Object]
7
12
  def self.[](*elements)
8
13
  self.new(elements)
9
14
  end
10
15
 
16
+ ##
17
+ # @param [Array] elements
18
+ # @yield [list]
19
+ # @yieldparam [List] list
11
20
  def initialize(elements = [], &block)
12
21
  @pair = nil
13
22
  unshift(*elements) unless elements.empty?
14
23
  block.call(self) if block_given?
15
24
  end
16
25
 
26
+ ##
27
+ # @return [String]
17
28
  def inspect
18
29
  "(" << map { |value| value.inspect }.join(' ') << ")"
19
30
  end
20
31
 
21
- def head() first end
22
- def tail() rest end
32
+ ##
33
+ # @return [Object]
34
+ def head
35
+ first
36
+ end
37
+
38
+ ##
39
+ # @return [Object]
40
+ def tail
41
+ rest
42
+ end
23
43
 
44
+ ##
45
+ # @return [Object]
24
46
  def rest
25
47
  empty? ? false : @pair.tail
26
48
  end
27
49
 
28
- # Array interface
29
-
50
+ ##
51
+ # @param [Object] other
52
+ # @return [Object]
30
53
  def &(other)
31
54
  self.class.new(self.to_a & other.to_a)
32
55
  end
33
56
 
57
+ ##
58
+ # @param [Object] other
59
+ # @return [Object]
34
60
  def |(other)
35
61
  self.class.new(self.to_a | other.to_a)
36
62
  end
37
63
 
64
+ ##
65
+ # @param [Object] times
66
+ # @return [Object]
38
67
  def *(times)
39
68
  result = (self.to_a * times)
40
69
  result.is_a?(Array) ? self.class.new(result) : result
41
70
  end
42
71
 
72
+ ##
73
+ # @param [Object] other
74
+ # @return [Object]
43
75
  def +(other)
44
76
  self.class.new(self.to_a + other.to_a)
45
77
  end
46
78
 
79
+ ##
80
+ # @param [Object] other
81
+ # @return [Object]
47
82
  def -(other)
48
83
  self.class.new(self.to_a - other.to_a)
49
84
  end
50
85
 
86
+ ##
87
+ # @param [Object] object
88
+ # @return [Object]
51
89
  def <<(object)
52
90
  push(object)
53
91
  self
54
92
  end
55
93
 
94
+ ##
95
+ # @param [Object] other
96
+ # @return [Object]
56
97
  def <=>(other)
57
98
  to_a <=> other.to_a
58
99
  end
59
100
 
101
+ ##
102
+ # @param [Object] other
103
+ # @return [Object]
60
104
  def ==(other)
61
105
  case other
62
106
  when List
@@ -68,56 +112,89 @@ module SXP
68
112
  end
69
113
  end
70
114
 
115
+ ##
116
+ # @param [Array] args
117
+ # @return [Object]
71
118
  def [](*args)
72
119
  result = to_a[*args]
73
120
  result.is_a?(Array) ? self.class.new(result) : result # FIXME
74
121
  end
75
122
 
123
+ ##
124
+ # @param [Array] args
125
+ # @return [Object]
76
126
  def []=(*args)
77
127
  raise NotImplementedError # TODO
78
128
  end
79
129
 
130
+ ##
131
+ # @param [Object] object
132
+ # @return [Object]
80
133
  def assoc(object)
81
134
  raise NotImplementedError # TODO
82
135
  end
83
136
 
137
+ ##
138
+ # @param [Integer] index
139
+ # @return [Object]
84
140
  def at(index)
85
141
  to_a.at(index)
86
142
  end
87
143
 
144
+ ##
145
+ # @return [Object]
88
146
  def clear
89
147
  @pair = nil
90
148
  self
91
149
  end
92
150
 
151
+ ##
152
+ # @return [Object]
93
153
  def collect!(&block)
94
154
  raise NotImplementedError # TODO
95
155
  end
96
156
 
157
+ ##
158
+ # @return [Object]
97
159
  def compact
98
160
  self.class.new(to_a.compact)
99
161
  end
100
162
 
163
+ ##
164
+ # @return [Object]
101
165
  def compact!
102
166
  raise NotImplementedError # TODO
103
167
  end
104
168
 
169
+ ##
170
+ # @param [Object] other
171
+ # @return [Object]
105
172
  def concat(other)
106
173
  raise NotImplementedError # TODO
107
174
  end
108
175
 
176
+ ##
177
+ # @param [Object] object
178
+ # @return [Object]
109
179
  def delete(object, &block)
110
180
  raise NotImplementedError # TODO
111
181
  end
112
182
 
183
+ ##
184
+ # @param [Integer] index
185
+ # @return [Object]
113
186
  def delete_at(index)
114
187
  raise NotImplementedError # TODO
115
188
  end
116
189
 
190
+ ##
191
+ # @return [Object]
117
192
  def delete_if(&block)
118
193
  raise NotImplementedError # TODO
119
194
  end
120
195
 
196
+ ##
197
+ # @return [Enumerator]
121
198
  def each(&block)
122
199
  pair = @pair
123
200
  while pair != nil
@@ -127,19 +204,25 @@ module SXP
127
204
  self
128
205
  end
129
206
 
207
+ ##
208
+ # @return [Enumerator]
130
209
  def each_index(&block)
131
210
  index = 0
132
211
  each do
133
212
  block.call(index)
134
213
  index += 1
135
214
  end
136
- self
137
215
  end
138
216
 
217
+ ##
218
+ # @return [Boolean]
139
219
  def empty?
140
220
  @pair.nil?
141
221
  end
142
222
 
223
+ ##
224
+ # @param [Object] other
225
+ # @return [Boolean]
143
226
  def eql?(other)
144
227
  case other
145
228
  when self then true
@@ -148,14 +231,23 @@ module SXP
148
231
  end
149
232
  end
150
233
 
234
+ ##
235
+ # @param [Array] args
236
+ # @return [Object]
151
237
  def fetch(*args, &block)
152
238
  to_a.fetch(*args, &block)
153
239
  end
154
240
 
241
+ ##
242
+ # @param [Array] args
243
+ # @return [Object]
155
244
  def fill(*args, &block)
156
245
  raise NotImplementedError # TODO
157
246
  end
158
247
 
248
+ ##
249
+ # @param [Integer] count
250
+ # @return [Object]
159
251
  def first(count = nil)
160
252
  case
161
253
  when count.nil?
@@ -167,30 +259,50 @@ module SXP
167
259
  end
168
260
  end
169
261
 
262
+ ##
263
+ # @return [Object]
170
264
  def flatten
171
265
  raise NotImplementedError # TODO
172
266
  end
173
267
 
268
+ ##
269
+ # @return [Object]
174
270
  def flatten!
175
271
  raise NotImplementedError # TODO
176
272
  end
177
273
 
274
+ ##
275
+ # @param [Object] object
276
+ # @return [Object]
178
277
  def include?(object)
179
278
  to_a.include?(object)
180
279
  end
181
280
 
281
+ ##
282
+ # @param [Object] object
283
+ # @return [Object]
182
284
  def index(object)
183
285
  to_a.index(object)
184
286
  end
185
287
 
288
+ ##
289
+ # @param [Integer] index
290
+ # @param [Array] objects
291
+ # @return [Object]
186
292
  def insert(index, *objects)
187
293
  raise NotImplementedError # TODO
188
294
  end
189
295
 
296
+ ##
297
+ # @param [String] separator
298
+ # @return [Object]
190
299
  def join(separator = $,)
191
300
  to_a.join(separator)
192
301
  end
193
302
 
303
+ ##
304
+ # @param [Integer] count
305
+ # @return [Object]
194
306
  def last(count = nil)
195
307
  case
196
308
  when count.nil?
@@ -200,38 +312,60 @@ module SXP
200
312
  end
201
313
  end
202
314
 
315
+ ##
316
+ # @return [Integer]
203
317
  def length
204
318
  @length ||= to_a.length
205
319
  end
206
320
 
321
+ ##
322
+ # @return [Object]
207
323
  def map!(&block)
208
324
  collect!(&block)
209
325
  end
210
326
 
327
+ ##
328
+ # @return [Integer]
211
329
  def nitems
212
330
  to_a.nitems
213
331
  end
214
332
 
333
+ ##
334
+ # @param [Object] template
335
+ # @return [Object]
215
336
  def pack(template)
216
337
  to_a.pack(template)
217
338
  end
218
339
 
340
+ ##
341
+ # @return [Object]
219
342
  def pop
220
343
  raise NotImplementedError # TODO
221
344
  end
222
345
 
346
+ ##
347
+ # @param [Array] objects
348
+ # @return [Object]
223
349
  def push(*objects)
224
350
  raise NotImplementedError # TODO
225
351
  end
226
352
 
353
+ ##
354
+ # @param [Object] key
355
+ # @return [Object]
227
356
  def rassoc(key)
228
357
  raise NotImplementedError # TODO
229
358
  end
230
359
 
360
+ ##
361
+ # @return [Object]
231
362
  def reject!(&block)
232
363
  raise NotImplementedError # TODO
233
364
  end
234
365
 
366
+ ##
367
+ # @param [Object] other_list
368
+ # @return [Object]
235
369
  def replace(other_list)
236
370
  case other_list
237
371
  when Pair
@@ -247,72 +381,110 @@ module SXP
247
381
  self
248
382
  end
249
383
 
384
+ ##
385
+ # @return [Object]
250
386
  def reverse
251
387
  self.class.new(to_a.reverse)
252
388
  end
253
389
 
390
+ ##
391
+ # @return [Object]
254
392
  def reverse!
255
393
  raise NotImplementedError # TODO
256
394
  end
257
395
 
396
+ ##
397
+ # @return [Object]
258
398
  def reverse_each(&block)
259
399
  to_a.reverse_each(&block)
260
400
  self
261
401
  end
262
402
 
403
+ ##
404
+ # @param [Object] object
405
+ # @return [Object]
263
406
  def rindex(object)
264
407
  to_a.rindex(object)
265
408
  end
266
409
 
410
+ ##
411
+ # @return [Object]
267
412
  def shift
268
413
  raise NotImplementedError # TODO
269
414
  end
270
415
 
416
+ ##
417
+ # @return [Integer]
271
418
  def size
272
419
  length
273
420
  end
274
421
 
422
+ ##
423
+ # @param [Array] args
424
+ # @return [Object]
275
425
  def slice(*args)
276
426
  self[*args]
277
427
  end
278
428
 
429
+ ##
430
+ # @param [Array] args
431
+ # @return [Object]
279
432
  def slice!(*args)
280
433
  raise NotImplementedError # TODO
281
434
  end
282
435
 
436
+ ##
437
+ # @return [Object]
283
438
  def sort(&block)
284
439
  (array = to_a).sort!(&block)
285
440
  self.class.new(array)
286
441
  end
287
442
 
443
+ ##
444
+ # @return [Object]
288
445
  def sort!
289
446
  raise NotImplementedError # TODO
290
447
  end
291
448
 
449
+ ##
450
+ # @return [List]
292
451
  def to_list
293
452
  self
294
453
  end
295
454
 
455
+ ##
456
+ # @return [Pair]
296
457
  def to_pair
297
458
  @pair
298
459
  end
299
460
 
461
+ ##
462
+ # @return [String]
300
463
  def to_s
301
464
  join
302
465
  end
303
466
 
467
+ ##
468
+ # @return [Object]
304
469
  def transpose
305
470
  self.class.new(to_a.transpose)
306
471
  end
307
472
 
473
+ ##
474
+ # @return [Object]
308
475
  def uniq
309
476
  self.class.new(to_a.uniq)
310
477
  end
311
478
 
479
+ ##
480
+ # @return [Object]
312
481
  def uniq!
313
482
  raise NotImplementedError # TODO
314
483
  end
315
484
 
485
+ ##
486
+ # @param [Array] objects
487
+ # @return [Object]
316
488
  def unshift(*objects)
317
489
  objects.reverse_each do |object|
318
490
  @pair = Pair.new(object, @pair)
@@ -320,8 +492,11 @@ module SXP
320
492
  self
321
493
  end
322
494
 
495
+ ##
496
+ # @param [Array] selector
497
+ # @return [Object]
323
498
  def values_at(*selector)
324
499
  self.class.new(to_a.values_at(*selector))
325
500
  end
326
- end
327
- end
501
+ end # class List
502
+ end # module SXP
data/lib/sxp/pair.rb CHANGED
@@ -1,39 +1,64 @@
1
1
  module SXP
2
+ ##
2
3
  class Pair
4
+ # @return [Object]
3
5
  attr_accessor :head
6
+
7
+ # @return [Object]
4
8
  attr_accessor :tail
5
9
 
10
+ ##
11
+ # @param [Object] head
12
+ # @param [Object] tail
6
13
  def initialize(head = nil, tail = nil)
7
14
  @head, @tail = head, tail
8
15
  end
9
16
 
10
- def inspect
11
- case
12
- when tail.nil?
13
- "(#{head.inspect})"
14
- else
15
- "(#{head.inspect} . #{tail.inspect})"
16
- end
17
- end
18
-
17
+ ##
18
+ # Returns `true` if the head and tail of this pair are both `nil`.
19
+ #
20
+ # @return [Boolean]
19
21
  def empty?
20
22
  head.nil? && tail.nil?
21
23
  end
22
24
 
23
25
  ##
24
- # @see http://srfi.schemers.org/srfi-1/srfi-1.html#ImproperLists
26
+ # Returns `true` if the tail of this pair is not `nil` or another pair.
27
+ #
28
+ # @return [Boolean]
29
+ # @see http://srfi.schemers.org/srfi-1/srfi-1.html#ImproperLists
25
30
  def dotted?
26
31
  !proper?
27
32
  end
28
33
 
29
34
  ##
30
- # @see http://srfi.schemers.org/srfi-1/srfi-1.html#ImproperLists
35
+ # Returns `true` if the tail of this pair is `nil` or another pair.
36
+ #
37
+ # @return [Boolean]
38
+ # @see http://srfi.schemers.org/srfi-1/srfi-1.html#ImproperLists
31
39
  def proper?
32
40
  tail.nil? || tail.is_a?(Pair)
33
41
  end
34
42
 
43
+ ##
44
+ # Returns an array representation of this pair.
45
+ #
46
+ # @return [Array]
35
47
  def to_a
36
48
  [head, tail]
37
49
  end
38
- end
39
- end
50
+
51
+ ##
52
+ # Returns a developer-friendly representation of this pair.
53
+ #
54
+ # @return [String]
55
+ def inspect
56
+ case
57
+ when tail.nil?
58
+ "(#{head.inspect})"
59
+ else
60
+ "(#{head.inspect} . #{tail.inspect})"
61
+ end
62
+ end
63
+ end # class Pair
64
+ end # module SXP
data/lib/sxp/reader.rb CHANGED
@@ -1,67 +1,6 @@
1
1
  module SXP
2
2
  ##
3
- # Reads all S-expressions from a given input URI using the HTTP or FTP
4
- # protocols.
5
- #
6
- # @param [String, #to_s] url
7
- # @param [Hash{Symbol => Object}] options
8
- # @return [Enumerable<Object>]
9
- def self.read_url(url, options = {})
10
- require 'openuri'
11
- open(url.to_s, 'rb', nil, options) { |io| read_all(io, options) }
12
- end
13
-
14
- ##
15
- # Reads all S-expressions from the given input files.
16
- #
17
- # @param [Enumerable<String>] filenames
18
- # @param [Hash{Symbol => Object}] options
19
- # @return [Enumerable<Object>]
20
- def self.read_files(*filenames)
21
- options = filenames.last.is_a?(Hash) ? filenames.pop : {}
22
- filenames.map { |filename| read_file(filename, options) }.inject { |sxps, sxp| sxps + sxp }
23
- end
24
-
25
- ##
26
- # Reads all S-expressions from a given input file.
27
- #
28
- # @param [String, #to_s] filename
29
- # @param [Hash{Symbol => Object}] options
30
- # @return [Enumerable<Object>]
31
- def self.read_file(filename, options = {})
32
- File.open(filename.to_s, 'rb') { |io| read_all(io, options) }
33
- end
34
-
35
- ##
36
- # Reads all S-expressions from the given input stream.
37
- #
38
- # @param [IO, StringIO, String] input
39
- # @param [Hash{Symbol => Object}] options
40
- # @return [Enumerable<Object>]
41
- def self.read_all(input, options = {})
42
- Reader.new(input, options).read_all
43
- end
44
-
45
- ##
46
- # Reads one S-expression from the given input stream.
47
- #
48
- # @param [IO, StringIO, String] input
49
- # @param [Hash{Symbol => Object}] options
50
- # @return [Object]
51
- def self.read(input, options = {})
52
- Reader.new(input, options).read
53
- end
54
-
55
- class << self
56
- alias_method :parse, :read
57
- alias_method :parse_all, :read_all
58
- alias_method :parse_files, :read_files
59
- alias_method :parse_file, :read_file
60
- alias_method :parse_url, :read_url
61
- alias_method :parse_uri, :read_url # @deprecated
62
- alias_method :read_uri, :read_url # @deprecated
63
- end
64
-
3
+ # The base class for S-expression parsers.
65
4
  class Reader
66
5
  include Enumerable
67
6
 
@@ -76,8 +15,12 @@ module SXP
76
15
  RATIONAL = /^([+-]?\d+)\/(\d+)$/
77
16
  ATOM = /^[^\s()\[\]]+/
78
17
 
18
+ # @return [Object]
79
19
  attr_reader :input
80
20
 
21
+ ##
22
+ # @param [Object] input
23
+ # @param [Hash{Symbol => Object}] options
81
24
  def initialize(input, options = {})
82
25
  case
83
26
  when [:getc, :ungetc, :eof?].all? { |x| input.respond_to?(x) }
@@ -90,10 +33,17 @@ module SXP
90
33
  end
91
34
  end
92
35
 
36
+ ##
37
+ # @yield [object]
38
+ # @yieldparam [Object] object
39
+ # @return [Enumerator]
93
40
  def each(&block)
94
- block.call(read)
41
+ block.call(read) if block_given? # FIXME
95
42
  end
96
43
 
44
+ ##
45
+ # @param [Hash{Symbol => Object}] options
46
+ # @return [Array]
97
47
  def read_all(options = {})
98
48
  list = []
99
49
  catch (:eof) do
@@ -102,6 +52,9 @@ module SXP
102
52
  list
103
53
  end
104
54
 
55
+ ##
56
+ # @param [Hash{Symbol => Object}] options
57
+ # @return [Object]
105
58
  def read(options = {})
106
59
  skip_comments
107
60
  token, value = read_token
@@ -122,6 +75,8 @@ module SXP
122
75
 
123
76
  alias_method :skip, :read
124
77
 
78
+ ##
79
+ # @return [Object]
125
80
  def read_token
126
81
  case peek_char
127
82
  when nil then :eof
@@ -133,6 +88,8 @@ module SXP
133
88
  end
134
89
  end
135
90
 
91
+ ##
92
+ # @param [Array]
136
93
  def read_list
137
94
  list = []
138
95
  catch (:eol) do
@@ -141,23 +98,28 @@ module SXP
141
98
  list
142
99
  end
143
100
 
101
+ ##
102
+ # @return [Object]
144
103
  def read_sharp
145
104
  skip_char # '#'
146
105
  case char = read_char
147
- when ?n then nil
148
- when ?f then false
149
- when ?t then true
150
- when ?b then read_integer(2)
151
- when ?o then read_integer(8)
152
- when ?d then read_integer(10)
153
- when ?x then read_integer(16)
106
+ when ?n then nil
107
+ when ?f then false
108
+ when ?t then true
109
+ when ?b then read_integer(2)
110
+ when ?o then read_integer(8)
111
+ when ?d then read_integer(10)
112
+ when ?x then read_integer(16)
154
113
  when ?\\ then read_character
155
- when ?; then skip; read
156
- when ?! then skip_line # shebang
114
+ when ?; then skip; read
115
+ when ?! then skip_line; read # shebang
157
116
  else raise Error, "invalid sharp-sign read syntax: ##{char.chr}"
158
117
  end
159
118
  end
160
119
 
120
+ ##
121
+ # @param [Integer] base
122
+ # @return [Integer]
161
123
  def read_integer(base = 10)
162
124
  case buffer = read_literal
163
125
  when self.class.const_get(:"INTEGER_BASE_#{base}")
@@ -166,6 +128,8 @@ module SXP
166
128
  end
167
129
  end
168
130
 
131
+ ##
132
+ # @return [Object]
169
133
  def read_atom
170
134
  case buffer = read_literal
171
135
  when '.' then buffer.to_sym
@@ -176,6 +140,8 @@ module SXP
176
140
  end
177
141
  end
178
142
 
143
+ ##
144
+ # @return [String]
179
145
  def read_string
180
146
  buffer = String.new
181
147
  skip_char # '"'
@@ -190,6 +156,8 @@ module SXP
190
156
  buffer
191
157
  end
192
158
 
159
+ ##
160
+ # @return [String]
193
161
  def read_character
194
162
  case char = read_char
195
163
  when ?b then ?\b
@@ -203,12 +171,16 @@ module SXP
203
171
  end
204
172
  end
205
173
 
174
+ ##
175
+ # @return [String]
206
176
  def read_literal
207
177
  buffer = String.new
208
178
  buffer << read_char while !eof? && peek_char.chr =~ ATOM
209
179
  buffer
210
180
  end
211
181
 
182
+ ##
183
+ # @return [void]
212
184
  def skip_comments
213
185
  until eof?
214
186
  case (char = peek_char).chr
@@ -219,18 +191,25 @@ module SXP
219
191
  end
220
192
  end
221
193
 
194
+ ##
195
+ # @param [Integer] count
196
+ # @return [String]
222
197
  def read_chars(count = 1)
223
198
  buffer = ''
224
199
  count.times { buffer << read_char.chr }
225
200
  buffer
226
201
  end
227
202
 
203
+ ##
204
+ # @return [String]
228
205
  def read_char
229
206
  char = @input.getc
230
207
  raise EOF, 'unexpected end of input' if char.nil?
231
208
  char
232
209
  end
233
210
 
211
+ ##
212
+ # @return [void]
234
213
  def skip_line
235
214
  loop do
236
215
  break if eof? || read_char.chr == $/
@@ -239,13 +218,18 @@ module SXP
239
218
 
240
219
  alias_method :skip_char, :read_char
241
220
 
221
+ ##
222
+ # @return [String]
242
223
  def peek_char
243
224
  char = @input.getc
244
225
  @input.ungetc char unless char.nil?
245
226
  char
246
227
  end
247
228
 
248
- def eof?() @input.eof? end
249
- end
250
-
251
- end
229
+ ##
230
+ # @return [Boolean]
231
+ def eof?
232
+ @input.eof?
233
+ end
234
+ end # class Reader
235
+ end # module SXP
data/lib/sxp/version.rb CHANGED
@@ -2,7 +2,7 @@ module SXP
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- TINY = 3
5
+ TINY = 4
6
6
  EXTRA = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
data/lib/sxp/writer.rb CHANGED
@@ -1,34 +1,94 @@
1
+ ##
2
+ # Extensions for Ruby's `Object` class.
1
3
  class Object
4
+ ##
5
+ # Returns the SXP representation of this object.
6
+ #
7
+ # @return [String]
2
8
  def to_sxp
3
9
  to_s.to_json
4
10
  end
5
11
  end
6
12
 
13
+ ##
14
+ # Extensions for Ruby's `NilClass` class.
7
15
  class NilClass
8
- def to_sxp; '#n'; end
16
+ ##
17
+ # Returns the SXP representation of this object.
18
+ #
19
+ # @return [String]
20
+ def to_sxp
21
+ '#n'
22
+ end
9
23
  end
10
24
 
25
+ ##
26
+ # Extensions for Ruby's `FalseClass` class.
11
27
  class FalseClass
12
- def to_sxp; '#f'; end
28
+ ##
29
+ # Returns the SXP representation of this object.
30
+ #
31
+ # @return [String]
32
+ def to_sxp
33
+ '#f'
34
+ end
13
35
  end
14
36
 
37
+ ##
38
+ # Extensions for Ruby's `TrueClass` class.
15
39
  class TrueClass
16
- def to_sxp; '#t'; end
40
+ ##
41
+ # Returns the SXP representation of this object.
42
+ #
43
+ # @return [String]
44
+ def to_sxp
45
+ '#t'
46
+ end
17
47
  end
18
48
 
49
+ ##
50
+ # Extensions for Ruby's `String` class.
19
51
  class String
20
- def to_sxp; inspect; end
52
+ ##
53
+ # Returns the SXP representation of this object.
54
+ #
55
+ # @return [String]
56
+ def to_sxp
57
+ inspect
58
+ end
21
59
  end
22
60
 
61
+ ##
62
+ # Extensions for Ruby's `Symbol` class.
23
63
  class Symbol
24
- def to_sxp; to_s; end
64
+ ##
65
+ # Returns the SXP representation of this object.
66
+ #
67
+ # @return [String]
68
+ def to_sxp
69
+ to_s
70
+ end
25
71
  end
26
72
 
73
+ ##
74
+ # Extensions for Ruby's `Integer` class.
27
75
  class Integer
28
- def to_sxp; to_s; end
76
+ ##
77
+ # Returns the SXP representation of this object.
78
+ #
79
+ # @return [String]
80
+ def to_sxp
81
+ to_s
82
+ end
29
83
  end
30
84
 
85
+ ##
86
+ # Extensions for Ruby's `Float` class.
31
87
  class Float
88
+ ##
89
+ # Returns the SXP representation of this object.
90
+ #
91
+ # @return [String]
32
92
  def to_sxp
33
93
  case
34
94
  when nan? then 'nan.'
@@ -38,19 +98,37 @@ class Float
38
98
  end
39
99
  end
40
100
 
101
+ ##
102
+ # Extensions for Ruby's `Array` class.
41
103
  class Array
104
+ ##
105
+ # Returns the SXP representation of this object.
106
+ #
107
+ # @return [String]
42
108
  def to_sxp
43
109
  '(' << map { |x| x.to_sxp }.join(' ') << ')'
44
110
  end
45
111
  end
46
112
 
113
+ ##
114
+ # Extensions for Ruby's `Time` class.
47
115
  class Time
116
+ ##
117
+ # Returns the SXP representation of this object.
118
+ #
119
+ # @return [String]
48
120
  def to_sxp
49
121
  '#@' << (respond_to?(:xmlschema) ? xmlschema : to_i).to_s
50
122
  end
51
123
  end
52
124
 
125
+ ##
126
+ # Extensions for Ruby's `Regexp` class.
53
127
  class Regexp
128
+ ##
129
+ # Returns the SXP representation of this object.
130
+ #
131
+ # @return [String]
54
132
  def to_sxp
55
133
  '#' << inspect
56
134
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Arto Bendiken
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-14 00:00:00 +02:00
17
+ date: 2010-05-25 00:00:00 +02:00
18
18
  default_executable: sxp2rdf
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency