rubyjs 0.7.1 → 0.8.0

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.
Files changed (61) hide show
  1. data/examples/client_server/README +18 -0
  2. data/examples/client_server/Rakefile +5 -0
  3. data/examples/client_server/client.js +749 -0
  4. data/examples/client_server/client.rb +12 -0
  5. data/examples/client_server/index.html +7 -0
  6. data/examples/client_server/server.rb +17 -0
  7. data/examples/hw/hw.js +234 -216
  8. data/rubyjs.gemspec +2 -2
  9. data/src/rubyjs.rb +0 -1
  10. data/src/rubyjs/compiler.rb +21 -8
  11. data/src/rubyjs/debug_name_generator.rb +23 -6
  12. data/src/rubyjs/model.rb +14 -8
  13. data/test/browser.test.html +1 -1
  14. data/test/browser.test.js +2337 -1992
  15. data/test/test_yield.rb +2 -0
  16. metadata +108 -158
  17. data/patches/parse_tree.rb.diff +0 -34
  18. data/vendor/ParseTree-1.7.1-patched/History.txt +0 -217
  19. data/vendor/ParseTree-1.7.1-patched/Manifest.txt +0 -22
  20. data/vendor/ParseTree-1.7.1-patched/README.txt +0 -110
  21. data/vendor/ParseTree-1.7.1-patched/Rakefile +0 -41
  22. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_abc +0 -89
  23. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_audit +0 -28
  24. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_deps +0 -62
  25. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_show +0 -49
  26. data/vendor/ParseTree-1.7.1-patched/demo/printer.rb +0 -20
  27. data/vendor/ParseTree-1.7.1-patched/lib/composite_sexp_processor.rb +0 -49
  28. data/vendor/ParseTree-1.7.1-patched/lib/parse_tree.rb +0 -1013
  29. data/vendor/ParseTree-1.7.1-patched/lib/sexp.rb +0 -235
  30. data/vendor/ParseTree-1.7.1-patched/lib/sexp_processor.rb +0 -330
  31. data/vendor/ParseTree-1.7.1-patched/lib/unique.rb +0 -15
  32. data/vendor/ParseTree-1.7.1-patched/test/pt_testcase.rb +0 -1221
  33. data/vendor/ParseTree-1.7.1-patched/test/something.rb +0 -53
  34. data/vendor/ParseTree-1.7.1-patched/test/test_all.rb +0 -13
  35. data/vendor/ParseTree-1.7.1-patched/test/test_composite_sexp_processor.rb +0 -69
  36. data/vendor/ParseTree-1.7.1-patched/test/test_parse_tree.rb +0 -216
  37. data/vendor/ParseTree-1.7.1-patched/test/test_sexp.rb +0 -291
  38. data/vendor/ParseTree-1.7.1-patched/test/test_sexp_processor.rb +0 -244
  39. data/vendor/ParseTree-1.7.1-patched/validate.sh +0 -31
  40. data/vendor/ParseTree-1.7.1/History.txt +0 -217
  41. data/vendor/ParseTree-1.7.1/Manifest.txt +0 -22
  42. data/vendor/ParseTree-1.7.1/README.txt +0 -110
  43. data/vendor/ParseTree-1.7.1/Rakefile +0 -41
  44. data/vendor/ParseTree-1.7.1/bin/parse_tree_abc +0 -89
  45. data/vendor/ParseTree-1.7.1/bin/parse_tree_audit +0 -28
  46. data/vendor/ParseTree-1.7.1/bin/parse_tree_deps +0 -62
  47. data/vendor/ParseTree-1.7.1/bin/parse_tree_show +0 -49
  48. data/vendor/ParseTree-1.7.1/demo/printer.rb +0 -20
  49. data/vendor/ParseTree-1.7.1/lib/composite_sexp_processor.rb +0 -49
  50. data/vendor/ParseTree-1.7.1/lib/parse_tree.rb +0 -1004
  51. data/vendor/ParseTree-1.7.1/lib/sexp.rb +0 -235
  52. data/vendor/ParseTree-1.7.1/lib/sexp_processor.rb +0 -330
  53. data/vendor/ParseTree-1.7.1/lib/unique.rb +0 -15
  54. data/vendor/ParseTree-1.7.1/test/pt_testcase.rb +0 -1221
  55. data/vendor/ParseTree-1.7.1/test/something.rb +0 -53
  56. data/vendor/ParseTree-1.7.1/test/test_all.rb +0 -13
  57. data/vendor/ParseTree-1.7.1/test/test_composite_sexp_processor.rb +0 -69
  58. data/vendor/ParseTree-1.7.1/test/test_parse_tree.rb +0 -216
  59. data/vendor/ParseTree-1.7.1/test/test_sexp.rb +0 -291
  60. data/vendor/ParseTree-1.7.1/test/test_sexp_processor.rb +0 -244
  61. data/vendor/ParseTree-1.7.1/validate.sh +0 -31
@@ -1,1013 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- abort "*** Sorry, ParseTree doesn't work with ruby #{RUBY_VERSION}" if
4
- RUBY_VERSION >= "1.9"
5
-
6
- begin require 'rubygems'; rescue LoadError; end
7
-
8
- require 'inline'
9
-
10
- ##
11
- # ParseTree is a RubyInline-style extension that accesses and
12
- # traverses the internal parse tree created by ruby.
13
- #
14
- # class Example
15
- # def blah
16
- # return 1 + 1
17
- # end
18
- # end
19
- #
20
- # ParseTree.new.parse_tree(Example)
21
- # => [[:class, :Example, :Object,
22
- # [:defn,
23
- # "blah",
24
- # [:scope,
25
- # [:block,
26
- # [:args],
27
- # [:return, [:call, [:lit, 1], "+", [:array, [:lit, 1]]]]]]]]]
28
-
29
- class ParseTree
30
-
31
- VERSION = '1.7.1'
32
-
33
- ##
34
- # Front end translation method.
35
-
36
- def self.translate(klass_or_str, method=nil)
37
- pt = self.new(false)
38
- case klass_or_str
39
- when String then
40
- sexp = pt.parse_tree_for_string(klass_or_str).first
41
- if method then
42
- # class, scope, block, *methods
43
- sexp.last.last[1..-1].find do |defn|
44
- defn[1] == method
45
- end
46
- else
47
- sexp
48
- end
49
- else
50
- unless method.nil? then
51
- if method.to_s =~ /^self\./ then
52
- method = method.to_s[5..-1].intern
53
- pt.parse_tree_for_method(klass_or_str, method, true)
54
- else
55
- pt.parse_tree_for_method(klass_or_str, method)
56
- end
57
- else
58
- pt.parse_tree(klass_or_str).first
59
- end
60
- end
61
- end
62
-
63
- ##
64
- # Initializes a ParseTree instance. Includes newline nodes if
65
- # +include_newlines+ which defaults to +$DEBUG+.
66
-
67
- def initialize(include_newlines=$DEBUG)
68
- if include_newlines then
69
- warn "WARNING: include_newlines=true from #{caller[0..9].join(', ')}"
70
- end
71
- @include_newlines = include_newlines
72
- end
73
-
74
- ##
75
- # Main driver for ParseTree. Returns an array of arrays containing
76
- # the parse tree for +klasses+.
77
- #
78
- # Structure:
79
- #
80
- # [[:class, classname, superclassname, [:defn :method1, ...], ...], ...]
81
- #
82
- # NOTE: v1.0 - v1.1 had the signature (klass, meth=nil). This wasn't
83
- # used much at all and since parse_tree_for_method already existed,
84
- # it was deemed more useful to expand this method to do multiple
85
- # classes.
86
-
87
- def parse_tree(*klasses)
88
- result = []
89
- klasses.each do |klass|
90
- # TODO: remove this on v 1.1
91
- raise "You should call parse_tree_for_method(#{klasses.first}, #{klass}) instead of parse_tree" if Symbol === klass or String === klass
92
- klassname = klass.name rescue '' # HACK klass.name should never be nil
93
- # Tempfile's DelegateClass(File) seems to
94
- # cause this
95
- klassname = "UnnamedClass_#{klass.object_id}" if klassname.empty?
96
- klassname = klassname.to_sym
97
-
98
- code = if Class === klass then
99
- sc = klass.superclass
100
- sc_name = ((sc.nil? or sc.name.empty?) ? "nil" : sc.name).intern
101
- [:class, klassname, [:const, sc_name]]
102
- else
103
- [:module, klassname]
104
- end
105
-
106
- method_names = []
107
- method_names += klass.instance_methods false
108
- method_names += klass.private_instance_methods false
109
- # protected methods are included in instance_methods, go figure!
110
-
111
- method_names.sort.each do |m|
112
- code << parse_tree_for_method(klass, m.to_sym)
113
- end
114
-
115
- klass.singleton_methods(false).sort.each do |m|
116
- code << parse_tree_for_method(klass, m.to_sym, true)
117
- end
118
-
119
- result << code
120
- end
121
- return result
122
- end
123
-
124
- ##
125
- # Returns the parse tree for just one +method+ of a class +klass+.
126
- #
127
- # Format:
128
- #
129
- # [:defn, :name, :body]
130
-
131
- def parse_tree_for_method(klass, method, is_cls_meth=false)
132
- $stderr.puts "** parse_tree_for_method(#{klass}, #{method}):" if $DEBUG
133
- r = parse_tree_for_meth(klass, method.to_sym, @include_newlines, is_cls_meth)
134
- r[1] = :"self.#{r[1]}" if is_cls_meth
135
- r
136
- end
137
-
138
- ##
139
- # Returns the parse tree for a string +source+.
140
- #
141
- # Format:
142
- #
143
- # [[sexps] ... ]
144
-
145
- def parse_tree_for_string(source, filename = nil, line = nil,
146
- newlines = false)
147
- filename ||= '(string)'
148
- line ||= 1
149
- return parse_tree_for_str(source, filename, line, newlines)
150
- end
151
-
152
- if RUBY_VERSION < "1.8.4" then
153
- inline do |builder|
154
- builder.add_type_converter("bool", '', '')
155
- builder.c_singleton "
156
- bool has_alloca() {
157
- (void)self;
158
- #ifdef C_ALLOCA
159
- return Qtrue;
160
- #else
161
- return Qfalse;
162
- #endif
163
- }"
164
- end
165
- else
166
- def self.has_alloca
167
- true
168
- end
169
- end
170
-
171
-
172
- NODE_NAMES = [
173
- # 00
174
- :method, :fbody, :cfunc, :scope, :block,
175
- :if, :case, :when, :opt_n, :while,
176
- # 10
177
- :until, :iter, :for, :break, :next,
178
- :redo, :retry, :begin, :rescue, :resbody,
179
- # 20
180
- :ensure, :and, :or, :not, :masgn,
181
- :lasgn, :dasgn, :dasgn_curr, :gasgn, :iasgn,
182
- # 30
183
- :cdecl, :cvasgn, :cvdecl, :op_asgn1, :op_asgn2,
184
- :op_asgn_and, :op_asgn_or, :call, :fcall, :vcall,
185
- # 40
186
- :super, :zsuper, :array, :zarray, :hash,
187
- :return, :yield, :lvar, :dvar, :gvar,
188
- # 50
189
- :ivar, :const, :cvar, :nth_ref, :back_ref,
190
- :match, :match2, :match3, :lit, :str,
191
- # 60
192
- :dstr, :xstr, :dxstr, :evstr, :dregx,
193
- :dregx_once, :args, :argscat, :argspush, :splat,
194
- # 70
195
- :to_ary, :svalue, :block_arg, :block_pass, :defn,
196
- :defs, :alias, :valias, :undef, :class,
197
- # 80
198
- :module, :sclass, :colon2, :colon3, :cref,
199
- :dot2, :dot3, :flip2, :flip3, :attrset,
200
- # 90
201
- :self, :nil, :true, :false, :defined,
202
- # 95
203
- :newline, :postexe, :alloca, :dmethod, :bmethod,
204
- # 100
205
- :memo, :ifunc, :dsym, :attrasgn,
206
- :last
207
- ]
208
-
209
- if RUBY_VERSION < "1.8.4" then
210
- NODE_NAMES.delete :alloca unless has_alloca
211
- end
212
-
213
- if RUBY_VERSION > "1.9" then
214
- NODE_NAMES.insert NODE_NAMES.index(:hash), :values
215
- NODE_NAMES.insert NODE_NAMES.index(:defined), :errinfo
216
- NODE_NAMES.insert NODE_NAMES.index(:last), :prelude, :lambda
217
- NODE_NAMES.delete :dmethod
218
- NODE_NAMES[128] = NODE_NAMES.delete :newline
219
- end
220
-
221
- ############################################################
222
- # END of rdoc methods
223
- ############################################################
224
-
225
- inline do |builder|
226
- builder.add_type_converter("bool", '', '')
227
- builder.add_type_converter("ID *", '', '')
228
- builder.add_type_converter("NODE *", '(NODE *)', '(VALUE)')
229
- builder.include '"intern.h"'
230
- builder.include '"version.h"'
231
- builder.include '"rubysig.h"'
232
- builder.include '"node.h"'
233
- builder.include '"st.h"'
234
- builder.include '"env.h"'
235
- builder.add_compile_flags "-Wall"
236
- builder.add_compile_flags "-W"
237
- builder.add_compile_flags "-Wpointer-arith"
238
- builder.add_compile_flags "-Wcast-qual"
239
- builder.add_compile_flags "-Wcast-align"
240
- builder.add_compile_flags "-Wwrite-strings"
241
- builder.add_compile_flags "-Wmissing-noreturn"
242
- # NOTE: If you get weird compiler errors like:
243
- # dereferencing type-punned pointer will break strict-aliasing rules
244
- # PLEASE do one of the following:
245
- # 1) Get me a login on your box so I can repro this and get it fixed.
246
- # 2) Fix it and send me the patch
247
- # 3) (quick, but dirty and bad), comment out the following line:
248
- builder.add_compile_flags "-Werror"
249
- # NOTE: this flag doesn't work w/ gcc 2.95.x - the FreeBSD default
250
- # builder.add_compile_flags "-Wno-strict-aliasing"
251
- # ruby.h screws these up hardcore:
252
- # builder.add_compile_flags "-Wundef"
253
- # builder.add_compile_flags "-Wconversion"
254
- # builder.add_compile_flags "-Wstrict-prototypes"
255
- # builder.add_compile_flags "-Wmissing-prototypes"
256
- # builder.add_compile_flags "-Wsign-compare"
257
-
258
- def self.if_version(test, version, str)
259
- RUBY_VERSION.send(test, version) ? str : ""
260
- end
261
-
262
- builder.prefix %{
263
- #define nd_3rd u3.node
264
- static unsigned case_level = 0;
265
- }
266
-
267
- builder.prefix %{
268
- static VALUE wrap_into_node(const char * name, VALUE val) {
269
- VALUE n = rb_ary_new();
270
- rb_ary_push(n, ID2SYM(rb_intern(name)));
271
- rb_ary_push(n, val);
272
- return n;
273
- }
274
- }
275
-
276
- builder.prefix %{
277
- struct METHOD {
278
- VALUE klass, rklass;
279
- VALUE recv;
280
- ID id, oid;
281
- #{if_version :>, "1.8.2", "int safe_level;"}
282
- NODE *body;
283
- };
284
-
285
- struct BLOCK {
286
- NODE *var;
287
- NODE *body;
288
- VALUE self;
289
- struct FRAME frame;
290
- struct SCOPE *scope;
291
- VALUE klass;
292
- NODE *cref;
293
- int iter;
294
- int vmode;
295
- int flags;
296
- int uniq;
297
- struct RVarmap *dyna_vars;
298
- VALUE orig_thread;
299
- VALUE wrapper;
300
- VALUE block_obj;
301
- struct BLOCK *outer;
302
- struct BLOCK *prev;
303
- };
304
- } unless RUBY_VERSION >= "1.9" # we got matz to add this to env.h
305
-
306
- ##
307
- # add_to_parse_tree(ary, node, include_newlines, local_variables)
308
-
309
- builder.c_raw %Q@
310
- static void add_to_parse_tree(VALUE ary,
311
- NODE * n,
312
- VALUE newlines,
313
- ID * locals) {
314
- NODE * volatile node = n;
315
- NODE * volatile contnode = NULL;
316
- VALUE old_ary = Qnil;
317
- VALUE current;
318
- VALUE node_name;
319
- static VALUE node_names = Qnil;
320
-
321
- if (NIL_P(node_names)) {
322
- node_names = rb_const_get_at(rb_path2class("ParseTree"),rb_intern("NODE_NAMES"));
323
- }
324
-
325
- if (!node) return;
326
-
327
- again:
328
-
329
- if (node) {
330
- node_name = rb_ary_entry(node_names, nd_type(node));
331
- if (RTEST(ruby_debug)) {
332
- fprintf(stderr, "%15s: %s%s%s\\n",
333
- rb_id2name(SYM2ID(node_name)),
334
- (RNODE(node)->u1.node != NULL ? "u1 " : " "),
335
- (RNODE(node)->u2.node != NULL ? "u2 " : " "),
336
- (RNODE(node)->u3.node != NULL ? "u3 " : " "));
337
- }
338
- } else {
339
- node_name = ID2SYM(rb_intern("ICKY"));
340
- }
341
-
342
- current = rb_ary_new();
343
- rb_ary_push(ary, current);
344
- rb_ary_push(current, node_name);
345
-
346
- again_no_block:
347
-
348
- switch (nd_type(node)) {
349
-
350
- case NODE_BLOCK:
351
- if (contnode) {
352
- add_to_parse_tree(current, node, newlines, locals);
353
- break;
354
- }
355
- contnode = node->nd_next;
356
-
357
- // FIX: this will break the moment there is a block w/in a block
358
- old_ary = ary;
359
- ary = current;
360
- node = node->nd_head;
361
- if (nd_type(node) == NODE_DASGN_CURR
362
- && (!node->nd_value || nd_type(node->nd_value) == NODE_DASGN_CURR)) {
363
- goto finish;
364
- }
365
- goto again;
366
- break;
367
-
368
- case NODE_FBODY:
369
- case NODE_DEFINED:
370
- add_to_parse_tree(current, node->nd_head, newlines, locals);
371
- break;
372
-
373
- case NODE_COLON2:
374
- add_to_parse_tree(current, node->nd_head, newlines, locals);
375
- rb_ary_push(current, ID2SYM(node->nd_mid));
376
- break;
377
-
378
- case NODE_MATCH2:
379
- case NODE_MATCH3:
380
- add_to_parse_tree(current, node->nd_recv, newlines, locals);
381
- add_to_parse_tree(current, node->nd_value, newlines, locals);
382
- break;
383
-
384
- case NODE_BEGIN:
385
- case NODE_OPT_N:
386
- case NODE_NOT:
387
- add_to_parse_tree(current, node->nd_body, newlines, locals);
388
- break;
389
-
390
- case NODE_IF:
391
- add_to_parse_tree(current, node->nd_cond, newlines, locals);
392
- if (node->nd_body) {
393
- add_to_parse_tree(current, node->nd_body, newlines, locals);
394
- } else {
395
- rb_ary_push(current, Qnil);
396
- }
397
- if (node->nd_else) {
398
- add_to_parse_tree(current, node->nd_else, newlines, locals);
399
- } else {
400
- rb_ary_push(current, Qnil);
401
- }
402
- break;
403
-
404
- case NODE_CASE:
405
- case_level++;
406
- if (node->nd_head != NULL) {
407
- add_to_parse_tree(current, node->nd_head, newlines, locals); /* expr */
408
- } else {
409
- rb_ary_push(current, Qnil);
410
- }
411
- node = node->nd_body;
412
- while (node) {
413
- add_to_parse_tree(current, node, newlines, locals);
414
- if (nd_type(node) == NODE_WHEN) { /* when */
415
- node = node->nd_next;
416
- } else {
417
- break; /* else */
418
- }
419
- if (! node) {
420
- rb_ary_push(current, Qnil); /* no else */
421
- }
422
- }
423
- case_level--;
424
- break;
425
-
426
- case NODE_WHEN:
427
- if (!case_level) { /* when without case, ie, no expr in case */
428
- rb_ary_pop(ary); /* reset what current is pointing at */
429
- node = NEW_CASE(0, node);
430
- goto again;
431
- }
432
- add_to_parse_tree(current, node->nd_head, newlines, locals); /* args */
433
- if (node->nd_body) {
434
- add_to_parse_tree(current, node->nd_body, newlines, locals); /* body */
435
- } else {
436
- rb_ary_push(current, Qnil);
437
- }
438
- break;
439
-
440
- case NODE_WHILE:
441
- case NODE_UNTIL:
442
- add_to_parse_tree(current, node->nd_cond, newlines, locals);
443
- if (node->nd_body) {
444
- add_to_parse_tree(current, node->nd_body, newlines, locals);
445
- } else {
446
- rb_ary_push(current, Qnil);
447
- }
448
- rb_ary_push(current, node->nd_3rd == 0 ? Qfalse : Qtrue);
449
- break;
450
-
451
- case NODE_BLOCK_PASS:
452
- add_to_parse_tree(current, node->nd_body, newlines, locals);
453
- add_to_parse_tree(current, node->nd_iter, newlines, locals);
454
- break;
455
-
456
- case NODE_ITER:
457
- case NODE_FOR:
458
- add_to_parse_tree(current, node->nd_iter, newlines, locals);
459
- if (node->nd_var != (NODE *)1
460
- && node->nd_var != (NODE *)2
461
- && node->nd_var != NULL) {
462
- add_to_parse_tree(current, node->nd_var, newlines, locals);
463
- } else {
464
- if (node->nd_var == NULL)
465
- {
466
- // e.g. proc {}
467
- rb_ary_push(current, Qnil);
468
- }
469
- else
470
- {
471
- // e.g. proc {||}
472
- rb_ary_push(current, ID2SYM(rb_intern("zero_arguments")));
473
- }
474
- }
475
- add_to_parse_tree(current, node->nd_body, newlines, locals);
476
- break;
477
-
478
- case NODE_BREAK:
479
- case NODE_NEXT:
480
- case NODE_YIELD:
481
- if (node->nd_stts)
482
- add_to_parse_tree(current, node->nd_stts, newlines, locals);
483
- break;
484
-
485
- case NODE_RESCUE:
486
- add_to_parse_tree(current, node->nd_1st, newlines, locals);
487
- add_to_parse_tree(current, node->nd_2nd, newlines, locals);
488
- add_to_parse_tree(current, node->nd_3rd, newlines, locals);
489
- break;
490
-
491
- // rescue body:
492
- // begin stmt rescue exception => var; stmt; [rescue e2 => v2; s2;]* end
493
- // stmt rescue stmt
494
- // a = b rescue c
495
-
496
- case NODE_RESBODY:
497
- if (node->nd_3rd) {
498
- add_to_parse_tree(current, node->nd_3rd, newlines, locals);
499
- } else {
500
- rb_ary_push(current, Qnil);
501
- }
502
- add_to_parse_tree(current, node->nd_2nd, newlines, locals);
503
- add_to_parse_tree(current, node->nd_1st, newlines, locals);
504
- break;
505
-
506
- case NODE_ENSURE:
507
- add_to_parse_tree(current, node->nd_head, newlines, locals);
508
- if (node->nd_ensr) {
509
- add_to_parse_tree(current, node->nd_ensr, newlines, locals);
510
- }
511
- break;
512
-
513
- case NODE_AND:
514
- case NODE_OR:
515
- add_to_parse_tree(current, node->nd_1st, newlines, locals);
516
- add_to_parse_tree(current, node->nd_2nd, newlines, locals);
517
- break;
518
-
519
- case NODE_DOT2:
520
- case NODE_DOT3:
521
- case NODE_FLIP2:
522
- case NODE_FLIP3:
523
- add_to_parse_tree(current, node->nd_beg, newlines, locals);
524
- add_to_parse_tree(current, node->nd_end, newlines, locals);
525
- break;
526
-
527
- case NODE_RETURN:
528
- if (node->nd_stts)
529
- add_to_parse_tree(current, node->nd_stts, newlines, locals);
530
- break;
531
-
532
- case NODE_ARGSCAT:
533
- case NODE_ARGSPUSH:
534
- add_to_parse_tree(current, node->nd_head, newlines, locals);
535
- add_to_parse_tree(current, node->nd_body, newlines, locals);
536
- break;
537
-
538
- case NODE_CALL:
539
- case NODE_FCALL:
540
- case NODE_VCALL:
541
- if (nd_type(node) != NODE_FCALL)
542
- add_to_parse_tree(current, node->nd_recv, newlines, locals);
543
- rb_ary_push(current, ID2SYM(node->nd_mid));
544
- if (node->nd_args || nd_type(node) != NODE_FCALL)
545
- add_to_parse_tree(current, node->nd_args, newlines, locals);
546
- break;
547
-
548
- case NODE_SUPER:
549
- add_to_parse_tree(current, node->nd_args, newlines, locals);
550
- break;
551
-
552
- case NODE_BMETHOD:
553
- {
554
- struct BLOCK *data;
555
- Data_Get_Struct(node->nd_cval, struct BLOCK, data);
556
- add_to_parse_tree(current, data->var, newlines, locals);
557
- add_to_parse_tree(current, data->body, newlines, locals);
558
- break;
559
- }
560
- break;
561
-
562
- #{if_version :>, "1.9", '#if 0'}
563
- case NODE_DMETHOD:
564
- {
565
- struct METHOD *data;
566
- Data_Get_Struct(node->nd_cval, struct METHOD, data);
567
- rb_ary_push(current, ID2SYM(data->id));
568
- add_to_parse_tree(current, data->body, newlines, locals);
569
- break;
570
- }
571
- #{if_version :>, "1.9", '#endif'}
572
-
573
- case NODE_METHOD:
574
- fprintf(stderr, "u1 = %p u2 = %p u3 = %p\\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
575
- add_to_parse_tree(current, node->nd_3rd, newlines, locals);
576
- break;
577
-
578
- case NODE_SCOPE:
579
- add_to_parse_tree(current, node->nd_next, newlines, node->nd_tbl);
580
- break;
581
-
582
- case NODE_OP_ASGN1:
583
- add_to_parse_tree(current, node->nd_recv, newlines, locals);
584
- #{if_version :>, "1.8.4", "#if 0"}
585
- #{if_version :<=, "1.8.4", "#if 1"}
586
- add_to_parse_tree(current, node->nd_args->nd_next, newlines, locals);
587
- rb_ary_pop(rb_ary_entry(current, -1)); // no idea why I need this
588
- #else
589
- add_to_parse_tree(current, node->nd_args->nd_2nd, newlines, locals);
590
- #endif
591
- switch (node->nd_mid) {
592
- case 0:
593
- rb_ary_push(current, ID2SYM(rb_intern("||")));
594
- break;
595
- case 1:
596
- rb_ary_push(current, ID2SYM(rb_intern("&&")));
597
- break;
598
- default:
599
- rb_ary_push(current, ID2SYM(node->nd_mid));
600
- break;
601
- }
602
- add_to_parse_tree(current, node->nd_args->nd_head, newlines, locals);
603
- break;
604
-
605
- case NODE_OP_ASGN2:
606
- add_to_parse_tree(current, node->nd_recv, newlines, locals);
607
- rb_ary_push(current, ID2SYM(node->nd_next->nd_aid));
608
-
609
- switch (node->nd_next->nd_mid) {
610
- case 0:
611
- rb_ary_push(current, ID2SYM(rb_intern("||")));
612
- break;
613
- case 1:
614
- rb_ary_push(current, ID2SYM(rb_intern("&&")));
615
- break;
616
- default:
617
- rb_ary_push(current, ID2SYM(node->nd_next->nd_mid));
618
- break;
619
- }
620
-
621
- add_to_parse_tree(current, node->nd_value, newlines, locals);
622
- break;
623
-
624
- case NODE_OP_ASGN_AND:
625
- case NODE_OP_ASGN_OR:
626
- add_to_parse_tree(current, node->nd_head, newlines, locals);
627
- add_to_parse_tree(current, node->nd_value, newlines, locals);
628
- break;
629
-
630
- case NODE_MASGN:
631
- add_to_parse_tree(current, node->nd_head, newlines, locals);
632
- if (node->nd_args && node->nd_args != (NODE *)-1) {
633
- add_to_parse_tree(current, node->nd_args, newlines, locals);
634
- }
635
- add_to_parse_tree(current, node->nd_value, newlines, locals);
636
- break;
637
-
638
- case NODE_LASGN:
639
- case NODE_IASGN:
640
- case NODE_DASGN:
641
- case NODE_DASGN_CURR:
642
- case NODE_CDECL:
643
- case NODE_CVASGN:
644
- case NODE_CVDECL:
645
- case NODE_GASGN:
646
- rb_ary_push(current, ID2SYM(node->nd_vid));
647
- add_to_parse_tree(current, node->nd_value, newlines, locals);
648
- break;
649
-
650
- case NODE_VALIAS: // u1 u2 (alias $global $global2)
651
- #{if_version :>, "1.8.4", "#if 0"}
652
- #{if_version :<=, "1.8.4", "#if 1"}
653
- rb_ary_push(current, ID2SYM(node->u2.id));
654
- rb_ary_push(current, ID2SYM(node->u1.id));
655
- #else
656
- rb_ary_push(current, ID2SYM(node->u1.id));
657
- rb_ary_push(current, ID2SYM(node->u2.id));
658
- #endif
659
- break;
660
- case NODE_ALIAS: // u1 u2 (alias :blah :blah2)
661
- #{if_version :>, "1.8.4", "#if 0"}
662
- #{if_version :<=, "1.8.4", "#if 1"}
663
- rb_ary_push(current, wrap_into_node("lit", ID2SYM(node->u2.id)));
664
- rb_ary_push(current, wrap_into_node("lit", ID2SYM(node->u1.id)));
665
- #else
666
- add_to_parse_tree(current, node->nd_1st, newlines, locals);
667
- add_to_parse_tree(current, node->nd_2nd, newlines, locals);
668
- #endif
669
- break;
670
-
671
- case NODE_UNDEF: // u2 (undef name, ...)
672
- #{if_version :>, "1.8.4", "#if 0"}
673
- #{if_version :<=, "1.8.4", "#if 1"}
674
- rb_ary_push(current, wrap_into_node("lit", ID2SYM(node->u2.id)));
675
- #else
676
- add_to_parse_tree(current, node->nd_value, newlines, locals);
677
- #endif
678
- break;
679
-
680
- case NODE_COLON3: // u2 (::OUTER_CONST)
681
- rb_ary_push(current, ID2SYM(node->u2.id));
682
- break;
683
-
684
- case NODE_HASH:
685
- {
686
- NODE *list;
687
-
688
- list = node->nd_head;
689
- while (list) {
690
- add_to_parse_tree(current, list->nd_head, newlines, locals);
691
- list = list->nd_next;
692
- if (list == 0)
693
- rb_bug("odd number list for Hash");
694
- add_to_parse_tree(current, list->nd_head, newlines, locals);
695
- list = list->nd_next;
696
- }
697
- }
698
- break;
699
-
700
- case NODE_ARRAY:
701
- while (node) {
702
- add_to_parse_tree(current, node->nd_head, newlines, locals);
703
- node = node->nd_next;
704
- }
705
- break;
706
-
707
- case NODE_DSTR:
708
- case NODE_DSYM:
709
- case NODE_DXSTR:
710
- case NODE_DREGX:
711
- case NODE_DREGX_ONCE:
712
- {
713
- NODE *list = node->nd_next;
714
- rb_ary_push(current, rb_str_new3(node->nd_lit));
715
- while (list) {
716
- if (list->nd_head) {
717
- switch (nd_type(list->nd_head)) {
718
- case NODE_STR:
719
- add_to_parse_tree(current, list->nd_head, newlines, locals);
720
- break;
721
- case NODE_EVSTR:
722
- add_to_parse_tree(current, list->nd_head->nd_body, newlines, locals);
723
- break;
724
- default:
725
- add_to_parse_tree(current, list->nd_head, newlines, locals);
726
- break;
727
- }
728
- }
729
- list = list->nd_next;
730
- }
731
- }
732
- break;
733
-
734
- case NODE_DEFN:
735
- case NODE_DEFS:
736
- if (node->nd_defn) {
737
- if (nd_type(node) == NODE_DEFS)
738
- add_to_parse_tree(current, node->nd_recv, newlines, locals);
739
- rb_ary_push(current, ID2SYM(node->nd_mid));
740
- add_to_parse_tree(current, node->nd_defn, newlines, locals);
741
- }
742
- break;
743
-
744
- case NODE_CLASS:
745
- case NODE_MODULE:
746
- rb_ary_push(current, ID2SYM((ID)node->nd_cpath->nd_mid));
747
- if (nd_type(node) == NODE_CLASS) {
748
- if (node->nd_super) {
749
- add_to_parse_tree(current, node->nd_super, newlines, locals);
750
- } else {
751
- rb_ary_push(current, Qnil);
752
- }
753
- }
754
- add_to_parse_tree(current, node->nd_body, newlines, locals);
755
- break;
756
-
757
- case NODE_SCLASS:
758
- add_to_parse_tree(current, node->nd_recv, newlines, locals);
759
- add_to_parse_tree(current, node->nd_body, newlines, locals);
760
- break;
761
-
762
- case NODE_ARGS: {
763
- long arg_count = (long)node->nd_rest;
764
- if (locals && (node->nd_cnt || node->nd_opt || arg_count != -1)) {
765
- int i;
766
- int max_args;
767
- NODE *optnode;
768
-
769
- max_args = node->nd_cnt;
770
- for (i = 0; i < max_args; i++) {
771
- // regular arg names
772
- rb_ary_push(current, ID2SYM(locals[i + 3]));
773
- }
774
-
775
- optnode = node->nd_opt;
776
- while (optnode) {
777
- // optional arg names
778
- rb_ary_push(current, ID2SYM(locals[i + 3]));
779
- i++;
780
- optnode = optnode->nd_next;
781
- }
782
-
783
- if (arg_count > 0) {
784
- // *arg name
785
- VALUE sym = rb_str_intern(rb_str_plus(rb_str_new2("*"), rb_str_new2(rb_id2name(locals[i + 3]))));
786
- rb_ary_push(current, sym);
787
- } else if (arg_count == 0) {
788
- // nothing to do in this case, empty list
789
- } else if (arg_count == -1) {
790
- // nothing to do in this case, handled above
791
- } else if (arg_count == -2) {
792
- // nothing to do in this case, no name == no use
793
- } else {
794
- rb_raise(rb_eArgError,
795
- "not a clue what this arg value is: %ld", arg_count);
796
- }
797
-
798
- optnode = node->nd_opt;
799
- // block?
800
- if (optnode) {
801
- add_to_parse_tree(current, node->nd_opt, newlines, locals);
802
- }
803
- }
804
- } break;
805
-
806
- case NODE_LVAR:
807
- case NODE_DVAR:
808
- case NODE_IVAR:
809
- case NODE_CVAR:
810
- case NODE_GVAR:
811
- case NODE_CONST:
812
- case NODE_ATTRSET:
813
- rb_ary_push(current, ID2SYM(node->nd_vid));
814
- break;
815
-
816
- case NODE_XSTR: // u1 (%x{ls})
817
- case NODE_STR: // u1
818
- case NODE_LIT:
819
- rb_ary_push(current, node->nd_lit);
820
- break;
821
-
822
- case NODE_MATCH: // u1 -> [:lit, u1]
823
- {
824
- rb_ary_push(current, wrap_into_node("lit", node->nd_lit));
825
- }
826
- break;
827
-
828
- case NODE_NEWLINE:
829
- rb_ary_push(current, INT2FIX(nd_line(node)));
830
- rb_ary_push(current, rb_str_new2(node->nd_file));
831
-
832
- if (! RTEST(newlines)) rb_ary_pop(ary); // nuke it
833
-
834
- node = node->nd_next;
835
- goto again;
836
- break;
837
-
838
- case NODE_NTH_REF: // u2 u3 ($1) - u3 is local_cnt('~') ignorable?
839
- rb_ary_push(current, INT2FIX(node->nd_nth));
840
- break;
841
-
842
- case NODE_BACK_REF: // u2 u3 ($& etc)
843
- {
844
- char c = node->nd_nth;
845
- rb_ary_push(current, rb_str_intern(rb_str_new(&c, 1)));
846
- }
847
- break;
848
-
849
- case NODE_BLOCK_ARG: // u1 u3 (def x(&b)
850
- rb_ary_push(current, ID2SYM(node->u1.id));
851
- break;
852
-
853
- // these nodes are empty and do not require extra work:
854
- case NODE_RETRY:
855
- case NODE_FALSE:
856
- case NODE_NIL:
857
- case NODE_SELF:
858
- case NODE_TRUE:
859
- case NODE_ZARRAY:
860
- case NODE_ZSUPER:
861
- case NODE_REDO:
862
- break;
863
-
864
- case NODE_SPLAT:
865
- case NODE_TO_ARY:
866
- case NODE_SVALUE: // a = b, c
867
- add_to_parse_tree(current, node->nd_head, newlines, locals);
868
- break;
869
-
870
- case NODE_ATTRASGN: // literal.meth = y u1 u2 u3
871
- // node id node
872
- if (node->nd_1st == RNODE(1)) {
873
- add_to_parse_tree(current, NEW_SELF(), newlines, locals);
874
- } else {
875
- add_to_parse_tree(current, node->nd_1st, newlines, locals);
876
- }
877
- rb_ary_push(current, ID2SYM(node->u2.id));
878
- add_to_parse_tree(current, node->nd_3rd, newlines, locals);
879
- break;
880
-
881
- case NODE_EVSTR:
882
- add_to_parse_tree(current, node->nd_2nd, newlines, locals);
883
- break;
884
-
885
- case NODE_POSTEXE: // END { ... }
886
- // Nothing to do here... we are in an iter block
887
- break;
888
-
889
- case NODE_CFUNC:
890
- rb_ary_push(current, INT2FIX(node->nd_cfnc));
891
- rb_ary_push(current, INT2FIX(node->nd_argc));
892
- break;
893
-
894
- #{if_version :<, "1.9", "#if 0"}
895
- case NODE_ERRINFO:
896
- case NODE_VALUES:
897
- case NODE_PRELUDE:
898
- case NODE_LAMBDA:
899
- puts("no worky in 1.9 yet");
900
- break;
901
- #{if_version :<, "1.9", "#endif"}
902
-
903
- // Nodes we found but have yet to decypher
904
- // I think these are all runtime only... not positive but...
905
- case NODE_MEMO: // enum.c zip
906
- case NODE_CREF:
907
- case NODE_IFUNC:
908
- // #defines:
909
- // case NODE_LMASK:
910
- // case NODE_LSHIFT:
911
- default:
912
- rb_warn("Unhandled node #%d type '%s'", nd_type(node), rb_id2name(SYM2ID(rb_ary_entry(node_names, nd_type(node)))));
913
- if (RNODE(node)->u1.node != NULL) rb_warning("unhandled u1 value");
914
- if (RNODE(node)->u2.node != NULL) rb_warning("unhandled u2 value");
915
- if (RNODE(node)->u3.node != NULL) rb_warning("unhandled u3 value");
916
- if (RTEST(ruby_debug)) fprintf(stderr, "u1 = %p u2 = %p u3 = %p\\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
917
- rb_ary_push(current, INT2FIX(-99));
918
- rb_ary_push(current, INT2FIX(nd_type(node)));
919
- break;
920
- }
921
-
922
- finish:
923
- if (contnode) {
924
- node = contnode;
925
- contnode = NULL;
926
- current = ary;
927
- ary = old_ary;
928
- old_ary = Qnil;
929
- goto again_no_block;
930
- }
931
- }
932
- @ # end of add_to_parse_tree block
933
-
934
- builder.c %Q{
935
- static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE newlines, VALUE is_cls_meth) {
936
- VALUE n;
937
- NODE *node = NULL;
938
- ID id;
939
- VALUE result = rb_ary_new();
940
- VALUE version = rb_const_get_at(rb_cObject,rb_intern("RUBY_VERSION"));
941
-
942
- (void) self; // quell warnings
943
-
944
- if (strcmp(StringValuePtr(version), #{RUBY_VERSION.inspect})) {
945
- rb_fatal("bad version, %s != #{RUBY_VERSION}\\n", StringValuePtr(version));
946
- }
947
-
948
- id = rb_to_id(method);
949
- if (RTEST(is_cls_meth)) { // singleton method
950
- klass = CLASS_OF(klass);
951
- }
952
- if (st_lookup(RCLASS(klass)->m_tbl, id, &n)) {
953
- node = (NODE*)n;
954
- rb_ary_push(result, ID2SYM(rb_intern("defn")));
955
- rb_ary_push(result, ID2SYM(id));
956
- add_to_parse_tree(result, node->nd_body, newlines, NULL);
957
- } else {
958
- rb_ary_push(result, Qnil);
959
- }
960
-
961
- return result;
962
- }
963
- }
964
-
965
- builder.prefix " extern NODE *ruby_eval_tree_begin; " \
966
- if RUBY_VERSION < '1.9.0'
967
-
968
- builder.c %Q{
969
- static VALUE parse_tree_for_str(VALUE source, VALUE filename, VALUE line,
970
- VALUE newlines) {
971
- VALUE tmp;
972
- VALUE result = rb_ary_new();
973
- NODE *node = NULL;
974
- int critical;
975
-
976
- (void) self; // quell warnings
977
-
978
- tmp = rb_check_string_type(filename);
979
- if (NIL_P(tmp)) {
980
- filename = rb_str_new2("(string)");
981
- }
982
-
983
- if (NIL_P(line)) {
984
- line = LONG2FIX(1);
985
- }
986
-
987
- newlines = RTEST(newlines);
988
-
989
- ruby_nerrs = 0;
990
- StringValue(source);
991
- critical = rb_thread_critical;
992
- rb_thread_critical = Qtrue;
993
- ruby_in_eval++;
994
- node = rb_compile_string(StringValuePtr(filename), source, NUM2INT(line));
995
- ruby_in_eval--;
996
- rb_thread_critical = critical;
997
-
998
- if (ruby_nerrs > 0) {
999
- ruby_nerrs = 0;
1000
- #if RUBY_VERSION_CODE < 190
1001
- ruby_eval_tree_begin = 0;
1002
- #endif
1003
- rb_exc_raise(ruby_errinfo);
1004
- }
1005
-
1006
- add_to_parse_tree(result, node, newlines, NULL);
1007
-
1008
- return result;
1009
- }
1010
- }
1011
-
1012
- end # inline call
1013
- end # ParseTree class