RubyToC 1.0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +69 -0
- data/Makefile +49 -0
- data/Manifest.txt +98 -0
- data/README.txt +75 -0
- data/demo/char.rb +13 -0
- data/demo/factorial.rb +11 -0
- data/demo/hello.rb +11 -0
- data/demo/misc.rb +25 -0
- data/demo/newarray.rb +11 -0
- data/demo/strcat.rb +12 -0
- data/rewrite.rb +32 -0
- data/rewriter.rb +356 -0
- data/ruby_to_c.rb +680 -0
- data/support.rb +317 -0
- data/test_all.rb +9 -0
- data/test_extras.rb +143 -0
- data/test_rewriter.rb +292 -0
- data/test_ruby_to_c.rb +533 -0
- data/test_support.rb +525 -0
- data/test_type_checker.rb +838 -0
- data/test_typed_sexp_processor.rb +134 -0
- data/translate.rb +31 -0
- data/type.rb +33 -0
- data/type_checker.rb +922 -0
- data/typed_sexp_processor.rb +88 -0
- data/validate.sh +49 -0
- data/zcomparable.rb +300 -0
- metadata +74 -0
data/test_rewriter.rb
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
begin require 'rubygems' rescue LoadError end
|
6
|
+
require 'test/unit'
|
7
|
+
require 'rewriter'
|
8
|
+
require 'r2ctestcase'
|
9
|
+
require 'parse_tree'
|
10
|
+
|
11
|
+
class TestRewriter < R2CTestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@processor = Rewriter.new
|
15
|
+
@rewrite = Rewriter.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_process_call
|
19
|
+
input = [:call, [:lit, 1], :+, [:arglist, [:lit, 1]]]
|
20
|
+
expect = input.deep_clone
|
21
|
+
|
22
|
+
assert_equal expect, @rewrite.process(input)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_process_defn_block
|
26
|
+
input = [:defn, :meth, [:scope, [:block, [:args], [:return, [:nil]]]]]
|
27
|
+
output = [:defn, :meth, [:args], [:scope, [:block, [:return, [:nil]]]]]
|
28
|
+
|
29
|
+
assert_equal output, @rewrite.process(input)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_process_defn_ivar
|
33
|
+
input = [:defn, :name, [:ivar, :@name]]
|
34
|
+
output = [:defn, :name, [:args], [:scope, [:block, [:return, [:ivar, :@name]]]]]
|
35
|
+
|
36
|
+
assert_equal output, @rewrite.process(input)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_process_defn_attrset
|
40
|
+
input = [:defn, :meth, [:attrset, :@name]]
|
41
|
+
output = [:defn, :meth, [:args, :arg], [:scope, [:block, [:return, [:iasgn, :@name, [:lvar, :arg]]]]]]
|
42
|
+
|
43
|
+
assert_equal output, @rewrite.process(input)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_process_fcall
|
47
|
+
input = [:fcall, :puts, [:array, [:lit, 1]]]
|
48
|
+
expect = [:call, nil, :puts, [:arglist, [:lit, 1]]]
|
49
|
+
assert_equal expect, @rewrite.process(input)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_process_vcall_2
|
53
|
+
input = [:vcall, :method]
|
54
|
+
output = [:call, nil, :method, nil]
|
55
|
+
|
56
|
+
assert_equal output, @rewrite.process(input)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_process_case
|
60
|
+
input = [:case,
|
61
|
+
[:lvar, :var],
|
62
|
+
[:when, [:array, [:lit, 1]], [:str, "1"]],
|
63
|
+
[:when, [:array, [:lit, 2], [:lit, 3]], [:str, "2, 3"]],
|
64
|
+
[:when, [:array, [:lit, 4]], [:str, "4"]],
|
65
|
+
[:str, "else"]]
|
66
|
+
|
67
|
+
expected = [:if,
|
68
|
+
[:call,
|
69
|
+
[:lvar, :var],
|
70
|
+
:===,
|
71
|
+
[:arglist, [:lit, 1]]],
|
72
|
+
[:str, "1"],
|
73
|
+
[:if,
|
74
|
+
[:or,
|
75
|
+
[:call,
|
76
|
+
[:lvar, :var],
|
77
|
+
:===,
|
78
|
+
[:arglist, [:lit, 2]]],
|
79
|
+
[:call,
|
80
|
+
[:lvar, :var],
|
81
|
+
:===,
|
82
|
+
[:arglist, [:lit, 3]]]],
|
83
|
+
[:str, "2, 3"],
|
84
|
+
[:if,
|
85
|
+
[:call,
|
86
|
+
[:lvar, :var],
|
87
|
+
:===,
|
88
|
+
[:arglist, [:lit, 4]]],
|
89
|
+
[:str, "4"],
|
90
|
+
[:str, "else"]]]]
|
91
|
+
|
92
|
+
assert_equal expected, @rewrite.process(input)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_process_case_2
|
96
|
+
input = [:case,
|
97
|
+
[:lvar, :var],
|
98
|
+
[:when, [:array, [:lit, 1]], [:lasgn, :ret, [:str, "1"]]],
|
99
|
+
[:when,
|
100
|
+
[:array, [:lit, 2], [:lit, 3], [:lit, 5]],
|
101
|
+
[:lasgn, :ret, [:str, "2, 3"]]],
|
102
|
+
[:when, [:array, [:lit, 4]], [:lasgn, :ret, [:str, "4"]]],
|
103
|
+
[:lasgn, :ret, [:str, "else"]]]
|
104
|
+
|
105
|
+
expected = s(:if,
|
106
|
+
s(:call,
|
107
|
+
s(:lvar, :var),
|
108
|
+
:===,
|
109
|
+
s(:arglist, s(:lit, 1))),
|
110
|
+
s(:lasgn, :ret, s(:str, "1")),
|
111
|
+
s(:if,
|
112
|
+
s(:or,
|
113
|
+
s(:call, s(:lvar, :var), :===, s(:arglist, s(:lit, 2))),
|
114
|
+
s(:or,
|
115
|
+
s(:call, s(:lvar, :var), :===, s(:arglist, s(:lit, 3))),
|
116
|
+
s(:call, s(:lvar, :var), :===, s(:arglist, s(:lit, 5))))),
|
117
|
+
s(:lasgn, :ret, s(:str, "2, 3")),
|
118
|
+
s(:if,
|
119
|
+
s(:call, s(:lvar, :var), :===, s(:arglist, s(:lit, 4))),
|
120
|
+
s(:lasgn, :ret, s(:str, "4")),
|
121
|
+
s(:lasgn, :ret, s(:str, "else")))))
|
122
|
+
|
123
|
+
assert_equal expected, @rewrite.process(input)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_process_iter
|
127
|
+
input = [:iter,
|
128
|
+
[:call, [:lit, 3], :downto, [:array, [:lit, 1]]],
|
129
|
+
[:dasgn_curr, :n],
|
130
|
+
[:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]]
|
131
|
+
expected = s(:dummy,
|
132
|
+
s(:lasgn, :n, s(:lit, 3)),
|
133
|
+
s(:while,
|
134
|
+
s(:call,
|
135
|
+
s(:lvar, :n),
|
136
|
+
:>=,
|
137
|
+
s(:arglist, s(:lit, 1))),
|
138
|
+
s(:block,
|
139
|
+
s(:call,
|
140
|
+
nil,
|
141
|
+
:puts,
|
142
|
+
s(:arglist,
|
143
|
+
s(:call,
|
144
|
+
s(:lvar, :n),
|
145
|
+
:to_s,
|
146
|
+
nil))),
|
147
|
+
s(:lasgn, :n, s(:call,
|
148
|
+
s(:lvar, :n),
|
149
|
+
:-,
|
150
|
+
s(:arglist, s(:lit, 1))))), true))
|
151
|
+
|
152
|
+
assert_equal expected, @rewrite.process(input)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_iter_downto_nested
|
156
|
+
input = [:block,
|
157
|
+
[:iter,
|
158
|
+
[:call, [:lvar, :n], :downto, [:array, [:lit, 0]]],
|
159
|
+
[:dasgn_curr, :i],
|
160
|
+
[:iter,
|
161
|
+
[:call, [:dvar, :i], :downto, [:array, [:lit, 0]]],
|
162
|
+
[:dasgn_curr, :j],
|
163
|
+
[:nil]]]]
|
164
|
+
|
165
|
+
expected = s(:block,
|
166
|
+
s(:dummy,
|
167
|
+
s(:lasgn, :i, s(:lvar, :n)),
|
168
|
+
s(:while,
|
169
|
+
s(:call, s(:lvar, :i), :>=,
|
170
|
+
s(:arglist, s(:lit, 0))),
|
171
|
+
s(:block,
|
172
|
+
s(:dummy,
|
173
|
+
s(:lasgn, :j, s(:lvar, :i)),
|
174
|
+
s(:while,
|
175
|
+
s(:call, s(:lvar, :j), :>=,
|
176
|
+
s(:arglist, s(:lit, 0))),
|
177
|
+
s(:block,
|
178
|
+
s(:nil),
|
179
|
+
s(:lasgn, :j,
|
180
|
+
s(:call, s(:lvar, :j), :-,
|
181
|
+
s(:arglist, s(:lit, 1))))), true)),
|
182
|
+
s(:lasgn, :i,
|
183
|
+
s(:call, s(:lvar, :i), :-,
|
184
|
+
s(:arglist, s(:lit, 1))))), true)))
|
185
|
+
|
186
|
+
assert_equal expected, @rewrite.process(input)
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_iter_upto_nested
|
190
|
+
input = [:block,
|
191
|
+
[:iter,
|
192
|
+
[:call, [:lvar, :n], :upto, [:array, [:lit, 0]]],
|
193
|
+
[:dasgn_curr, :i],
|
194
|
+
[:iter,
|
195
|
+
[:call, [:dvar, :i], :upto, [:array, [:lit, 0]]],
|
196
|
+
[:dasgn_curr, :j],
|
197
|
+
[:nil]]]]
|
198
|
+
|
199
|
+
expected = s(:block,
|
200
|
+
s(:dummy,
|
201
|
+
s(:lasgn, :i, s(:lvar, :n)),
|
202
|
+
s(:while,
|
203
|
+
s(:call, s(:lvar, :i), :<=,
|
204
|
+
s(:arglist, s(:lit, 0))),
|
205
|
+
s(:block,
|
206
|
+
s(:dummy,
|
207
|
+
s(:lasgn, :j, s(:lvar, :i)),
|
208
|
+
s(:while,
|
209
|
+
s(:call, s(:lvar, :j), :<=,
|
210
|
+
s(:arglist, s(:lit, 0))),
|
211
|
+
s(:block,
|
212
|
+
s(:nil),
|
213
|
+
s(:lasgn, :j,
|
214
|
+
s(:call, s(:lvar, :j), :+,
|
215
|
+
s(:arglist, s(:lit, 1))))), true)),
|
216
|
+
s(:lasgn, :i,
|
217
|
+
s(:call, s(:lvar, :i), :+,
|
218
|
+
s(:arglist, s(:lit, 1))))), true)))
|
219
|
+
|
220
|
+
assert_equal expected, @rewrite.process(input)
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_process_until
|
224
|
+
input = [:until,
|
225
|
+
[:call,
|
226
|
+
[:lvar, :a],
|
227
|
+
:==,
|
228
|
+
[:array, [:lvar, :b]]],
|
229
|
+
[:fcall,
|
230
|
+
:puts,
|
231
|
+
[:array, [:lit, 2]]],
|
232
|
+
true]
|
233
|
+
output = s(:while,
|
234
|
+
s(:not,
|
235
|
+
s(:call,
|
236
|
+
s(:lvar, :a),
|
237
|
+
:==,
|
238
|
+
s(:arglist, s(:lvar, :b)))),
|
239
|
+
s(:call,
|
240
|
+
nil,
|
241
|
+
:puts,
|
242
|
+
s(:arglist, s(:lit, 2))),
|
243
|
+
true)
|
244
|
+
assert_equal output, @rewrite.process(input)
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_process_when
|
248
|
+
input = [:when, [:array, [:lit, 1]], [:str, "1"]]
|
249
|
+
|
250
|
+
expected = [:when, [[:lit, 1]], [:str, "1"]]
|
251
|
+
|
252
|
+
assert_equal expected, @rewrite.process(input)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
class TestR2CRewriter < R2CTestCase
|
257
|
+
|
258
|
+
def setup
|
259
|
+
@processor = R2CRewriter.new
|
260
|
+
@rewrite = R2CRewriter.new
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_process_call_rewritten
|
264
|
+
|
265
|
+
input = t(:call,
|
266
|
+
t(:str, "this", Type.str),
|
267
|
+
:+,
|
268
|
+
t(:array, t(:str, "that", Type.str)),
|
269
|
+
Type.str)
|
270
|
+
expected = t(:call,
|
271
|
+
nil,
|
272
|
+
:strcat,
|
273
|
+
t(:array,
|
274
|
+
t(:str, "this", Type.str),
|
275
|
+
t(:str, "that", Type.str)),
|
276
|
+
Type.str)
|
277
|
+
|
278
|
+
assert_equal expected, @rewrite.process(input)
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_process_call_same
|
282
|
+
|
283
|
+
input = t(:call,
|
284
|
+
t(:lit, 1, Type.long),
|
285
|
+
:+,
|
286
|
+
t(:array, t(:lit, 2, Type.long)),
|
287
|
+
Type.long)
|
288
|
+
expected = input.deep_clone
|
289
|
+
|
290
|
+
assert_equal expected, @rewrite.process(input)
|
291
|
+
end
|
292
|
+
end
|
data/test_ruby_to_c.rb
ADDED
@@ -0,0 +1,533 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'ruby_to_c'
|
7
|
+
require 'r2ctestcase'
|
8
|
+
|
9
|
+
class TestTypeMap < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def test_c_type_long
|
12
|
+
assert_equal "long", TypeMap.c_type(Type.long)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_c_type_long_list
|
16
|
+
assert_equal "long_array", TypeMap.c_type(Type.long_list)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_c_type_str
|
20
|
+
assert_equal "str", TypeMap.c_type(Type.str)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_c_type_str_list
|
24
|
+
assert_equal "str_array", TypeMap.c_type(Type.str_list)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_c_type_bool
|
28
|
+
assert_equal "VALUE", TypeMap.c_type(Type.bool)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_c_type_void
|
32
|
+
assert_equal "void", TypeMap.c_type(Type.void)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_c_type_float
|
36
|
+
assert_equal "double", TypeMap.c_type(Type.float)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_c_type_symbol
|
40
|
+
assert_equal "symbol", TypeMap.c_type(Type.symbol)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_c_type_value
|
44
|
+
assert_equal "VALUE", TypeMap.c_type(Type.value)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_c_type_unknown
|
48
|
+
assert_equal "VALUE", TypeMap.c_type(Type.unknown)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class TestRubyToC < R2CTestCase
|
53
|
+
|
54
|
+
def setup
|
55
|
+
@ruby_to_c = RubyToC.new
|
56
|
+
@ruby_to_c.env.extend
|
57
|
+
@processor = @ruby_to_c
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_translator
|
61
|
+
Object.class_eval "class Suck; end"
|
62
|
+
input = [:class, :Suck, :Object,
|
63
|
+
[:defn, :something, [:scope, [:block, [:args], [:fcall, :"whaaa\?"]]]],
|
64
|
+
[:defn, :foo, [:scope, [:block, [:args], [:vcall, :something]]]]]
|
65
|
+
expected = "// class Suck\n\n// ERROR: NoMethodError: undefined method `[]=' for nil:NilClass\n\nvoid\nfoo() {\nsomething();\n}"
|
66
|
+
assert_equal expected, RubyToC.translator.process(input)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_env
|
70
|
+
assert_not_nil @ruby_to_c.env
|
71
|
+
assert_kind_of Environment, @ruby_to_c.env
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_prototypes
|
75
|
+
assert_equal [], @ruby_to_c.prototypes
|
76
|
+
@ruby_to_c.process t(:defn,
|
77
|
+
:empty,
|
78
|
+
t(:args),
|
79
|
+
t(:scope),
|
80
|
+
Type.function([], Type.void))
|
81
|
+
|
82
|
+
assert_equal "void empty();\n", @ruby_to_c.prototypes.first
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_process_and
|
86
|
+
input = t(:and, t(:lit, 1, Type.long), t(:lit, 2, Type.long))
|
87
|
+
output = "1 && 2"
|
88
|
+
|
89
|
+
assert_equal output, @ruby_to_c.process(input)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_process_args_normal
|
93
|
+
input = t(:args,
|
94
|
+
t(:foo, Type.long),
|
95
|
+
t(:bar, Type.long))
|
96
|
+
output = "(long foo, long bar)"
|
97
|
+
|
98
|
+
assert_equal output, @ruby_to_c.process(input)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_process_args_empty
|
102
|
+
input = t(:args)
|
103
|
+
output = "()"
|
104
|
+
|
105
|
+
assert_equal output, @ruby_to_c.process(input)
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_process_array_empty
|
109
|
+
input = t(:array)
|
110
|
+
output = "[]"
|
111
|
+
|
112
|
+
assert_equal output, @ruby_to_c.process(input)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_process_array_single
|
116
|
+
input = t(:array,
|
117
|
+
t(:lvar, :arg1, Type.long))
|
118
|
+
output = "arg1"
|
119
|
+
|
120
|
+
assert_equal output, @ruby_to_c.process(input)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_process_array_multiple
|
124
|
+
input = t(:array,
|
125
|
+
t(:lvar, :arg1, Type.long),
|
126
|
+
t(:lvar, :arg2, Type.long))
|
127
|
+
output = "arg1, arg2"
|
128
|
+
|
129
|
+
assert_equal output, @ruby_to_c.process(input)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_process_call
|
133
|
+
input = t(:call, nil, :name, nil)
|
134
|
+
output = "name()"
|
135
|
+
|
136
|
+
assert_equal output, @ruby_to_c.process(input)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_process_call_lhs
|
140
|
+
input = t(:call, t(:lit, 1, Type.long), :name, nil)
|
141
|
+
output = "name(1)"
|
142
|
+
|
143
|
+
assert_equal output, @ruby_to_c.process(input)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_process_call_lhs_rhs
|
147
|
+
input = t(:call,
|
148
|
+
t(:lit, 1, Type.long),
|
149
|
+
:name,
|
150
|
+
t(:array, t(:str, "foo")))
|
151
|
+
output = "name(1, \"foo\")"
|
152
|
+
|
153
|
+
assert_equal output, @ruby_to_c.process(input)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_process_call_rhs
|
157
|
+
input = t(:call,
|
158
|
+
nil,
|
159
|
+
:name,
|
160
|
+
t(:array,
|
161
|
+
t(:str, "foo")))
|
162
|
+
output = "name(\"foo\")"
|
163
|
+
|
164
|
+
assert_equal output, @ruby_to_c.process(input)
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_process_call_nil?
|
168
|
+
input = t(:call,
|
169
|
+
t(:lvar, :arg, Type.long),
|
170
|
+
:nil?,
|
171
|
+
nil)
|
172
|
+
output = "NIL_P(arg)"
|
173
|
+
|
174
|
+
assert_equal output, @ruby_to_c.process(input)
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_process_call_operator
|
178
|
+
methods = t(:==, :<, :>, :-, :+, :*, :/, :%, :<=, :>=)
|
179
|
+
|
180
|
+
methods.each do |method|
|
181
|
+
input = t(:call,
|
182
|
+
t(:lit, 1, Type.long),
|
183
|
+
method,
|
184
|
+
t(:array, t(:lit, 2, Type.long)))
|
185
|
+
output = "1 #{method} 2"
|
186
|
+
|
187
|
+
assert_equal output, @ruby_to_c.process(input)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_process_block
|
192
|
+
input = t(:block, t(:return, t(:nil)))
|
193
|
+
output = "return Qnil;\n"
|
194
|
+
|
195
|
+
assert_equal output, @ruby_to_c.process(input)
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_process_block_multiple
|
199
|
+
input = t(:block,
|
200
|
+
t(:str, "foo"),
|
201
|
+
t(:return, t(:nil)))
|
202
|
+
output = "\"foo\";\nreturn Qnil;\n"
|
203
|
+
|
204
|
+
assert_equal output, @ruby_to_c.process(input)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_process_dasgn_curr
|
208
|
+
input = t(:dasgn_curr, :x, Type.long)
|
209
|
+
output = "x"
|
210
|
+
|
211
|
+
assert_equal output, @ruby_to_c.process(input)
|
212
|
+
# HACK - see test_type_checker equivalent test
|
213
|
+
# assert_equal Type.long, @ruby_to_c.env.lookup("x")
|
214
|
+
end
|
215
|
+
|
216
|
+
# TODO: fix for 1.8.2
|
217
|
+
def test_process_defn
|
218
|
+
input = t(:defn,
|
219
|
+
:empty,
|
220
|
+
t(:args),
|
221
|
+
t(:scope),
|
222
|
+
Type.function([], Type.void))
|
223
|
+
output = "void\nempty() {\n}"
|
224
|
+
assert_equal output, @ruby_to_c.process(input)
|
225
|
+
|
226
|
+
assert_equal ["void empty();\n"], @ruby_to_c.prototypes
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_process_defn_with_args_and_body
|
231
|
+
input = t(:defn, :empty,
|
232
|
+
t(:args,
|
233
|
+
t(:foo, Type.long),
|
234
|
+
t(:bar, Type.long)),
|
235
|
+
t(:scope,
|
236
|
+
t(:block,
|
237
|
+
t(:lit, 5, Type.long))),
|
238
|
+
Type.function([], Type.void))
|
239
|
+
output = "void\nempty(long foo, long bar) {\n5;\n}"
|
240
|
+
|
241
|
+
assert_equal output, @ruby_to_c.process(input)
|
242
|
+
end
|
243
|
+
|
244
|
+
def disabled_test_dstr
|
245
|
+
input = t(:dstr,
|
246
|
+
"var is ",
|
247
|
+
t(:lvar, :var),
|
248
|
+
t(:str, ". So there."))
|
249
|
+
output = "sprintf stuff goes here"
|
250
|
+
|
251
|
+
flunk "Way too hard right now"
|
252
|
+
assert_equal output, @ruby_to_c.process(input)
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_process_dvar
|
256
|
+
input = t(:dvar, :dvar, Type.long)
|
257
|
+
output = "dvar"
|
258
|
+
|
259
|
+
assert_equal output, @ruby_to_c.process(input)
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_process_false
|
263
|
+
input = t(:false)
|
264
|
+
output = "Qfalse"
|
265
|
+
|
266
|
+
assert_equal output, @ruby_to_c.process(input)
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_process_gvar
|
270
|
+
input = t(:gvar, :$stderr, Type.long)
|
271
|
+
output = "stderr"
|
272
|
+
|
273
|
+
assert_equal output, @ruby_to_c.process(input)
|
274
|
+
assert_raises RuntimeError do
|
275
|
+
@ruby_to_c.process t(:gvar, :$some_gvar, Type.long)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_process_iasgn
|
280
|
+
input = t(:iasgn, :@blah, t(:lit, 42, Type.long), Type.long)
|
281
|
+
expected = "self->blah = 42"
|
282
|
+
|
283
|
+
assert_equal expected, @ruby_to_c.process(input)
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_process_if
|
287
|
+
input = t(:if,
|
288
|
+
t(:call,
|
289
|
+
t(:lit, 1, Type.long),
|
290
|
+
:==,
|
291
|
+
t(:array, t(:lit, 2, Type.long))),
|
292
|
+
t(:str, "not equal"),
|
293
|
+
nil)
|
294
|
+
output = "if (1 == 2) {\n\"not equal\";\n}"
|
295
|
+
|
296
|
+
assert_equal output, @ruby_to_c.process(input)
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_process_if_else
|
300
|
+
input = t(:if,
|
301
|
+
t(:call,
|
302
|
+
t(:lit, 1, Type.long),
|
303
|
+
:==,
|
304
|
+
t(:array, t(:lit, 2, Type.long))),
|
305
|
+
t(:str, "not equal"),
|
306
|
+
t(:str, "equal"))
|
307
|
+
output = "if (1 == 2) {\n\"not equal\";\n} else {\n\"equal\";\n}"
|
308
|
+
|
309
|
+
assert_equal output, @ruby_to_c.process(input)
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_process_if_block
|
313
|
+
input = t(:if,
|
314
|
+
t(:call,
|
315
|
+
t(:lit, 1, Type.long),
|
316
|
+
:==,
|
317
|
+
t(:array, t(:lit, 2, Type.long))),
|
318
|
+
t(:block,
|
319
|
+
t(:lit, 5, Type.long),
|
320
|
+
t(:str, "not equal")),
|
321
|
+
nil)
|
322
|
+
output = "if (1 == 2) {\n5;\n\"not equal\";\n}"
|
323
|
+
|
324
|
+
assert_equal output, @ruby_to_c.process(input)
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_process_iter
|
328
|
+
var_type = Type.long_list
|
329
|
+
input = t(:iter,
|
330
|
+
t(:call,
|
331
|
+
t(:lvar, :array, var_type),
|
332
|
+
:each,
|
333
|
+
nil),
|
334
|
+
t(:dasgn_curr, :x, Type.long),
|
335
|
+
t(:call,
|
336
|
+
nil,
|
337
|
+
:puts,
|
338
|
+
t(:array,
|
339
|
+
t(:call,
|
340
|
+
t(:dvar,
|
341
|
+
:x,
|
342
|
+
Type.long),
|
343
|
+
:to_s,
|
344
|
+
nil))))
|
345
|
+
output = "unsigned long index_x;
|
346
|
+
for (index_x = 0; index_x < array.length; ++index_x) {
|
347
|
+
long x = array.contents[index_x];
|
348
|
+
puts(to_s(x));
|
349
|
+
}"
|
350
|
+
|
351
|
+
assert_equal output, @ruby_to_c.process(input)
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_process_ivar
|
355
|
+
@ruby_to_c.env.add :@blah, Type.long
|
356
|
+
input = t(:ivar, :@blah, Type.long)
|
357
|
+
expected = "self->blah"
|
358
|
+
|
359
|
+
assert_equal expected, @ruby_to_c.process(input)
|
360
|
+
end
|
361
|
+
|
362
|
+
def test_process_lasgn
|
363
|
+
input = t(:lasgn, :var, t(:str, "foo"), Type.str)
|
364
|
+
output = "var = \"foo\""
|
365
|
+
|
366
|
+
assert_equal output, @ruby_to_c.process(input)
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_process_lasgn_array
|
370
|
+
input = t(:lasgn,
|
371
|
+
:var,
|
372
|
+
t(:array,
|
373
|
+
t(:str, "foo", Type.str),
|
374
|
+
t(:str, "bar", Type.str)),
|
375
|
+
Type.str_list)
|
376
|
+
output = "var.length = 2;
|
377
|
+
var.contents = (str*) malloc(sizeof(str) * var.length);
|
378
|
+
var.contents[0] = \"foo\";
|
379
|
+
var.contents[1] = \"bar\""
|
380
|
+
|
381
|
+
assert_equal output, @ruby_to_c.process(input)
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_process_lit_float
|
385
|
+
input = t(:lit, 1.0, Type.float)
|
386
|
+
output = "1.0"
|
387
|
+
|
388
|
+
assert_equal output, @ruby_to_c.process(input)
|
389
|
+
end
|
390
|
+
|
391
|
+
def test_process_lit_long
|
392
|
+
input = t(:lit, 1, Type.long)
|
393
|
+
output = "1"
|
394
|
+
|
395
|
+
assert_equal output, @ruby_to_c.process(input)
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_process_lit_sym
|
399
|
+
input = t(:lit, :sym, Type.symbol)
|
400
|
+
output = ":sym"
|
401
|
+
|
402
|
+
assert_equal output, @ruby_to_c.process(input)
|
403
|
+
end
|
404
|
+
|
405
|
+
def test_process_lvar
|
406
|
+
input = t(:lvar, :arg, Type.long)
|
407
|
+
output = "arg"
|
408
|
+
|
409
|
+
assert_equal output, @ruby_to_c.process(input)
|
410
|
+
end
|
411
|
+
|
412
|
+
def test_process_nil
|
413
|
+
input = t(:nil)
|
414
|
+
output = "Qnil"
|
415
|
+
|
416
|
+
assert_equal output, @ruby_to_c.process(input)
|
417
|
+
end
|
418
|
+
|
419
|
+
def test_process_not
|
420
|
+
input = t(:not, t(:true, Type.bool), Type.bool)
|
421
|
+
output = "!(Qtrue)"
|
422
|
+
|
423
|
+
assert_equal output, @ruby_to_c.process(input)
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_process_or
|
427
|
+
input = t(:or, t(:lit, 1, Type.long), t(:lit, 2, Type.long))
|
428
|
+
output = "1 || 2"
|
429
|
+
|
430
|
+
assert_equal output, @ruby_to_c.process(input)
|
431
|
+
end
|
432
|
+
|
433
|
+
def test_process_return
|
434
|
+
input = t(:return, t(:nil))
|
435
|
+
output = "return Qnil"
|
436
|
+
|
437
|
+
assert_equal output, @ruby_to_c.process(input)
|
438
|
+
end
|
439
|
+
|
440
|
+
def test_process_str
|
441
|
+
input = t(:str, "foo", Type.str)
|
442
|
+
output = "\"foo\""
|
443
|
+
|
444
|
+
assert_equal output, @ruby_to_c.process(input)
|
445
|
+
end
|
446
|
+
|
447
|
+
def test_process_str_multi
|
448
|
+
input = t(:str, "foo
|
449
|
+
bar", Type.str)
|
450
|
+
output = "\"foo\\nbar\""
|
451
|
+
|
452
|
+
assert_equal output, @ruby_to_c.process(input)
|
453
|
+
end
|
454
|
+
|
455
|
+
def test_process_str_backslashed
|
456
|
+
input = t(:str, "foo\nbar", Type.str)
|
457
|
+
output = "\"foo\\nbar\""
|
458
|
+
|
459
|
+
assert_equal output, @ruby_to_c.process(input)
|
460
|
+
end
|
461
|
+
|
462
|
+
def test_process_scope
|
463
|
+
input = t(:scope,
|
464
|
+
t(:block,
|
465
|
+
t(:return, t(:nil))))
|
466
|
+
output = "{\nreturn Qnil;\n}"
|
467
|
+
|
468
|
+
assert_equal output, @ruby_to_c.process(input)
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_process_scope_empty
|
472
|
+
input = t(:scope)
|
473
|
+
output = "{\n}"
|
474
|
+
|
475
|
+
assert_equal output, @ruby_to_c.process(input)
|
476
|
+
end
|
477
|
+
|
478
|
+
def test_process_scope_var_set
|
479
|
+
input = t(:scope, t(:block,
|
480
|
+
t(:lasgn, :arg,
|
481
|
+
t(:str, "declare me"),
|
482
|
+
Type.str),
|
483
|
+
t(:return, t(:nil))))
|
484
|
+
output = "{\nstr arg;\narg = \"declare me\";\nreturn Qnil;\n}"
|
485
|
+
|
486
|
+
assert_equal output, @ruby_to_c.process(input)
|
487
|
+
end
|
488
|
+
|
489
|
+
def test_process_true
|
490
|
+
input = t(:true)
|
491
|
+
output = "Qtrue"
|
492
|
+
|
493
|
+
assert_equal output, @ruby_to_c.process(input)
|
494
|
+
end
|
495
|
+
|
496
|
+
def test_process_unless
|
497
|
+
input = t(:if,
|
498
|
+
t(:call,
|
499
|
+
t(:lit, 1, Type.long),
|
500
|
+
:==,
|
501
|
+
t(:array, t(:lit, 2, Type.long))),
|
502
|
+
nil,
|
503
|
+
t(:str, "equal"))
|
504
|
+
output = "if (1 == 2) {\n;\n} else {\n\"equal\";\n}"
|
505
|
+
|
506
|
+
assert_equal output, @ruby_to_c.process(input)
|
507
|
+
end
|
508
|
+
|
509
|
+
def test_process_while
|
510
|
+
input = t(:while,
|
511
|
+
t(:call, t(:lvar, :n), :<=, t(:array, t(:lit, 3, Type.long))),
|
512
|
+
t(:block,
|
513
|
+
t(:call,
|
514
|
+
nil,
|
515
|
+
:puts,
|
516
|
+
t(:array,
|
517
|
+
t(:call,
|
518
|
+
t(:lvar, :n),
|
519
|
+
:to_s,
|
520
|
+
nil))),
|
521
|
+
t(:lasgn, :n,
|
522
|
+
t(:call,
|
523
|
+
t(:lvar, :n),
|
524
|
+
:+,
|
525
|
+
t(:array,
|
526
|
+
t(:lit, 1, Type.long))),
|
527
|
+
Type.long)), true) # NOTE Type.long needed but not used
|
528
|
+
|
529
|
+
expected = "while (n <= 3) {\nputs(to_s(n));\nn = n + 1;\n}"
|
530
|
+
|
531
|
+
assert_equal expected, @ruby_to_c.process(input)
|
532
|
+
end
|
533
|
+
end
|