ParseTree 1.5.0 → 1.6.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.
@@ -1,18 +1,35 @@
1
+ *** 1.6.0 / 2006-10-11
2
+
3
+ + 2 major enhancements:
4
+ + PTTC just got a major enema. 2k lines o' diff.
5
+ + All in all, removed 829 lines of code and made it a lot more solid.
6
+ + 6 minor enhancements:
7
+ + Added sort rake task.
8
+ + Added a basic front-end method to ParseTree: translate, takes string or Class and optional method name.
9
+ + Class now has nil for unspecified superclass. No way to tell if it is being reopened.
10
+ + SexpProcessor's unsupported array now defaults to all the internal nodes.
11
+ + Added Unique from ruby2c project.
12
+ + something.rb got slimmed down to near nothing. About to be retired.
13
+ + 7 bug fixes:
14
+ + Added changeset to Hoe spec.
15
+ + Fixed up description to use paragraphs_of.
16
+ + Fixed op_asgn1, alias, undef, dsym, match.
17
+
1
18
  *** 1.5.0 / 2006-09-24
2
19
 
3
20
  + 5 minor enhancements:
4
- Added parse_tree_audit.
5
- Added reporting of unsupported nodes that have processors.
6
- YAY! class method support! generated as :"self.blah"
7
- Add parse_tree_for_string.
8
- Converted Rakefile+gemspec to Hoe-based Rakefile.
21
+ + Added parse_tree_audit.
22
+ + Added reporting of unsupported nodes that have processors.
23
+ + YAY! class method support! generated as :"self.blah"
24
+ + Add parse_tree_for_string.
25
+ + Converted Rakefile+gemspec to Hoe-based Rakefile.
9
26
  + 6 bug fixes:
10
- Did some preliminary work on 1.9 compatibility.
11
- Fixed tests for some changes/clarifications.
12
- Fixed resbody: should have nil exceptions list when no exception rescued.
13
- Fixed op_asgn1 and op_asgn2.
14
- Fixed incompatibility with new inline changes.
15
- Fixed VALUE decl in parse_tree.rb
27
+ + Did some preliminary work on 1.9 compatibility.
28
+ + Fixed tests for some changes/clarifications.
29
+ + Fixed resbody: should have nil exceptions list when no exception rescued.
30
+ + Fixed op_asgn1 and op_asgn2.
31
+ + Fixed incompatibility with new inline changes.
32
+ + Fixed VALUE decl in parse_tree.rb
16
33
 
17
34
  *** 1.4.1 / 2006-04-10
18
35
 
@@ -1,7 +1,7 @@
1
1
  History.txt
2
- Rakefile
3
2
  Manifest.txt
4
3
  README.txt
4
+ Rakefile
5
5
  bin/parse_tree_abc
6
6
  bin/parse_tree_audit
7
7
  bin/parse_tree_deps
@@ -11,6 +11,7 @@ lib/composite_sexp_processor.rb
11
11
  lib/parse_tree.rb
12
12
  lib/sexp.rb
13
13
  lib/sexp_processor.rb
14
+ lib/unique.rb
14
15
  test/pt_testcase.rb
15
16
  test/something.rb
16
17
  test/test_all.rb
data/Rakefile CHANGED
@@ -8,7 +8,8 @@ require './lib/parse_tree.rb'
8
8
 
9
9
  Hoe.new("ParseTree", ParseTree::VERSION) do |p|
10
10
  p.summary = "Extract and enumerate ruby parse trees."
11
- p.description = File.read("README.txt").split(/\n\n+/)[2]
11
+ p.description = p.paragraphs_of("README.txt", 2).join("\n\n")
12
+ p.changes = p.paragraphs_of("History.txt", 1).join("\n\n")
12
13
  p.clean_globs << File.expand_path("~/.ruby_inline")
13
14
  p.extra_deps << ['RubyInline', '>= 3.2.0']
14
15
  end
@@ -28,3 +29,11 @@ desc 'Run a very basic demo'
28
29
  task :demo do
29
30
  sh "echo 1+1 | ruby #{Hoe::RUBY_FLAGS} ./bin/parse_tree_show -f"
30
31
  end
32
+
33
+ desc 'Show what tests are not sorted'
34
+ task :sort do
35
+ sh "pgrep '^ \\\"(\\w+)' test/pt_testcase.rb | cut -f 2 -d\\\" > x"
36
+ sh "sort x > y"
37
+ sh "diff x y"
38
+ sh "rm -f x y"
39
+ end
@@ -25,7 +25,24 @@ require 'inline'
25
25
 
26
26
  class ParseTree
27
27
 
28
- VERSION = '1.5.0'
28
+ VERSION = '1.6.0'
29
+
30
+ ##
31
+ # Front end translation method.
32
+
33
+ def self.translate(klass_or_str, method=nil)
34
+ pt = self.new(false)
35
+ case klass_or_str
36
+ when String
37
+ pt.parse_tree_for_string(klass_or_str).first
38
+ else
39
+ unless method.nil? then
40
+ pt.parse_tree_for_method(klass_or_str, method)
41
+ else
42
+ pt.parse_tree(klass_or_str).first
43
+ end
44
+ end
45
+ end
29
46
 
30
47
  ##
31
48
  # Initializes a ParseTree instance. Includes newline nodes if
@@ -510,7 +527,7 @@ again_no_block:
510
527
 
511
528
  case NODE_OP_ASGN1:
512
529
  add_to_parse_tree(current, node->nd_recv, newlines, locals);
513
- add_to_parse_tree(current, node->nd_args->nd_next, newlines, locals);
530
+ add_to_parse_tree(current, node->nd_args->nd_2nd, newlines, locals);
514
531
  switch (node->nd_mid) {
515
532
  case 0:
516
533
  rb_ary_push(current, ID2SYM(rb_intern("||")));
@@ -572,14 +589,20 @@ again_no_block:
572
589
  add_to_parse_tree(current, node->nd_value, newlines, locals);
573
590
  break;
574
591
 
575
- case NODE_ALIAS: // u1 u2 (alias :blah :blah2)
576
592
  case NODE_VALIAS: // u1 u2 (alias $global $global2)
577
593
  rb_ary_push(current, ID2SYM(node->u1.id));
578
594
  rb_ary_push(current, ID2SYM(node->u2.id));
579
595
  break;
596
+ case NODE_ALIAS: // u1 u2 (alias :blah :blah2)
597
+ add_to_parse_tree(current, node->nd_1st, newlines, locals);
598
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals);
599
+ break;
600
+
601
+ case NODE_UNDEF: // u2 (undef name, ...)
602
+ add_to_parse_tree(current, node->nd_value, newlines, locals);
603
+ break;
580
604
 
581
605
  case NODE_COLON3: // u2 (::OUTER_CONST)
582
- case NODE_UNDEF: // u2 (undef instvar)
583
606
  rb_ary_push(current, ID2SYM(node->u2.id));
584
607
  break;
585
608
 
@@ -607,14 +630,12 @@ again_no_block:
607
630
  break;
608
631
 
609
632
  case NODE_DSTR:
633
+ case NODE_DSYM:
610
634
  case NODE_DXSTR:
611
635
  case NODE_DREGX:
612
636
  case NODE_DREGX_ONCE:
613
637
  {
614
638
  NODE *list = node->nd_next;
615
- if (nd_type(node) == NODE_DREGX || nd_type(node) == NODE_DREGX_ONCE) {
616
- break;
617
- }
618
639
  rb_ary_push(current, rb_str_new3(node->nd_lit));
619
640
  while (list) {
620
641
  if (list->nd_head) {
@@ -648,8 +669,12 @@ again_no_block:
648
669
  case NODE_CLASS:
649
670
  case NODE_MODULE:
650
671
  rb_ary_push(current, ID2SYM((ID)node->nd_cpath->nd_mid));
651
- if (node->nd_super && nd_type(node) == NODE_CLASS) {
652
- add_to_parse_tree(current, node->nd_super, newlines, locals);
672
+ if (nd_type(node) == NODE_CLASS) {
673
+ if (node->nd_super) {
674
+ add_to_parse_tree(current, node->nd_super, newlines, locals);
675
+ } else {
676
+ rb_ary_push(current, Qnil);
677
+ }
653
678
  }
654
679
  add_to_parse_tree(current, node->nd_body, newlines, locals);
655
680
  break;
@@ -716,10 +741,18 @@ again_no_block:
716
741
  case NODE_XSTR: // u1 (%x{ls})
717
742
  case NODE_STR: // u1
718
743
  case NODE_LIT:
719
- case NODE_MATCH:
720
744
  rb_ary_push(current, node->nd_lit);
721
745
  break;
722
746
 
747
+ case NODE_MATCH: // u1 -> [:lit, u1]
748
+ {
749
+ VALUE n = rb_ary_new();
750
+ rb_ary_push(n, ID2SYM(rb_intern("lit")));
751
+ rb_ary_push(n, node->nd_lit);
752
+ rb_ary_push(current, n);
753
+ }
754
+ break;
755
+
723
756
  case NODE_NEWLINE:
724
757
  rb_ary_push(current, INT2FIX(nd_line(node)));
725
758
  rb_ary_push(current, rb_str_new2(node->nd_file));
@@ -773,10 +806,6 @@ again_no_block:
773
806
  add_to_parse_tree(current, node->nd_3rd, newlines, locals);
774
807
  break;
775
808
 
776
- case NODE_DSYM: // :"\#\{foo}" u1 u2 u3
777
- add_to_parse_tree(current, node->nd_3rd, newlines, locals);
778
- break;
779
-
780
809
  case NODE_EVSTR:
781
810
  add_to_parse_tree(current, node->nd_2nd, newlines, locals);
782
811
  break;
@@ -137,7 +137,7 @@ class SexpProcessor
137
137
  @warn_on_default = true
138
138
  @auto_shift_type = false
139
139
  @strict = false
140
- @unsupported = []
140
+ @unsupported = [:alloca, :cfunc, :cref, :evstr, :ifunc, :last, :memo, :newline, :opt_n, :method] # internal nodes that you can't get to
141
141
  @unsupported_checked = false
142
142
  @debug = {}
143
143
  @expected = Sexp
@@ -217,7 +217,7 @@ class SexpProcessor
217
217
  exp = new_exp
218
218
  end
219
219
 
220
- # now do a pass with the real processor (or generic
220
+ # now do a pass with the real processor (or generic)
221
221
  meth = @processors[type] || @default_method
222
222
  if meth then
223
223
 
@@ -0,0 +1,15 @@
1
+ ##
2
+ # Unique creates unique variable names.
3
+
4
+ class Unique
5
+ def self.reset # mostly for testing
6
+ @@curr = 0
7
+ end
8
+
9
+ def self.next
10
+ @@curr += 1
11
+ "temp_#{@@curr}".intern
12
+ end
13
+
14
+ reset
15
+ end
@@ -1,12 +1,29 @@
1
1
  require 'test/unit/testcase'
2
- require 'sexp_processor' # for deep_clone FIX
3
- require 'typed_sexp'
2
+ require 'sexp_processor' # for deep_clone
4
3
  require 'unique'
5
4
 
6
- # TODO: str -> char * in ansi c
7
- # TODO: add tests that mix types up to fuck up RubyC type checker
5
+ class Examples
6
+ attr_reader :reader
7
+ attr_writer :writer
8
8
 
9
- class R2CTestCase < Test::Unit::TestCase
9
+ def a_method; 1+1; end
10
+ alias an_alias a_method
11
+
12
+ def self.bmethod_maker
13
+ define_method(:bmethod_added) do |x|
14
+ x + 1
15
+ end
16
+ end
17
+
18
+ def self.dmethod_maker
19
+ define_method :dmethod_added, self.method(:bmethod_maker)
20
+ end if RUBY_VERSION < "1.9"
21
+
22
+ bmethod_maker
23
+ dmethod_maker if RUBY_VERSION < "1.9"
24
+ end
25
+
26
+ class ParseTreeTestCase < Test::Unit::TestCase
10
27
 
11
28
  attr_accessor :processor # to be defined by subclass
12
29
 
@@ -19,1298 +36,882 @@ class R2CTestCase < Test::Unit::TestCase
19
36
  Unique.reset
20
37
  end
21
38
 
22
- @@testcase_order = %w(Ruby ParseTree Rewriter TypeChecker CRewriter RubyToAnsiC RubyToRubyC)
39
+ @@testcase_order = %w(Ruby ParseTree)
23
40
 
24
41
  @@testcases = {
42
+
43
+ "alias" => {
44
+ "Ruby" => "class X\n alias :y :x\nend",
45
+ "ParseTree" => [:class, :X, nil,
46
+ [:scope, [:alias, [:lit, :y], [:lit, :x]]]],
47
+ "Ruby2Ruby" => "class X\n alias_method :y, :x\n \nend", # FIX dbl \n
48
+ },
25
49
 
26
- "accessor" => {
27
- "Ruby" => "attr_reader :accessor",
28
- "ParseTree" => [:defn, :accessor, [:ivar, :@accessor]],
29
- "Rewriter" => s(:defn, :accessor, s(:args),
30
- s(:scope,
31
- s(:block, s(:return, s(:ivar, :@accessor))))),
32
- "TypeChecker" => :skip,
33
- "CRewriter" => :skip,
34
- "RubyToAnsiC" => :skip,
35
- "RubyToRubyC" => :skip,
36
- },
37
-
38
- "accessor_equals" => {
39
- "Ruby" => "attr_writer :accessor",
40
- "ParseTree" => [:defn, :accessor=, [:attrset, :@accessor]],
41
- "Rewriter" => s(:defn,
42
- :accessor=,
43
- s(:args, :arg),
44
- s(:scope,
45
- s(:block,
46
- s(:return,
47
- s(:iasgn, :@accessor, s(:lvar, :arg)))))),
48
- "TypeChecker" => :skip,
49
- "CRewriter" => :skip,
50
- "RubyToRubyC" => :skip,
51
- "RubyToAnsiC" => :skip,
52
- },
53
-
54
- "defn_bbegin" => {
55
- "Ruby" => "def bbegin()
56
- begin
57
- 1 + 1
58
- rescue SyntaxError
59
- e1 = $!
60
- 2
61
- rescue Exception
62
- e2 = $!
63
- 3
64
- else
65
- 4end
66
- ensure
67
- 5
68
- end",
69
- "ParseTree" => [:defn, :bbegin,
70
- [:scope,
71
- [:block,
72
- [:args],
73
- [:begin,
74
- [:ensure,
75
- [:rescue,
76
- [:call, [:lit, 1], :+, [:array, [:lit, 1]]],
77
- [:resbody,
78
- [:array, [:const, :SyntaxError]],
79
- [:block, [:lasgn, :e1, [:gvar, :$!]], [:lit, 2]],
80
- [:resbody,
81
- [:array, [:const, :Exception]],
82
- [:block, [:lasgn, :e2, [:gvar, :$!]], [:lit, 3]]]],
83
- [:lit, 4]],
84
- [:lit, 5]]]]]],
85
- "Rewriter" => s(:defn, :bbegin,
86
- s(:args),
87
- s(:scope,
88
- s(:block,
89
- s(:begin,
90
- s(:ensure,
91
- s(:rescue,
92
- s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1))),
93
- s(:resbody,
94
- s(:array, s(:const, :SyntaxError)),
95
- s(:block, s(:lasgn, :e1, s(:gvar, :$!)),
96
- s(:lit, 2)),
97
- s(:resbody,
98
- s(:array, s(:const, :Exception)),
99
- s(:block, s(:lasgn, :e2, s(:gvar, :$!)),
100
- s(:lit, 3)))),
101
- s(:lit, 4)),
102
- s(:lit, 5)))))),
103
- "TypeChecker" => t(:defn, :bbegin,
104
- t(:args),
105
- t(:scope,
106
- t(:block,
107
- t(:begin,
108
- t(:ensure,
109
- t(:rescue,
110
- t(:call,
111
- t(:lit, 1, Type.long),
112
- :+,
113
- t(:arglist, t(:lit, 1, Type.long)), Type.long),
114
- t(:resbody,
115
- t(:array, t(:const, :SyntaxError, Type.fucked)),
116
- t(:block,
117
- t(:lasgn, :e1, t(:gvar, :$!, Type.unknown),
118
- Type.unknown),
119
- t(:lit, 2, Type.long), Type.unknown),
120
- t(:resbody,
121
- t(:array, t(:const, :Exception, Type.fucked)),
122
- t(:block,
123
- t(:lasgn, :e2, t(:gvar, :$!, Type.unknown),
124
- Type.unknown),
125
- t(:lit, 3, Type.long), Type.unknown),
126
- Type.unknown), Type.long),
127
- t(:lit, 4, Type.long), Type.long),
128
- t(:lit, 5, Type.long))), Type.unknown),
129
- Type.void),
130
- Type.function(Type.unknown, [], Type.void)),
131
- "CRewriter" => :same,
132
- "RubyToRubyC" => :unsupported,
133
- "RubyToAnsiC" => :unsupported,
134
- },
135
-
136
- "bools" => {
137
- "Ruby" => "def bools(arg1)
138
- if (arg1.nil?)
139
- return false
140
- else
141
- return true
142
- end
143
- end",
144
- "ParseTree" => [:defn, :bools,
145
- [:scope,
146
- [:block,
147
- [:args, :arg1],
148
- [:if,
149
- [:call, [:lvar, :arg1], "nil?".intern], # emacs is freakin'
150
- [:return, [:false]],
151
- [:return, [:true]]]]]],
152
- "Rewriter" => s(:defn, :bools,
153
- s(:args, :arg1),
154
- s(:scope,
155
- s(:block,
156
- s(:if,
157
- s(:call,
158
- s(:lvar, :arg1),
159
- :nil?,
160
- nil),
161
- s(:return, s(:false)),
162
- s(:return, s(:true)))))),
163
- # TODO: why does return false have type void?
164
- "TypeChecker" => t(:defn, :bools,
165
- t(:args, t(:arg1, Type.value)),
166
- t(:scope,
167
- t(:block,
168
- t(:if,
169
- t(:call,
170
- t(:lvar, :arg1, Type.value),
171
- :nil?,
172
- nil,
173
- Type.bool),
174
- t(:return,
175
- t(:false, Type.bool),
176
- Type.void),
177
- t(:return,
178
- t(:true, Type.bool),
179
- Type.void),
180
- Type.void),
181
- Type.unknown),
182
- Type.void),
183
- Type.function(Type.unknown, [Type.value], Type.bool)),
184
- "CRewriter" => :same,
185
- "RubyToRubyC" => "static VALUE\nrrc_c_bools(VALUE self, VALUE arg1) {\nif (NIL_P(arg1)) {\nreturn Qfalse;\n} else {\nreturn Qtrue;\n}\n}",
186
- "RubyToAnsiC" => "bool\nbools(void * arg1) {\nif (arg1) {\nreturn 0;\n} else {\nreturn 1;\n}\n}",
187
- },
188
-
189
- # TODO: move all call tests here
190
- "call_arglist" => {
191
- "Ruby" => "puts(42)",
192
- "ParseTree" => [:fcall, :puts, [:array, [:lit, 42]]],
193
- "Rewriter" => s(:call, nil, :puts, s(:arglist, s(:lit, 42))),
194
- "TypeChecker" => :skip,
195
- "CRewriter" => :skip,
196
- "RubyToRubyC" => :skip,
197
- "RubyToAnsiC" => :skip,
50
+ "and" => {
51
+ "Ruby" => "(a and b)",
52
+ "ParseTree" => [:and, [:vcall, :a], [:vcall, :b]],
198
53
  },
199
54
 
200
- "call_attrasgn" => {
201
- "Ruby" => "42.method=(y)",
202
- "ParseTree" => [:attrasgn, [:lit, 42], :method=, [:array, [:lvar, :y]]],
203
- "Rewriter" => s(:call, s(:lit, 42), :method=, s(:arglist, s(:lvar, :y))),
204
- "TypeChecker" => :skip,
205
- "CRewriter" => :skip,
206
- "RubyToRubyC" => :skip,
207
- "RubyToAnsiC" => :skip,
55
+ "args" => {
56
+ "Ruby" => "def x(a, b = 42, \*c, &d)\n p(a, b, c, d)\nend",
57
+ "ParseTree" => [:defn, :x,
58
+ [:scope,
59
+ [:block,
60
+ [:args, :a, :b, "*c".intern, # s->e
61
+ [:block, [:lasgn, :b, [:lit, 42]]]],
62
+ [:block_arg, :d],
63
+ [:fcall, :p,
64
+ [:array, [:lvar, :a], [:lvar, :b],
65
+ [:lvar, :c], [:lvar, :d]]]]]]
66
+ },
67
+
68
+ "argscat" => {
69
+ "Ruby" => "a = b, c, *d",
70
+ "ParseTree" => [:lasgn, :a,
71
+ [:svalue,
72
+ [:argscat,
73
+ [:array, [:vcall, :b], [:vcall, :c]],
74
+ [:vcall, :d]]]],
208
75
  },
209
76
 
210
- "call_self" => {
77
+ "argspush" => {
78
+ "Ruby" => "a[*b] = c",
79
+ "ParseTree" => [:attrasgn,
80
+ [:vcall, :a],
81
+ :[]=,
82
+ [:argspush, [:splat, [:vcall, :b]], [:vcall, :c]]],
83
+ "Ruby2Ruby" => "a.[]=(*b, c)" # HACK until we can get things ironed out
84
+ },
85
+
86
+ "array" => {
87
+ "Ruby" => "[1, :b, \"c\"]",
88
+ "ParseTree" => [:array, [:lit, 1], [:lit, :b], [:str, "c"]],
89
+ },
90
+
91
+ "attrasgn" => {
92
+ "Ruby" => "y = 0\n42.method=(y)\n",
93
+ "ParseTree" => [:block,
94
+ [:lasgn, :y, [:lit, 0]],
95
+ [:attrasgn, [:lit, 42], :method=, [:array, [:lvar, :y]]]],
96
+ },
97
+
98
+ "attrset" => {
99
+ "Ruby" => [Examples, :writer=],
100
+ "ParseTree" => [:defn, :writer=, [:attrset, :@writer]],
101
+ "Ruby2Ruby" => "attr_writer :writer"
102
+ },
103
+
104
+ "back_ref" => {
105
+ "Ruby" => "[$&, $`, $', $+]",
106
+ "ParseTree" => [:array,
107
+ [:back_ref, :&],
108
+ [:back_ref, "`".intern], # symbol was fucking up emacs
109
+ [:back_ref, "'".intern], # s->e
110
+ [:back_ref, :+]],
111
+ },
112
+
113
+ "begin" => {
114
+ "Ruby" => "begin\n (1 + 1)\nend",
115
+ "ParseTree" => [:begin, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]],
116
+ },
117
+
118
+ "block_pass" => {
119
+ "Ruby" => "a(&b)",
120
+ "ParseTree" => [:block_pass, [:vcall, :b], [:fcall, :a]],
121
+ },
122
+
123
+ "bmethod" => {
124
+ "Ruby" => [Examples, :bmethod_added],
125
+ "ParseTree" => [:defn,
126
+ :bmethod_added,
127
+ [:bmethod,
128
+ [:dasgn_curr, :x],
129
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]],
130
+ "Ruby2Ruby" => "def bmethod_added(x)\n (x + 1)\nend"
131
+ },
132
+
133
+ "break" => {
134
+ "Ruby" => "loop do\n if true then\n break\n end\nend",
135
+ "ParseTree" => [:iter,
136
+ [:fcall, :loop], nil, [:if, [:true], [:break], nil]],
137
+ },
138
+
139
+ "break_arg" => {
140
+ "Ruby" => "loop do\n if true then\n break 42\n end\nend",
141
+ "ParseTree" => [:iter,
142
+ [:fcall, :loop], nil,
143
+ [:if, [:true], [:break, [:lit, 42]], nil]],
144
+ },
145
+
146
+ "call" => {
211
147
  "Ruby" => "self.method",
212
148
  "ParseTree" => [:call, [:self], :method],
213
- "Rewriter" => s(:call, s(:lvar, :self), :method, nil),
214
- "TypeChecker" => :skip,
215
- "CRewriter" => :skip,
216
- "RubyToRubyC" => :skip,
217
- "RubyToAnsiC" => :skip,
218
- },
219
-
220
- "case_stmt" => {
221
- "Ruby" => "
222
- def case_stmt()
223
- var = 2
224
- result = \"\"
225
- case var
226
- when 1
227
- puts(\"something\")
228
- result = \"red\"
229
- when 2, 3
230
- result = \"yellow\"
231
- when 4
232
- else
233
- result = \"green\"
234
- end
235
- case result
236
- when \"red\"
237
- var = 1
238
- when \"yellow\"
239
- var = 2
240
- when \"green\"
241
- var = 3
242
- else
243
- end
244
- return result
245
- end",
246
- "ParseTree" => [:defn, :case_stmt,
247
- [:scope,
248
- [:block,
249
- [:args],
250
- [:lasgn, :var, [:lit, 2]],
251
- [:lasgn, :result, [:str, ""]],
252
- [:case,
253
- [:lvar, :var],
254
- [:when,
255
- [:array, [:lit, 1]],
256
- [:block,
257
- [:fcall, :puts, [:array, [:str, "something"]]],
258
- [:lasgn, :result, [:str, "red"]]]],
259
- [:when,
260
- [:array, [:lit, 2], [:lit, 3]],
261
- [:lasgn, :result, [:str, "yellow"]]],
262
- [:when, [:array, [:lit, 4]], nil],
263
- [:lasgn, :result, [:str, "green"]]],
264
- [:case,
265
- [:lvar, :result],
266
- [:when, [:array, [:str, "red"]], [:lasgn, :var, [:lit, 1]]],
267
- [:when, [:array, [:str, "yellow"]], [:lasgn, :var, [:lit, 2]]],
268
- [:when, [:array, [:str, "green"]], [:lasgn, :var, [:lit, 3]]],
269
- nil],
270
- [:return, [:lvar, :result]]]]],
271
- "Rewriter" => s(:defn, :case_stmt,
272
- s(:args),
273
- s(:scope,
274
- s(:block,
275
- s(:lasgn, :var, s(:lit, 2)),
276
- s(:lasgn, :result, s(:str, "")),
277
- s(:if,
278
- s(:call,
279
- s(:lvar, :var),
280
- :===,
281
- s(:arglist, s(:lit, 1))),
282
- s(:block,
283
- s(:call,
284
- nil,
285
- :puts,
286
- s(:arglist, s(:str, "something"))),
287
- s(:lasgn, :result, s(:str, "red"))),
288
- s(:if,
289
- s(:or,
290
- s(:call,
291
- s(:lvar, :var),
292
- :===,
293
- s(:arglist, s(:lit, 2))),
294
- s(:call,
295
- s(:lvar, :var),
296
- :===,
297
- s(:arglist, s(:lit, 3)))),
298
- s(:lasgn, :result, s(:str, "yellow")),
299
- s(:if,
300
- s(:call,
301
- s(:lvar, :var),
302
- :===,
303
- s(:arglist, s(:lit, 4))),
304
- nil,
305
- s(:lasgn, :result, s(:str, "green"))))),
306
- s(:if,
307
- s(:call,
308
- s(:lvar, :result),
309
- :===,
310
- s(:arglist, s(:str, "red"))),
311
- s(:lasgn, :var, s(:lit, 1)),
312
- s(:if,
313
- s(:call,
314
- s(:lvar, :result),
315
- :===,
316
- s(:arglist, s(:str, "yellow"))),
317
- s(:lasgn, :var, s(:lit, 2)),
318
- s(:if,
319
- s(:call,
320
- s(:lvar, :result),
321
- :===,
322
- s(:arglist, s(:str, "green"))),
323
- s(:lasgn, :var, s(:lit, 3)),
324
- nil))),
325
- s(:return, s(:lvar, :result))))),
326
- "TypeChecker" => t(:defn, :case_stmt,
327
- t(:args),
328
- t(:scope,
329
- t(:block,
330
- t(:lasgn,
331
- :var,
332
- t(:lit, 2, Type.long),
333
- Type.long),
334
- t(:lasgn,
335
- :result,
336
- t(:str, "", Type.str),
337
- Type.str),
338
- t(:if,
339
- t(:call,
340
- t(:lvar, :var, Type.long),
341
- :case_equal_long,
342
- t(:arglist, t(:lit, 1, Type.long)),
343
- Type.bool),
344
- t(:block,
345
- t(:call,
346
- nil,
347
- :puts,
348
- t(:arglist,
349
- t(:str, "something", Type.str)),
350
- Type.void),
351
- t(:lasgn,
352
- :result,
353
- t(:str, "red", Type.str),
354
- Type.str),
355
- Type.str),
356
- t(:if,
357
- t(:or,
358
- t(:call,
359
- t(:lvar, :var, Type.long),
360
- :case_equal_long,
361
- t(:arglist, t(:lit, 2, Type.long)),
362
- Type.bool),
363
- t(:call,
364
- t(:lvar, :var, Type.long),
365
- :case_equal_long,
366
- t(:arglist, t(:lit, 3, Type.long)),
367
- Type.bool),
368
- Type.bool),
369
- t(:lasgn,
370
- :result,
371
- t(:str, "yellow", Type.str),
372
- Type.str),
373
- t(:if,
374
- t(:call,
375
- t(:lvar, :var, Type.long),
376
- :case_equal_long,
377
- t(:arglist, t(:lit, 4, Type.long)),
378
- Type.bool),
379
- nil,
380
- t(:lasgn,
381
- :result,
382
- t(:str, "green", Type.str),
383
- Type.str),
384
- Type.str),
385
- Type.str),
386
- Type.str),
387
- t(:if,
388
- t(:call,
389
- t(:lvar, :result, Type.str),
390
- :case_equal_str,
391
- t(:arglist, t(:str, "red", Type.str)),
392
- Type.bool),
393
- t(:lasgn, :var, t(:lit, 1, Type.long), Type.long),
394
- t(:if,
395
- t(:call,
396
- t(:lvar, :result, Type.str),
397
- :case_equal_str,
398
- t(:arglist, t(:str, "yellow", Type.str)),
399
- Type.bool),
400
- t(:lasgn, :var, t(:lit, 2, Type.long), Type.long),
401
- t(:if,
402
- t(:call,
403
- t(:lvar, :result, Type.str),
404
- :case_equal_str,
405
- t(:arglist,
406
- t(:str, "green", Type.str)),
407
- Type.bool),
408
- t(:lasgn,
409
- :var,
410
- t(:lit, 3, Type.long),
411
- Type.long),
412
- nil,
413
- Type.long),
414
- Type.long),
415
- Type.long),
416
- t(:return,
417
- t(:lvar, :result, Type.str),
418
- Type.void),
419
- Type.unknown),
420
- Type.void),
421
- Type.function(Type.unknown, [], Type.str)),
422
- "CRewriter" => :same,
423
- # HACK: I don't like the semis after the if blocks, but it is a compromise right now
424
- "RubyToRubyC" => "static VALUE
425
- rrc_c_case_stmt(VALUE self) {
426
- VALUE result;
427
- VALUE var;
428
- var = LONG2NUM(2);
429
- result = rb_str_new2(\"\");
430
- if (rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(1))) {
431
- rb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"something\"));
432
- result = rb_str_new2(\"red\");
433
- } else {
434
- if (rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(2)) || rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(3))) {
435
- result = rb_str_new2(\"yellow\");
436
- } else {
437
- if (rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(4))) {
438
- ;
439
- } else {
440
- result = rb_str_new2(\"green\");
441
- }
442
- }
443
- };
444
- if (rb_funcall(result, rb_intern(\"===\"), 1, rb_str_new2(\"red\"))) {
445
- var = LONG2NUM(1);
446
- } else {
447
- if (rb_funcall(result, rb_intern(\"===\"), 1, rb_str_new2(\"yellow\"))) {
448
- var = LONG2NUM(2);
449
- } else {
450
- if (rb_funcall(result, rb_intern(\"===\"), 1, rb_str_new2(\"green\"))) {
451
- var = LONG2NUM(3);
452
- }
453
- }
454
- };
455
- return result;
456
- }",
457
- "RubyToAnsiC" => "str
458
- case_stmt() {
459
- str result;
460
- long var;
461
- var = 2;
462
- result = \"\";
463
- if (case_equal_long(var, 1)) {
464
- puts(\"something\");
465
- result = \"red\";
466
- } else {
467
- if (case_equal_long(var, 2) || case_equal_long(var, 3)) {
468
- result = \"yellow\";
469
- } else {
470
- if (case_equal_long(var, 4)) {
471
- ;
472
- } else {
473
- result = \"green\";
474
- }
475
- }
476
- };
477
- if (case_equal_str(result, \"red\")) {
478
- var = 1;
479
- } else {
480
- if (case_equal_str(result, \"yellow\")) {
481
- var = 2;
482
- } else {
483
- if (case_equal_str(result, \"green\")) {
484
- var = 3;
485
- }
486
- }
487
- };
488
- return result;
489
- }",
149
+ },
150
+
151
+ "call_arglist" => {
152
+ "Ruby" => "puts(42)",
153
+ "ParseTree" => [:fcall, :puts, [:array, [:lit, 42]]],
154
+ },
155
+
156
+ "case" => {
157
+ "Ruby" => "var = 2\nresult = \"\"\ncase var\nwhen 1 then\n puts(\"something\")\n result = \"red\"\nwhen 2, 3 then\n result = \"yellow\"\nwhen 4 then\n # do nothing\nelse\n result = \"green\"\nend\ncase result\nwhen \"red\" then\n var = 1\nwhen \"yellow\" then\n var = 2\nwhen \"green\" then\n var = 3\nelse\n # do nothing\nend\n",
158
+ "ParseTree" => [:block,
159
+ [:lasgn, :var, [:lit, 2]],
160
+ [:lasgn, :result, [:str, ""]],
161
+ [:case,
162
+ [:lvar, :var],
163
+ [:when,
164
+ [:array, [:lit, 1]],
165
+ [:block,
166
+ [:fcall, :puts, [:array, [:str, "something"]]],
167
+ [:lasgn, :result, [:str, "red"]]]],
168
+ [:when,
169
+ [:array, [:lit, 2], [:lit, 3]],
170
+ [:lasgn, :result, [:str, "yellow"]]],
171
+ [:when, [:array, [:lit, 4]], nil],
172
+ [:lasgn, :result, [:str, "green"]]],
173
+ [:case,
174
+ [:lvar, :result],
175
+ [:when, [:array, [:str, "red"]],
176
+ [:lasgn, :var, [:lit, 1]]],
177
+ [:when, [:array, [:str, "yellow"]],
178
+ [:lasgn, :var, [:lit, 2]]],
179
+ [:when, [:array, [:str, "green"]],
180
+ [:lasgn, :var, [:lit, 3]]],
181
+ nil]]
182
+ },
183
+
184
+ "cdecl" => {
185
+ "Ruby" => "X = 42",
186
+ "ParseTree" => [:cdecl, :X, [:lit, 42]],
187
+ },
188
+
189
+ "class" => {
190
+ "Ruby" => "class X < Array\n def blah\n puts(\"hello\")\n end\n \nend",
191
+ "ParseTree" => [:class,
192
+ :X,
193
+ [:const, :Array],
194
+ [:scope,
195
+ [:defn,
196
+ :blah,
197
+ [:scope,
198
+ [:block,
199
+ [:args],
200
+ [:fcall, :puts, [:array, [:str, "hello"]]]]]]]],
201
+ },
202
+
203
+ "class_obj" => {
204
+ "Ruby" => "class X\n def blah\n puts(\"hello\")\n end\n \nend",
205
+ "ParseTree" => [:class,
206
+ :X,
207
+ nil,
208
+ [:scope,
209
+ [:defn,
210
+ :blah,
211
+ [:scope,
212
+ [:block,
213
+ [:args],
214
+ [:fcall, :puts, [:array, [:str, "hello"]]]]]]]],
215
+ },
216
+
217
+ "colon2" => {
218
+ "Ruby" => "X::Y",
219
+ "ParseTree" => [:colon2, [:const, :X], :Y],
220
+ },
221
+
222
+ "colon3" => {
223
+ "Ruby" => "::X",
224
+ "ParseTree" => [:colon3, :X],
490
225
  },
491
226
 
492
227
  "conditional1" => {
493
- "Ruby" => "if (42 == 0)\n return 1\n\nend",
494
- "ParseTree" => [:if, [:call, [:lit, 42], :==, [:array, [:lit, 0]]], [:return, [:lit, 1]], nil],
495
- "Rewriter" => s(:if, s(:call, s(:lit, 42), :==, s(:arglist, s(:lit, 0))), s(:return, s(:lit, 1)), nil),
496
- "TypeChecker" => t(:if,
497
- t(:call, t(:lit, 42, Type.long), :==,
498
- t(:arglist, t(:lit, 0, Type.long)),
499
- Type.bool),
500
- t(:return, t(:lit, 1, Type.long), Type.void),
501
- nil,
502
- Type.void),
503
- "CRewriter" => t(:if,
504
- t(:call, t(:lit, 42, Type.long), :==,
505
- t(:arglist, t(:lit, 0, Type.long)),
506
- Type.bool),
507
- t(:return, t(:lit, 1, Type.long), Type.void),
508
- nil,
509
- Type.void),
510
- "RubyToRubyC" => "if (rb_funcall(LONG2NUM(42), rb_intern(\"==\"), 1, LONG2NUM(0))) {\nreturn LONG2NUM(1);\n}",
511
- "RubyToAnsiC" => "if (42 == 0) {\nreturn 1;\n}",
228
+ "Ruby" => "if (42 == 0) then\n return 1\nend",
229
+ "ParseTree" => [:if,
230
+ [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
231
+ [:return, [:lit, 1]],
232
+ nil],
512
233
  },
513
234
 
514
235
  "conditional2" => {
515
- "Ruby" => "unless (42 == 0)\n return 2\nend",
516
- "ParseTree" => [:if, [:call, [:lit, 42], :==, [:array, [:lit, 0]]], nil, [:return, [:lit, 2]]],
517
- "Rewriter" => s(:if,
518
- s(:call, s(:lit, 42),
519
- :==, s(:arglist, s(:lit, 0))),
520
- nil,
521
- s(:return, s(:lit, 2))),
522
- "TypeChecker" => t(:if,
523
- t(:call,
524
- t(:lit, 42, Type.long),
525
- :==,
526
- t(:arglist,
527
- t(:lit, 0, Type.long)),
528
- Type.bool),
529
- nil,
530
- t(:return, t(:lit, 2, Type.long), Type.void),
531
- Type.void),
532
- "CRewriter" => :same,
533
- "RubyToRubyC" => "if (rb_funcall(LONG2NUM(42), rb_intern(\"==\"), 1, LONG2NUM(0))) {\n;\n} else {\nreturn LONG2NUM(2);\n}",
534
- "RubyToAnsiC" => "if (42 == 0) {\n;\n} else {\nreturn 2;\n}",
236
+ "Ruby" => "unless (42 == 0) then\n return 2\nend",
237
+ "ParseTree" => [:if,
238
+ [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
239
+ nil,
240
+ [:return, [:lit, 2]]],
535
241
  },
536
242
 
537
243
  "conditional3" => {
538
- "Ruby" => "if (42 == 0)\n return 3\nelse\n return 4\nend",
244
+ "Ruby" => "if (42 == 0) then\n return 3\nelse\n return 4\nend",
539
245
  "ParseTree" => [:if, [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
540
- [:return, [:lit, 3]],
541
- [:return, [:lit, 4]]],
542
- "Rewriter" => s(:if,
543
- s(:call,
544
- s(:lit, 42),
545
- :==,
546
- s(:arglist, s(:lit, 0))),
547
- s(:return, s(:lit, 3)),
548
- s(:return, s(:lit, 4))),
549
- "TypeChecker" => t(:if,
550
- t(:call,
551
- t(:lit, 42, Type.long),
552
- :==,
553
- t(:arglist,
554
- t(:lit, 0, Type.long)),
555
- Type.bool),
556
- t(:return,
557
- t(:lit, 3, Type.long),
558
-
559
- Type.void),
560
- t(:return,
561
- t(:lit, 4, Type.long),
562
- Type.void),
563
- Type.void),
564
- "CRewriter" => :same,
565
- "RubyToRubyC" => "if (rb_funcall(LONG2NUM(42), rb_intern(\"==\"), 1, LONG2NUM(0))) {\nreturn LONG2NUM(3);\n} else {\nreturn LONG2NUM(4);\n}",
566
- "RubyToAnsiC" => "if (42 == 0) {\nreturn 3;\n} else {\nreturn 4;\n}",
246
+ [:return, [:lit, 3]],
247
+ [:return, [:lit, 4]]],
567
248
  },
568
249
 
569
250
  "conditional4" => {
570
- "Ruby" => "if (42 == 0)
571
- return 2
572
- else
573
- if (42 < 0)
574
- return 3
575
- else
576
- return 4
577
- end
578
- end",
251
+ "Ruby" => "if (42 == 0) then\n return 2\nelsif (42 < 0) then\n return 3\nelse\n return 4\nend",
579
252
  "ParseTree" => [:if,
580
- [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
581
- [:return, [:lit, 2]],
582
- [:if,
583
- [:call, [:lit, 42], :<, [:array, [:lit, 0]]],
584
- [:return, [:lit, 3]],
585
- [:return, [:lit, 4]]]],
586
- "Rewriter" => s(:if,
587
- s(:call,
588
- s(:lit, 42),
589
- :==,
590
- s(:arglist, s(:lit, 0))),
591
- s(:return, s(:lit, 2)),
592
- s(:if,
593
- s(:call,
594
- s(:lit, 42),
595
- :<,
596
- s(:arglist, s(:lit, 0))),
597
- s(:return, s(:lit, 3)),
598
- s(:return, s(:lit, 4)))),
599
- "TypeChecker" => t(:if,
600
- t(:call,
601
- t(:lit, 42, Type.long),
602
- :==,
603
- t(:arglist,
604
- t(:lit, 0, Type.long)),
605
- Type.bool),
606
- t(:return,
607
- t(:lit, 2, Type.long),
608
- Type.void),
609
- t(:if,
610
- t(:call,
611
- t(:lit, 42, Type.long),
612
- :<,
613
- t(:arglist,
614
- t(:lit, 0, Type.long)),
615
- Type.bool),
616
- t(:return,
617
- t(:lit, 3, Type.long),
618
- Type.void),
619
- t(:return,
620
- t(:lit, 4, Type.long),
621
- Type.void),
622
- Type.void),
623
- Type.void),
624
- "CRewriter" => :same,
625
- "RubyToRubyC" => "if (rb_funcall(LONG2NUM(42), rb_intern(\"==\"), 1, LONG2NUM(0))) {\nreturn LONG2NUM(2);\n} else {\nif (rb_funcall(LONG2NUM(42), rb_intern(\"<\"), 1, LONG2NUM(0))) {\nreturn LONG2NUM(3);\n} else {\nreturn LONG2NUM(4);\n}\n}",
626
- "RubyToAnsiC" => "if (42 == 0) {\nreturn 2;\n} else {\nif (42 < 0) {\nreturn 3;\n} else {\nreturn 4;\n}\n}",
627
- },
628
-
629
- "defn_bmethod_added" => {
630
- "Ruby" => "def bmethod_added(x)\n x + 1\nend",
631
- "ParseTree" => [:defn, :bmethod_added,
632
- [:bmethod,
633
- [:dasgn_curr, :x],
634
- [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]],
635
- "Rewriter" => s(:defn,
636
- :bmethod_added,
637
- s(:args, :x),
638
- s(:scope,
639
- s(:block,
640
- s(:call, s(:lvar, :x), :+, s(:arglist, s(:lit, 1)))))),
641
- "TypeChecker" => :skip,
642
- "CRewriter" => :skip,
643
- "RubyToRubyC" => :skip,
644
- "RubyToAnsiC" => :skip,
253
+ [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
254
+ [:return, [:lit, 2]],
255
+ [:if,
256
+ [:call, [:lit, 42], :<, [:array, [:lit, 0]]],
257
+ [:return, [:lit, 3]],
258
+ [:return, [:lit, 4]]]],
259
+ },
260
+
261
+ "const" => {
262
+ "Ruby" => "X",
263
+ "ParseTree" => [:const, :X],
264
+ },
265
+
266
+ "cvar" => {
267
+ "Ruby" => "@@x",
268
+ "ParseTree" => [:cvar, :@@x],
269
+ },
270
+
271
+ "cvasgn" => {
272
+ "Ruby" => "def x\n @@blah = 1\nend",
273
+ "ParseTree" => [:defn, :x,
274
+ [:scope,
275
+ [:block, [:args], [:cvasgn, :@@blah, [:lit, 1]]]]]
276
+ },
277
+
278
+ "cvdecl" => {
279
+ "Ruby" => "class X\n @@blah = 1\n \nend",
280
+ "ParseTree" => [:class, :X, nil,
281
+ [:scope, [:cvdecl, :@@blah, [:lit, 1]]]],
282
+ },
283
+
284
+ "dasgn" => {
285
+ "Ruby" => "a.each do |x|\n b.each do |y|\n x = (x + 1)\n end\nend",
286
+ "ParseTree" => [:iter,
287
+ [:call, [:vcall, :a], :each],
288
+ [:dasgn_curr, :x],
289
+ [:iter,
290
+ [:call, [:vcall, :b], :each],
291
+ [:dasgn_curr, :y],
292
+ [:dasgn, :x,
293
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]],
294
+ },
295
+
296
+ "defined" => {
297
+ "Ruby" => "defined? $x",
298
+ "ParseTree" => [:defined, [:gvar, :$x]],
645
299
  },
646
300
 
647
301
  "defn_empty" => {
648
- "Ruby" => "def empty()\n nil\nend",
302
+ "Ruby" => "def empty\n # do nothing\nend",
649
303
  "ParseTree" => [:defn, :empty, [:scope, [:block, [:args], [:nil]]]],
650
- "Rewriter" => s(:defn, :empty,
651
- s(:args), s(:scope, s(:block, s(:nil)))),
652
- "TypeChecker" => t(:defn, :empty,
653
- t(:args),
654
- t(:scope,
655
- t(:block,
656
- t(:nil, Type.value),
657
- Type.unknown),
658
- Type.void),
659
- Type.function(Type.unknown, [], Type.void)),
660
- "CRewriter" => :same,
661
- "RubyToRubyC" => "static VALUE\nrrc_c_empty(VALUE self) {\nQnil;\n}",
662
- "RubyToAnsiC" => "void\nempty() {\nNULL;\n}",
663
- },
664
-
665
- "defn_zarray" => {
666
- "Ruby" => "def empty()\n a = []\n return a\nend",
667
- "ParseTree" => [:defn, :empty, [:scope, [:block, [:args], [:lasgn, :a, [:zarray]], [:return, [:lvar, :a]]]]],
668
- "Rewriter" => s(:defn,
669
- :empty,
670
- s(:args),
671
- s(:scope, s(:block, s(:lasgn, :a, s(:array)), s(:return, s(:lvar, :a))))),
672
- "TypeChecker" => t(:defn,
673
- :empty,
674
- t(:args),
675
- t(:scope,
676
- t(:block,
677
- t(:lasgn, :a, t(:array), Type.unknown_list),
678
- t(:return,
679
- t(:lvar,
680
- :a, Type.unknown_list), Type.void),
681
- Type.unknown), Type.void),
682
- Type.function(Type.unknown, [], Type.unknown_list)),
683
- "CRewriter" => :same,
684
- "RubyToRubyC" => "static VALUE\nrrc_c_empty(VALUE self) {\nVALUE a;\na = rb_ary_new2(0);\nreturn a;\n}",
685
- "RubyToAnsiC" => "void *\nempty() {\nvoid * a;\na = (void *) malloc(sizeof(void *) * 0);\nreturn a;\n}",
304
+ },
305
+
306
+ "defn_is_something" => {
307
+ "Ruby" => "def something?\n # do nothing\nend",
308
+ "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]],
686
309
  },
687
310
 
688
311
  "defn_or" => {
689
- "Ruby" => "def |()\n nil\nend",
312
+ "Ruby" => "def |\n # do nothing\nend",
690
313
  "ParseTree" => [:defn, :|, [:scope, [:block, [:args], [:nil]]]],
691
- "Rewriter" => s(:defn, :|,
692
- s(:args), s(:scope, s(:block, s(:nil)))),
693
- "TypeChecker" => t(:defn, :|,
694
- t(:args),
695
- t(:scope,
696
- t(:block,
697
- t(:nil, Type.value),
698
- Type.unknown),
699
- Type.void),
700
- Type.function(Type.unknown, [], Type.void)),
701
- "CRewriter" => :same,
702
- "RubyToRubyC" => "static VALUE\nrrc_c_or(VALUE self) {\nQnil;\n}",
703
- "RubyToAnsiC" => "void\nor() {\nNULL;\n}",
314
+ },
315
+
316
+ "defn_zarray" => { # tests memory allocation for returns
317
+ "Ruby" => "def empty\n a = []\n return a\nend",
318
+ "ParseTree" => [:defn, :empty,
319
+ [:scope,
320
+ [:block, [:args],
321
+ [:lasgn, :a, [:zarray]], [:return, [:lvar, :a]]]]],
704
322
  },
705
323
 
706
- "defn_is_something" => {
707
- "Ruby" => "def something?()\n nil\nend",
708
- "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]],
709
- "Rewriter" => s(:defn, :something?,
710
- s(:args), s(:scope, s(:block, s(:nil)))),
711
- "TypeChecker" => t(:defn, :something?,
712
- t(:args),
713
- t(:scope,
714
- t(:block,
715
- t(:nil, Type.value),
716
- Type.unknown),
717
- Type.void),
718
- Type.function(Type.unknown, [], Type.void)),
719
- "CRewriter" => :same,
720
- "RubyToRubyC" => "static VALUE\nrrc_c_is_something(VALUE self) {\nQnil;\n}",
721
- "RubyToAnsiC" => "void\nis_something() {\nNULL;\n}",
722
- },
723
-
724
- "defn_fbody" => {
725
- "Ruby" => "def aliased()\n puts(42)\nend",
726
- "ParseTree" => [:defn, :aliased,
727
- [:fbody,
728
- [:scope,
729
- [:block,
730
- [:args],
731
- [:fcall, :puts, [:array, [:lit, 42]]]]]]],
732
- "Rewriter" => s(:defn, :aliased,
733
- s(:args),
734
- s(:scope,
735
- s(:block,
736
- s(:call, nil, :puts, s(:arglist, s(:lit, 42)))))),
737
- "TypeChecker" => :skip,
738
- "CRewriter" => :skip,
739
- "RubyToRubyC" => :skip,
740
- "RubyToAnsiC" => :skip,
741
- },
742
-
743
- "defn_optargs" => {
744
- "Ruby" => "def x(a, *args)\n p(a, args)\nend",
745
- "ParseTree" => [:defn, :x,
324
+ "defs" => {
325
+ "Ruby" => "def self.x(y)\n (y + 1)\nend",
326
+ "ParseTree" => [:defs, [:self], :x,
746
327
  [:scope,
747
328
  [:block,
748
- [:args, :a, :"*args"],
749
- [:fcall, :p,
750
- [:array, [:lvar, :a], [:lvar, :args]]]]]],
751
- "Rewriter" => s(:defn, :x,
752
- s(:args, :a, :"*args"),
753
- s(:scope,
754
- s(:block,
755
- s(:call, nil, :p,
756
- s(:arglist, s(:lvar, :a), s(:lvar, :args)))))),
757
- "TypeChecker" => :skip,
758
- "CRewriter" => :skip,
759
- "RubyToRubyC" => :skip,
760
- "RubyToAnsiC" => :skip,
761
- },
762
-
763
- "dmethod_added" => {
764
- "Ruby" => "def dmethod_added\n define_method(:bmethod_added)\n x {|(x + 1)|\n }end",
329
+ [:args, :y],
330
+ [:call, [:lvar, :y], :+, [:array, [:lit, 1]]]]]],
331
+ },
332
+
333
+ "dmethod" => {
334
+ "Ruby" => [Examples, :dmethod_added],
765
335
  "ParseTree" => [:defn,
766
- :dmethod_added,
767
- [:dmethod,
768
- :bmethod_maker,
769
- [:scope,
770
- [:block,
771
- [:args],
772
- [:iter,
773
- [:fcall, :define_method, [:array, [:lit, :bmethod_added]]],
774
- [:dasgn_curr, :x],
775
- [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]]]],
776
- "Rewriter" => s(:defn,
777
- :dmethod_added,
778
- s(:args, :x),
779
- s(:scope,
780
- s(:block,
781
- s(:call, s(:lvar, :x), :+,
782
- s(:arglist, s(:lit, 1)))))),
783
- "TypeChecker" => :skip,
784
- "CRewriter" => :skip,
785
- "RubyToRubyC" => :skip,
786
- "RubyToAnsiC" => :skip,
336
+ :dmethod_added,
337
+ [:dmethod,
338
+ :bmethod_maker,
339
+ [:scope,
340
+ [:block,
341
+ [:args],
342
+ [:iter,
343
+ [:fcall, :define_method,
344
+ [:array, [:lit, :bmethod_added]]],
345
+ [:dasgn_curr, :x],
346
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]]]],
347
+ "Ruby2Ruby" => "def dmethod_added(x)\n (x + 1)\nend"
348
+ },
349
+
350
+ "dot2" => {
351
+ "Ruby" => "(a..b)",
352
+ "ParseTree" => [:dot2, [:vcall, :a], [:vcall, :b]],
353
+ },
354
+
355
+ "dot3" => {
356
+ "Ruby" => "(a...b)",
357
+ "ParseTree" => [:dot3, [:vcall, :a], [:vcall, :b]],
358
+ },
359
+
360
+ "dregx" => {
361
+ "Ruby" => "/x#\{(1 + 1)}y/",
362
+ "ParseTree" => [:dregx, "x",
363
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
364
+ },
365
+
366
+ "dregx_once" => {
367
+ "Ruby" => "/x#\{(1 + 1)}y/o",
368
+ "ParseTree" => [:dregx_once, "x",
369
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
370
+ },
371
+
372
+ "dstr" => {
373
+ "Ruby" => "argl = 1\n\"x#\{argl}y\"\n",
374
+ "ParseTree" => [:block,
375
+ [:lasgn, :argl, [:lit, 1]],
376
+ [:dstr, "x", [:lvar, :argl],
377
+ [:str, "y"]]],
378
+ },
379
+
380
+ "dsym" => {
381
+ "Ruby" => ":\"x#\{(1 + 1)}y\"",
382
+ "ParseTree" => [:dsym, "x",
383
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
384
+ },
385
+
386
+ "dxstr" => {
387
+ "Ruby" => "t = 5\n`touch #\{t}`\n",
388
+ "ParseTree" => [:block,
389
+ [:lasgn, :t, [:lit, 5]],
390
+ [:dxstr, 'touch ', [:lvar, :t]]],
391
+ },
392
+
393
+ "ensure" => {
394
+ "Ruby" => "def bbegin\n begin\n (1 + 1)\n rescue SyntaxError => e1\n 2\n rescue Exception => e2\n 3\n else\n 4\n ensure\n 5\n end\nend",
395
+ "ParseTree" => [:defn, :bbegin,
396
+ [:scope,
397
+ [:block,
398
+ [:args],
399
+ [:begin,
400
+ [:ensure,
401
+ [:rescue,
402
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]],
403
+ [:resbody,
404
+ [:array, [:const, :SyntaxError]],
405
+ [:block, [:lasgn, :e1, [:gvar, :$!]], [:lit, 2]],
406
+ [:resbody,
407
+ [:array, [:const, :Exception]],
408
+ [:block, [:lasgn, :e2, [:gvar, :$!]], [:lit, 3]]]],
409
+ [:lit, 4]],
410
+ [:lit, 5]]]]]],
411
+ },
412
+
413
+ "false" => {
414
+ "Ruby" => "false",
415
+ "ParseTree" => [:false],
416
+ },
417
+
418
+ "fbody" => {
419
+ "Ruby" => [Examples, :an_alias],
420
+ "ParseTree" => [:defn, :an_alias,
421
+ [:fbody,
422
+ [:scope,
423
+ [:block,
424
+ [:args],
425
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]]]],
426
+ "Ruby2Ruby" => "def an_alias\n (1 + 1)\nend"
427
+ },
428
+
429
+ "fcall" => {
430
+ "Ruby" => "p(4)",
431
+ "ParseTree" => [:fcall, :p, [:array, [:lit, 4]]],
432
+ },
433
+
434
+ "flip2" => {
435
+ "Ruby" => "x = if ((i % 4) == 0)..((i % 3) == 0) then\n i\nelse\n nil\nend",
436
+ "ParseTree" => [:lasgn,
437
+ :x,
438
+ [:if,
439
+ [:flip2,
440
+ [:call,
441
+ [:call, [:vcall, :i], :%, [:array, [:lit, 4]]],
442
+ :==,
443
+ [:array, [:lit, 0]]],
444
+ [:call,
445
+ [:call, [:vcall, :i], :%, [:array, [:lit, 3]]],
446
+ :==,
447
+ [:array, [:lit, 0]]]],
448
+ [:vcall, :i],
449
+ [:nil]]],
450
+ },
451
+
452
+ "flip3" => {
453
+ "Ruby" => "x = if ((i % 4) == 0)...((i % 3) == 0) then\n i\nelse\n nil\nend",
454
+ "ParseTree" => [:lasgn,
455
+ :x,
456
+ [:if,
457
+ [:flip3,
458
+ [:call,
459
+ [:call, [:vcall, :i], :%, [:array, [:lit, 4]]],
460
+ :==,
461
+ [:array, [:lit, 0]]],
462
+ [:call,
463
+ [:call, [:vcall, :i], :%, [:array, [:lit, 3]]],
464
+ :==,
465
+ [:array, [:lit, 0]]]],
466
+ [:vcall, :i],
467
+ [:nil]]],
468
+ },
469
+
470
+ "for" => {
471
+ "Ruby" => "for o in ary\n puts(o)\nend\n",
472
+ "ParseTree" => [:for, [:vcall, :ary], [:lasgn, :o],
473
+ [:fcall, :puts, [:array, [:lvar, :o]]]],
474
+ },
475
+
476
+ "gasgn" => {
477
+ "Ruby" => "$x = 42",
478
+ "ParseTree" => [:gasgn, :$x, [:lit, 42]],
787
479
  },
788
480
 
789
481
  "global" => {
790
482
  "Ruby" => "$stderr",
791
483
  "ParseTree" => [:gvar, :$stderr],
792
- "Rewriter" => s(:gvar, :$stderr),
793
- # TODO: test s(:gvar, :$stderr) != t(:gvar, $stderr, Type.file)
794
- "TypeChecker" => t(:gvar, :$stderr, Type.file),
795
- "CRewriter" => :same,
796
- "RubyToRubyC" => "rb_gv_get(\"$stderr\")",
797
- "RubyToAnsiC" => "stderr",
798
- },
799
-
800
- "interpolated" => {
801
- "Ruby" => "\"var is \#{argl}. So there.\"",
802
- "ParseTree" => [:dstr,
803
- "var is ", [:lvar, :argl], [:str, ". So there."]],
804
- "Rewriter" => s(:dstr,
805
- "var is ", s(:lvar, :argl), s(:str, ". So there.")),
806
- "TypeChecker" => t(:dstr,
807
- "var is ",
808
- t(:lvar, :argl, Type.long),
809
- t(:str, ". So there.", Type.str),
810
- Type.str),
811
- "CRewriter" => :same,
812
- "RubyToRubyC" => "rb_funcall(rb_mKernel, rb_intern(\"sprintf\"), 4, rb_str_new2(\"%s%s%s\"), rb_str_new2(\"var is \"), argl, rb_str_new2(\". So there.\"))",
813
- "RubyToAnsiC" => :unsupported,
814
- },
815
-
816
- "iter" => {
484
+ },
485
+
486
+ "gvar" => {
487
+ "Ruby" => "$x",
488
+ "ParseTree" => [:gvar, :$x],
489
+ },
490
+
491
+ "hash" => {
492
+ "Ruby" => "{ 1 => 2, 3 => 4 }",
493
+ "ParseTree" => [:hash, [:lit, 1], [:lit, 2], [:lit, 3], [:lit, 4]],
494
+ },
495
+
496
+ "iasgn" => {
497
+ "Ruby" => "@a = 4",
498
+ "ParseTree" => [:iasgn, :@a, [:lit, 4]],
499
+ },
500
+
501
+ "iteration1" => {
817
502
  "Ruby" => "loop do end",
818
503
  "ParseTree" => [:iter, [:fcall, :loop], nil],
819
- "Rewriter" => s(:iter,
820
- s(:call, nil, :loop, nil),
821
- s(:dasgn_curr, :temp_1),
822
- nil),
823
- "TypeChecker" => t(:iter,
824
- t(:call, nil, :loop, nil, Type.unknown),
825
- t(:dasgn_curr, :temp_1, Type.unknown),
826
- nil,
827
- Type.unknown),
828
- "CRewriter" => [:defx,
829
- t(:iter,
830
- t(:call, nil, :loop, nil, Type.unknown),
831
- t(:args,
832
- t(:array, t(:dasgn_curr, :temp_1, Type.unknown), Type.void),
833
- t(:array, Type.void), Type.void),
834
- t(:call, nil,
835
- :temp_2,
836
- s(:arglist, s(:dasgn_curr, :temp_1, Type.unknown),
837
- t(:nil)))),
838
- [t(:defx,
839
- :temp_2,
840
- t(:args, :temp_2, :temp_3),
841
- t(:scope, t(:block, nil)), Type.void)]],
842
- "RubyToRubyC" => "",
843
- "RubyToAnsiC" => "",
844
504
  },
845
505
 
846
506
  "iteration2" => {
507
+ "Ruby" => "array = [1, 2, 3]\narray.each do |x|\n puts(x.to_s)\nend\n",
508
+ "ParseTree" => [:block,
509
+ [:lasgn, :array,
510
+ [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
511
+ [:iter,
512
+ [:call, [:lvar, :array], :each],
513
+ [:dasgn_curr, :x],
514
+ [:fcall, :puts, [:array, [:call, [:dvar, :x], :to_s]]]]],
515
+ },
516
+
517
+ "iteration3" => {
518
+ "Ruby" => "1.upto(3) do |n|\n puts(n.to_s)\nend",
847
519
  "ParseTree" => [:iter,
848
- [:call, [:lvar, :arrays], :each],
849
- [:dasgn_curr, :x],
850
- [:fcall, :puts, [:arrays, [:dvar, :x]]]],
851
- "Rewriter" => s(:iter,
852
- s(:call, s(:lvar, :arrays), :each, nil),
853
- s(:dasgn_curr, :x),
854
- s(:call, nil, :puts, s(:arglist, s(:dvar, :x)))),
855
- "TypeChecker" => t(:iter,
856
- t(:call,
857
- t(:lvar, :arrays, Type.str_list),
858
- :each,
859
- nil, Type.unknown),
860
- t(:dasgn_curr, :x, Type.str),
861
- t(:call, nil, :puts,
862
- t(:arglist, t(:dvar, :x, Type.str)),
863
- Type.void),
864
- Type.void),
865
- "CRewriter" => [:defx,
866
- t(:iter,
867
- t(:call,
868
- t(:lvar, :arrays, Type.str_list),
869
- :each,
870
- nil, Type.unknown),
871
- t(:args,
872
- t(:array, t(:dasgn_curr, :x, Type.str), Type.void),
873
- t(:array, t(:lvar, :arrays, Type.value), Type.void), Type.void),
874
- t(:call, nil, :temp_1, t(:arglist, t(:dasgn_curr, :x, Type.str), t(:nil)))),
875
- [t(:defx,
876
- :temp_1,
877
- t(:args, :temp_2, :temp_3),
878
- t(:scope,
879
- t(:block,
880
- t(:call,
881
- nil,
882
- :puts,
883
- t(:arglist, t(:dvar, :x, Type.str)), Type.void))), Type.void)]],
884
- "RubyToRubyC" => 'unsigned long index_temp_1;
885
- VALUE temp_2 = rb_funcall(arrays, rb_intern("to_a"), 0);
886
- unsigned long temp_1_max = FIX2LONG(rb_funcall(temp_2, rb_intern("size"), 0));
887
- for (index_temp_1 = 0; index_temp_1 < temp_1_max; ++index_temp_1) {
888
- VALUE x;
889
- x = rb_funcall(temp_2, rb_intern("at"), 1, LONG2FIX(index_temp_1));
890
- rb_funcall(self, rb_intern("puts"), 1, x);
891
- }",
892
- "RubyToAnsiC" => "unsigned long index_x;
893
- for (index_x = 0; arrays[index_x] != NULL; ++index_x) {
894
- str x = arrays[index_x];
895
- puts(x);
896
- }',
520
+ [:call, [:lit, 1], :upto, [:array, [:lit, 3]]],
521
+ [:dasgn_curr, :n],
522
+ [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
897
523
  },
898
524
 
899
-
900
525
  "iteration4" => {
901
- "Ruby" => "1.upto(3) {|n|\n puts(n.to_s)\n}",
526
+ "Ruby" => "3.downto(1) do |n|\n puts(n.to_s)\nend",
902
527
  "ParseTree" => [:iter,
903
- [:call, [:lit, 1], :upto, [:array, [:lit, 3]]],
904
- [:dasgn_curr, :n],
905
- [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
906
- "Rewriter" => s(:dummy,
907
- s(:lasgn, :n, s(:lit, 1)),
908
- s(:while,
909
- s(:call, s(:lvar, :n), :<=, s(:arglist, s(:lit, 3))),
910
- s(:block,
911
- s(:call,
912
- nil,
913
- :puts,
914
- s(:arglist, s(:call, s(:lvar, :n), :to_s, nil))),
915
- s(:lasgn, :n,
916
- s(:call, s(:lvar, :n),
917
- :+,
918
- s(:arglist, s(:lit, 1))))), true)),
919
- "TypeChecker" => t(:dummy, t(:lasgn, :n, t(:lit, 1, Type.long), Type.long),
920
- t(:while,
921
- t(:call,
922
- t(:lvar, :n, Type.long),
923
- :<=,
924
- t(:arglist, t(:lit, 3, Type.long)), Type.bool),
925
- t(:block,
926
- t(:call, nil, :puts,
927
- t(:arglist,
928
- t(:call,
929
- t(:lvar, :n, Type.long),
930
- :to_s,
931
- nil, Type.str)), Type.void),
932
- t(:lasgn, :n,
933
- t(:call,
934
- t(:lvar, :n, Type.long),
935
- :+,
936
- t(:arglist,
937
- t(:lit,
938
- 1, Type.long)),
939
- Type.long), Type.long), Type.unknown), true)),
940
- "CRewriter" => :same,
941
- "RubyToRubyC" => '',
942
- "RubyToAnsiC" => 'n = 1;
943
- while (n <= 3) {
944
- puts(to_s(n));
945
- n = n + 1;
946
- }',
528
+ [:call, [:lit, 3], :downto, [:array, [:lit, 1]]],
529
+ [:dasgn_curr, :n],
530
+ [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
947
531
  },
948
532
 
949
533
  "iteration5" => {
950
- "Ruby" => "3.downto(1) {|n|\n puts(n.to_s)\n}",
951
- "ParseTree" => [:iter,
952
- [:call, [:lit, 3], :downto, [:array, [:lit, 1]]],
953
- [:dasgn_curr, :n],
954
- [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
955
- "Rewriter" => s(:dummy, s(:lasgn, :n, s(:lit, 3)), s(:while,
956
- s(:call, s(:lvar, :n), :>=, s(:arglist, s(:lit, 1))),
957
- s(:block,
958
- s(:call, nil, :puts,
959
- s(:arglist, s(:call, s(:lvar, :n), :to_s, nil))),
960
- s(:lasgn, :n, s(:call, s(:lvar, :n),
961
- :-, s(:arglist, s(:lit, 1))))), true)),
962
- "TypeChecker" => t(:dummy,
963
- t(:lasgn, :n, t(:lit, 3, Type.long), Type.long),
964
- t(:while,
965
- t(:call,
966
- t(:lvar, :n, Type.long),
967
- :>=,
968
- t(:arglist, t(:lit, 1, Type.long)), Type.bool),
969
- t(:block,
970
- t(:call, nil, :puts,
971
- t(:arglist,
972
- t(:call,
973
- t(:lvar, :n, Type.long),
974
- :to_s,
975
- nil, Type.str)), Type.void),
976
- t(:lasgn, :n,
977
- t(:call,
978
- t(:lvar, :n, Type.long),
979
- :-,
980
- t(:arglist, t(:lit, 1, Type.long)),
981
- Type.long),
982
- Type.long),
983
- Type.unknown), true)),
984
- "CRewriter" => :same,
985
- "RubyToRubyC" => '',
986
- "RubyToAnsiC" => 'n = 3;
987
- while (n >= 1) {
988
- puts(to_s(n));
989
- n = n - 1;
990
- }',
534
+ "Ruby" => "argl = 10\nwhile (argl >= 1) do\n puts(\"hello\")\n argl = (argl - 1)\nend\n",
535
+ "ParseTree" => [:block,
536
+ [:lasgn, :argl, [:lit, 10]],
537
+ [:while,
538
+ [:call, [:lvar, :argl], :>=, [:array, [:lit, 1]]],
539
+ [:block,
540
+ [:fcall, :puts, [:array, [:str, "hello"]]],
541
+ [:lasgn,
542
+ :argl,
543
+ [:call, [:lvar, :argl],
544
+ :-, [:array, [:lit, 1]]]]], true]],
991
545
  },
992
546
 
993
547
  "iteration6" => {
994
- "Ruby" => "while ((argl >= (1))) do\nputs((\"hello\"))\nargl = (argl - (1))\n\nend",
995
- "ParseTree" => [:while, [:call, [:lvar, :argl],
996
- :>=, [:arglist, [:lit, 1]]], [:block,
997
- [:call, nil, :puts, [:arglist, [:str, "hello"]]],
998
- [:lasgn,
999
- :argl,
1000
- [:call, [:lvar, :argl],
1001
- :-, [:arglist, [:lit, 1]]]]], true],
1002
- "Rewriter" => s(:while,
1003
- s(:call, s(:lvar, :argl),
1004
- :>=, s(:arglist, s(:lit, 1))),
1005
- s(:block,
1006
- s(:call, nil, :puts, s(:arglist, s(:str, "hello"))),
1007
- s(:lasgn,
1008
- :argl,
1009
- s(:call, s(:lvar, :argl),
1010
- :-, s(:arglist, s(:lit, 1))))), true),
1011
- "TypeChecker" => t(:while,
1012
- t(:call, t(:lvar, :argl, Type.long),
1013
- :>=,
1014
- t(:arglist, t(:lit, 1, Type.long)), Type.bool),
1015
- t(:block,
1016
- t(:call, nil, :puts,
1017
- t(:arglist, t(:str, "hello", Type.str)),
1018
- Type.void),
1019
- t(:lasgn,
1020
- :argl,
1021
- t(:call, t(:lvar, :argl, Type.long),
1022
- :-,
1023
- t(:arglist, t(:lit, 1, Type.long)), Type.long),
1024
- Type.long),
1025
- Type.unknown), true),
1026
- "CRewriter" => :same,
1027
- "RubyToRubyC" => '',
1028
- "RubyToAnsiC" => 'while (argl >= 1) {
1029
- puts("hello");
1030
- argl = argl - 1;
1031
- }',
1032
- },
1033
-
1034
- # TODO: this might still be too much
1035
- "lasgn_call" => {
1036
- "Ruby" => "c = 2 + 3",
1037
- "ParseTree" => [:lasgn, :c, [:call, [:lit, 2], :+, [:arglist, [:lit, 3]]]],
1038
- "Rewriter" => s(:lasgn, :c, s(:call, s(:lit, 2), :+, s(:arglist, s(:lit, 3)))),
1039
- "TypeChecker" => t(:lasgn, :c,
1040
- t(:call,
1041
- t(:lit, 2, Type.long),
1042
- :+,
1043
- t(:arglist,
1044
- t(:lit, 3, Type.long)),
1045
- Type.long),
1046
- Type.long),
1047
- "CRewriter" => :same,
1048
- "RubyToRubyC" => 'c = rb_funcall(LONG2NUM(2), rb_intern("+"), 1, LONG2NUM(3))', # FIX: probably not "c ="
1049
- "RubyToAnsiC" => "c = 2 + 3",
548
+ "Ruby" => "array1 = [1, 2, 3]\narray2 = [4, 5, 6, 7]\narray1.each do |x|\n array2.each do |y|\n puts(x.to_s)\n puts(y.to_s)\n end\nend\n",
549
+ "ParseTree" => [:block,
550
+ [:lasgn, :array1,
551
+ [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
552
+ [:lasgn, :array2,
553
+ [:array, [:lit, 4], [:lit, 5], [:lit, 6], [:lit, 7]]],
554
+ [:iter,
555
+ [:call,
556
+ [:lvar, :array1], :each],
557
+ [:dasgn_curr, :x],
558
+ [:iter,
559
+ [:call,
560
+ [:lvar, :array2], :each],
561
+ [:dasgn_curr, :y],
562
+ [:block,
563
+ [:fcall, :puts,
564
+ [:array, [:call, [:dvar, :x], :to_s]]],
565
+ [:fcall, :puts,
566
+ [:array, [:call, [:dvar, :y], :to_s]]]]]]],
567
+ },
568
+
569
+ "ivar" => {
570
+ "Ruby" => [Examples, :reader],
571
+ "ParseTree" => [:defn, :reader, [:ivar, :@reader]],
572
+ "Ruby2Ruby" => "attr_reader :reader"
1050
573
  },
1051
574
 
1052
575
  "lasgn_array" => {
1053
576
  "Ruby" => "var = [\"foo\", \"bar\"]",
1054
577
  "ParseTree" => [:lasgn, :var, [:array,
1055
- [:str, "foo"],
1056
- [:str, "bar"]]],
1057
- "Rewriter" => s(:lasgn, :var, s(:array,
1058
- s(:str, "foo"),
1059
- s(:str, "bar"))),
1060
- "TypeChecker" => t(:lasgn,
1061
- :var,
1062
- t(:array,
1063
- t(:str, "foo", Type.str),
1064
- t(:str, "bar", Type.str)),
1065
- Type.str_list),
1066
- "CRewriter" => :same,
1067
- "RubyToRubyC" => 'var = rb_ary_new2(2);
1068
- rb_ary_store(var, 0, rb_str_new2("foo"));
1069
- rb_ary_store(var, 1, rb_str_new2("bar"))',
1070
- "RubyToAnsiC" => 'var = (str) malloc(sizeof(str) * 2);
1071
- var[0] = "foo";
1072
- var[1] = "bar"'
1073
- },
578
+ [:str, "foo"],
579
+ [:str, "bar"]]],
580
+ },
581
+
582
+ "lasgn_call" => {
583
+ "Ruby" => "c = (2 + 3)",
584
+ "ParseTree" => [:lasgn, :c, [:call, [:lit, 2], :+, [:array, [:lit, 3]]]],
585
+ },
1074
586
 
1075
587
  "lit_bool_false" => {
1076
588
  "Ruby" => "false",
1077
589
  "ParseTree" => [:false],
1078
- "Rewriter" => s(:false),
1079
- "TypeChecker" => t(:false, Type.bool),
1080
- "CRewriter" => :same,
1081
- "RubyToRubyC" => "Qfalse",
1082
- "RubyToAnsiC" => "0",
1083
590
  },
1084
591
 
1085
592
  "lit_bool_true" => {
1086
593
  "Ruby" => "true",
1087
594
  "ParseTree" => [:true],
1088
- "Rewriter" => s(:true),
1089
- "TypeChecker" => t(:true, Type.bool),
1090
- "CRewriter" => :same,
1091
- "RubyToRubyC" => "Qtrue",
1092
- "RubyToAnsiC" => "1",
1093
595
  },
1094
596
 
1095
597
  "lit_float" => {
1096
598
  "Ruby" => "1.1",
1097
599
  "ParseTree" => [:lit, 1.1],
1098
- "Rewriter" => s(:lit, 1.1),
1099
- "TypeChecker" => t(:lit, 1.1, Type.float),
1100
- "CRewriter" => :same,
1101
- "RubyToRubyC" => "rb_float_new(1.1)",
1102
- "RubyToAnsiC" => "1.1",
1103
600
  },
1104
601
 
1105
602
  "lit_long" => {
1106
603
  "Ruby" => "1",
1107
604
  "ParseTree" => [:lit, 1],
1108
- "Rewriter" => s(:lit, 1),
1109
- "TypeChecker" => t(:lit, 1, Type.long),
1110
- "CRewriter" => :same,
1111
- "RubyToRubyC" => "LONG2NUM(1)",
1112
- "RubyToAnsiC" => "1",
1113
605
  },
1114
606
 
1115
- "lit_sym" => {
1116
- "Ruby" => ":x",
1117
- "ParseTree" => [:lit, :x],
1118
- "Rewriter" => s(:lit, :x),
1119
- "TypeChecker" => t(:lit, :x, Type.symbol),
1120
- "CRewriter" => :same,
1121
- "RubyToRubyC" => 'ID2SYM(rb_intern("x"))',
1122
- "RubyToAnsiC" => '"x"', # HACK WRONG! (or... is it?)
607
+ "lit_range2" => {
608
+ "Ruby" => "(1..10)",
609
+ "ParseTree" => [:lit, 1..10],
610
+ },
611
+
612
+ "lit_range3" => {
613
+ "Ruby" => "(1...10)",
614
+ "ParseTree" => [:lit, 1...10],
615
+ },
616
+
617
+ "lit_regexp" => {
618
+ "Ruby" => "/x/",
619
+ "ParseTree" => [:lit, /x/],
1123
620
  },
1124
621
 
1125
622
  "lit_str" => {
1126
623
  "Ruby" => "\"x\"",
1127
624
  "ParseTree" => [:str, "x"],
1128
- "Rewriter" => s(:str, "x"),
1129
- "TypeChecker" => t(:str, "x", Type.str),
1130
- "CRewriter" => :same,
1131
- "RubyToRubyC" => 'rb_str_new2("x")',
1132
- "RubyToAnsiC" => '"x"',
1133
- },
1134
-
1135
- "multi_args" => {
1136
- "Ruby" => "def multi_args(arg1, arg2)\n arg3 = ((arg1 * arg2) * 7)\n puts(arg3.to_s)\n return \"foo\"\nend",
1137
- "ParseTree" => [:defn, :multi_args,
1138
- [:scope,
1139
- [:block,
1140
- [:args, :arg1, :arg2],
1141
- [:lasgn,
1142
- :arg3,
1143
- [:call,
1144
- [:call, [:lvar, :arg1], :*, [:array, [:lvar, :arg2]]],
1145
- :*,
1146
- [:array, [:lit, 7]]]],
1147
- [:fcall, :puts, [:array, [:call, [:lvar, :arg3], :to_s]]],
1148
- [:return, [:str, "foo"]]]]],
1149
- "Rewriter" => s(:defn, :multi_args,
1150
- s(:args, :arg1, :arg2),
1151
- s(:scope,
1152
- s(:block,
1153
- s(:lasgn, :arg3,
1154
- s(:call,
1155
- s(:call,
1156
- s(:lvar, :arg1),
1157
- :*,
1158
- s(:arglist, s(:lvar, :arg2))),
1159
- :*,
1160
- s(:arglist, s(:lit, 7)))),
1161
- s(:call,
1162
- nil,
1163
- :puts,
1164
- s(:arglist,
1165
- s(:call,
1166
- s(:lvar, :arg3),
1167
- :to_s,
1168
- nil))),
1169
- s(:return, s(:str, "foo"))))),
1170
- "TypeChecker" => t(:defn, :multi_args,
1171
- t(:args,
1172
- t(:arg1, Type.long),
1173
- t(:arg2, Type.long)),
1174
- t(:scope,
1175
- t(:block,
1176
- t(:lasgn,
1177
- :arg3,
1178
- t(:call,
1179
- t(:call,
1180
- t(:lvar, :arg1, Type.long),
1181
- :*,
1182
- t(:arglist,
1183
- t(:lvar,
1184
- :arg2,
1185
- Type.long)),
1186
- Type.long),
1187
- :*,
1188
- t(:arglist,
1189
- t(:lit, 7, Type.long)),
1190
- Type.long),
1191
- Type.long),
1192
- t(:call,
1193
- nil,
1194
- :puts,
1195
- t(:arglist,
1196
- t(:call,
1197
- t(:lvar, :arg3, Type.long),
1198
- :to_s,
1199
- nil,
1200
- Type.str)),
1201
- Type.void),
1202
- t(:return, t(:str, "foo", Type.str),
1203
- Type.void),
1204
- Type.unknown),
1205
- Type.void),
1206
- Type.function(Type.unknown,
1207
- [Type.long, Type.long], Type.str)),
1208
- "CRewriter" => :same,
1209
- "RubyToRubyC" => "static VALUE
1210
- rrc_c_multi_args(VALUE self, VALUE arg1, VALUE arg2) {
1211
- VALUE arg3;
1212
- arg3 = rb_funcall(rb_funcall(arg1, rb_intern(\"*\"), 1, arg2), rb_intern(\"*\"), 1, LONG2NUM(7));
1213
- rb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(arg3, rb_intern(\"to_s\"), 0));
1214
- return rb_str_new2(\"foo\");
1215
- }",
1216
- "RubyToAnsiC" => "str
1217
- multi_args(long arg1, long arg2) {
1218
- long arg3;
1219
- arg3 = arg1 * arg2 * 7;
1220
- puts(to_s(arg3));
1221
- return \"foo\";
1222
- }",
1223
- },
1224
-
625
+ },
626
+
627
+ "lit_sym" => {
628
+ "Ruby" => ":x",
629
+ "ParseTree" => [:lit, :x],
630
+ },
631
+
632
+ "masgn" => {
633
+ "Ruby" => "a, b = c, d",
634
+ "ParseTree" => [:masgn,
635
+ [:array, [:lasgn, :a], [:lasgn, :b]],
636
+ [:array, [:vcall, :c], [:vcall, :d]]],
637
+ },
638
+
639
+ "match" => {
640
+ "Ruby" => "if /x/ then\n 1\nend",
641
+ "ParseTree" => [:if, [:match, [:lit, /x/]], [:lit, 1], nil],
642
+ },
643
+
644
+ "match2" => {
645
+ "Ruby" => "/x/ =~ \"blah\"",
646
+ "ParseTree" => [:match2, [:lit, /x/], [:str, "blah"]],
647
+ },
648
+
649
+ "match3" => {
650
+ "Ruby" => "\"blah\" =~ /x/",
651
+ "ParseTree" => [:match3, [:lit, /x/], [:str, "blah"]],
652
+ },
653
+
654
+ "module" => {
655
+ "Ruby" => "module X\n def y\n # do nothing\n end\n \nend",
656
+ "ParseTree" => [:module, :X,
657
+ [:scope,
658
+ [:defn, :y, [:scope, [:block, [:args], [:nil]]]]]],
659
+ },
660
+
661
+ "next" => {
662
+ "Ruby" => "loop do\n if false then\n next\n end\nend",
663
+ "ParseTree" => [:iter,
664
+ [:fcall, :loop],
665
+ nil,
666
+ [:if, [:false], [:next], nil]],
667
+ },
668
+
669
+ "not" => {
670
+ "Ruby" => "(not true)",
671
+ "ParseTree" => [:not, [:true]],
672
+ },
673
+
674
+ "nth_ref" => {
675
+ "Ruby" => "$1",
676
+ "ParseTree" => [:nth_ref, 1],
677
+ },
678
+
679
+ "op_asgn1" => {
680
+ "Ruby" => "b = []\nb[1] ||= 10\nb[2] &&= 11\nb[3] += 12\n",
681
+ "ParseTree" => [:block,
682
+ [:lasgn, :b, [:zarray]],
683
+ [:op_asgn1, [:lvar, :b],
684
+ [:array, [:lit, 1]], "||".intern, [:lit, 10]], # s->e
685
+ [:op_asgn1, [:lvar, :b],
686
+ [:array, [:lit, 2]], "&&".intern, [:lit, 11]], # s->e
687
+ [:op_asgn1, [:lvar, :b],
688
+ [:array, [:lit, 3]], :+, [:lit, 12]]],
689
+ },
690
+
691
+ "op_asgn2" => {
692
+ "Ruby" => "s = Struct.new(:var)\nc = s.new(nil)\nc.var ||= 20\nc.var &&= 21\nc.var += 22\nc.d.e.f ||= 42\n",
693
+ "ParseTree" => [:block,
694
+ [:lasgn, :s,
695
+ [:call, [:const, :Struct],
696
+ :new, [:array, [:lit, :var]]]],
697
+ [:lasgn, :c,
698
+ [:call, [:lvar, :s], :new, [:array, [:nil]]]],
699
+
700
+ [:op_asgn2, [:lvar, :c], :var=, "||".intern, # s->e
701
+ [:lit, 20]],
702
+ [:op_asgn2, [:lvar, :c], :var=, "&&".intern, # s->e
703
+ [:lit, 21]],
704
+ [:op_asgn2, [:lvar, :c], :var=, :+, [:lit, 22]],
705
+
706
+ [:op_asgn2,
707
+ [:call,
708
+ [:call, [:lvar, :c], :d], :e], :f=, "||".intern,
709
+ [:lit, 42]]],
710
+ },
711
+
712
+ "op_asgn_and" => {
713
+ "Ruby" => "a = 0\na &&= 2\n",
714
+ "ParseTree" => [:block,
715
+ [:lasgn, :a, [:lit, 0]],
716
+ [:op_asgn_and, [:lvar, :a], [:lasgn, :a, [:lit, 2]]]],
717
+ },
718
+
719
+ "op_asgn_or" => {
720
+ "Ruby" => "a = 0\na ||= 1\n",
721
+ "ParseTree" => [:block,
722
+ [:lasgn, :a, [:lit, 0]],
723
+ [:op_asgn_or, [:lvar, :a], [:lasgn, :a, [:lit, 1]]]],
724
+ },
725
+
726
+ "or" => {
727
+ "Ruby" => "(a or b)",
728
+ "ParseTree" => [:or, [:vcall, :a], [:vcall, :b]],
729
+ },
730
+
731
+ "postexe" => {
732
+ "Ruby" => "END {\n 1\n}",
733
+ "ParseTree" => [:iter, [:postexe], nil, [:lit, 1]],
734
+ },
735
+
736
+ "redo" => {
737
+ "Ruby" => "loop do\n if false then\n redo\n end\nend",
738
+ "ParseTree" => [:iter,
739
+ [:fcall, :loop], nil, [:if, [:false], [:redo], nil]],
740
+ },
741
+
742
+ # "rescue" => { # TODO: expression style rescues
743
+ # "Ruby" => "blah rescue nil",
744
+ # "ParseTree" => [:rescue, [:vcall, :blah], [:resbody, nil, [:nil]]],
745
+ # },
746
+
747
+ "rescue_block" => {
748
+ "Ruby" => "begin\n blah\nrescue\n # do nothing\nend\n",
749
+ "ParseTree" => [:begin, [:rescue, [:vcall, :blah], [:resbody, nil]]]
750
+ },
751
+
752
+ "rescue_exceptions" => {
753
+ "Ruby" => "begin\n blah\nrescue RuntimeError => r\n # do nothing\nend\n",
754
+ "ParseTree" => [:begin,
755
+ [:rescue,
756
+ [:vcall, :blah],
757
+ [:resbody,
758
+ [:array, [:const, :RuntimeError]],
759
+ [:lasgn, :r, [:gvar, :$!]]]]],
760
+ },
761
+
762
+ "retry" => {
763
+ "Ruby" => "retry",
764
+ "ParseTree" => [:retry],
765
+ },
766
+
767
+ "sclass" => {
768
+ "Ruby" => "class << self\n 42\nend",
769
+ "ParseTree" => [:sclass, [:self], [:scope, [:lit, 42]]],
770
+ },
771
+
772
+ "splat" => {
773
+ "Ruby" => "a(*b)",
774
+ "ParseTree" => [:fcall, :a, [:splat, [:vcall, :b]]],
775
+ },
776
+
777
+ "super" => {
778
+ "Ruby" => "def x\n super(4)\nend",
779
+ "ParseTree" => [:defn, :x,
780
+ [:scope,
781
+ [:block,
782
+ [:args],
783
+ [:super, [:array, [:lit, 4]]]]]],
784
+ },
785
+
786
+ "super_multi" => {
787
+ "Ruby" => "def x\n super(4, 2, 1)\nend",
788
+ "ParseTree" => [:defn, :x,
789
+ [:scope,
790
+ [:block,
791
+ [:args],
792
+ [:super, [:array, [:lit, 4], [:lit, 2], [:lit, 1]]]]]],
793
+ },
794
+
795
+ "svalue" => {
796
+ "Ruby" => "a = *b",
797
+ "ParseTree" => [:lasgn, :a, [:svalue, [:splat, [:vcall, :b]]]],
798
+ },
799
+
800
+ "to_ary" => {
801
+ "Ruby" => "a, b = c",
802
+ "ParseTree" => [:masgn,
803
+ [:array, [:lasgn, :a], [:lasgn, :b]],
804
+ [:to_ary, [:vcall, :c]]],
805
+ },
806
+
807
+ "true" => {
808
+ "Ruby" => "true",
809
+ "ParseTree" => [:true],
810
+ },
811
+
812
+ "undef" => {
813
+ "Ruby" => "undef :x",
814
+ "ParseTree" => [:undef, [:lit, :x]],
815
+ },
816
+
817
+ "undef_multi" => {
818
+ "Ruby" => "undef :x, :y, :z",
819
+ "ParseTree" => [:block,
820
+ [:undef, [:lit, :x]],
821
+ [:undef, [:lit, :y]],
822
+ [:undef, [:lit, :z]]],
823
+ "Ruby2Ruby" => "undef :x\nundef :y\nundef :z\n",
824
+ },
825
+
826
+ "until" => {
827
+ "Ruby" => "until false do\n (1 + 1)\nend",
828
+ "ParseTree" => [:until, [:false],
829
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
830
+ },
831
+
832
+ "valias" => {
833
+ "Ruby" => "alias $y $x",
834
+ "ParseTree" => [:valias, :$y, :$x],
835
+ },
836
+
1225
837
  "vcall" => {
1226
838
  "Ruby" => "method",
1227
839
  "ParseTree" => [:vcall, :method],
1228
- "Rewriter" => s(:call, nil, :method, nil),
1229
- "TypeChecker" => t(:call, nil, :method, nil, Type.unknown),
1230
- "CRewriter" => :same,
1231
- "RubyToRubyC" => "rb_funcall(self, rb_intern(\"method\"), 0)",
1232
- "RubyToAnsiC" => "method()",
1233
840
  },
1234
841
 
1235
842
  "whiles" => {
1236
- "Ruby" => "def whiles()\n while (false) do\n puts(\"false\")\n end\n begin\n puts(\"true\")\n end while (false)\nend",
843
+ "Ruby" => "def whiles\n while false do\n puts(\"false\")\n end\n begin\n puts(\"true\")\n end while false\nend",
1237
844
  "ParseTree" => [:defn,
1238
- :whiles,
1239
- [:scope,
1240
- [:block,
1241
- [:args],
1242
- [:while, [:false],
1243
- [:fcall, :puts, [:array, [:str, "false"]]], true],
1244
- [:while, [:false],
1245
- [:fcall, :puts, [:array, [:str, "true"]]], false]]]],
1246
- "Rewriter" => s(:defn,
1247
- :whiles,
1248
- s(:args),
1249
- s(:scope,
1250
- s(:block,
1251
- s(:while,
1252
- s(:false),
1253
- s(:call, nil, :puts, s(:arglist, s(:str, "false"))),
1254
- true),
1255
- s(:while,
1256
- s(:false),
1257
- s(:call, nil, :puts, s(:arglist, s(:str, "true"))),
1258
- false)))),
1259
- "TypeChecker" => t(:defn,
1260
- :whiles,
1261
- t(:args),
1262
- t(:scope,
1263
- t(:block,
1264
- t(:while,
1265
- t(:false, Type.bool),
1266
- t(:call,
1267
- nil,
1268
- :puts,
1269
- t(:arglist, t(:str, "false", Type.str)), Type.void),
1270
- true),
1271
- t(:while,
1272
- t(:false, Type.bool),
1273
- t(:call,
1274
- nil,
1275
- :puts,
1276
- t(:arglist, t(:str, "true", Type.str)), Type.void),
1277
- false),
1278
- Type.unknown),
1279
- Type.void),
1280
- Type.function(Type.unknown, [], Type.void)),
1281
- "CRewriter" => :same,
1282
- "RubyToRubyC" => "static VALUE
1283
- rrc_c_whiles(VALUE self) {
1284
- while (Qfalse) {
1285
- rb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"false\"));
1286
- };
1287
- {
1288
- rb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"true\"));
1289
- } while (Qfalse);
1290
- }",
1291
- "RubyToAnsiC" => "void
1292
- whiles() {
1293
- while (0) {
1294
- puts(\"false\");
1295
- };
1296
- {
1297
- puts(\"true\");
1298
- } while (0);
1299
- }",
845
+ :whiles,
846
+ [:scope,
847
+ [:block,
848
+ [:args],
849
+ [:while, [:false],
850
+ [:fcall, :puts, [:array, [:str, "false"]]], true],
851
+ [:while, [:false],
852
+ [:fcall, :puts, [:array, [:str, "true"]]], false]]]],
853
+ },
854
+
855
+ "xstr" => {
856
+ "Ruby" => "`touch 5`",
857
+ "ParseTree" => [:xstr, 'touch 5'],
858
+ },
859
+
860
+ "yield" => {
861
+ "Ruby" => "yield",
862
+ "ParseTree" => [:yield],
863
+ },
864
+
865
+ "yield_arg" => {
866
+ "Ruby" => "yield(42)",
867
+ "ParseTree" => [:yield, [:lit, 42]],
868
+ },
869
+
870
+ "yield_args" => {
871
+ "Ruby" => "yield(42, 24)",
872
+ "ParseTree" => [:yield, [:array, [:lit, 42], [:lit, 24]]],
1300
873
  },
1301
874
 
1302
875
  "zarray" => {
1303
876
  "Ruby" => "a = []",
1304
877
  "ParseTree" => [:lasgn, :a, [:zarray]],
1305
- "Rewriter" => s(:lasgn, :a, s(:array)),
1306
- "TypeChecker" => t(:lasgn, :a, t(:array), Type.unknown_list),
1307
- "CRewriter" => :same,
1308
- # TODO: need to verify that our variable decl will be correct
1309
- "RubyToRubyC" => "a = rb_ary_new2(0)",
1310
- "RubyToAnsiC" => "a = (void *) malloc(sizeof(void *) * 0)",
878
+ },
879
+
880
+ "zsuper" => {
881
+ "Ruby" => "def x\n super\nend",
882
+ "ParseTree" => [:defn, :x, [:scope, [:block, [:args], [:zsuper]]]],
1311
883
  },
1312
884
  }
1313
885
 
886
+ # def test_audit_nodes
887
+ # # TODO: audit @@testcases.keys against node list - do two way audit, rename everything
888
+ # nodes = ParseTree::NODE_NAMES.map { |s| s.to_s }.sort
889
+ # tested = @@testcases.keys.map { |s| s.to_s }.sort
890
+ # if processor.respond_to? :unsupported then
891
+ # nodes -= processor.unsupported
892
+ # else
893
+ # SexpProcessor.new.unsupported
894
+ # # HACK
895
+ # nodes -= [:alloca, :argspush, :cfunc, :cref, :evstr, :ifunc, :last, :memo, :newline, :opt_n, :method].map { |s| s.to_s }
896
+ # end
897
+
898
+ # untested = nodes-tested
899
+
900
+ # puts
901
+ # p :untested_nodes => untested, :extra_nodes => tested-nodes
902
+
903
+ # untested.each do |node|
904
+ # puts %(
905
+ # "#{node}" => {
906
+ # "Ruby" => "XXX",
907
+ # "ParseTree" => [],
908
+ # },
909
+ # )
910
+ # end
911
+
912
+ # flunk
913
+ # end
914
+
1314
915
  def self.previous(key)
1315
916
  idx = @@testcase_order.index(key)-1
1316
917
  case key
@@ -1359,6 +960,7 @@ puts(\"true\");
1359
960
  else
1360
961
  extra_expected = []
1361
962
  extra_input = []
963
+
1362
964
  _, expected, extra_expected = *expected if Array === expected and expected.first == :defx
1363
965
  _, input, extra_input = *input if Array === input and input.first == :defx
1364
966
 
@@ -1371,8 +973,5 @@ puts(\"true\");
1371
973
  end
1372
974
  end
1373
975
 
1374
- def test_stoopid
1375
- # do nothing - shuts up empty test class requirement
1376
- end
1377
-
976
+ undef_method :default_test
1378
977
  end