cast 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/CHANGELOG +50 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.markdown +1948 -0
- data/Rakefile +22 -0
- data/cast.gemspec +20 -0
- data/ext/cast.c +6 -0
- data/ext/extconf.rb +1 -1
- data/ext/parser.c +2 -2
- data/ext/yylex.c +2592 -4171
- data/ext/yylex.re +20 -26
- data/lib/cast.rb +11 -16
- data/lib/cast/c.tab.rb +2252 -2231
- data/lib/cast/c.y +185 -161
- data/lib/cast/c_nodes.rb +181 -391
- data/lib/cast/inspect.rb +8 -10
- data/lib/cast/node.rb +362 -365
- data/lib/cast/node_list.rb +156 -165
- data/lib/cast/parse.rb +86 -65
- data/lib/cast/preprocessor.rb +72 -0
- data/lib/cast/tempfile.rb +33 -0
- data/lib/cast/to_s.rb +83 -75
- data/lib/cast/version.rb +11 -0
- data/test/all.rb +5 -0
- data/test/{test_c_nodes.rb → c_nodes_test.rb} +91 -23
- data/test/lexer_test.rb +323 -0
- data/test/{test_node_list.rb → node_list_test.rb} +367 -396
- data/test/{test_node.rb → node_test.rb} +142 -160
- data/test/{test_parse.rb → parse_test.rb} +63 -17
- data/test/{test_parser.rb → parser_test.rb} +62 -22
- data/test/preprocessor_test.rb +87 -0
- data/test/render_test.rb +2086 -0
- data/test/{run.rb → test_helper.rb} +76 -88
- metadata +100 -54
- data/README +0 -6
- data/doc/index.html +0 -2505
- data/ext/cast_ext.c +0 -10
data/lib/cast/node_list.rb
CHANGED
@@ -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,20 +230,18 @@ 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
241
|
@array[index = 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)
|
@@ -262,7 +252,7 @@ module C
|
|
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)
|
@@ -273,21 +263,21 @@ module C
|
|
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,14 +426,14 @@ 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
438
|
ret = @array.pop
|
451
439
|
removed_(ret)
|
@@ -456,11 +444,11 @@ module C
|
|
456
444
|
arg = args[0]
|
457
445
|
arg = @array.length if @array.length < arg
|
458
446
|
ret = @array.slice!(-arg, arg)
|
459
|
-
removed_
|
447
|
+
removed_(*ret)
|
460
448
|
return ret
|
461
449
|
end
|
462
450
|
end
|
463
|
-
def shift
|
451
|
+
def shift(*args)
|
464
452
|
if args.empty?
|
465
453
|
ret = @array.shift
|
466
454
|
removed_ ret
|
@@ -470,12 +458,12 @@ module C
|
|
470
458
|
arg = args[0]
|
471
459
|
arg = @array.length if @array.length < arg
|
472
460
|
ret = @array.slice!(0, arg)
|
473
|
-
removed_
|
461
|
+
removed_(*ret)
|
474
462
|
end
|
475
463
|
adjust_indices_(0)
|
476
464
|
return ret
|
477
465
|
end
|
478
|
-
def insert
|
466
|
+
def insert(i, *newnodes)
|
479
467
|
(0..@array.length).include? i or
|
480
468
|
raise IndexError, "index #{i} out of NodeList (length #{@array.length})"
|
481
469
|
newnodes = add_prep(newnodes)
|
@@ -484,14 +472,14 @@ module C
|
|
484
472
|
adjust_indices_(i)
|
485
473
|
return self
|
486
474
|
end
|
487
|
-
def <<
|
488
|
-
newnode = *add_prep([newnode])
|
475
|
+
def <<(newnode)
|
476
|
+
newnode, = *add_prep([newnode])
|
489
477
|
@array << newnode
|
490
478
|
added_(newnode)
|
491
479
|
adjust_indices_(@array.length - 1)
|
492
480
|
return self
|
493
481
|
end
|
494
|
-
def []=
|
482
|
+
def []=(*args)
|
495
483
|
newnodes = args.pop
|
496
484
|
i, n, splat = parse_index(*args)
|
497
485
|
oldnodes = @array[i, n] or
|
@@ -499,7 +487,7 @@ module C
|
|
499
487
|
if splat
|
500
488
|
newnodes = add_prep(newnodes, oldnodes)
|
501
489
|
else
|
502
|
-
|
490
|
+
# newnodes is a single node (not an Array)
|
503
491
|
newnodes = add_prep([newnodes], [oldnodes])
|
504
492
|
end
|
505
493
|
@array[i, n] = newnodes
|
@@ -513,7 +501,7 @@ module C
|
|
513
501
|
adjust_indices_(i)
|
514
502
|
return newnodes
|
515
503
|
end
|
516
|
-
def concat
|
504
|
+
def concat(other)
|
517
505
|
other = other.to_a
|
518
506
|
other = add_prep(other)
|
519
507
|
len = @array.length
|
@@ -522,7 +510,7 @@ module C
|
|
522
510
|
adjust_indices_(len)
|
523
511
|
return self
|
524
512
|
end
|
525
|
-
def delete_at
|
513
|
+
def delete_at(index)
|
526
514
|
if index < @array.length
|
527
515
|
ret = @array.delete_at(index)
|
528
516
|
removed_(ret)
|
@@ -538,7 +526,7 @@ module C
|
|
538
526
|
removed_(*nodes)
|
539
527
|
return self
|
540
528
|
end
|
541
|
-
def replace
|
529
|
+
def replace(other)
|
542
530
|
other = other.to_a
|
543
531
|
other = add_prep(other)
|
544
532
|
oldnodes = @array.dup
|
@@ -551,10 +539,10 @@ module C
|
|
551
539
|
end
|
552
540
|
|
553
541
|
class NodeChain
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
def first
|
542
|
+
#
|
543
|
+
# const methods
|
544
|
+
#
|
545
|
+
def first(n=nil)
|
558
546
|
if n.nil?
|
559
547
|
return @first
|
560
548
|
else
|
@@ -568,7 +556,7 @@ module C
|
|
568
556
|
return ret
|
569
557
|
end
|
570
558
|
end
|
571
|
-
def last
|
559
|
+
def last(n=nil)
|
572
560
|
if n.nil?
|
573
561
|
return @last
|
574
562
|
else
|
@@ -610,12 +598,12 @@ module C
|
|
610
598
|
end
|
611
599
|
return ret
|
612
600
|
end
|
613
|
-
def []
|
601
|
+
def [](*args)
|
614
602
|
i, n, splat = parse_index(*args)
|
615
603
|
return nil if i >= @length
|
616
604
|
node = get_(i)
|
617
605
|
if splat
|
618
|
-
|
606
|
+
# return an array of Nodes
|
619
607
|
n = length-i if n > length-i
|
620
608
|
ret = ::Array.new(n) do
|
621
609
|
r = node
|
@@ -624,7 +612,7 @@ module C
|
|
624
612
|
end
|
625
613
|
return ret
|
626
614
|
else
|
627
|
-
|
615
|
+
# return a Node
|
628
616
|
return node
|
629
617
|
end
|
630
618
|
end
|
@@ -635,7 +623,7 @@ module C
|
|
635
623
|
def empty?
|
636
624
|
@length.zero?
|
637
625
|
end
|
638
|
-
def index
|
626
|
+
def index(node)
|
639
627
|
curr = @first
|
640
628
|
i = 0
|
641
629
|
while curr
|
@@ -645,7 +633,7 @@ module C
|
|
645
633
|
end
|
646
634
|
return nil
|
647
635
|
end
|
648
|
-
def rindex
|
636
|
+
def rindex(node)
|
649
637
|
curr = @last
|
650
638
|
i = @length - 1
|
651
639
|
while curr
|
@@ -655,34 +643,34 @@ module C
|
|
655
643
|
end
|
656
644
|
return nil
|
657
645
|
end
|
658
|
-
def values_at
|
646
|
+
def values_at(*args)
|
659
647
|
args.map!{|i| self[i]}
|
660
648
|
end
|
661
|
-
def join
|
649
|
+
def join(*args)
|
662
650
|
self.to_a.join(*args)
|
663
651
|
end
|
664
652
|
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
def push
|
653
|
+
#
|
654
|
+
# non-const methods
|
655
|
+
#
|
656
|
+
def push(*newnodes)
|
669
657
|
newnodes = add_prep(newnodes)
|
670
658
|
added_(*newnodes)
|
671
659
|
link_(@last, newnodes, nil)
|
672
660
|
return self
|
673
661
|
end
|
674
|
-
def <<
|
662
|
+
def <<(newnode)
|
675
663
|
return push(newnode)
|
676
664
|
end
|
677
|
-
def unshift
|
665
|
+
def unshift(*newnodes)
|
678
666
|
newnodes = add_prep(newnodes)
|
679
667
|
added_(*newnodes)
|
680
668
|
link_(nil, newnodes, @first)
|
681
669
|
return self
|
682
670
|
end
|
683
|
-
def pop
|
671
|
+
def pop(n=nil)
|
684
672
|
if n
|
685
|
-
|
673
|
+
# return an Array of Nodes
|
686
674
|
ret = last(n)
|
687
675
|
return ret if ret.empty?
|
688
676
|
link2_(ret.first.instance_variable_get(:@prev), nil)
|
@@ -690,16 +678,16 @@ module C
|
|
690
678
|
return ret
|
691
679
|
else
|
692
680
|
return nil if empty?
|
693
|
-
|
681
|
+
# return a Node
|
694
682
|
ret = @last
|
695
683
|
link2_(@last.instance_variable_get(:@prev), nil)
|
696
684
|
removed_(ret)
|
697
685
|
return ret
|
698
686
|
end
|
699
687
|
end
|
700
|
-
def shift
|
688
|
+
def shift(n=nil)
|
701
689
|
if n
|
702
|
-
|
690
|
+
# return an Array of Nodes
|
703
691
|
ret = first(n)
|
704
692
|
return ret if ret.empty?
|
705
693
|
link2_(nil, ret.last.instance_variable_get(:@next))
|
@@ -707,14 +695,14 @@ module C
|
|
707
695
|
return ret
|
708
696
|
else
|
709
697
|
return nil if empty?
|
710
|
-
|
698
|
+
# return a Node
|
711
699
|
ret = @first
|
712
700
|
link2_(nil, @first.instance_variable_get(:@next))
|
713
701
|
removed_(ret)
|
714
702
|
return ret
|
715
703
|
end
|
716
704
|
end
|
717
|
-
def insert
|
705
|
+
def insert(i, *newnodes)
|
718
706
|
(0..@length).include? i or
|
719
707
|
raise IndexError, "index #{i} out of NodeList"
|
720
708
|
if i == @length
|
@@ -723,7 +711,7 @@ module C
|
|
723
711
|
insert_before(self[i], *newnodes)
|
724
712
|
end
|
725
713
|
end
|
726
|
-
def []=
|
714
|
+
def []=(*args)
|
727
715
|
newnodes = args.pop
|
728
716
|
i, n, splat = parse_index(*args)
|
729
717
|
oldnodes = self[i, n] or
|
@@ -750,10 +738,10 @@ module C
|
|
750
738
|
end
|
751
739
|
return newnodes
|
752
740
|
end
|
753
|
-
def concat
|
741
|
+
def concat(other)
|
754
742
|
return push(*other.to_a)
|
755
743
|
end
|
756
|
-
def delete_at
|
744
|
+
def delete_at(index)
|
757
745
|
node = self[index]
|
758
746
|
remove_node(node)
|
759
747
|
return node
|
@@ -764,15 +752,15 @@ module C
|
|
764
752
|
@length = 0
|
765
753
|
return self
|
766
754
|
end
|
767
|
-
def replace
|
755
|
+
def replace(other)
|
768
756
|
return clear.push(*other.to_a)
|
769
757
|
end
|
770
758
|
|
771
759
|
private
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
def link_
|
760
|
+
#
|
761
|
+
# Link up `nodes' between `a' and `b'.
|
762
|
+
#
|
763
|
+
def link_(a, nodes, b)
|
776
764
|
if nodes.empty?
|
777
765
|
if a.nil?
|
778
766
|
@first = b
|
@@ -785,7 +773,7 @@ module C
|
|
785
773
|
b.instance_variable_set(:@prev, a)
|
786
774
|
end
|
787
775
|
else
|
788
|
-
|
776
|
+
# connect `a' and `b'
|
789
777
|
first = nodes.first
|
790
778
|
if a.nil?
|
791
779
|
@first = first
|
@@ -799,7 +787,7 @@ module C
|
|
799
787
|
b.instance_variable_set(:@prev, last)
|
800
788
|
end
|
801
789
|
|
802
|
-
|
790
|
+
# connect `nodes'
|
803
791
|
if nodes.length == 1
|
804
792
|
node = nodes[0]
|
805
793
|
node.instance_variable_set(:@prev, a)
|
@@ -817,8 +805,10 @@ module C
|
|
817
805
|
end
|
818
806
|
end
|
819
807
|
end
|
820
|
-
|
821
|
-
|
808
|
+
#
|
809
|
+
# Special case for 2
|
810
|
+
#
|
811
|
+
def link2_(a, b)
|
822
812
|
if a.nil?
|
823
813
|
@first = b
|
824
814
|
else
|
@@ -830,17 +820,18 @@ module C
|
|
830
820
|
b.instance_variable_set(:@prev, a) unless b.nil?
|
831
821
|
end
|
832
822
|
end
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
823
|
+
|
824
|
+
#
|
825
|
+
# Return the `i'th Node. Assume `i' is in 0...length.
|
826
|
+
#
|
827
|
+
def get_(i)
|
828
|
+
# return a Node
|
838
829
|
if i < (@length >> 1)
|
839
|
-
|
830
|
+
# go from the beginning
|
840
831
|
node = @first
|
841
832
|
i.times{node = node.next}
|
842
833
|
else
|
843
|
-
|
834
|
+
# go from the end
|
844
835
|
node = @last
|
845
836
|
(@length - 1 - i).times{node = node.prev}
|
846
837
|
end
|