ruby2ruby 1.1.7 → 1.1.8

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.
data/.autotest ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ Autotest.add_hook :initialize do |at|
4
+ at.extra_files << "../../ParseTree/dev/test/pt_testcase.rb"
5
+ at.extra_files << "../../ParseTree/dev/lib/unified_ruby.rb"
6
+ at.libs << ":../../ParseTree/dev/lib:../../ParseTree/dev/test"
7
+
8
+ (1..4).each do |n|
9
+ at.extra_class_map["TestRuby2Ruby#{n}"] = "test/test_ruby2ruby.rb"
10
+ end
11
+
12
+ at.add_mapping(/unified|pt_testcase/) do |f, _|
13
+ at.files_matching(/^test.*rb$/)
14
+ end
15
+ end
data/History.txt CHANGED
@@ -1,15 +1,36 @@
1
+ === 1.1.8 / 2007-08-21
2
+
3
+ * 6 minor enhancements:
4
+
5
+ * Added super awesome .autotest file. YAY!
6
+ * Removed nil.method_missing... too many ppl bitching about it.
7
+ * Renamed RubyToRuby (the class name) to Ruby2Ruby.
8
+ * Restructured self-translation tests so they were friendlier when dying.
9
+ * Strings are now always one line long only.
10
+ * Fully in sync with ParseTree and ruby_parser.
11
+
12
+ * 2 bug fixes:
13
+
14
+ * Fixed a number of issues/bugs discovered via ruby_parser.
15
+ * Cleaned out some dead code and hacks we don't need anymore.
16
+
1
17
  === 1.1.7 / 2007-08-21
2
18
 
3
19
  * 2 major enhancements:
20
+
4
21
  * Switched to ParseTree's UnifiedRuby... much much cleaner now!
5
22
  * Made test_ruby2ruby MUCH more rigorous with circular testing.
23
+
6
24
  * 5 minor enhancements:
25
+
7
26
  * Add r2r_show command like parse_tree_show.
8
27
  * Add parens for :block nodes as appropriate. May be overzealous.
9
28
  * Make SexpAny work with #==.
10
29
  * Removed calls to processor_stack / caller in favor of self.context.
11
30
  * Some style differences, eschew rescue.
31
+
12
32
  * 6 bug fixes:
33
+
13
34
  * Fix R2R bug with masgn/argscat.
14
35
  * Fixed a bug with new resbody unification.
15
36
  * Fixes for changes to pt_testcase.
@@ -20,19 +41,25 @@
20
41
  === 1.1.6 / 2007-06-05
21
42
 
22
43
  * 2 minor enhancements:
44
+
23
45
  * Extended tests for dstr/dsym/drgx to test against embedded slashes and quotes.
24
46
  * Updated for dasgn_curr changes to PT.
47
+
25
48
  * 2 bug fixes:
49
+
26
50
  * Fixed a bug with begin/rescue/ensure.
27
51
  * Fixed argscat and blockpass bug. blah(42, *args, &block) handled.
28
52
 
29
53
  === 1.1.5 / 2007-02-13
30
54
 
31
55
  * 3 minor enhancements:
56
+
32
57
  * Can now heckle ActiveRecord::Base in full.
33
58
  * Cleaned up 1-liner generating code.
34
59
  * Made clean/simple rescues 1-liners.
60
+
35
61
  * 7 bug fixes:
62
+
36
63
  * Finally got the rest of block_pass working.
37
64
  * Fixed block_pass on procs in iters. UGH!
38
65
  * Fixed attrasgn in masgn.
@@ -44,11 +71,14 @@
44
71
  === 1.1.4 / 2007-01-15
45
72
 
46
73
  * 4 minor enhancements:
74
+
47
75
  * Added some extra rewriting code and tests for various bmethods. Ugh.
48
76
  * Added support for splatted block args.
49
77
  * Refactored class/module and dsym/dstr.
50
78
  * Short if/unless statements are now post-conditional expressions.
79
+
51
80
  * 4 bug fixes:
81
+
52
82
  * Finally fixed eric's nebulous proc code-in-goalposts bug.
53
83
  * Fixed dasgn_curr so block's dasgn vars decl goes away (bug 7420).
54
84
  * Fixed dmethod. I think the tests were bogus before.
@@ -57,16 +87,22 @@
57
87
  === 1.1.3 / 2006-12-20
58
88
 
59
89
  * 1 minor enhancement
90
+
60
91
  * Unit tests do self-translation and retesting for 3 generations! Solid. BAM!
92
+
61
93
  * 1 bug fixes
94
+
62
95
  * iasgn inside masgn was totally borked in ruby2ruby.
63
96
 
64
97
  === 1.1.2 / 2006-12-19
65
98
 
66
99
  * 2 minor enhancements
100
+
67
101
  * Improved []= and [] to be more idiomatic.
68
102
  * Support for nested whens (from when case has no expression).
103
+
69
104
  * 3 bug fixes
105
+
70
106
  * Fixed case output when there is no case expression.
71
107
  * NEARLY have RubyToRuby self-cloning and passing tests again.
72
108
  * Minor cleanup
@@ -74,6 +110,7 @@
74
110
  === 1.1.1 / 2006-11-13
75
111
 
76
112
  * 3 bug fixes
113
+
77
114
  * Fixed procs
78
115
  * Cleaned return when no return values.
79
116
  * Rewrote process_if. No more elsif but no more bugs. :)
@@ -81,7 +118,6 @@
81
118
  === 1.1.0 / 2006-10-11
82
119
 
83
120
  * 2 major enhancements
121
+
84
122
  * Released separately from ZenHacks.
85
123
  * Major overhaul/audit from the new ParseTree test infrastructure. Very complete now.
86
-
87
-
data/Manifest.txt CHANGED
@@ -1,3 +1,4 @@
1
+ .autotest
1
2
  History.txt
2
3
  Manifest.txt
3
4
  README.txt
data/README.txt CHANGED
@@ -28,7 +28,7 @@ easier in ruby than ever before.
28
28
 
29
29
  (The MIT License)
30
30
 
31
- Copyright (c) 2006 Ryan Davis
31
+ Copyright (c) 2006-2007 Ryan Davis
32
32
 
33
33
  Permission is hereby granted, free of charge, to any person obtaining
34
34
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ Hoe.new('ruby2ruby', RubyToRuby::VERSION) do |p|
13
13
  p.summary = 'ruby2ruby provides a means of generating pure ruby code easily from ParseTree\'s Sexps.'
14
14
  p.description = p.paragraphs_of('README.txt', 2).join
15
15
  p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1].map {|u| u.strip }
16
- p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
+ p.changes = p.paragraphs_of('History.txt', 0..4).join("\n\n")
17
17
  p.clean_globs << File.expand_path("~/.ruby_inline")
18
18
  p.extra_deps << "ParseTree"
19
19
  end
data/lib/ruby2ruby.rb CHANGED
@@ -5,16 +5,10 @@ require 'parse_tree'
5
5
  require 'sexp_processor'
6
6
  require 'unified_ruby'
7
7
 
8
- class NilClass # Objective-C trick
9
- def method_missing(msg, *args, &block)
10
- nil
11
- end
12
- end
13
-
14
- class RubyToRuby < SexpProcessor
8
+ class Ruby2Ruby < SexpProcessor
15
9
  include UnifiedRuby
16
10
 
17
- VERSION = '1.1.7'
11
+ VERSION = '1.1.8'
18
12
  LINE_LENGTH = 78
19
13
 
20
14
  ##
@@ -84,17 +78,6 @@ class RubyToRuby < SexpProcessor
84
78
  end
85
79
  when :block_arg then
86
80
  args << "&#{arg.last}"
87
- when :array then
88
- names = arg
89
- vals = exp.shift
90
- names.shift
91
- vals.shift
92
- v_size = vals.size
93
-
94
- args << process(names.shift) until names.size == v_size
95
- names.zip(vals) do |name, val|
96
- args << "#{process name} = #{process val}"
97
- end
98
81
  else
99
82
  raise "unknown arg type #{arg.first.inspect}"
100
83
  end
@@ -130,13 +113,7 @@ class RubyToRuby < SexpProcessor
130
113
  end
131
114
 
132
115
  def process_argspush(exp)
133
- args = []
134
-
135
- until exp.empty? do
136
- args << process(exp.shift)
137
- end
138
-
139
- "#{args.join ', '}"
116
+ process_arglist(exp)
140
117
  end
141
118
 
142
119
  def process_array(exp)
@@ -151,7 +128,7 @@ class RubyToRuby < SexpProcessor
151
128
  case name
152
129
  when :[]= then
153
130
  rhs = process args.pop
154
- args[0] = :arglist
131
+ args[0] = :arglist if args[0] == :array
155
132
  "#{receiver}[#{process(args)}] = #{rhs}"
156
133
  else
157
134
  if args then
@@ -172,7 +149,7 @@ class RubyToRuby < SexpProcessor
172
149
  code << "begin"
173
150
  until exp.empty?
174
151
  src = process(exp.shift)
175
- src = indent(src) unless src =~ /\nrescue/ # ensures no level 0 rescues
152
+ src = indent(src) unless src =~ /(^|\n)rescue/ # ensures no level 0 rescues
176
153
  code << src
177
154
  end
178
155
  code << "end" unless is_rescue
@@ -182,6 +159,7 @@ class RubyToRuby < SexpProcessor
182
159
  def process_block(exp)
183
160
  result = []
184
161
 
162
+ exp << nil if exp.empty?
185
163
  until exp.empty? do
186
164
  code = exp.shift
187
165
  if code.nil? or code.first == :nil then
@@ -240,11 +218,11 @@ class RubyToRuby < SexpProcessor
240
218
  end
241
219
 
242
220
  def process_call(exp)
243
- receiver_node_type = exp.first.first
221
+ receiver_node_type = exp.first.nil? ? nil : exp.first.first
244
222
  receiver = process exp.shift
245
223
 
246
224
  receiver = "(#{receiver})" if
247
- RubyToRuby::ASSIGN_NODES.include? receiver_node_type
225
+ Ruby2Ruby::ASSIGN_NODES.include? receiver_node_type
248
226
 
249
227
  name = exp.shift
250
228
  args_exp = exp.shift rescue nil
@@ -256,7 +234,7 @@ class RubyToRuby < SexpProcessor
256
234
  end
257
235
 
258
236
  case name
259
- when :<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>> then #
237
+ when :<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :** then
260
238
  "(#{receiver} #{name} #{args})"
261
239
  when :[] then
262
240
  "#{receiver}[#{args}]"
@@ -333,34 +311,32 @@ class RubyToRuby < SexpProcessor
333
311
 
334
312
  def process_dasgn_curr(exp)
335
313
  lhs = exp.shift.to_s
336
- rhs = exp.shift rescue nil
337
- return lhs if rhs.nil?
314
+ rhs = (exp.empty? ? nil : exp.shift)
315
+ if rhs.nil? then
316
+ if self.context[1] == :block then
317
+ return ''
318
+ end
319
+
320
+ return lhs
321
+ end
338
322
  return "#{lhs} = #{process rhs}" unless rhs.first == :dasgn_curr
339
323
 
340
324
  # keep recursing. ensure that the leaf node assigns to _something_
341
- rhs = process rhs
342
- if rhs =~ /=/ then
343
- "#{lhs} = #{rhs}"
344
- else
345
- ""
346
- end
325
+ "#{lhs} = #{process rhs}"
347
326
  end
348
327
 
349
328
  def process_dasgn(exp)
350
- "#{exp.shift.to_s} = #{process(exp.shift)}"
329
+ if exp.size == 1 then
330
+ exp.shift.to_s
331
+ else
332
+ "#{exp.shift} = #{process(exp.shift)}"
333
+ end
351
334
  end
352
335
 
353
336
  def process_defined(exp)
354
337
  "defined? #{process(exp.shift)}"
355
338
  end
356
339
 
357
- def process_defs(exp)
358
- receiver = process(exp.shift)
359
- name = exp.shift
360
- exp.unshift "#{receiver}.#{name}"
361
- process_defn(exp)
362
- end
363
-
364
340
  def process_defn(exp)
365
341
  type1 = exp[1].first
366
342
  type2 = exp[2].first rescue nil
@@ -380,32 +356,20 @@ class RubyToRuby < SexpProcessor
380
356
  end
381
357
 
382
358
  case type1
383
- when :cfunc then
384
- s = "# method '#{exp.shift}' defined in a C function"
385
- exp.shift
386
- return s
387
359
  when :scope, :args then
388
360
  name = exp.shift
389
361
  args = process(exp.shift)
390
362
  args = "" if args == "()"
391
363
  body = indent(process(exp.shift))
392
364
  return "def #{name}#{args}\n#{body}\nend".gsub(/\n\s*\n+/, "\n")
393
- when :fcall then
394
- # skip the fcall (to define_method and such) and grab the body
395
- name = exp.shift
396
- exp.shift # :fcall to define_method
397
- body = process(exp.shift)
398
- raise "no"
399
365
  else
400
366
  raise "Unknown defn type: #{type1} for #{exp.inspect}"
401
367
  end
402
368
  end
403
369
 
404
- def process_defx(exp) # custom node type - TODO why in r2r?
405
- name = exp.shift
406
- args = process(exp.shift)
407
- body = indent(process(exp.shift))
408
- return "defx #{name}#{args}\n#{body}end".gsub(/\n\s*\n+/, "\n")
370
+ def process_defs(exp)
371
+ exp.unshift "#{process(exp.shift)}.#{exp.shift}"
372
+ process_defn(exp)
409
373
  end
410
374
 
411
375
  def process_dot2(exp)
@@ -416,27 +380,8 @@ class RubyToRuby < SexpProcessor
416
380
  "(#{process exp.shift}...#{process exp.shift})"
417
381
  end
418
382
 
419
- def util_dthing(exp, dump=false)
420
- s = []
421
- s << exp.shift.dump[1..-2]
422
- until exp.empty?
423
- pt = exp.shift
424
- s << case pt.first
425
- when :str then
426
- if dump then
427
- pt.last.dump[1..-2]
428
- else
429
- pt.last.gsub(%r%/%, '\/')
430
- end
431
- else
432
- "#\{#{process(pt)}}"
433
- end
434
- end
435
- s
436
- end
437
-
438
383
  def process_dregx(exp)
439
- "/#{util_dthing(exp).join}/"
384
+ "/" << util_dthing(exp, true) << "/"
440
385
  end
441
386
 
442
387
  def process_dregx_once(exp)
@@ -444,11 +389,11 @@ class RubyToRuby < SexpProcessor
444
389
  end
445
390
 
446
391
  def process_dstr(exp)
447
- "\"#{util_dthing(exp, true).join}\""
392
+ "\"#{util_dthing(exp)}\""
448
393
  end
449
394
 
450
395
  def process_dsym(exp)
451
- ":" + process_dstr(exp)
396
+ ":#{process_dstr(exp)}"
452
397
  end
453
398
 
454
399
  def process_dvar(exp)
@@ -465,6 +410,10 @@ class RubyToRuby < SexpProcessor
465
410
  return "#{body}\nensure\n#{indent ens}"
466
411
  end
467
412
 
413
+ def process_evstr(exp)
414
+ process exp.shift
415
+ end
416
+
468
417
  def process_false(exp)
469
418
  "false"
470
419
  end
@@ -493,8 +442,13 @@ class RubyToRuby < SexpProcessor
493
442
  def process_for(exp)
494
443
  recv = process exp.shift
495
444
  iter = process exp.shift
496
- body = process exp.shift
497
- return "for #{iter} in #{recv}\n#{indent body}\nend\n"
445
+ body = exp.empty? ? nil : process(exp.shift)
446
+
447
+ result = ["for #{iter} in #{recv} do"]
448
+ result << indent(body ? body : "# do nothing")
449
+ result << "end"
450
+
451
+ result.join("\n")
498
452
  end
499
453
 
500
454
  def process_gasgn(exp)
@@ -510,7 +464,13 @@ class RubyToRuby < SexpProcessor
510
464
  until exp.empty?
511
465
  result << "#{process(exp.shift)} => #{process(exp.shift)}"
512
466
  end
513
- return "{ #{result.join(', ')} }"
467
+
468
+ case self.context[1]
469
+ when :arglist, :argscat then
470
+ return "#{result.join(', ')}" # HACK - this will break w/ 2 hashes as args
471
+ else
472
+ return "{ #{result.join(', ')} }"
473
+ end
514
474
  end
515
475
 
516
476
  def process_iasgn(exp)
@@ -522,15 +482,11 @@ class RubyToRuby < SexpProcessor
522
482
  end
523
483
  end
524
484
 
525
- def cond_indent_process(pt)
526
- (pt and pt.first == :block) ? process(pt) : indent(process(pt))
527
- end
528
-
529
485
  def process_if(exp)
530
- expand = RubyToRuby::ASSIGN_NODES.include? exp.first.first
531
- c = process exp.shift
532
- t = process exp.shift
533
- f = process exp.shift
486
+ expand = Ruby2Ruby::ASSIGN_NODES.include? exp.first.first
487
+ c = process exp.shift
488
+ t = process exp.shift
489
+ f = process exp.shift
534
490
 
535
491
  c = "(#{c.chomp})" if c =~ /\n/
536
492
 
@@ -561,7 +517,8 @@ class RubyToRuby < SexpProcessor
561
517
 
562
518
  def process_iter(exp)
563
519
  iter = process exp.shift
564
- args = process exp.shift
520
+ args = exp.shift
521
+ args = (args == 0) ? '' : process(args)
565
522
  body = exp.empty? ? nil : process(exp.shift)
566
523
 
567
524
  b, e = if iter == "END" then
@@ -588,13 +545,9 @@ class RubyToRuby < SexpProcessor
588
545
  result = []
589
546
  result << "#{iter} #{b}"
590
547
  result << " |#{args}|" if args
591
- if body then
592
- result << "\n"
593
- result << indent(body.strip)
594
- result << "\n"
595
- else
596
- result << ' '
597
- end
548
+ result << "\n"
549
+ result << indent(body.strip)
550
+ result << "\n"
598
551
  result << e
599
552
  result.join
600
553
  end
@@ -632,7 +585,7 @@ class RubyToRuby < SexpProcessor
632
585
  rhs = exp.empty? ? nil : exp.shift
633
586
 
634
587
  unless exp.empty? then
635
- rhs[-1] = splat(rhs[-1])
588
+ rhs[-1] = splat(rhs[-1]) unless rhs == s(:splat)
636
589
  lhs << rhs
637
590
  rhs = exp.shift
638
591
  end
@@ -650,18 +603,28 @@ class RubyToRuby < SexpProcessor
650
603
  end
651
604
  when :dasgn_curr then
652
605
  lhs = [ splat(lhs.last) ]
606
+ when :splat then
607
+ lhs = [ :"*" ]
653
608
  else
654
609
  raise "no clue: #{lhs.inspect}"
655
610
  end
656
611
 
612
+ if context[1] == :iter and rhs then
613
+ lhs << splat(rhs.last)
614
+ rhs = nil
615
+ end
616
+
657
617
  unless rhs.nil? then
658
- # HACK - but seems to work (see to_ary test) assert_type rhs, :array
659
- rhs = if rhs.shift == :argscat then
660
- [process_argscat(rhs)]
618
+ t = rhs.first
619
+ rhs = if t == :argscat then
620
+ rhs.shift
621
+ process_argscat(rhs)
661
622
  else
662
- rhs.map { |r| process(r) }
623
+ r = process(rhs)
624
+ r = r[1..-2] if t != :to_ary
625
+ r
663
626
  end
664
- return "#{lhs.join(", ")} = #{rhs.join(", ")}"
627
+ return "#{lhs.join(", ")} = #{rhs}"
665
628
  else
666
629
  return lhs.join(", ")
667
630
  end
@@ -689,7 +652,12 @@ class RubyToRuby < SexpProcessor
689
652
  end
690
653
 
691
654
  def process_next(exp)
692
- "next"
655
+ val = exp.empty? ? nil : process(exp.shift)
656
+ if val then
657
+ "next #{val}"
658
+ else
659
+ "next"
660
+ end
693
661
  end
694
662
 
695
663
  def process_nil(exp)
@@ -759,12 +727,19 @@ class RubyToRuby < SexpProcessor
759
727
  list = sexp.shift
760
728
  body = sexp.shift
761
729
 
762
- var = if list and list.size > 1 and list.last.first == :lasgn then
730
+ var = if list and
731
+ list.size > 1 and
732
+ [:lasgn, :dasgn, :dasgn_curr].include? list.last.first then
763
733
  list.pop[1]
764
734
  else
765
735
  nil
766
736
  end
767
737
 
738
+ # FIX: omg this is horrid. I should be punished
739
+ var = body.delete_at(1)[1] if
740
+ [:dasgn_curr, :dasgn].include? body[1][0] unless
741
+ var or body.nil? rescue nil
742
+
768
743
  if list and list.size > 1 then
769
744
  list[0] = :arglist
770
745
  code << "rescue #{process(list)}"
@@ -799,24 +774,25 @@ class RubyToRuby < SexpProcessor
799
774
  current = self.context[1]
800
775
  case current
801
776
  when :begin, :ensure, :block then
802
- body = process exp.shift
803
- resbody = exp.empty? ? nil : process(exp.shift)
777
+ body = (exp.first.first == :resbody) ? nil : process(exp.shift)
778
+ resbody = exp.empty? ? '' : process(exp.shift)
804
779
  els = exp.empty? ? nil : process(exp.shift)
805
780
 
806
781
  code = []
807
- code << indent(body)
782
+ code << indent(body) if body
808
783
  code << resbody
809
784
  if els then
810
785
  code << "else"
811
786
  code << indent(els)
812
787
  else
813
- unless [:block, :ensure].include? current then
814
- code << "end\n"
788
+ unless [:block].include? current then
789
+ code << "end\n" unless current == :ensure
815
790
  else
816
- r = [body, resbody.gsub(/rescue\n\s+/, 'rescue ')].join(' ')
791
+ r = [body, resbody.gsub(/rescue\n\s+/, 'rescue ')].compact.join(' ')
817
792
  code = [r] if (@indent+r).size < LINE_LENGTH and r !~ /\n/
818
793
  end
819
794
  end
795
+
820
796
  code.join("\n").chomp
821
797
  else # a rescue b and others
822
798
  body = process exp.shift
@@ -864,7 +840,11 @@ class RubyToRuby < SexpProcessor
864
840
  end
865
841
 
866
842
  def process_splat(exp)
867
- "*#{process(exp.shift)}"
843
+ if exp.empty? then
844
+ "*"
845
+ else
846
+ "*#{process(exp.shift)}"
847
+ end
868
848
  end
869
849
 
870
850
  def process_str(exp)
@@ -873,7 +853,7 @@ class RubyToRuby < SexpProcessor
873
853
 
874
854
  def process_super(exp)
875
855
  args = exp.shift
876
- args[0] = :arglist
856
+ args[0] = :arglist if args[0] == :array
877
857
  "super(#{process(args)})"
878
858
  end
879
859
 
@@ -901,22 +881,22 @@ class RubyToRuby < SexpProcessor
901
881
  "alias #{exp.shift} #{exp.shift}"
902
882
  end
903
883
 
904
- # def process_vcall(exp)
905
- # recv = exp.shift # nil
906
- # name = exp.shift
907
- # args = exp.shift # nil
908
- # return name.to_s
909
- # end
910
-
911
884
  def process_when(exp)
912
885
  src = []
913
886
 
887
+ if self.context[1] == :array then # ugh. matz! why not an argscat?!?
888
+ val = process(exp.shift)
889
+ exp.shift # empty body
890
+ return "*#{val}"
891
+ end
892
+
914
893
  until exp.empty?
915
894
  cond = process(exp.shift).to_s[1..-2]
916
895
  code = indent(process(exp.shift))
917
896
  code = indent "# do nothing" if code =~ /\A\s*\Z/
918
897
  src << "when #{cond} then\n#{code.chomp}"
919
898
  end
899
+
920
900
  src.join("\n")
921
901
  end
922
902
 
@@ -972,18 +952,53 @@ class RubyToRuby < SexpProcessor
972
952
  end
973
953
 
974
954
  ############################################################
975
- # Rewriters
955
+ # Rewriters:
976
956
 
977
- def rewrite_defs(exp)
978
- receiver = exp.shift
979
- result = rewrite_defn(exp)
980
- result.unshift receiver
981
- result
957
+ def rewrite_rescue exp
958
+ exp = s(:begin, exp) if
959
+ context[1] == :block unless
960
+ context[2] == :scope and [:defn, :defs].include? context[3]
961
+ exp
982
962
  end
983
963
 
984
964
  ############################################################
985
965
  # Utility Methods:
986
966
 
967
+ def util_dthing(exp, regx = false)
968
+ s = []
969
+ suck = true
970
+ if suck then
971
+ x = exp.shift.gsub(/"/, '\"').gsub(/\n/, '\n')
972
+ else
973
+ x = exp.shift.dump[1..-2]
974
+ end
975
+ x.gsub!(/\//, '\/') if regx
976
+
977
+ s << x
978
+ until exp.empty?
979
+ pt = exp.shift
980
+ case pt
981
+ when Sexp then
982
+ case pt.first
983
+ when :str then
984
+ if suck then
985
+ x = pt.last.gsub(/"/, '\"').gsub(/\n/, '\n')
986
+ else
987
+ x = pt.last.dump[1..-2]
988
+ end
989
+ x.gsub!(/\//, '\/') if regx
990
+ s << x
991
+ else
992
+ s << '#{' << process(pt) << '}' # do not use interpolation here
993
+ end
994
+ else
995
+ # do nothing - yet
996
+ end
997
+ end
998
+
999
+ s.join
1000
+ end
1001
+
987
1002
  def util_module_or_class(exp, is_class=false)
988
1003
  s = "#{exp.shift}"
989
1004
 
@@ -1012,6 +1027,8 @@ class RubyToRuby < SexpProcessor
1012
1027
  end
1013
1028
  end
1014
1029
 
1030
+ RubyToRuby = Ruby2Ruby # For backwards compatibilty... TODO: remove 2008-03-28
1031
+
1015
1032
  class Method
1016
1033
  def with_class_and_method_name
1017
1034
  if self.inspect =~ /<Method: (.*)\#(.*)>/ then
@@ -1031,7 +1048,7 @@ class Method
1031
1048
  end
1032
1049
 
1033
1050
  def to_ruby
1034
- RubyToRuby.new.process(self.to_sexp)
1051
+ Ruby2Ruby.new.process(self.to_sexp)
1035
1052
  end
1036
1053
  end
1037
1054
 
@@ -1048,7 +1065,7 @@ class UnboundMethod
1048
1065
  name = ProcStoreTmp.name
1049
1066
  ProcStoreTmp.send(:define_method, name, self)
1050
1067
  m = ProcStoreTmp.new.method(name)
1051
- result = m.to_ruby.sub(/def #{name}\(([^\)]*)\)/,
1068
+ result = m.to_ruby.sub(/def #{name}(?:\(([^\)]*)\))?/,
1052
1069
  'proc { |\1|').sub(/end\Z/, '}')
1053
1070
  return result
1054
1071
  end
@@ -2,16 +2,15 @@
2
2
 
3
3
  $TESTING = true
4
4
 
5
+ $: << 'lib'
6
+
5
7
  require 'test/unit'
6
- begin require 'rubygems'; rescue LoadError; end
7
8
  require 'ruby2ruby'
8
9
  require 'pt_testcase'
9
10
 
10
- # TODO: rename file so autotest stops bitching
11
-
12
- class TestRubyToRuby < Test::Unit::TestCase
11
+ class TestRuby2Ruby < Test::Unit::TestCase
13
12
  def setup
14
- @processor = RubyToRuby.new
13
+ @processor = Ruby2Ruby.new
15
14
  end
16
15
 
17
16
  def test_proc_to_ruby
@@ -31,39 +30,52 @@ class TestRubyToRuby < Test::Unit::TestCase
31
30
 
32
31
  def util_thingy(type)
33
32
  s(type,
34
- "blah",
33
+ 'blah"blah',
35
34
  s(:call, s(:lit, 1), :+, s(:array, s(:lit, 1))),
36
35
  s(:str, 'blah"blah/blah'))
37
36
  end
38
37
 
39
38
  def test_dregx_slash
40
39
  inn = util_thingy(:dregx)
41
- out = '/blah#{(1 + 1)}blah"blah\/blah/'
40
+ out = "/blah\\\"blah#\{(1 + 1)}blah\\\"blah\\/blah/"
42
41
 
43
42
  assert_equal out, @processor.process(inn)
44
43
 
45
44
  r = eval(out)
46
- assert_equal(/blah2blah"blah\/blah/, r)
45
+ assert_equal(/blah\"blah2blah\"blah\/blah/, r)
47
46
  end
48
47
 
49
48
  def test_dstr_quote
50
49
  inn = util_thingy(:dstr)
51
- out = '"blah#{(1 + 1)}blah\"blah/blah"'
50
+ out = "\"blah\\\"blah#\{(1 + 1)}blah\\\"blah/blah\""
52
51
 
53
52
  assert_equal out, @processor.process(inn)
54
53
 
55
54
  r = eval(out)
56
- assert_equal "blah2blah\"blah/blah", r
55
+ assert_equal "blah\"blah2blah\"blah/blah", r
57
56
  end
58
57
 
59
58
  def test_dsym_quote
60
59
  inn = util_thingy(:dsym)
61
- out = ':"blah#{(1 + 1)}blah\"blah/blah"'
60
+ out = ":\"blah\\\"blah#\{(1 + 1)}blah\\\"blah/blah\""
62
61
 
63
62
  assert_equal out, @processor.process(inn)
64
63
 
65
64
  r = eval(out)
66
- assert_equal :"blah2blah\"blah/blah", r
65
+ assert_equal :"blah\"blah2blah\"blah/blah", r
66
+ end
67
+
68
+ def test_proc_to_sexp
69
+ p = proc { 1 + 1 }
70
+ s = [:proc, nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]
71
+ assert_equal s, p.to_sexp
72
+ end
73
+
74
+ def test_unbound_method_to_ruby
75
+ r = "proc { ||\n p = proc { (1 + 1) }\n s = [:proc, nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]\n assert_equal(s, p.to_sexp)\n}"
76
+ m = self.class.instance_method(:test_proc_to_sexp)
77
+
78
+ assert_equal r, m.to_ruby
67
79
  end
68
80
 
69
81
  eval ParseTreeTestCase.testcases.map { |node, data|
@@ -85,25 +97,34 @@ end
85
97
  # Converts a +target+ using a +processor+ and converts +target+ name
86
98
  # in the source adding +gen+ to allow easy renaming.
87
99
 
88
- def morph_and_eval(processor, target, gen)
100
+ def morph_and_eval(processor, target, gen, n)
89
101
  begin
90
102
  old_name = target.name
91
103
  new_name = target.name.sub(/\d*$/, gen.to_s)
92
104
  ruby = processor.translate(target).sub(old_name, new_name)
105
+
93
106
  eval ruby
94
107
  target.constants.each do |constant|
95
108
  eval "#{new_name}::#{constant} = #{old_name}::#{constant}"
96
109
  end
97
110
  rescue SyntaxError => e
98
- puts
99
- puts ruby
100
- puts
101
- raise e
111
+ warn "Self-Translation Generation #{n} failed:"
112
+ warn "#{e.class}: #{e.message}"
113
+ warn ""
114
+ warn ruby
115
+ warn ""
102
116
  rescue => e
103
- puts
104
- puts ruby
105
- puts
106
- raise e
117
+ warn "Self-Translation Generation #{n} failed:"
118
+ warn "#{e.class}: #{e.message}"
119
+ warn ""
120
+ warn ruby
121
+ warn ""
122
+ else
123
+ begin
124
+ yield if block_given?
125
+ rescue
126
+ # probably already handled
127
+ end
107
128
  end
108
129
  end
109
130
 
@@ -116,28 +137,30 @@ end
116
137
  # s
117
138
  # t new 2 3
118
139
 
119
- # Self-Translation: 1st Generation - morph RubyToRuby using RubyToRuby
120
- morph_and_eval RubyToRuby, RubyToRuby, 2
121
- class TestRubyToRuby1 < TestRubyToRuby
122
- def setup
123
- @processor = RubyToRuby2.new
140
+ # Self-Translation: 1st Generation - morph Ruby2Ruby using Ruby2Ruby
141
+ morph_and_eval Ruby2Ruby, Ruby2Ruby, 2, 1 do
142
+ class TestRuby2Ruby1 < TestRuby2Ruby
143
+ def setup
144
+ @processor = Ruby2Ruby2.new
145
+ end
124
146
  end
125
147
  end
126
148
 
127
- # Self-Translation: 2nd Generation - morph TestRubyToRuby using RubyToRuby
128
- morph_and_eval RubyToRuby, TestRubyToRuby, 2
129
-
130
- # Self-Translation: 3rd Generation - test RubyToRuby2 with TestRubyToRuby1
131
- class TestRubyToRuby3 < TestRubyToRuby2
132
- def setup
133
- @processor = RubyToRuby2.new
149
+ # Self-Translation: 2nd Generation - morph TestRuby2Ruby using Ruby2Ruby
150
+ morph_and_eval Ruby2Ruby, TestRuby2Ruby, 2, 2 do
151
+ # Self-Translation: 3rd Generation - test Ruby2Ruby2 with TestRuby2Ruby1
152
+ class TestRuby2Ruby3 < TestRuby2Ruby2
153
+ def setup
154
+ @processor = Ruby2Ruby2.new
155
+ end
134
156
  end
135
157
  end
136
158
 
137
159
  # Self-Translation: 4th (and final) Generation - fully circular
138
- morph_and_eval RubyToRuby2, RubyToRuby2, 3
139
- class TestRubyToRuby4 < TestRubyToRuby3
140
- def setup
141
- @processor = RubyToRuby3.new
160
+ morph_and_eval(Ruby2Ruby2, Ruby2Ruby2, 3, 4) do
161
+ class TestRuby2Ruby4 < TestRuby2Ruby3
162
+ def setup
163
+ @processor = Ruby2Ruby3.new
164
+ end
142
165
  end
143
- end
166
+ end rescue nil # for Ruby2Ruby2 at the top
metadata CHANGED
@@ -1,72 +1,80 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: ruby2ruby
5
3
  version: !ruby/object:Gem::Version
6
- version: 1.1.7
7
- date: 2007-08-21 00:00:00 -07:00
8
- summary: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps.
9
- require_paths:
10
- - lib
11
- email: ryand-ruby@zenspider.com
12
- homepage: http://seattlerb.rubyforge.org/
13
- rubyforge_project: seattlerb
14
- description: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps. This makes making dynamic language processors much easier in ruby than ever before.
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 1.1.8
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Ryan Davis
31
- files:
32
- - History.txt
33
- - Manifest.txt
34
- - README.txt
35
- - Rakefile
36
- - bin/r2r_show
37
- - lib/ruby2ruby.rb
38
- - test/test_ruby2ruby.rb
39
- test_files:
40
- - test/test_ruby2ruby.rb
41
- rdoc_options:
42
- - --main
43
- - README.txt
44
- extra_rdoc_files:
45
- - History.txt
46
- - Manifest.txt
47
- - README.txt
48
- executables:
49
- - r2r_show
50
- extensions: []
51
-
52
- requirements: []
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
53
11
 
12
+ date: 2007-12-22 00:00:00 -08:00
13
+ default_executable:
54
14
  dependencies:
55
15
  - !ruby/object:Gem::Dependency
56
16
  name: ParseTree
57
17
  version_requirement:
58
- version_requirements: !ruby/object:Gem::Version::Requirement
18
+ version_requirements: !ruby/object:Gem::Requirement
59
19
  requirements:
60
- - - ">"
20
+ - - ">="
61
21
  - !ruby/object:Gem::Version
62
- version: 0.0.0
22
+ version: "0"
63
23
  version:
64
24
  - !ruby/object:Gem::Dependency
65
25
  name: hoe
66
26
  version_requirement:
67
- version_requirements: !ruby/object:Gem::Version::Requirement
27
+ version_requirements: !ruby/object:Gem::Requirement
68
28
  requirements:
69
29
  - - ">="
70
30
  - !ruby/object:Gem::Version
71
- version: 1.3.0
31
+ version: 1.4.0
72
32
  version:
33
+ description: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps. This makes making dynamic language processors much easier in ruby than ever before.
34
+ email: ryand-ruby@zenspider.com
35
+ executables:
36
+ - r2r_show
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - History.txt
41
+ - Manifest.txt
42
+ - README.txt
43
+ files:
44
+ - .autotest
45
+ - History.txt
46
+ - Manifest.txt
47
+ - README.txt
48
+ - Rakefile
49
+ - bin/r2r_show
50
+ - lib/ruby2ruby.rb
51
+ - test/test_ruby2ruby.rb
52
+ has_rdoc: true
53
+ homepage: http://seattlerb.rubyforge.org/
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --main
57
+ - README.txt
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ requirements: []
73
+
74
+ rubyforge_project: seattlerb
75
+ rubygems_version: 1.0.1
76
+ signing_key:
77
+ specification_version: 2
78
+ summary: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps.
79
+ test_files:
80
+ - test/test_ruby2ruby.rb