RubyToC 1.0.0.4 → 1.0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ $TESTING = true
4
+
5
+ require 'test/unit'
6
+ require 'ruby_to_ruby_c'
7
+ require 'r2ctestcase'
8
+
9
+ # TODO: maybe make this a subclass of TestRubyToAnsiC??? might be a bad idea
10
+ class TestRubyToRubyC < R2CTestCase
11
+
12
+ def setup
13
+ @ruby_to_c = RubyToRubyC.new
14
+ @ruby_to_c.env.extend
15
+ @processor = @ruby_to_c
16
+ end
17
+
18
+ def test_translator
19
+ Object.class_eval "class Suck; end"
20
+ input = [:class, :Suck, :Object,
21
+ [:defn, :something, [:scope, [:block, [:args], [:fcall, :"whaaa\?"]]]],
22
+ [:defn, :foo, [:scope, [:block, [:args], [:vcall, :something]]]]]
23
+ expected = "// class Suck\n\nVALUE\nsomething() {\nrb_funcall(self, rb_intern(\"whaaa?\"), 0);\n}\n\nVALUE\nfoo() {\nrb_funcall(self, rb_intern(\"something\"), 0);\n}"
24
+ assert_equal expected, RubyToRubyC.translator.process(input)
25
+ end
26
+
27
+ end
@@ -335,8 +335,15 @@ class TestEnvironment < Test::Unit::TestCase
335
335
  end
336
336
 
337
337
  def test_add
338
- assert_equal 42, @env.add('var', 42)
339
- assert_equal 42, @env.lookup('var')
338
+ assert_equal 42, @env.add(:var, 42)
339
+ assert_equal 42, @env.lookup(:var)
340
+ end
341
+
342
+ def test_add_depth
343
+ @env.scope do
344
+ assert_equal 42, @env.add(:var, 42, 1)
345
+ end
346
+ assert_equal 42, @env.lookup(:var)
340
347
  end
341
348
 
342
349
  def test_add_raises_on_illegal
@@ -345,28 +352,41 @@ class TestEnvironment < Test::Unit::TestCase
345
352
  end
346
353
 
347
354
  assert_raises RuntimeError do
348
- @env.add 1, 'foo'
355
+ @env.add 1, :foo
349
356
  end
350
357
  end
351
358
 
352
359
  def test_add_segmented
353
360
  @env.scope do
354
- @env.add 'var', 42
355
- assert_equal 42, @env.lookup('var')
361
+ @env.add :var, 42
362
+ assert_equal 42, @env.lookup(:var)
356
363
  end
357
364
 
358
365
  assert_raises NameError do
359
- @env.lookup('var')
366
+ @env.lookup(:var)
360
367
  end
361
368
  end
362
369
 
363
370
  def test_current
364
- @env.add 'var', 42
371
+ @env.add :var, 42
365
372
 
366
- expected = { 'var' => 42 }
373
+ expected = { :var => 42 }
367
374
  assert_equal expected, @env.current
368
375
  end
369
376
 
377
+ def test_all
378
+ @env.scope do
379
+ @env.add :x, 42
380
+ @env.scope do
381
+ @env.add :y, 24
382
+ @env.add :x, 15
383
+ expected = { :x => 15, :y => 24 }
384
+
385
+ assert_equal expected, @env.all
386
+ end
387
+ end
388
+ end
389
+
370
390
  def test_depth
371
391
  assert_equal 1, @env.depth
372
392
 
@@ -394,48 +414,65 @@ class TestEnvironment < Test::Unit::TestCase
394
414
  end
395
415
 
396
416
  def test_lookup
397
- @env.add 'var', 1
398
- assert_equal 1, @env.lookup('var')
417
+ @env.add :var, 1
418
+ assert_equal 1, @env.lookup(:var)
399
419
  end
400
420
 
401
421
  def test_lookup_raises
402
422
  assert_raises NameError do
403
- @env.lookup('var')
423
+ @env.lookup(:var)
404
424
  end
405
425
  end
406
426
 
407
427
  def test_lookup_extended
408
- @env.add 'var', 1
409
- assert_equal 1, @env.lookup('var')
428
+ @env.add :var, 1
429
+ assert_equal 1, @env.lookup(:var)
410
430
 
411
431
  @env.scope do
412
- assert_equal 1, @env.lookup('var')
432
+ assert_equal 1, @env.lookup(:var)
413
433
  end
414
434
  end
415
435
 
416
436
  def test_scope
417
- @env.add 'var', 1
418
- assert_equal 1, @env.lookup('var')
437
+ @env.add :var, 1
438
+ assert_equal 1, @env.lookup(:var)
419
439
 
420
440
  @env.scope do
421
- @env.add 'var', 2
422
- assert_equal 2, @env.lookup('var')
441
+ @env.add :var, 2
442
+ assert_equal 2, @env.lookup(:var)
443
+ end
444
+
445
+ assert_equal 1, @env.lookup(:var)
446
+ end
447
+
448
+ def test_scope_raise
449
+ @env.add :a, 2
450
+
451
+ begin
452
+ @env.scope do
453
+ @env.add :a, 1
454
+ @env.add :b, 2
455
+ raise "woo"
456
+ end
457
+ rescue
458
+ # should replicate baddies
423
459
  end
424
460
 
425
- assert_equal 1, @env.lookup('var')
461
+ expected = { :a => 2 }
462
+ assert_equal expected, @env.all
426
463
  end
427
464
 
428
465
  def test_unextend
429
466
  @env.extend
430
467
 
431
- @env.add 'var', 1
468
+ @env.add :var, 1
432
469
 
433
- assert_equal 1, @env.lookup('var')
470
+ assert_equal 1, @env.lookup(:var)
434
471
 
435
472
  @env.unextend
436
473
 
437
474
  assert_raises NameError do
438
- @env.lookup 'var'
475
+ @env.lookup :var
439
476
  end
440
477
  end
441
478
 
@@ -448,63 +485,63 @@ class TestFunctionTable < Test::Unit::TestCase
448
485
  end
449
486
 
450
487
  def test_add_function
451
- type = @function_table.add_function 'func', Type.long
488
+ type = @function_table.add_function :func, Type.long
452
489
 
453
490
  assert_equal Type.long, type
454
- assert_equal Type.long, @function_table['func']
491
+ assert_equal Type.long, @function_table[:func]
455
492
  end
456
493
 
457
494
  def test_cheat
458
- @function_table.add_function 'func', Type.long
459
- @function_table.add_function 'func', Type.str
495
+ @function_table.add_function :func, Type.long
496
+ @function_table.add_function :func, Type.str
460
497
 
461
- assert_equal [Type.long, Type.str], @function_table.cheat('func')
498
+ assert_equal [Type.long, Type.str], @function_table.cheat(:func)
462
499
  end
463
500
 
464
501
  def test_has_key?
465
- @function_table.add_function 'func', Type.long
502
+ @function_table.add_function :func, Type.long
466
503
 
467
- assert_equal true, @function_table.has_key?('func')
504
+ assert_equal true, @function_table.has_key?(:func)
468
505
  assert_equal false, @function_table.has_key?('no such func')
469
506
  end
470
507
 
471
508
  def test_index
472
- @function_table.add_function 'func', Type.long
509
+ @function_table.add_function :func, Type.long
473
510
 
474
- assert_equal Type.long, @function_table['func']
511
+ assert_equal Type.long, @function_table[:func]
475
512
 
476
- @function_table.add_function 'func', Type.str
513
+ @function_table.add_function :func, Type.str
477
514
 
478
- assert_equal Type.long, @function_table['func']
515
+ assert_equal Type.long, @function_table[:func]
479
516
  end
480
517
 
481
518
  def test_unify_one_type
482
- @function_table.add_function 'func', Type.unknown
519
+ @function_table.add_function :func, Type.unknown
483
520
 
484
- @function_table.unify 'func', Type.long do
521
+ @function_table.unify :func, Type.long do
485
522
  flunk "Block should not have been called"
486
523
  end
487
524
 
488
- assert_equal Type.long, @function_table['func']
525
+ assert_equal Type.long, @function_table[:func]
489
526
  end
490
527
 
491
528
  def test_unify_two_type
492
- @function_table.add_function 'func', Type.unknown
493
- @function_table.add_function 'func', Type.str
529
+ @function_table.add_function :func, Type.unknown
530
+ @function_table.add_function :func, Type.str
494
531
 
495
- @function_table.unify 'func', Type.long do
532
+ @function_table.unify :func, Type.long do
496
533
  flunk "Block should not have been called"
497
534
  end
498
535
 
499
- assert_equal Type.long, @function_table['func']
536
+ assert_equal Type.long, @function_table[:func]
500
537
  end
501
538
 
502
539
  def test_unify_block_called_no_type
503
- @function_table.add_function 'func', Type.str
540
+ @function_table.add_function :func, Type.str
504
541
 
505
542
  test_var = false
506
543
 
507
- @function_table.unify 'func', Type.long do
544
+ @function_table.unify :func, Type.long do
508
545
  test_var = true
509
546
  end
510
547
 
@@ -514,7 +551,7 @@ class TestFunctionTable < Test::Unit::TestCase
514
551
  def test_unify_block_called_no_unify
515
552
  test_var = false
516
553
 
517
- @function_table.unify 'func', Type.long do
554
+ @function_table.unify :func, Type.long do
518
555
  test_var = true
519
556
  end
520
557
 
@@ -50,6 +50,33 @@ class TestTypeChecker < R2CTestCase
50
50
  @type_checker.functions[:>])
51
51
  end
52
52
 
53
+ def test_defn_call_unify
54
+ # pre-registered function, presumibly through another :call elsewhere
55
+ add_fake_function :specific, Type.unknown, Type.unknown, Type.unknown
56
+
57
+ # now in specific, unify with a long
58
+ # puts "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
59
+ # pp @type_checker.functions
60
+ s = @type_checker.process(s(:defn, :specific,
61
+ s(:args, :x),
62
+ s(:scope,
63
+ s(:block,
64
+ s(:lasgn, :x, s(:lit, 2))))))
65
+ # pp @type_checker.functions
66
+ s_type = @type_checker.functions[:specific]
67
+
68
+ # p s_type
69
+
70
+ assert_equal(Type.long,
71
+ s_type.list_type.formal_types[0])
72
+ # HACK flunk "eric hasn't finished writing me yet. guilt. guilt. guilt."
73
+ end
74
+
75
+ def test_env
76
+ @type_checker.env.add :blah, Type.long
77
+ assert_equal Type.long, @type_checker.env.lookup(:blah)
78
+ end
79
+
53
80
  def test_functions
54
81
  # bootstrap populates functions
55
82
  assert @type_checker.functions.has_key?(:puts)
@@ -57,27 +84,10 @@ class TestTypeChecker < R2CTestCase
57
84
  @type_checker.functions[:>])
58
85
  end
59
86
 
60
- def test_env
61
- @type_checker.env.add :blah, Type.long
62
- assert_equal Type.long, @type_checker.env.lookup(:blah)
63
- end
64
-
65
87
  def test_genv
66
88
  assert_equal Type.file, @type_checker.genv.lookup(:$stderr)
67
89
  end
68
90
 
69
- def test_translate
70
- result = @type_checker.translate DumbClass, :empty
71
- expect = t(:defn,
72
- :empty,
73
- t(:args),
74
- t(:scope,
75
- t(:block,
76
- t(:nil, Type.value), Type.unknown), Type.void),
77
- Type.function(Type.unknown, [], Type.void))
78
- assert_equal(expect, result)
79
- end
80
-
81
91
  def test_process_args
82
92
  @type_checker.env.extend
83
93
 
@@ -97,6 +107,18 @@ class TestTypeChecker < R2CTestCase
97
107
  assert_equal output, @type_checker.process(input)
98
108
  end
99
109
 
110
+ def test_process_array_multiple
111
+ add_fake_var :arg1, Type.long
112
+ add_fake_var :arg2, Type.str
113
+
114
+ input = t(:array, t(:lvar, :arg1), t(:lvar, :arg2))
115
+ output = t(:array,
116
+ t(:lvar, :arg1, Type.long),
117
+ t(:lvar, :arg2, Type.str))
118
+
119
+ assert_equal output, @type_checker.process(input)
120
+ end
121
+
100
122
  def test_process_array_single
101
123
  add_fake_var :arg1, Type.long
102
124
 
@@ -110,14 +132,62 @@ class TestTypeChecker < R2CTestCase
110
132
  assert_equal output, result
111
133
  end
112
134
 
113
- def test_process_array_multiple
114
- add_fake_var :arg1, Type.long
115
- add_fake_var :arg2, Type.str
135
+ def test_process_block
136
+ input = t(:block, t(:return, t(:nil)))
137
+ # FIX: should this really be void for return?
138
+ output = t(:block,
139
+ t(:return,
140
+ t(:nil, Type.value),
141
+ Type.void),
142
+ Type.unknown)
116
143
 
117
- input = t(:array, t(:lvar, :arg1), t(:lvar, :arg2))
118
- output = t(:array,
119
- t(:lvar, :arg1, Type.long),
120
- t(:lvar, :arg2, Type.str))
144
+ assert_equal output, @type_checker.process(input)
145
+ end
146
+
147
+ def test_process_block_multiple
148
+ input = t(:block,
149
+ t(:str, :foo),
150
+ t(:return, t(:nil)))
151
+ output = t(:block,
152
+ t(:str, :foo, Type.str),
153
+ t(:return,
154
+ t(:nil, Type.value),
155
+ Type.void),
156
+ Type.unknown)
157
+
158
+ assert_equal output, @type_checker.process(input)
159
+ end
160
+
161
+ def test_process_call_case_equal_long
162
+ add_fake_var :number, Type.unknown
163
+
164
+ input = t(:call,
165
+ t(:lit, 1),
166
+ :===,
167
+ t(:arglist, t(:lvar, :number)))
168
+ output = t(:call,
169
+ t(:lit, 1, Type.long),
170
+ :case_equal_long,
171
+ t(:arglist,
172
+ t(:lvar, :number, Type.long)),
173
+ Type.bool)
174
+
175
+ assert_equal output, @type_checker.process(input)
176
+ end
177
+
178
+ def test_process_call_case_equal_string
179
+ add_fake_var :string, Type.unknown
180
+
181
+ input = t(:call,
182
+ t(:str, 'foo'),
183
+ :===,
184
+ t(:arglist, t(:lvar, :string)))
185
+ output = t(:call,
186
+ t(:str, 'foo', Type.str),
187
+ :case_equal_str,
188
+ t(:arglist,
189
+ t(:lvar, :string, Type.str)),
190
+ Type.bool)
121
191
 
122
192
  assert_equal output, @type_checker.process(input)
123
193
  end
@@ -269,63 +339,6 @@ class TestTypeChecker < R2CTestCase
269
339
  @type_checker.functions[:unify_3_outer].list_type.formal_types[0])
270
340
  end
271
341
 
272
- def test_defn_call_unify
273
-
274
- # pre-registered function, presumibly through another :call elsewhere
275
- add_fake_function :specific, Type.unknown, Type.unknown, Type.unknown
276
-
277
- # now in specific, unify with a long
278
- # puts "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
279
- # pp @type_checker.functions
280
- s = @type_checker.process(s(:defn, :specific,
281
- s(:args, :x),
282
- s(:scope,
283
- s(:block,
284
- s(:lasgn, :x, s(:lit, 2))))))
285
- # pp @type_checker.functions
286
- s_type = @type_checker.functions[:specific]
287
-
288
- # p s_type
289
-
290
- assert_equal(Type.long,
291
- s_type.list_type.formal_types[0])
292
- # HACK flunk "eric hasn't finished writing me yet. guilt. guilt. guilt."
293
- end
294
-
295
- def test_process_call_case_equal_long
296
- add_fake_var :number, Type.unknown
297
-
298
- input = t(:call,
299
- t(:lit, 1),
300
- :===,
301
- t(:arglist, t(:lvar, :number)))
302
- output = t(:call,
303
- t(:lit, 1, Type.long),
304
- :case_equal_long,
305
- t(:arglist,
306
- t(:lvar, :number, Type.long)),
307
- Type.bool)
308
-
309
- assert_equal output, @type_checker.process(input)
310
- end
311
-
312
- def test_process_call_case_equal_string
313
- add_fake_var :string, Type.unknown
314
-
315
- input = t(:call,
316
- t(:str, 'foo'),
317
- :===,
318
- t(:arglist, t(:lvar, :string)))
319
- output = t(:call,
320
- t(:str, 'foo', Type.str),
321
- :case_equal_str,
322
- t(:arglist,
323
- t(:lvar, :string, Type.str)),
324
- Type.bool)
325
-
326
- assert_equal output, @type_checker.process(input)
327
- end
328
-
329
342
  # HACK: putting class X above w/ some consts
330
343
  def test_process_class
331
344
  input = s(:class, :X, :Object,
@@ -370,32 +383,6 @@ class TestTypeChecker < R2CTestCase
370
383
  assert_equal output, @type_checker.process(input)
371
384
  end
372
385
 
373
- def test_process_block
374
- input = t(:block, t(:return, t(:nil)))
375
- # FIX: should this really be void for return?
376
- output = t(:block,
377
- t(:return,
378
- t(:nil, Type.value),
379
- Type.void),
380
- Type.unknown)
381
-
382
- assert_equal output, @type_checker.process(input)
383
- end
384
-
385
- def test_process_block_multiple
386
- input = t(:block,
387
- t(:str, :foo),
388
- t(:return, t(:nil)))
389
- output = t(:block,
390
- t(:str, :foo, Type.str),
391
- t(:return,
392
- t(:nil, Type.value),
393
- Type.void),
394
- Type.unknown)
395
-
396
- assert_equal output, @type_checker.process(input)
397
- end
398
-
399
386
  def test_process_dasgn_curr
400
387
  @type_checker.env.extend
401
388
  input = t(:dasgn_curr, :x)
@@ -450,7 +437,7 @@ class TestTypeChecker < R2CTestCase
450
437
  assert_equal output, @type_checker.process(input)
451
438
  end
452
439
 
453
- def test_gasgn
440
+ def test_process_gasgn
454
441
  input = s(:gasgn, :$blah, s(:lit, 42))
455
442
  expected = t(:gasgn, :$blah, t(:lit, 42, Type.long), Type.long)
456
443
 
@@ -606,6 +593,13 @@ class TestTypeChecker < R2CTestCase
606
593
  assert_equal output, @type_checker.process(input)
607
594
  end
608
595
 
596
+ def test_process_lit_float
597
+ input = t(:lit, 1.0)
598
+ output = t(:lit, 1.0, Type.float)
599
+
600
+ assert_equal output, @type_checker.process(input)
601
+ end
602
+
609
603
  def test_process_lit_long
610
604
  input = t(:lit, 1)
611
605
  output = t(:lit, 1, Type.long)
@@ -620,13 +614,6 @@ class TestTypeChecker < R2CTestCase
620
614
  assert_equal output, @type_checker.process(input)
621
615
  end
622
616
 
623
- def test_process_lit_float
624
- input = t(:lit, 1.0)
625
- output = t(:lit, 1.0, Type.float)
626
-
627
- assert_equal output, @type_checker.process(input)
628
- end
629
-
630
617
  def test_process_lvar
631
618
  add_fake_var :arg, Type.long
632
619
  input = t(:lvar, :arg)
@@ -669,21 +656,6 @@ class TestTypeChecker < R2CTestCase
669
656
  assert_equal output, @type_checker.process(input)
670
657
  end
671
658
 
672
- # HACK is this test valid? I don't think so
673
- # def test_process_return_empty
674
- # input = t(:return)
675
- # output = t(:return, t(:nil, Type.value), Type.void)
676
- #
677
- # assert_equal output, @type_checker.process(input)
678
- # end
679
-
680
- def test_process_str
681
- input = t(:str, "foo")
682
- output = t(:str, "foo", Type.str)
683
-
684
- assert_equal output, @type_checker.process(input)
685
- end
686
-
687
659
  def test_process_scope
688
660
  input = t(:scope,
689
661
  t(:block,
@@ -706,6 +678,13 @@ class TestTypeChecker < R2CTestCase
706
678
  assert_equal output, @type_checker.process(input)
707
679
  end
708
680
 
681
+ def test_process_str
682
+ input = t(:str, "foo")
683
+ output = t(:str, "foo", Type.str)
684
+
685
+ assert_equal output, @type_checker.process(input)
686
+ end
687
+
709
688
  def test_process_true
710
689
  input = t(:true)
711
690
  output = t(:true, Type.bool)
@@ -745,6 +724,18 @@ class TestTypeChecker < R2CTestCase
745
724
  assert_equal expected, @type_checker.process(input)
746
725
  end
747
726
 
727
+ def test_translate
728
+ result = @type_checker.translate DumbClass, :empty
729
+ expect = t(:defn,
730
+ :empty,
731
+ t(:args),
732
+ t(:scope,
733
+ t(:block,
734
+ t(:nil, Type.value), Type.unknown), Type.void),
735
+ Type.function(Type.unknown, [], Type.void))
736
+ assert_equal(expect, result)
737
+ end
738
+
748
739
  def add_fake_function(name, reciever_type, return_type, *arg_types)
749
740
  @type_checker.functions.add_function(name,
750
741
  Type.function(reciever_type, arg_types, return_type))