ruby2ruby 1.1.7 → 1.1.8

Sign up to get free protection for your applications and to get access to all the features.
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