ParseTree 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,12 @@
1
+ *** 1.3.0 / 2004-12-06
2
+
3
+ + 3 minor enhancements
4
+ + Finished supporting pretty much all nodes (that we can figger out).
5
+ + If $DEBUG, or true passed to new, then we now output the :newline nodes.
6
+ + We output much better extra debugging info if $DEBUG.
7
+ + 1 bug fixes
8
+ + Fixed README for new output style.
9
+
1
10
  *** 1.2.0 / 2004-11-29
2
11
 
3
12
  + 9 minor enhancements
@@ -27,7 +36,6 @@
27
36
  + Added super as a call in abc.rb's metrics
28
37
  + Commented out a compiler flag to work with GCC 2.95.
29
38
 
30
-
31
39
  *** 1.0.0 / 2004-11-06
32
40
 
33
41
  + 1 major enhancement
data/README.txt CHANGED
@@ -21,12 +21,12 @@ As an example:
21
21
  becomes:
22
22
 
23
23
  [:defn,
24
- "conditional1",
24
+ :conditional1,
25
25
  [:scope,
26
26
  [:block,
27
- [:args, "arg1"],
27
+ [:args, :arg1],
28
28
  [:if,
29
- [:call, [:lvar, "arg1"], "==", [:array, [:lit, 0]]],
29
+ [:call, [:lvar, :arg1], :==, [:array, [:lit, 0]]],
30
30
  [:return, [:lit, 1]],
31
31
  nil],
32
32
  [:return, [:lit, 0]]]]]
@@ -27,7 +27,15 @@ end
27
27
 
28
28
  class ParseTree
29
29
 
30
- VERSION = '1.2.0'
30
+ VERSION = '1.3.0'
31
+
32
+ ##
33
+ # Initializes a ParseTree instance. Includes newline nodes if
34
+ # +include_newlines+ which defaults to +$DEBUG+.
35
+
36
+ def initialize(include_newlines=$DEBUG)
37
+ @include_newlines = include_newlines
38
+ end
31
39
 
32
40
  ##
33
41
  # Main driver for ParseTree. Returns an array of arrays containing
@@ -76,15 +84,17 @@ class ParseTree
76
84
  # [:defn, :name, :body]
77
85
 
78
86
  def parse_tree_for_method(klass, method)
79
- parse_tree_for_meth(klass, method.to_sym)
87
+ parse_tree_for_meth(klass, method.to_sym, @include_newlines)
80
88
  end
81
89
 
82
90
  inline do |builder|
83
91
  builder.add_type_converter("VALUE", '', '')
92
+ builder.add_type_converter("ID *", '', '')
84
93
  builder.add_type_converter("NODE *", '(NODE *)', '(VALUE)')
85
94
  builder.include '"intern.h"'
86
95
  builder.include '"node.h"'
87
96
  builder.include '"st.h"'
97
+ builder.include '"env.h"'
88
98
  builder.add_compile_flags "-Wall"
89
99
  builder.add_compile_flags "-W"
90
100
  builder.add_compile_flags "-Wpointer-arith"
@@ -103,6 +113,35 @@ class ParseTree
103
113
  # builder.add_compile_flags "-Wsign-compare",
104
114
 
105
115
  builder.prefix %q{
116
+ #define nd_3rd u3.node
117
+
118
+ struct METHOD {
119
+ VALUE klass, rklass;
120
+ VALUE recv;
121
+ ID id, oid;
122
+ NODE *body;
123
+ };
124
+
125
+ struct BLOCK {
126
+ NODE *var;
127
+ NODE *body;
128
+ VALUE self;
129
+ struct FRAME frame;
130
+ struct SCOPE *scope;
131
+ VALUE klass;
132
+ NODE *cref;
133
+ int iter;
134
+ int vmode;
135
+ int flags;
136
+ int uniq;
137
+ struct RVarmap *dyna_vars;
138
+ VALUE orig_thread;
139
+ VALUE wrapper;
140
+ VALUE block_obj;
141
+ struct BLOCK *outer;
142
+ struct BLOCK *prev;
143
+ };
144
+
106
145
  static char node_type_string[][60] = {
107
146
  // 00
108
147
  "method", "fbody", "cfunc", "scope", "block",
@@ -147,10 +186,10 @@ class ParseTree
147
186
  }
148
187
 
149
188
  builder.c_raw %q^
150
- // FIX!!!
151
- static ID *dump_local_tbl;
152
-
153
- static void add_to_parse_tree(VALUE ary, NODE * n) {
189
+ static void add_to_parse_tree(VALUE ary,
190
+ NODE * n,
191
+ VALUE newlines,
192
+ ID * locals) {
154
193
  NODE * volatile node = n;
155
194
  NODE * volatile contnode = NULL;
156
195
  VALUE old_ary = Qnil;
@@ -164,8 +203,11 @@ again:
164
203
  if (node) {
165
204
  node_name = ID2SYM(rb_intern(node_type_string[nd_type(node)]));
166
205
  if (RTEST(ruby_debug)) {
167
- fputs(node_type_string[nd_type(node)], stderr);
168
- fputs("\n", stderr);
206
+ fprintf(stderr, "%15s: %s%s%s\n",
207
+ node_type_string[nd_type(node)],
208
+ (RNODE(node)->u1.node != NULL ? "u1 " : " "),
209
+ (RNODE(node)->u2.node != NULL ? "u2 " : " "),
210
+ (RNODE(node)->u3.node != NULL ? "u3 " : " "));
169
211
  }
170
212
  } else {
171
213
  node_name = ID2SYM(rb_intern("ICKY"));
@@ -181,7 +223,7 @@ again_no_block:
181
223
 
182
224
  case NODE_BLOCK:
183
225
  if (contnode) {
184
- add_to_parse_tree(current, node);
226
+ add_to_parse_tree(current, node, newlines, locals);
185
227
  break;
186
228
  }
187
229
 
@@ -196,11 +238,11 @@ again_no_block:
196
238
 
197
239
  case NODE_FBODY:
198
240
  case NODE_DEFINED:
199
- add_to_parse_tree(current, node->nd_head);
241
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
200
242
  break;
201
243
 
202
244
  case NODE_COLON2:
203
- add_to_parse_tree(current, node->nd_head);
245
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
204
246
  rb_ary_push(current, ID2SYM(node->nd_mid));
205
247
  break;
206
248
 
@@ -210,33 +252,33 @@ again_no_block:
210
252
 
211
253
  case NODE_MATCH2:
212
254
  case NODE_MATCH3:
213
- add_to_parse_tree(current, node->nd_recv);
214
- add_to_parse_tree(current, node->nd_value);
255
+ add_to_parse_tree(current, node->nd_recv, newlines, locals);
256
+ add_to_parse_tree(current, node->nd_value, newlines, locals);
215
257
  break;
216
258
 
217
259
  case NODE_OPT_N:
218
- add_to_parse_tree(current, node->nd_body);
260
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
219
261
  break;
220
262
 
221
263
  case NODE_IF:
222
- add_to_parse_tree(current, node->nd_cond);
264
+ add_to_parse_tree(current, node->nd_cond, newlines, locals);
223
265
  if (node->nd_body) {
224
- add_to_parse_tree(current, node->nd_body);
266
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
225
267
  } else {
226
268
  rb_ary_push(current, Qnil);
227
269
  }
228
270
  if (node->nd_else) {
229
- add_to_parse_tree(current, node->nd_else);
271
+ add_to_parse_tree(current, node->nd_else, newlines, locals);
230
272
  } else {
231
273
  rb_ary_push(current, Qnil);
232
274
  }
233
275
  break;
234
276
 
235
277
  case NODE_CASE:
236
- add_to_parse_tree(current, node->nd_head); /* expr */
278
+ add_to_parse_tree(current, node->nd_head, newlines, locals); /* expr */
237
279
  node = node->nd_body;
238
280
  while (node) {
239
- add_to_parse_tree(current, node);
281
+ add_to_parse_tree(current, node, newlines, locals);
240
282
  if (nd_type(node) == NODE_WHEN) { /* when */
241
283
  node = node->nd_next;
242
284
  } else {
@@ -249,9 +291,9 @@ again_no_block:
249
291
  break;
250
292
 
251
293
  case NODE_WHEN:
252
- add_to_parse_tree(current, node->nd_head); /* args */
294
+ add_to_parse_tree(current, node->nd_head, newlines, locals); /* args */
253
295
  if (node->nd_body) {
254
- add_to_parse_tree(current, node->nd_body); /* body */
296
+ add_to_parse_tree(current, node->nd_body, newlines, locals); /* body */
255
297
  } else {
256
298
  rb_ary_push(current, Qnil);
257
299
  }
@@ -259,148 +301,149 @@ again_no_block:
259
301
 
260
302
  case NODE_WHILE:
261
303
  case NODE_UNTIL:
262
- add_to_parse_tree(current, node->nd_cond);
263
- add_to_parse_tree(current, node->nd_body);
304
+ add_to_parse_tree(current, node->nd_cond, newlines, locals);
305
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
264
306
  break;
265
307
 
266
308
  case NODE_BLOCK_PASS:
267
- add_to_parse_tree(current, node->nd_body);
268
- add_to_parse_tree(current, node->nd_iter);
309
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
310
+ add_to_parse_tree(current, node->nd_iter, newlines, locals);
269
311
  break;
270
312
 
271
313
  case NODE_ITER:
272
314
  case NODE_FOR:
273
- add_to_parse_tree(current, node->nd_iter);
315
+ add_to_parse_tree(current, node->nd_iter, newlines, locals);
274
316
  if (node->nd_var != (NODE *)1
275
317
  && node->nd_var != (NODE *)2
276
318
  && node->nd_var != NULL) {
277
- add_to_parse_tree(current, node->nd_var);
319
+ add_to_parse_tree(current, node->nd_var, newlines, locals);
278
320
  } else {
279
321
  rb_ary_push(current, Qnil);
280
322
  }
281
- add_to_parse_tree(current, node->nd_body);
323
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
282
324
  break;
283
325
 
284
326
  case NODE_BREAK:
285
327
  case NODE_NEXT:
286
328
  case NODE_YIELD:
287
329
  if (node->nd_stts)
288
- add_to_parse_tree(current, node->nd_stts);
330
+ add_to_parse_tree(current, node->nd_stts, newlines, locals);
289
331
  break;
290
332
 
291
333
  case NODE_RESCUE:
292
- {
293
- NODE *resq, *n;
294
- int i;
334
+ add_to_parse_tree(current, node->nd_1st, newlines, locals);
335
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals);
336
+ break;
295
337
 
296
- add_to_parse_tree(current, node->nd_head);
297
- resq = node->nd_resq;
298
- while (resq) {
299
- if (nd_type(resq) == NODE_ARRAY) {
300
- n = resq;
301
- for (i = 0; i < resq->nd_alen; i++) {
302
- add_to_parse_tree(current, n->nd_head);
303
- n = n->nd_next;
304
- }
305
- } else {
306
- add_to_parse_tree(current, resq->nd_args);
307
- }
308
- add_to_parse_tree(current, resq->nd_body);
309
- resq = resq->nd_head;
310
- }
311
- if (node->nd_else) {
312
- add_to_parse_tree(current, node->nd_else);
313
- }
314
- }
338
+ case NODE_RESBODY: // stmt rescue stmt | a = b rescue c - no repro
339
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals);
340
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals);
341
+ add_to_parse_tree(current, node->nd_1st, newlines, locals);
315
342
  break;
316
343
 
317
344
  case NODE_ENSURE:
318
- add_to_parse_tree(current, node->nd_head);
345
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
319
346
  if (node->nd_ensr) {
320
- add_to_parse_tree(current, node->nd_ensr);
347
+ add_to_parse_tree(current, node->nd_ensr, newlines, locals);
321
348
  }
322
349
  break;
323
350
 
324
351
  case NODE_AND:
325
352
  case NODE_OR:
326
- add_to_parse_tree(current, node->nd_1st);
327
- add_to_parse_tree(current, node->nd_2nd);
353
+ add_to_parse_tree(current, node->nd_1st, newlines, locals);
354
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals);
328
355
  break;
329
356
 
330
357
  case NODE_NOT:
331
- add_to_parse_tree(current, node->nd_body);
358
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
332
359
  break;
333
360
 
334
361
  case NODE_DOT2:
335
362
  case NODE_DOT3:
336
363
  case NODE_FLIP2:
337
364
  case NODE_FLIP3:
338
- add_to_parse_tree(current, node->nd_beg);
339
- add_to_parse_tree(current, node->nd_end);
365
+ add_to_parse_tree(current, node->nd_beg, newlines, locals);
366
+ add_to_parse_tree(current, node->nd_end, newlines, locals);
340
367
  break;
341
368
 
342
369
  case NODE_RETURN:
343
370
  if (node->nd_stts)
344
- add_to_parse_tree(current, node->nd_stts);
371
+ add_to_parse_tree(current, node->nd_stts, newlines, locals);
345
372
  break;
346
373
 
347
374
  case NODE_ARGSCAT:
348
375
  case NODE_ARGSPUSH:
349
- add_to_parse_tree(current, node->nd_head);
350
- add_to_parse_tree(current, node->nd_body);
376
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
377
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
351
378
  break;
352
379
 
353
380
  case NODE_CALL:
354
381
  case NODE_FCALL:
355
382
  case NODE_VCALL:
356
383
  if (nd_type(node) != NODE_FCALL)
357
- add_to_parse_tree(current, node->nd_recv);
384
+ add_to_parse_tree(current, node->nd_recv, newlines, locals);
358
385
  rb_ary_push(current, ID2SYM(node->nd_mid));
359
386
  if (node->nd_args || nd_type(node) != NODE_FCALL)
360
- add_to_parse_tree(current, node->nd_args);
387
+ add_to_parse_tree(current, node->nd_args, newlines, locals);
361
388
  break;
362
389
 
363
390
  case NODE_SUPER:
364
- add_to_parse_tree(current, node->nd_args);
391
+ add_to_parse_tree(current, node->nd_args, newlines, locals);
392
+ break;
393
+
394
+ case NODE_BMETHOD:
395
+ {
396
+ struct BLOCK *data;
397
+ Data_Get_Struct(node->nd_cval, struct BLOCK, data);
398
+ add_to_parse_tree(current, data->var, newlines, locals);
399
+ add_to_parse_tree(current, data->body, newlines, locals);
400
+ break;
401
+ }
365
402
  break;
366
403
 
367
404
  case NODE_DMETHOD:
368
405
  {
369
406
  struct METHOD *data;
370
407
  Data_Get_Struct(node->nd_cval, struct METHOD, data);
408
+ rb_ary_push(current, ID2SYM(data->id));
409
+ add_to_parse_tree(current, data->body, newlines, locals);
371
410
  break;
372
411
  }
373
412
 
413
+ case NODE_METHOD:
414
+ fprintf(stderr, "u1 = %p u2 = %p u3 = %p\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
415
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals);
416
+ break;
417
+
374
418
  case NODE_SCOPE:
375
- dump_local_tbl = node->nd_tbl;
376
- add_to_parse_tree(current, node->nd_next);
419
+ add_to_parse_tree(current, node->nd_next, newlines, node->nd_tbl);
377
420
  break;
378
421
 
379
422
  case NODE_OP_ASGN1:
380
- add_to_parse_tree(current, node->nd_recv);
381
- add_to_parse_tree(current, node->nd_args->nd_next);
382
- add_to_parse_tree(current, node->nd_args->nd_head);
423
+ add_to_parse_tree(current, node->nd_recv, newlines, locals);
424
+ add_to_parse_tree(current, node->nd_args->nd_next, newlines, locals);
425
+ add_to_parse_tree(current, node->nd_args->nd_head, newlines, locals);
383
426
  break;
384
427
 
385
428
  case NODE_OP_ASGN2:
386
- add_to_parse_tree(current, node->nd_recv);
387
- add_to_parse_tree(current, node->nd_value);
429
+ add_to_parse_tree(current, node->nd_recv, newlines, locals);
430
+ add_to_parse_tree(current, node->nd_value, newlines, locals);
388
431
  break;
389
432
 
390
433
  case NODE_OP_ASGN_AND:
391
434
  case NODE_OP_ASGN_OR:
392
- add_to_parse_tree(current, node->nd_head);
393
- add_to_parse_tree(current, node->nd_value);
435
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
436
+ add_to_parse_tree(current, node->nd_value, newlines, locals);
394
437
  break;
395
438
 
396
439
  case NODE_MASGN:
397
- add_to_parse_tree(current, node->nd_head);
440
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
398
441
  if (node->nd_args) {
399
442
  if (node->nd_args != (NODE *)-1) {
400
- add_to_parse_tree(current, node->nd_args);
443
+ add_to_parse_tree(current, node->nd_args, newlines, locals);
401
444
  }
402
445
  }
403
- add_to_parse_tree(current, node->nd_value);
446
+ add_to_parse_tree(current, node->nd_value, newlines, locals);
404
447
  break;
405
448
 
406
449
  case NODE_LASGN:
@@ -412,7 +455,18 @@ again_no_block:
412
455
  case NODE_CVDECL:
413
456
  case NODE_GASGN:
414
457
  rb_ary_push(current, ID2SYM(node->nd_vid));
415
- add_to_parse_tree(current, node->nd_value);
458
+ add_to_parse_tree(current, node->nd_value, newlines, locals);
459
+ break;
460
+
461
+ case NODE_ALIAS: // u1 u2 (alias :blah :blah2)
462
+ case NODE_VALIAS: // u1 u2 (alias $global $global2)
463
+ rb_ary_push(current, ID2SYM(node->u1.id));
464
+ rb_ary_push(current, ID2SYM(node->u2.id));
465
+ break;
466
+
467
+ case NODE_COLON3: // u2 (::OUTER_CONST)
468
+ case NODE_UNDEF: // u2 (undef instvar)
469
+ rb_ary_push(current, ID2SYM(node->u2.id));
416
470
  break;
417
471
 
418
472
  case NODE_HASH:
@@ -421,11 +475,11 @@ again_no_block:
421
475
 
422
476
  list = node->nd_head;
423
477
  while (list) {
424
- add_to_parse_tree(current, list->nd_head);
478
+ add_to_parse_tree(current, list->nd_head, newlines, locals);
425
479
  list = list->nd_next;
426
480
  if (list == 0)
427
481
  rb_bug("odd number list for Hash");
428
- add_to_parse_tree(current, list->nd_head);
482
+ add_to_parse_tree(current, list->nd_head, newlines, locals);
429
483
  list = list->nd_next;
430
484
  }
431
485
  }
@@ -433,7 +487,7 @@ again_no_block:
433
487
 
434
488
  case NODE_ARRAY:
435
489
  while (node) {
436
- add_to_parse_tree(current, node->nd_head);
490
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
437
491
  node = node->nd_next;
438
492
  }
439
493
  break;
@@ -452,13 +506,13 @@ again_no_block:
452
506
  if (list->nd_head) {
453
507
  switch (nd_type(list->nd_head)) {
454
508
  case NODE_STR:
455
- add_to_parse_tree(current, list->nd_head);
509
+ add_to_parse_tree(current, list->nd_head, newlines, locals);
456
510
  break;
457
511
  case NODE_EVSTR:
458
- add_to_parse_tree(current, list->nd_head->nd_body);
512
+ add_to_parse_tree(current, list->nd_head->nd_body, newlines, locals);
459
513
  break;
460
514
  default:
461
- add_to_parse_tree(current, list->nd_head);
515
+ add_to_parse_tree(current, list->nd_head, newlines, locals);
462
516
  break;
463
517
  }
464
518
  }
@@ -471,9 +525,9 @@ again_no_block:
471
525
  case NODE_DEFS:
472
526
  if (node->nd_defn) {
473
527
  if (nd_type(node) == NODE_DEFS)
474
- add_to_parse_tree(current, node->nd_recv);
528
+ add_to_parse_tree(current, node->nd_recv, newlines, locals);
475
529
  rb_ary_push(current, ID2SYM(node->nd_mid));
476
- add_to_parse_tree(current, node->nd_defn);
530
+ add_to_parse_tree(current, node->nd_defn, newlines, locals);
477
531
  }
478
532
  break;
479
533
 
@@ -481,18 +535,18 @@ again_no_block:
481
535
  case NODE_MODULE:
482
536
  rb_ary_push(current, ID2SYM((ID)node->nd_cpath->nd_mid));
483
537
  if (node->nd_super && nd_type(node) == NODE_CLASS) {
484
- add_to_parse_tree(current, node->nd_super);
538
+ add_to_parse_tree(current, node->nd_super, newlines, locals);
485
539
  }
486
- add_to_parse_tree(current, node->nd_body);
540
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
487
541
  break;
488
542
 
489
543
  case NODE_SCLASS:
490
- add_to_parse_tree(current, node->nd_recv);
491
- add_to_parse_tree(current, node->nd_body);
544
+ add_to_parse_tree(current, node->nd_recv, newlines, locals);
545
+ add_to_parse_tree(current, node->nd_body, newlines, locals);
492
546
  break;
493
547
 
494
548
  case NODE_ARGS:
495
- if (dump_local_tbl &&
549
+ if (locals &&
496
550
  (node->nd_cnt || node->nd_opt || node->nd_rest != -1)) {
497
551
  int i;
498
552
  NODE *optnode;
@@ -500,13 +554,13 @@ again_no_block:
500
554
 
501
555
  for (i = 0; i < node->nd_cnt; i++) {
502
556
  // regular arg names
503
- rb_ary_push(current, ID2SYM(dump_local_tbl[i + 3]));
557
+ rb_ary_push(current, ID2SYM(locals[i + 3]));
504
558
  }
505
559
 
506
560
  optnode = node->nd_opt;
507
561
  while (optnode) {
508
562
  // optional arg names
509
- rb_ary_push(current, ID2SYM(dump_local_tbl[i + 3]));
563
+ rb_ary_push(current, ID2SYM(locals[i + 3]));
510
564
  i++;
511
565
  optnode = optnode->nd_next;
512
566
  }
@@ -514,7 +568,7 @@ again_no_block:
514
568
  arg_count = node->nd_rest;
515
569
  if (arg_count > 0) {
516
570
  // *arg name
517
- rb_ary_push(current, ID2SYM(dump_local_tbl[node->nd_rest + 1]));
571
+ rb_ary_push(current, ID2SYM(locals[node->nd_rest + 1]));
518
572
  } else if (arg_count == -1) {
519
573
  // nothing to do in this case, handled above
520
574
  } else if (arg_count == -2) {
@@ -527,85 +581,135 @@ again_no_block:
527
581
  optnode = node->nd_opt;
528
582
  // block?
529
583
  if (optnode) {
530
- add_to_parse_tree(current, node->nd_opt);
584
+ add_to_parse_tree(current, node->nd_opt, newlines, locals);
531
585
  }
532
586
  }
533
587
  break;
534
588
 
535
- case NODE_LVAR:
536
- case NODE_DVAR:
537
- case NODE_IVAR:
538
- case NODE_CVAR:
539
- case NODE_GVAR:
540
- case NODE_CONST:
541
- case NODE_ATTRSET:
542
- rb_ary_push(current, ID2SYM(node->nd_vid));
543
- break;
589
+ case NODE_LVAR:
590
+ case NODE_DVAR:
591
+ case NODE_IVAR:
592
+ case NODE_CVAR:
593
+ case NODE_GVAR:
594
+ case NODE_CONST:
595
+ case NODE_ATTRSET:
596
+ rb_ary_push(current, ID2SYM(node->nd_vid));
597
+ break;
544
598
 
545
- case NODE_STR:
546
- case NODE_LIT:
547
- rb_ary_push(current, node->nd_lit);
548
- break;
599
+ case NODE_XSTR: // u1 (%x{ls})
600
+ case NODE_STR: // u1
601
+ case NODE_LIT:
602
+ case NODE_MATCH:
603
+ rb_ary_push(current, node->nd_lit);
604
+ break;
549
605
 
550
- case NODE_NEWLINE:
551
- rb_ary_push(current, INT2FIX(nd_line(node)));
552
- rb_ary_push(current, rb_str_new2(node->nd_file));
553
- rb_ary_pop(ary); // nuke it for now
606
+ case NODE_NEWLINE:
607
+ rb_ary_push(current, INT2FIX(nd_line(node)));
608
+ rb_ary_push(current, rb_str_new2(node->nd_file));
554
609
 
555
- node = node->nd_next;
556
- goto again;
610
+ if (! RTEST(newlines)) rb_ary_pop(ary); // nuke it
557
611
 
558
- // these are things we know we do not need to translate to C.
559
- case NODE_BLOCK_ARG:
560
- case NODE_SELF:
561
- case NODE_NIL:
562
- case NODE_TRUE:
563
- case NODE_FALSE:
564
- case NODE_ZSUPER:
565
- case NODE_BMETHOD:
566
- case NODE_REDO:
567
- case NODE_RETRY:
568
- case NODE_COLON3:
569
- case NODE_NTH_REF:
570
- case NODE_BACK_REF:
571
- case NODE_ZARRAY:
572
- case NODE_XSTR:
573
- case NODE_UNDEF:
574
- case NODE_ALIAS:
575
- case NODE_VALIAS:
576
- break;
577
-
578
- default:
579
- rb_ary_push(current, INT2FIX(-99));
580
- rb_ary_push(current, INT2FIX(nd_type(node)));
581
- break;
582
- }
612
+ node = node->nd_next;
613
+ goto again;
614
+ break;
583
615
 
584
- // finish:
585
- if (contnode) {
586
- node = contnode;
587
- contnode = NULL;
588
- current = ary;
589
- ary = old_ary;
590
- old_ary = Qnil;
591
- goto again_no_block;
616
+ case NODE_NTH_REF: // u2 u3 ($1) - u3 is local_cnt('~') ignorable?
617
+ rb_ary_push(current, INT2FIX(node->nd_nth));
618
+ break;
619
+
620
+ case NODE_BACK_REF: // u2 u3 ($& etc)
621
+ {
622
+ char c = node->nd_nth;
623
+ rb_ary_push(current, rb_str_intern(rb_str_new(&c, 1)));
592
624
  }
625
+ break;
626
+
627
+ case NODE_BLOCK_ARG: // u1 u3 (def x(&b)
628
+ rb_ary_push(current, ID2SYM(node->u1.id));
629
+ break;
630
+
631
+ // these nodes are empty and do not require extra work:
632
+ case NODE_RETRY:
633
+ case NODE_FALSE:
634
+ case NODE_NIL:
635
+ case NODE_SELF:
636
+ case NODE_TRUE:
637
+ case NODE_ZARRAY:
638
+ case NODE_ZSUPER:
639
+ case NODE_REDO:
640
+ break;
641
+
642
+ case NODE_SPLAT:
643
+ case NODE_TO_ARY:
644
+ case NODE_SVALUE: // a = b, c
645
+ add_to_parse_tree(current, node->nd_head, newlines, locals);
646
+ break;
647
+
648
+ case NODE_ATTRASGN: // literal.meth = y u1 u2 u3
649
+ // node id node
650
+ add_to_parse_tree(current, node->nd_1st, newlines, locals);
651
+ rb_ary_push(current, ID2SYM(node->u2.id));
652
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals);
653
+ break;
654
+
655
+ case NODE_DSYM: // :"#{foo}" u1 u2 u3
656
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals);
657
+ break;
658
+
659
+ case NODE_EVSTR:
660
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals);
661
+ break;
662
+
663
+ case NODE_POSTEXE: // END { ... }
664
+ // Nothing to do here... we are in an iter block
665
+ break;
666
+
667
+ // Nodes we found but have yet to decypher
668
+ // I think these are all runtime only... not positive but...
669
+ case NODE_MEMO: // enum.c zip
670
+ case NODE_CFUNC:
671
+ case NODE_CREF:
672
+ case NODE_IFUNC:
673
+ // #defines:
674
+ // case NODE_LMASK:
675
+ // case NODE_LSHIFT:
676
+ default:
677
+ rb_warn("Unhandled node #%d type '%s'", nd_type(node), node_type_string[nd_type(node)]);
678
+ if (RNODE(node)->u1.node != NULL) rb_warning("unhandled u1 value");
679
+ if (RNODE(node)->u2.node != NULL) rb_warning("unhandled u2 value");
680
+ if (RNODE(node)->u3.node != NULL) rb_warning("unhandled u3 value");
681
+ if (RTEST(ruby_debug)) fprintf(stderr, "u1 = %p u2 = %p u3 = %p\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
682
+ rb_ary_push(current, INT2FIX(-99));
683
+ rb_ary_push(current, INT2FIX(nd_type(node)));
684
+ break;
593
685
  }
686
+
687
+ // finish:
688
+ if (contnode) {
689
+ node = contnode;
690
+ contnode = NULL;
691
+ current = ary;
692
+ ary = old_ary;
693
+ old_ary = Qnil;
694
+ goto again_no_block;
695
+ }
696
+ }
594
697
  ^ # end of add_to_parse_tree block
595
698
 
596
699
  builder.c %q{
597
- static VALUE parse_tree_for_meth(VALUE klass, VALUE method) {
700
+ static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE newlines) {
598
701
  NODE *node = NULL;
599
702
  ID id;
600
703
  VALUE result = rb_ary_new();
601
704
 
602
705
  (void) self; // quell warnings
706
+ (void) argc; // quell warnings
603
707
 
604
708
  id = rb_to_id(method);
605
709
  if (st_lookup(RCLASS(klass)->m_tbl, id, (st_data_t *) &node)) {
606
710
  rb_ary_push(result, ID2SYM(rb_intern("defn")));
607
711
  rb_ary_push(result, ID2SYM(id));
608
- add_to_parse_tree(result, node->nd_body);
712
+ add_to_parse_tree(result, node->nd_body, newlines, NULL);
609
713
  } else {
610
714
  rb_ary_push(result, Qnil);
611
715
  }
@@ -159,4 +159,16 @@ class Something
159
159
  5 == unknown_args(4, "known")
160
160
  end
161
161
 
162
+ def self.bmethod_maker
163
+ define_method(:bmethod_added) do |x|
164
+ x + 1
165
+ end
166
+ end
167
+
168
+ def self.dmethod_maker
169
+ define_method :dmethod_added, self.method(:bmethod_maker)
170
+ end
171
+
172
+ bmethod_maker
173
+ dmethod_maker
162
174
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'test/unit'
4
4
  require 'parse_tree'
5
- require 'something'
5
+ require 'test/something'
6
6
 
7
7
  class TestParseTree < Test::Unit::TestCase
8
8
 
@@ -244,10 +244,28 @@ class TestParseTree < Test::Unit::TestCase
244
244
  :unknown_args,
245
245
  [:array, [:lit, 4], [:str, "known"]]]]]]]]
246
246
 
247
+ @@bmethod_added = [:defn,
248
+ :bmethod_added,
249
+ [:bmethod,
250
+ [:dasgn_curr, :x],
251
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]
252
+
253
+ @@dmethod_added = [:defn,
254
+ :dmethod_added,
255
+ [:dmethod,
256
+ :bmethod_maker,
257
+ [:scope,
258
+ [:block,
259
+ [:args],
260
+ [:iter,
261
+ [:fcall, :define_method, [:array, [:lit, :bmethod_added]]],
262
+ [:dasgn_curr, :x],
263
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]]]]
264
+
247
265
  @@__all = [:class, :Something, :Object]
248
266
 
249
267
  def setup
250
- @thing = ParseTree.new
268
+ @thing = ParseTree.new(false)
251
269
  end
252
270
 
253
271
  Something.instance_methods(false).sort.each do |meth|
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.1
3
3
  specification_version: 1
4
4
  name: ParseTree
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.0
7
- date: 2004-11-29
6
+ version: 1.3.0
7
+ date: 2004-12-07
8
8
  summary: Extract and enumerate ruby parse trees.
9
9
  require_paths:
10
10
  - lib