cast 0.0.1 → 0.3.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/CHANGELOG +63 -0
- data/Gemfile +9 -0
- data/LICENSE +22 -0
- data/README.markdown +1924 -0
- data/Rakefile +29 -0
- data/cast.gemspec +18 -0
- data/ext/cast.c +6 -0
- data/ext/cast.h +141 -0
- data/ext/extconf.rb +2 -0
- data/ext/parser.c +287 -0
- data/ext/yylex.re +340 -0
- data/lib/cast.rb +11 -9
- data/lib/cast/c.y +904 -0
- data/lib/{c_nodes.rb → cast/c_nodes.rb} +188 -392
- data/lib/{to_debug.rb → cast/inspect.rb} +18 -20
- data/lib/cast/node.rb +741 -0
- data/lib/{node_list.rb → cast/node_list.rb} +175 -176
- data/lib/{parse.rb → cast/parse.rb} +86 -65
- data/lib/cast/preprocessor.rb +59 -0
- data/lib/cast/tempfile.rb +33 -0
- data/lib/{to_s.rb → cast/to_s.rb} +133 -80
- data/lib/cast/version.rb +11 -0
- data/test/c_nodes_test.rb +224 -0
- data/test/lexer_test.rb +335 -0
- data/test/{test_node_list.rb → node_list_test.rb} +401 -413
- data/test/{test_node.rb → node_test.rb} +186 -214
- data/test/parse_test.rb +2068 -0
- data/test/{test_parser.rb → parser_test.rb} +145 -58
- data/test/preprocessor_test.rb +85 -0
- data/test/render_test.rb +2116 -0
- data/test/test_helper.rb +198 -0
- metadata +83 -52
- data/README +0 -6
- data/doc/index.html +0 -2513
- data/install.rb +0 -14
- data/lib/c.tab.rb +0 -3433
- data/lib/c.y +0 -935
- data/lib/node.rb +0 -744
- data/test/common.rb +0 -174
- data/test/run.rb +0 -5
- data/test/test_c_nodes.rb +0 -160
- data/test/test_parse.rb +0 -2014
@@ -1,29 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
### ##################################################################
|
7
|
-
###
|
1
|
+
######################################################################
|
2
|
+
#
|
3
|
+
# NodeList and subclasses.
|
4
|
+
#
|
5
|
+
######################################################################
|
8
6
|
|
9
7
|
module C
|
10
|
-
|
11
|
-
|
8
|
+
# Declare all the classes, so we don't have to declare the
|
9
|
+
# inheritances later.
|
12
10
|
class NodeList < Node; abstract; end
|
13
11
|
class NodeArray < NodeList; end
|
14
12
|
class NodeChain < NodeList; end
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
### NodeList
|
20
|
-
###
|
21
|
-
### Abstract base class of the Node list classes.
|
22
|
-
###
|
23
|
-
### ================================================================
|
24
|
-
###
|
14
|
+
#
|
15
|
+
# Abstract base class of the Node list classes.
|
16
|
+
#
|
25
17
|
class NodeList
|
26
|
-
def self.[]
|
18
|
+
def self.[](*args)
|
27
19
|
new.concat(args)
|
28
20
|
end
|
29
21
|
|
@@ -32,11 +24,11 @@ module C
|
|
32
24
|
length
|
33
25
|
end
|
34
26
|
|
35
|
-
def ==
|
27
|
+
def ==(other)
|
36
28
|
return false if !other.is_a? C::NodeList
|
37
29
|
|
38
|
-
|
39
|
-
|
30
|
+
# none of the NodeList classes here have fields, but there's no
|
31
|
+
# reason why one can't subclass one to have fields
|
40
32
|
fields.each do |field|
|
41
33
|
mine = self .send(field.reader)
|
42
34
|
yours = other.send(field.reader)
|
@@ -69,23 +61,23 @@ module C
|
|
69
61
|
|
70
62
|
protected # -----------------------------------------------------
|
71
63
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
def parse_index
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
64
|
+
#
|
65
|
+
# Return `[i, n, splat?]', where if `args' is used as an index to
|
66
|
+
# ::Array#[]=, it is equivalent to calling:
|
67
|
+
#
|
68
|
+
# val = args.pop
|
69
|
+
# if splat?
|
70
|
+
# array[i, n] = *val
|
71
|
+
# else
|
72
|
+
# array[i, n] = val
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
def parse_index(*args)
|
76
|
+
# what we must do:
|
77
|
+
#
|
78
|
+
# -- move numbers into range 0..length-1
|
79
|
+
# -- i..j --> i...j+1
|
80
|
+
# -- i...j --> i, j-i
|
89
81
|
case args.length
|
90
82
|
when 1
|
91
83
|
arg = args.first
|
@@ -110,24 +102,24 @@ module C
|
|
110
102
|
end
|
111
103
|
end
|
112
104
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
def wrap_index
|
105
|
+
#
|
106
|
+
# Wrap the given index if less than 0, and return it.
|
107
|
+
#
|
108
|
+
def wrap_index(i)
|
117
109
|
i < 0 ? (i + length) : i
|
118
110
|
end
|
119
111
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
def add_prep
|
112
|
+
#
|
113
|
+
# Prepare the given nodes for addition. This means:
|
114
|
+
# -- clone any attached nodes as necessary
|
115
|
+
# -- set the nodes' parents to self.
|
116
|
+
#
|
117
|
+
# `oldnodes' are the nodes that will be replaced. These aren't
|
118
|
+
# cloned the first time they appear in `nodes'.
|
119
|
+
#
|
120
|
+
# Return the list of nodes to add.
|
121
|
+
#
|
122
|
+
def add_prep(nodes, oldnodes=nil)
|
131
123
|
if oldnodes
|
132
124
|
oldnodes = oldnodes.map{|n| n.object_id}
|
133
125
|
nodes.map! do |node|
|
@@ -147,16 +139,16 @@ module C
|
|
147
139
|
return nodes
|
148
140
|
end
|
149
141
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
def set_parent
|
142
|
+
#
|
143
|
+
# Set the parent of `node' to `val'.
|
144
|
+
#
|
145
|
+
def set_parent(node, val)
|
154
146
|
node.send(:parent=, val)
|
155
147
|
end
|
156
148
|
end
|
157
149
|
|
158
150
|
class NodeArray
|
159
|
-
def assert_invariants
|
151
|
+
def assert_invariants(testcase)
|
160
152
|
super
|
161
153
|
testcase.assert_same(::Array, @array)
|
162
154
|
@array.each_with_index do |node, i|
|
@@ -185,7 +177,7 @@ module C
|
|
185
177
|
end
|
186
178
|
|
187
179
|
class NodeChain
|
188
|
-
def assert_invariants
|
180
|
+
def assert_invariants(testcase)
|
189
181
|
super
|
190
182
|
assert_same(@length.zero?, @first.nil?)
|
191
183
|
assert_same(@length.zero?, @last.nil?)
|
@@ -238,56 +230,54 @@ module C
|
|
238
230
|
end
|
239
231
|
end
|
240
232
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
### ----------------------------------------------------------------
|
245
|
-
###
|
233
|
+
# ------------------------------------------------------------------
|
234
|
+
# Methods called from children
|
235
|
+
# ------------------------------------------------------------------
|
246
236
|
|
247
237
|
class NodeArray
|
248
|
-
def node_after
|
238
|
+
def node_after(node)
|
249
239
|
node.parent.equal? self or
|
250
240
|
raise ArgumentError, "node is not a child"
|
251
|
-
@array[
|
241
|
+
@array[node.instance_variable_get(:@parent_index) + 1]
|
252
242
|
end
|
253
243
|
|
254
|
-
def node_before
|
244
|
+
def node_before(node)
|
255
245
|
node.parent.equal? self or
|
256
246
|
raise ArgumentError, "node is not a child"
|
257
247
|
index = node.instance_variable_get(:@parent_index)
|
258
248
|
if index.zero?
|
259
249
|
return nil
|
260
250
|
else
|
261
|
-
return @array[index-1]
|
251
|
+
return @array[index - 1]
|
262
252
|
end
|
263
253
|
end
|
264
254
|
|
265
|
-
def remove_node
|
255
|
+
def remove_node(node)
|
266
256
|
node.parent.equal? self or
|
267
257
|
raise ArgumentError, "node is not a child"
|
268
258
|
index = node.instance_variable_get(:@parent_index)
|
269
|
-
|
259
|
+
node.instance_variable_set(:@parent_index, nil)
|
270
260
|
removed_(@array[index])
|
271
261
|
@array.delete_at(index)
|
272
262
|
adjust_indices_(index)
|
273
263
|
return self
|
274
264
|
end
|
275
265
|
|
276
|
-
def insert_after
|
266
|
+
def insert_after(node, *newnodes)
|
277
267
|
node.parent.equal? self or
|
278
268
|
raise ArgumentError, "node is not a child"
|
279
269
|
index = node.instance_variable_get(:@parent_index) + 1
|
280
270
|
insert(index, *newnodes)
|
281
271
|
return self
|
282
272
|
end
|
283
|
-
def insert_before
|
273
|
+
def insert_before(node, *newnodes)
|
284
274
|
node.parent.equal? self or
|
285
275
|
raise ArgumentError, "node is not a child"
|
286
276
|
index = node.instance_variable_get(:@parent_index)
|
287
277
|
insert(index, *newnodes)
|
288
278
|
return self
|
289
279
|
end
|
290
|
-
def replace_node
|
280
|
+
def replace_node(oldnode, *newnodes)
|
291
281
|
oldnode.parent.equal? self or
|
292
282
|
raise ArgumentError, "node is not a child"
|
293
283
|
index = oldnode.instance_variable_get(:@parent_index)
|
@@ -297,27 +287,27 @@ module C
|
|
297
287
|
|
298
288
|
private
|
299
289
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
def adjust_indices_
|
290
|
+
#
|
291
|
+
# Adjust the indices of all elements from index `from_i' to the
|
292
|
+
# end.
|
293
|
+
#
|
294
|
+
def adjust_indices_(from_i)
|
305
295
|
(from_i...@array.length).each do |i|
|
306
296
|
@array[i].instance_variable_set(:@parent_index, i)
|
307
297
|
end
|
308
298
|
end
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
def added_
|
299
|
+
#
|
300
|
+
# Called when something was added.
|
301
|
+
#
|
302
|
+
def added_(*nodes)
|
313
303
|
nodes.each do |n|
|
314
304
|
n.instance_variable_set(:@parent, self)
|
315
305
|
end
|
316
306
|
end
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
def removed_
|
307
|
+
#
|
308
|
+
# Called when something was removed.
|
309
|
+
#
|
310
|
+
def removed_(*nodes)
|
321
311
|
nodes.each do |n|
|
322
312
|
n.instance_variable_set(:@parent, nil)
|
323
313
|
end
|
@@ -325,17 +315,17 @@ module C
|
|
325
315
|
end
|
326
316
|
|
327
317
|
class NodeChain
|
328
|
-
def node_after
|
318
|
+
def node_after(node)
|
329
319
|
node.parent.equal? self or
|
330
320
|
raise ArgumentError, "node is not a child"
|
331
321
|
return node.instance_variable_get(:@next)
|
332
322
|
end
|
333
|
-
def node_before
|
323
|
+
def node_before(node)
|
334
324
|
node.parent.equal? self or
|
335
325
|
raise ArgumentError, "node is not a child"
|
336
326
|
return node.instance_variable_get(:@prev)
|
337
327
|
end
|
338
|
-
def remove_node
|
328
|
+
def remove_node(node)
|
339
329
|
node.parent.equal? self or
|
340
330
|
raise ArgumentError, "node is not a child"
|
341
331
|
node_prev = node.instance_variable_get(:@prev)
|
@@ -344,7 +334,7 @@ module C
|
|
344
334
|
link2_(node_prev, node_next)
|
345
335
|
return self
|
346
336
|
end
|
347
|
-
def insert_after
|
337
|
+
def insert_after(node, *newnodes)
|
348
338
|
node.parent.equal? self or
|
349
339
|
raise ArgumentError, "node is not a child"
|
350
340
|
newnodes = add_prep(newnodes)
|
@@ -353,7 +343,7 @@ module C
|
|
353
343
|
added_(*newnodes)
|
354
344
|
return self
|
355
345
|
end
|
356
|
-
def insert_before
|
346
|
+
def insert_before(node, *newnodes)
|
357
347
|
node.parent.equal? self or
|
358
348
|
raise ArgumentError, "node is not a child"
|
359
349
|
newnodes = add_prep(newnodes)
|
@@ -362,7 +352,7 @@ module C
|
|
362
352
|
added_(*newnodes)
|
363
353
|
return self
|
364
354
|
end
|
365
|
-
def replace_node
|
355
|
+
def replace_node(oldnode, *newnodes)
|
366
356
|
oldnode.parent.equal? self or
|
367
357
|
raise ArgumentError, "node is not a child"
|
368
358
|
newnodes = add_prep(newnodes, [oldnode])
|
@@ -373,27 +363,25 @@ module C
|
|
373
363
|
added_(*newnodes)
|
374
364
|
return self
|
375
365
|
end
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
def added_
|
366
|
+
#
|
367
|
+
# Called when something was added.
|
368
|
+
#
|
369
|
+
def added_(*newnodes)
|
380
370
|
newnodes.each{|n| n.instance_variable_set(:@parent, self)}
|
381
371
|
@length += newnodes.length
|
382
372
|
end
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
def removed_
|
373
|
+
#
|
374
|
+
# Called when something was removed.
|
375
|
+
#
|
376
|
+
def removed_(*nodes)
|
387
377
|
nodes.each{|n| n.instance_variable_set(:@parent, nil)}
|
388
378
|
@length -= nodes.length
|
389
379
|
end
|
390
380
|
end
|
391
381
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
### ----------------------------------------------------------------
|
396
|
-
###
|
382
|
+
# ------------------------------------------------------------------
|
383
|
+
# Array methods
|
384
|
+
# ------------------------------------------------------------------
|
397
385
|
|
398
386
|
class NodeArray
|
399
387
|
%w[
|
@@ -408,8 +396,8 @@ module C
|
|
408
396
|
join
|
409
397
|
].each do |m|
|
410
398
|
eval "
|
411
|
-
def #{m}
|
412
|
-
@array.#{m}
|
399
|
+
def #{m}(*args, &blk)
|
400
|
+
@array.#{m}(*args, &blk)
|
413
401
|
end
|
414
402
|
"
|
415
403
|
end
|
@@ -420,8 +408,8 @@ module C
|
|
420
408
|
each_index
|
421
409
|
].each do |m|
|
422
410
|
eval "
|
423
|
-
def #{m}
|
424
|
-
@array.#{m}
|
411
|
+
def #{m}(*args, &blk)
|
412
|
+
@array.#{m}(*args, &blk)
|
425
413
|
return self
|
426
414
|
end
|
427
415
|
"
|
@@ -430,7 +418,7 @@ module C
|
|
430
418
|
def to_a
|
431
419
|
@array.dup
|
432
420
|
end
|
433
|
-
def push
|
421
|
+
def push(*nodes)
|
434
422
|
nodes = add_prep(nodes)
|
435
423
|
i = @array.length
|
436
424
|
@array.push(*nodes)
|
@@ -438,36 +426,44 @@ module C
|
|
438
426
|
adjust_indices_(i)
|
439
427
|
return self
|
440
428
|
end
|
441
|
-
def unshift
|
429
|
+
def unshift(*nodes)
|
442
430
|
nodes = add_prep(nodes)
|
443
431
|
@array.unshift(*nodes)
|
444
432
|
added_(*nodes)
|
445
433
|
adjust_indices_(0)
|
446
434
|
return self
|
447
435
|
end
|
448
|
-
def pop
|
436
|
+
def pop(*args)
|
449
437
|
if args.empty?
|
450
|
-
ret = @array.pop
|
451
|
-
|
438
|
+
ret = @array.pop and
|
439
|
+
removed_(ret)
|
452
440
|
return ret
|
453
441
|
else
|
454
|
-
|
455
|
-
|
442
|
+
args.length == 1 or
|
443
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for 0..1)"
|
444
|
+
arg = args[0]
|
445
|
+
arg = @array.length if @array.length < arg
|
446
|
+
ret = @array.slice!(-arg, arg)
|
447
|
+
removed_(*ret)
|
456
448
|
return ret
|
457
449
|
end
|
458
450
|
end
|
459
|
-
def shift
|
451
|
+
def shift(*args)
|
460
452
|
if args.empty?
|
461
|
-
ret = @array.shift
|
462
|
-
|
453
|
+
ret = @array.shift and
|
454
|
+
removed_ ret
|
463
455
|
else
|
464
|
-
|
465
|
-
|
456
|
+
args.length == 1 or
|
457
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for 0..1)"
|
458
|
+
arg = args[0]
|
459
|
+
arg = @array.length if @array.length < arg
|
460
|
+
ret = @array.slice!(0, arg)
|
461
|
+
removed_(*ret)
|
466
462
|
end
|
467
|
-
adjust_indices_(0)
|
463
|
+
adjust_indices_(0) unless ret.nil?
|
468
464
|
return ret
|
469
465
|
end
|
470
|
-
def insert
|
466
|
+
def insert(i, *newnodes)
|
471
467
|
(0..@array.length).include? i or
|
472
468
|
raise IndexError, "index #{i} out of NodeList (length #{@array.length})"
|
473
469
|
newnodes = add_prep(newnodes)
|
@@ -476,14 +472,14 @@ module C
|
|
476
472
|
adjust_indices_(i)
|
477
473
|
return self
|
478
474
|
end
|
479
|
-
def <<
|
480
|
-
newnode = *add_prep([newnode])
|
475
|
+
def <<(newnode)
|
476
|
+
newnode, = *add_prep([newnode])
|
481
477
|
@array << newnode
|
482
478
|
added_(newnode)
|
483
479
|
adjust_indices_(@array.length - 1)
|
484
480
|
return self
|
485
481
|
end
|
486
|
-
def []=
|
482
|
+
def []=(*args)
|
487
483
|
newnodes = args.pop
|
488
484
|
i, n, splat = parse_index(*args)
|
489
485
|
oldnodes = @array[i, n] or
|
@@ -491,7 +487,7 @@ module C
|
|
491
487
|
if splat
|
492
488
|
newnodes = add_prep(newnodes, oldnodes)
|
493
489
|
else
|
494
|
-
|
490
|
+
# newnodes is a single node (not an Array)
|
495
491
|
newnodes = add_prep([newnodes], [oldnodes])
|
496
492
|
end
|
497
493
|
@array[i, n] = newnodes
|
@@ -505,7 +501,7 @@ module C
|
|
505
501
|
adjust_indices_(i)
|
506
502
|
return newnodes
|
507
503
|
end
|
508
|
-
def concat
|
504
|
+
def concat(other)
|
509
505
|
other = other.to_a
|
510
506
|
other = add_prep(other)
|
511
507
|
len = @array.length
|
@@ -514,7 +510,7 @@ module C
|
|
514
510
|
adjust_indices_(len)
|
515
511
|
return self
|
516
512
|
end
|
517
|
-
def delete_at
|
513
|
+
def delete_at(index)
|
518
514
|
if index < @array.length
|
519
515
|
ret = @array.delete_at(index)
|
520
516
|
removed_(ret)
|
@@ -530,7 +526,7 @@ module C
|
|
530
526
|
removed_(*nodes)
|
531
527
|
return self
|
532
528
|
end
|
533
|
-
def replace
|
529
|
+
def replace(other)
|
534
530
|
other = other.to_a
|
535
531
|
other = add_prep(other)
|
536
532
|
oldnodes = @array.dup
|
@@ -543,10 +539,10 @@ module C
|
|
543
539
|
end
|
544
540
|
|
545
541
|
class NodeChain
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
def first
|
542
|
+
#
|
543
|
+
# const methods
|
544
|
+
#
|
545
|
+
def first(n=nil)
|
550
546
|
if n.nil?
|
551
547
|
return @first
|
552
548
|
else
|
@@ -560,7 +556,7 @@ module C
|
|
560
556
|
return ret
|
561
557
|
end
|
562
558
|
end
|
563
|
-
def last
|
559
|
+
def last(n=nil)
|
564
560
|
if n.nil?
|
565
561
|
return @last
|
566
562
|
else
|
@@ -602,12 +598,12 @@ module C
|
|
602
598
|
end
|
603
599
|
return ret
|
604
600
|
end
|
605
|
-
def []
|
601
|
+
def [](*args)
|
606
602
|
i, n, splat = parse_index(*args)
|
607
603
|
return nil if i >= @length
|
608
604
|
node = get_(i)
|
609
605
|
if splat
|
610
|
-
|
606
|
+
# return an array of Nodes
|
611
607
|
n = length-i if n > length-i
|
612
608
|
ret = ::Array.new(n) do
|
613
609
|
r = node
|
@@ -616,7 +612,7 @@ module C
|
|
616
612
|
end
|
617
613
|
return ret
|
618
614
|
else
|
619
|
-
|
615
|
+
# return a Node
|
620
616
|
return node
|
621
617
|
end
|
622
618
|
end
|
@@ -627,7 +623,7 @@ module C
|
|
627
623
|
def empty?
|
628
624
|
@length.zero?
|
629
625
|
end
|
630
|
-
def index
|
626
|
+
def index(node)
|
631
627
|
curr = @first
|
632
628
|
i = 0
|
633
629
|
while curr
|
@@ -637,7 +633,7 @@ module C
|
|
637
633
|
end
|
638
634
|
return nil
|
639
635
|
end
|
640
|
-
def rindex
|
636
|
+
def rindex(node)
|
641
637
|
curr = @last
|
642
638
|
i = @length - 1
|
643
639
|
while curr
|
@@ -647,34 +643,34 @@ module C
|
|
647
643
|
end
|
648
644
|
return nil
|
649
645
|
end
|
650
|
-
def values_at
|
646
|
+
def values_at(*args)
|
651
647
|
args.map!{|i| self[i]}
|
652
648
|
end
|
653
|
-
def join
|
649
|
+
def join(*args)
|
654
650
|
self.to_a.join(*args)
|
655
651
|
end
|
656
652
|
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
def push
|
653
|
+
#
|
654
|
+
# non-const methods
|
655
|
+
#
|
656
|
+
def push(*newnodes)
|
661
657
|
newnodes = add_prep(newnodes)
|
662
658
|
added_(*newnodes)
|
663
659
|
link_(@last, newnodes, nil)
|
664
660
|
return self
|
665
661
|
end
|
666
|
-
def <<
|
662
|
+
def <<(newnode)
|
667
663
|
return push(newnode)
|
668
664
|
end
|
669
|
-
def unshift
|
665
|
+
def unshift(*newnodes)
|
670
666
|
newnodes = add_prep(newnodes)
|
671
667
|
added_(*newnodes)
|
672
668
|
link_(nil, newnodes, @first)
|
673
669
|
return self
|
674
670
|
end
|
675
|
-
def pop
|
671
|
+
def pop(n=nil)
|
676
672
|
if n
|
677
|
-
|
673
|
+
# return an Array of Nodes
|
678
674
|
ret = last(n)
|
679
675
|
return ret if ret.empty?
|
680
676
|
link2_(ret.first.instance_variable_get(:@prev), nil)
|
@@ -682,16 +678,16 @@ module C
|
|
682
678
|
return ret
|
683
679
|
else
|
684
680
|
return nil if empty?
|
685
|
-
|
681
|
+
# return a Node
|
686
682
|
ret = @last
|
687
683
|
link2_(@last.instance_variable_get(:@prev), nil)
|
688
684
|
removed_(ret)
|
689
685
|
return ret
|
690
686
|
end
|
691
687
|
end
|
692
|
-
def shift
|
688
|
+
def shift(n=nil)
|
693
689
|
if n
|
694
|
-
|
690
|
+
# return an Array of Nodes
|
695
691
|
ret = first(n)
|
696
692
|
return ret if ret.empty?
|
697
693
|
link2_(nil, ret.last.instance_variable_get(:@next))
|
@@ -699,14 +695,14 @@ module C
|
|
699
695
|
return ret
|
700
696
|
else
|
701
697
|
return nil if empty?
|
702
|
-
|
698
|
+
# return a Node
|
703
699
|
ret = @first
|
704
700
|
link2_(nil, @first.instance_variable_get(:@next))
|
705
701
|
removed_(ret)
|
706
702
|
return ret
|
707
703
|
end
|
708
704
|
end
|
709
|
-
def insert
|
705
|
+
def insert(i, *newnodes)
|
710
706
|
(0..@length).include? i or
|
711
707
|
raise IndexError, "index #{i} out of NodeList"
|
712
708
|
if i == @length
|
@@ -715,7 +711,7 @@ module C
|
|
715
711
|
insert_before(self[i], *newnodes)
|
716
712
|
end
|
717
713
|
end
|
718
|
-
def []=
|
714
|
+
def []=(*args)
|
719
715
|
newnodes = args.pop
|
720
716
|
i, n, splat = parse_index(*args)
|
721
717
|
oldnodes = self[i, n] or
|
@@ -742,10 +738,10 @@ module C
|
|
742
738
|
end
|
743
739
|
return newnodes
|
744
740
|
end
|
745
|
-
def concat
|
741
|
+
def concat(other)
|
746
742
|
return push(*other.to_a)
|
747
743
|
end
|
748
|
-
def delete_at
|
744
|
+
def delete_at(index)
|
749
745
|
node = self[index]
|
750
746
|
remove_node(node)
|
751
747
|
return node
|
@@ -756,15 +752,15 @@ module C
|
|
756
752
|
@length = 0
|
757
753
|
return self
|
758
754
|
end
|
759
|
-
def replace
|
755
|
+
def replace(other)
|
760
756
|
return clear.push(*other.to_a)
|
761
757
|
end
|
762
758
|
|
763
759
|
private
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
def link_
|
760
|
+
#
|
761
|
+
# Link up `nodes' between `a' and `b'.
|
762
|
+
#
|
763
|
+
def link_(a, nodes, b)
|
768
764
|
if nodes.empty?
|
769
765
|
if a.nil?
|
770
766
|
@first = b
|
@@ -777,7 +773,7 @@ module C
|
|
777
773
|
b.instance_variable_set(:@prev, a)
|
778
774
|
end
|
779
775
|
else
|
780
|
-
|
776
|
+
# connect `a' and `b'
|
781
777
|
first = nodes.first
|
782
778
|
if a.nil?
|
783
779
|
@first = first
|
@@ -790,8 +786,8 @@ module C
|
|
790
786
|
else
|
791
787
|
b.instance_variable_set(:@prev, last)
|
792
788
|
end
|
793
|
-
|
794
|
-
|
789
|
+
|
790
|
+
# connect `nodes'
|
795
791
|
if nodes.length == 1
|
796
792
|
node = nodes[0]
|
797
793
|
node.instance_variable_set(:@prev, a)
|
@@ -809,8 +805,10 @@ module C
|
|
809
805
|
end
|
810
806
|
end
|
811
807
|
end
|
812
|
-
|
813
|
-
|
808
|
+
#
|
809
|
+
# Special case for 2
|
810
|
+
#
|
811
|
+
def link2_(a, b)
|
814
812
|
if a.nil?
|
815
813
|
@first = b
|
816
814
|
else
|
@@ -822,17 +820,18 @@ module C
|
|
822
820
|
b.instance_variable_set(:@prev, a) unless b.nil?
|
823
821
|
end
|
824
822
|
end
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
823
|
+
|
824
|
+
#
|
825
|
+
# Return the `i'th Node. Assume `i' is in 0...length.
|
826
|
+
#
|
827
|
+
def get_(i)
|
828
|
+
# return a Node
|
830
829
|
if i < (@length >> 1)
|
831
|
-
|
830
|
+
# go from the beginning
|
832
831
|
node = @first
|
833
832
|
i.times{node = node.next}
|
834
833
|
else
|
835
|
-
|
834
|
+
# go from the end
|
836
835
|
node = @last
|
837
836
|
(@length - 1 - i).times{node = node.prev}
|
838
837
|
end
|