RubyToC 1.0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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_support.rb
ADDED
@@ -0,0 +1,525 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'type_checker'
|
7
|
+
|
8
|
+
class TestHandle < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@handle = Handle.new("text")
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_contents
|
15
|
+
assert_equal "text", @handle.contents
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_contents=
|
19
|
+
@handle.contents = "new text"
|
20
|
+
assert_equal "new text", @handle.contents
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_equals
|
24
|
+
obj = "foo"
|
25
|
+
handle1 = Handle.new obj
|
26
|
+
handle2 = Handle.new obj
|
27
|
+
assert_equal handle1, handle2
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_equals_reassign
|
31
|
+
obj = "foo"
|
32
|
+
handle2 = Handle.new obj
|
33
|
+
@handle.contents = obj
|
34
|
+
assert_equal @handle, handle2
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
class TestFunctionType < Test::Unit::TestCase
|
40
|
+
|
41
|
+
def setup
|
42
|
+
@function_type = FunctionType.new Type.void, [Type.long, Type.str], Type.value
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_formal_types
|
46
|
+
assert_equal [Type.long, Type.str], @function_type.formal_types
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_formal_types=
|
50
|
+
@function_type.formal_types = [Type.str, Type.long]
|
51
|
+
assert_equal [Type.str, Type.long], @function_type.formal_types
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_receiver_type
|
55
|
+
assert_equal Type.void, @function_type.receiver_type
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_receiver_type=
|
59
|
+
@function_type.receiver_type = Type.str
|
60
|
+
assert_equal Type.str, @function_type.receiver_type
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_return_type
|
64
|
+
assert_equal Type.value, @function_type.return_type
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_return_type=
|
68
|
+
@function_type.return_type = Type.long
|
69
|
+
assert_equal Type.long, @function_type.return_type
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_equals
|
73
|
+
funs = []
|
74
|
+
funs << FunctionType.new(Type.unknown, [], Type.unknown)
|
75
|
+
funs << FunctionType.new(Type.unknown, [Type.unknown], Type.unknown)
|
76
|
+
funs << FunctionType.new(Type.unknown, [], Type.long)
|
77
|
+
funs << FunctionType.new(Type.unknown, [Type.long], Type.unknown)
|
78
|
+
funs << FunctionType.new(Type.unknown, [Type.long], Type.long)
|
79
|
+
funs << FunctionType.new(Type.unknown, [Type.unknown, Type.unknown], Type.unknown)
|
80
|
+
funs << FunctionType.new(Type.unknown, [Type.long, Type.unknown], Type.unknown)
|
81
|
+
funs << FunctionType.new(Type.unknown, [Type.long, Type.long], Type.long)
|
82
|
+
#funs << FunctionType.new(Type.unknown, [], Type.long)
|
83
|
+
|
84
|
+
funs.each_with_index do |fun1, i|
|
85
|
+
funs.each_with_index do |fun2, j|
|
86
|
+
if i == j then
|
87
|
+
assert_equal fun1, fun2
|
88
|
+
else
|
89
|
+
assert_not_equal fun1, fun2
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_unify_components
|
96
|
+
fun1 = FunctionType.new(Type.unknown, [Type.unknown], Type.unknown)
|
97
|
+
fun2 = FunctionType.new(Type.long, [Type.long], Type.long)
|
98
|
+
fun1.unify_components fun2
|
99
|
+
assert_equal fun2, fun1
|
100
|
+
|
101
|
+
fun3 = FunctionType.new(Type.unknown, [Type.long], Type.unknown)
|
102
|
+
fun4 = FunctionType.new(Type.long, [Type.unknown], Type.long)
|
103
|
+
fun3.unify_components fun4
|
104
|
+
assert_equal fun4, fun3
|
105
|
+
|
106
|
+
fun5 = FunctionType.new(Type.unknown, [], Type.unknown)
|
107
|
+
fun6 = FunctionType.new(Type.long, [], Type.long)
|
108
|
+
fun5.unify_components fun6
|
109
|
+
assert_equal fun6, fun5
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_initialize_fail
|
113
|
+
assert_raises(RuntimeError) do
|
114
|
+
FunctionType.new(Type.unknown, nil, Type.long)
|
115
|
+
end
|
116
|
+
|
117
|
+
assert_raises(RuntimeError)do
|
118
|
+
FunctionType.new(Type.unknown, [], nil)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_unify_components_fail
|
123
|
+
fun1 = FunctionType.new(Type.long, [Type.str], Type.unknown)
|
124
|
+
fun2 = FunctionType.new(Type.unknown, [Type.long], Type.long)
|
125
|
+
assert_raises(TypeError) do
|
126
|
+
fun1.unify_components fun2
|
127
|
+
end
|
128
|
+
|
129
|
+
fun3 = FunctionType.new(Type.long, [], Type.unknown)
|
130
|
+
fun4 = FunctionType.new(Type.unknown, [Type.unknown], Type.long)
|
131
|
+
assert_raises(TypeError) do
|
132
|
+
fun3.unify_components fun4
|
133
|
+
end
|
134
|
+
|
135
|
+
fun5 = FunctionType.new(Type.long, [Type.unknown], Type.unknown)
|
136
|
+
fun6 = FunctionType.new(Type.unknown, [], Type.long)
|
137
|
+
assert_raises(TypeError) do
|
138
|
+
fun5.unify_components fun6
|
139
|
+
end
|
140
|
+
|
141
|
+
fun7 = FunctionType.new(Type.long, [], Type.str)
|
142
|
+
fun8 = FunctionType.new(Type.unknown, [], Type.long)
|
143
|
+
assert_raises(TypeError) do
|
144
|
+
fun7.unify_components fun8
|
145
|
+
end
|
146
|
+
|
147
|
+
fun9 = FunctionType.new(Type.long, [], Type.str)
|
148
|
+
funa = FunctionType.new(Type.str, [], Type.unknown)
|
149
|
+
assert_raises(TypeError) do
|
150
|
+
fun7.unify_components fun8
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
class TestType < Test::Unit::TestCase
|
157
|
+
|
158
|
+
def setup
|
159
|
+
@unknown = Type.unknown
|
160
|
+
@unknown_list = Type.unknown_list
|
161
|
+
@long = Type.long
|
162
|
+
@long_list = Type.new(:long, true)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_function?
|
166
|
+
assert ! @long.function?
|
167
|
+
assert ! @long_list.function?
|
168
|
+
assert ! @unknown.function?
|
169
|
+
assert ! @unknown_list.function?
|
170
|
+
assert Type.function(Type.str, [Type.str], Type.str).function?
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_list
|
174
|
+
assert_equal false, @long.list
|
175
|
+
assert_equal true, @long_list.list
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_list=
|
179
|
+
long = Type.long.deep_clone
|
180
|
+
long_list = Type.long_list.deep_clone
|
181
|
+
|
182
|
+
long.list = true
|
183
|
+
long_list.list = false
|
184
|
+
|
185
|
+
assert_equal true, long.list
|
186
|
+
assert_equal false, long_list.list
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_type
|
190
|
+
assert_kind_of Handle, @long.type
|
191
|
+
assert_equal :long, @long.type.contents
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_type=
|
195
|
+
long = Type.long.deep_clone
|
196
|
+
long.type = "something"
|
197
|
+
assert_equal "something", long.type
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_unknown_types
|
201
|
+
assert_raises(RuntimeError) do
|
202
|
+
Type.new(:some_made_up_type)
|
203
|
+
end
|
204
|
+
|
205
|
+
assert_raises(RuntimeError) do
|
206
|
+
Type.some_made_up_type
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_function
|
211
|
+
assert_nothing_raised do
|
212
|
+
Type.function([Type.unknown], Type.unknown)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_list_type
|
217
|
+
assert_equal :long, @long_list.list_type
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_equals
|
221
|
+
type = Type.long
|
222
|
+
assert_not_equal @unknown, type
|
223
|
+
assert_equal @long, type
|
224
|
+
assert_not_equal @long_list, type
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_hash
|
228
|
+
long1 = Type.long
|
229
|
+
long2 = Type.long
|
230
|
+
|
231
|
+
a = Type.unknown
|
232
|
+
a.unify long1
|
233
|
+
|
234
|
+
b = Type.unknown
|
235
|
+
b.unify long2
|
236
|
+
|
237
|
+
assert a == b, "=="
|
238
|
+
assert a === b, "==="
|
239
|
+
assert a.eql?(b), ".eql?"
|
240
|
+
assert_equal a.hash, b.hash, "hash"
|
241
|
+
|
242
|
+
assert_equal 1, [a, b].uniq.size
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_list_equal
|
246
|
+
type = Type.new(:long, true)
|
247
|
+
assert_not_equal @unknown, type
|
248
|
+
assert_not_equal @long, type
|
249
|
+
assert_equal @long_list, type
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_to_s
|
253
|
+
assert_equal "Type.long", @long.to_s
|
254
|
+
assert_equal "Type.long_list", @long_list.to_s
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_unknown?
|
258
|
+
assert_equal Type.unknown, Type.unknown
|
259
|
+
assert_not_same Type.unknown, Type.unknown
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_unknown_list
|
263
|
+
assert_equal @unknown_list, Type.unknown_list
|
264
|
+
assert_not_same Type.unknown_list, Type.unknown_list
|
265
|
+
assert @unknown_list.list?
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_unify_fail
|
269
|
+
long = Type.new(:long)
|
270
|
+
string = Type.new(:str)
|
271
|
+
long_list = Type.new(:long, true)
|
272
|
+
|
273
|
+
assert_raises(TypeError) do
|
274
|
+
long.unify string
|
275
|
+
end
|
276
|
+
|
277
|
+
assert_raises(TypeError) do
|
278
|
+
long.unify long_list
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def test_unify_simple
|
283
|
+
long = Type.new(:long)
|
284
|
+
unknown = Type.unknown
|
285
|
+
|
286
|
+
assert_equal @long, long
|
287
|
+
|
288
|
+
unknown.unify long
|
289
|
+
|
290
|
+
assert !unknown.list?
|
291
|
+
assert_equal long, unknown
|
292
|
+
assert_equal @long, unknown
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_unify_list
|
296
|
+
long_list = Type.new(:long, true)
|
297
|
+
unknown = Type.unknown
|
298
|
+
|
299
|
+
assert_equal @long_list, long_list
|
300
|
+
|
301
|
+
unknown.unify long_list
|
302
|
+
|
303
|
+
assert unknown.list?
|
304
|
+
assert_equal long_list, unknown
|
305
|
+
assert_equal @long_list, unknown
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_unify_link
|
309
|
+
unknown1 = Type.unknown
|
310
|
+
unknown2 = Type.unknown
|
311
|
+
long = Type.new(:long)
|
312
|
+
|
313
|
+
unknown1.unify unknown2
|
314
|
+
assert_same(unknown1.type, unknown2.type,
|
315
|
+
"Type of unified unknowns must be identical")
|
316
|
+
|
317
|
+
long.unify unknown2
|
318
|
+
assert_equal(long, unknown2)
|
319
|
+
assert_equal(long, unknown1,
|
320
|
+
"Type unified across all linked Types")
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_unify_function
|
324
|
+
fun = Type.function [Type.unknown], Type.unknown
|
325
|
+
@unknown.unify fun
|
326
|
+
assert_equal fun, @unknown
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
330
|
+
|
331
|
+
class TestEnvironment < Test::Unit::TestCase
|
332
|
+
|
333
|
+
def setup
|
334
|
+
@env = Environment.new
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_add
|
338
|
+
assert_equal 42, @env.add('var', 42)
|
339
|
+
assert_equal 42, @env.lookup('var')
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_add_raises_on_illegal
|
343
|
+
assert_raises RuntimeError do
|
344
|
+
@env.add nil, 1
|
345
|
+
end
|
346
|
+
|
347
|
+
assert_raises RuntimeError do
|
348
|
+
@env.add 1, 'foo'
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def test_add_segmented
|
353
|
+
@env.scope do
|
354
|
+
@env.add 'var', 42
|
355
|
+
assert_equal 42, @env.lookup('var')
|
356
|
+
end
|
357
|
+
|
358
|
+
assert_raises NameError do
|
359
|
+
@env.lookup('var')
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_current
|
364
|
+
@env.add 'var', 42
|
365
|
+
|
366
|
+
expected = { 'var' => 42 }
|
367
|
+
assert_equal expected, @env.current
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_depth
|
371
|
+
assert_equal 1, @env.depth
|
372
|
+
|
373
|
+
@env.scope do
|
374
|
+
assert_equal 2, @env.depth
|
375
|
+
end
|
376
|
+
|
377
|
+
assert_equal 1, @env.depth
|
378
|
+
end
|
379
|
+
|
380
|
+
def test_env
|
381
|
+
assert_equal [{}], @env.env
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_env=
|
385
|
+
@env.env = "something"
|
386
|
+
assert_equal "something", @env.env
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_extend
|
390
|
+
assert_equal [{}], @env.env
|
391
|
+
|
392
|
+
@env.extend
|
393
|
+
assert_equal [{}, {}], @env.env
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_lookup
|
397
|
+
@env.add 'var', 1
|
398
|
+
assert_equal 1, @env.lookup('var')
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_lookup_raises
|
402
|
+
assert_raises NameError do
|
403
|
+
@env.lookup('var')
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_lookup_extended
|
408
|
+
@env.add 'var', 1
|
409
|
+
assert_equal 1, @env.lookup('var')
|
410
|
+
|
411
|
+
@env.scope do
|
412
|
+
assert_equal 1, @env.lookup('var')
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_scope
|
417
|
+
@env.add 'var', 1
|
418
|
+
assert_equal 1, @env.lookup('var')
|
419
|
+
|
420
|
+
@env.scope do
|
421
|
+
@env.add 'var', 2
|
422
|
+
assert_equal 2, @env.lookup('var')
|
423
|
+
end
|
424
|
+
|
425
|
+
assert_equal 1, @env.lookup('var')
|
426
|
+
end
|
427
|
+
|
428
|
+
def test_unextend
|
429
|
+
@env.extend
|
430
|
+
|
431
|
+
@env.add 'var', 1
|
432
|
+
|
433
|
+
assert_equal 1, @env.lookup('var')
|
434
|
+
|
435
|
+
@env.unextend
|
436
|
+
|
437
|
+
assert_raises NameError do
|
438
|
+
@env.lookup 'var'
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
class TestFunctionTable < Test::Unit::TestCase
|
445
|
+
|
446
|
+
def setup
|
447
|
+
@function_table = FunctionTable.new
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_add_function
|
451
|
+
type = @function_table.add_function 'func', Type.long
|
452
|
+
|
453
|
+
assert_equal Type.long, type
|
454
|
+
assert_equal Type.long, @function_table['func']
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_cheat
|
458
|
+
@function_table.add_function 'func', Type.long
|
459
|
+
@function_table.add_function 'func', Type.str
|
460
|
+
|
461
|
+
assert_equal [Type.long, Type.str], @function_table.cheat('func')
|
462
|
+
end
|
463
|
+
|
464
|
+
def test_has_key?
|
465
|
+
@function_table.add_function 'func', Type.long
|
466
|
+
|
467
|
+
assert_equal true, @function_table.has_key?('func')
|
468
|
+
assert_equal false, @function_table.has_key?('no such func')
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_index
|
472
|
+
@function_table.add_function 'func', Type.long
|
473
|
+
|
474
|
+
assert_equal Type.long, @function_table['func']
|
475
|
+
|
476
|
+
@function_table.add_function 'func', Type.str
|
477
|
+
|
478
|
+
assert_equal Type.long, @function_table['func']
|
479
|
+
end
|
480
|
+
|
481
|
+
def test_unify_one_type
|
482
|
+
@function_table.add_function 'func', Type.unknown
|
483
|
+
|
484
|
+
@function_table.unify 'func', Type.long do
|
485
|
+
flunk "Block should not have been called"
|
486
|
+
end
|
487
|
+
|
488
|
+
assert_equal Type.long, @function_table['func']
|
489
|
+
end
|
490
|
+
|
491
|
+
def test_unify_two_type
|
492
|
+
@function_table.add_function 'func', Type.unknown
|
493
|
+
@function_table.add_function 'func', Type.str
|
494
|
+
|
495
|
+
@function_table.unify 'func', Type.long do
|
496
|
+
flunk "Block should not have been called"
|
497
|
+
end
|
498
|
+
|
499
|
+
assert_equal Type.long, @function_table['func']
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_unify_block_called_no_type
|
503
|
+
@function_table.add_function 'func', Type.str
|
504
|
+
|
505
|
+
test_var = false
|
506
|
+
|
507
|
+
@function_table.unify 'func', Type.long do
|
508
|
+
test_var = true
|
509
|
+
end
|
510
|
+
|
511
|
+
assert test_var, "Block not called"
|
512
|
+
end
|
513
|
+
|
514
|
+
def test_unify_block_called_no_unify
|
515
|
+
test_var = false
|
516
|
+
|
517
|
+
@function_table.unify 'func', Type.long do
|
518
|
+
test_var = true
|
519
|
+
end
|
520
|
+
|
521
|
+
assert test_var, "Block not called"
|
522
|
+
end
|
523
|
+
|
524
|
+
end
|
525
|
+
|