RubyToC 1.0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,838 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ $TESTING = true
4
+
5
+ require 'test/unit'
6
+ require 'type_checker'
7
+ require 'r2ctestcase'
8
+
9
+ # Test::Unit::Assertions.use_pp = false
10
+
11
+ class DumbClass # ZenTest SKIP
12
+ def empty
13
+ end
14
+ end
15
+
16
+ class X # ZenTest SKIP
17
+ VALUE = 42
18
+ end
19
+
20
+ class TestTypeChecker < R2CTestCase
21
+
22
+ def setup
23
+ @type_checker = TypeChecker.new
24
+ @processor = @type_checker
25
+ @type_checker.env.add :argl, Type.long
26
+ @type_checker.env.add :args, Type.str
27
+ @type_checker.env.add :arrayl, Type.long_list
28
+ @type_checker.env.add :arrayl2, Type.long_list
29
+ @type_checker.env.add :arrays, Type.str_list
30
+ @type_checker.genv.add :SyntaxError, Type.fucked
31
+ @type_checker.genv.add :Exception, Type.fucked
32
+ end
33
+
34
+ def test_and
35
+ input = t(:and, t(:true), t(:false))
36
+ output = t(:and, t(:true, Type.bool), t(:false, Type.bool), Type.bool)
37
+
38
+ assert_equal output, @type_checker.process(input)
39
+ end
40
+
41
+ def test_bootstrap
42
+ # bootstrap is automatically called by initialize
43
+ # TODO should we check for EVERYTHING we expect?
44
+
45
+ assert_equal Type.file, @type_checker.genv.lookup(:$stdin)
46
+ assert_equal Type.file, @type_checker.genv.lookup(:$stdout)
47
+ assert_equal Type.file, @type_checker.genv.lookup(:$stderr)
48
+
49
+ assert_equal(Type.function(Type.long, [Type.long], Type.bool),
50
+ @type_checker.functions[:>])
51
+ end
52
+
53
+ def test_functions
54
+ # bootstrap populates functions
55
+ assert @type_checker.functions.has_key?(:puts)
56
+ assert_equal(Type.function(Type.long, [Type.long], Type.bool),
57
+ @type_checker.functions[:>])
58
+ end
59
+
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
+ def test_genv
66
+ assert_equal Type.file, @type_checker.genv.lookup(:$stderr)
67
+ end
68
+
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
+ def test_process_args
82
+ @type_checker.env.extend
83
+
84
+ input = t(:args, :foo, :bar)
85
+ output = t(:args,
86
+ t(:foo, Type.unknown),
87
+ t(:bar, Type.unknown))
88
+
89
+ assert_equal output, @type_checker.process(input)
90
+ end
91
+
92
+ def test_process_args_empty
93
+ input = t(:args)
94
+ output = t(:args)
95
+ # TODO: this should be superseded by the new array functionality
96
+
97
+ assert_equal output, @type_checker.process(input)
98
+ end
99
+
100
+ def test_process_array_single
101
+ add_fake_var :arg1, Type.long
102
+
103
+ input = t(:array, t(:lvar, :arg1))
104
+ output = t(:array, t(:lvar, :arg1, Type.long))
105
+
106
+ result = @type_checker.process(input)
107
+
108
+ assert_equal Type.homo, result.sexp_type
109
+ assert_equal [ Type.long ], result.sexp_types
110
+ assert_equal output, result
111
+ end
112
+
113
+ def test_process_array_multiple
114
+ add_fake_var :arg1, Type.long
115
+ add_fake_var :arg2, Type.str
116
+
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))
121
+
122
+ assert_equal output, @type_checker.process(input)
123
+ end
124
+
125
+ def test_process_call_defined
126
+ add_fake_function :name, Type.void, Type.long, Type.str
127
+ input = t(:call,
128
+ nil,
129
+ :name,
130
+ t(:arglist, t(:str, "foo")))
131
+ output = t(:call,
132
+ nil,
133
+ :name,
134
+ t(:arglist, t(:str, "foo", Type.str)),
135
+ Type.long)
136
+
137
+ assert_equal output, @type_checker.process(input)
138
+ end
139
+
140
+ def test_process_call_defined_rhs
141
+ add_fake_function :name3, Type.long, Type.long, Type.str
142
+ input = t(:call,
143
+ t(:lit, 1),
144
+ :name3,
145
+ t(:arglist, t(:str, "foo")))
146
+ output = t(:call,
147
+ t(:lit, 1, Type.long),
148
+ :name3,
149
+ t(:arglist, t(:str, "foo", Type.str)),
150
+ Type.long)
151
+
152
+ assert_equal output, @type_checker.process(input)
153
+ end
154
+
155
+ def test_process_call_undefined
156
+ input = t(:call, nil, :name, nil)
157
+ output = t(:call, nil, :name, nil, Type.unknown)
158
+
159
+ assert_equal output, @type_checker.process(input)
160
+ # FIX returns unknown in s()
161
+ assert_equal(Type.function(Type.unknown, [], Type.unknown),
162
+ @type_checker.functions[:name])
163
+ end
164
+
165
+ def test_process_call_unify_1
166
+ add_fake_var :number, Type.long
167
+ input = t(:call,
168
+ t(:lit, 1),
169
+ :==,
170
+ t(:arglist,
171
+ t(:lvar, :number)))
172
+ output = t(:call,
173
+ t(:lit, 1, Type.long),
174
+ :==,
175
+ t(:arglist,
176
+ t(:lvar, :number, Type.long)),
177
+ Type.bool)
178
+
179
+ assert_equal output, @type_checker.process(input)
180
+ end
181
+
182
+ def test_process_call_unify_2
183
+ add_fake_var :number1, Type.unknown
184
+ add_fake_var :number2, Type.unknown
185
+
186
+ input = t(:call,
187
+ t(:lit, 1),
188
+ :==,
189
+ t(:arglist, t(:lvar, :number1)))
190
+ output = t(:call,
191
+ t(:lit, 1, Type.long),
192
+ :==,
193
+ t(:arglist,
194
+ t(:lvar, :number1, Type.long)),
195
+ Type.bool)
196
+
197
+ assert_equal output, @type_checker.process(input)
198
+
199
+ input = t(:call,
200
+ t(:lvar, :number2),
201
+ :==,
202
+ t(:arglist, t(:lit, 1)))
203
+ output = t(:call,
204
+ t(:lvar, :number2, Type.long),
205
+ :==,
206
+ t(:arglist,
207
+ t(:lit, 1, Type.long)),
208
+ Type.bool)
209
+
210
+ assert_equal output, @type_checker.process(input)
211
+ end
212
+
213
+ def test_process_call_unify_3
214
+ a_type = Type.unknown
215
+ add_fake_var :a, a_type # TODO: Type.unknown
216
+
217
+ # def unify_3_outer(a)
218
+ #
219
+ # unk
220
+ # ^
221
+ # |
222
+ # outer(., ., [+])
223
+
224
+ # assume the environment got everything set up correctly
225
+ add_fake_function(:unify_3_outer, Type.void, Type.void, a_type)
226
+
227
+ assert_equal(a_type,
228
+ @type_checker.functions[:unify_3_outer].list_type.formal_types[0])
229
+
230
+ # unify_3_inner(a) # call
231
+ #
232
+ # outer(., ., [+])
233
+ # |
234
+ # v
235
+ # unk
236
+ # ^
237
+ # |
238
+ # inner(., ., [+])
239
+
240
+ @type_checker.process(t(:call, t(:nil),
241
+ :unify_3_inner,
242
+ t(:arglist, t(:lvar, :a))))
243
+
244
+ assert_equal a_type, @type_checker.env.lookup(:a)
245
+ assert_equal(@type_checker.env.lookup(:a),
246
+ @type_checker.functions[:unify_3_inner].list_type.formal_types[0])
247
+
248
+ # def unify_3_inner(a)
249
+ # a = 1
250
+ # end
251
+ #
252
+ # outer(., ., [+])
253
+ # |
254
+ # v
255
+ # long
256
+ # ^
257
+ # |
258
+ # inner(., ., [+])
259
+
260
+ @type_checker.env.scope do
261
+ @type_checker.env.add :a, a_type
262
+
263
+ @type_checker.process t(:lasgn, :a, t(:lit, 1))
264
+ end
265
+
266
+ assert_equal a_type, Type.long
267
+
268
+ assert_equal(@type_checker.functions[:unify_3_inner].list_type.formal_types[0],
269
+ @type_checker.functions[:unify_3_outer].list_type.formal_types[0])
270
+ end
271
+
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
+ # HACK: putting class X above w/ some consts
330
+ def test_process_class
331
+ input = s(:class, :X, :Object,
332
+ s(:defn, :meth,
333
+ s(:args, :x),
334
+ s(:scope,
335
+ s(:block,
336
+ s(:lasgn, :x, s(:const, :VALUE))))))
337
+ output = t(:class, :X, :Object,
338
+ t(:defn, :meth,
339
+ t(:args, t(:x, Type.long)),
340
+ t(:scope,
341
+ t(:block,
342
+ t(:lasgn, :x,
343
+ t(:const, :VALUE, Type.long),
344
+ Type.long),
345
+ Type.unknown),
346
+ Type.void),
347
+ Type.function(Type.unknown, [Type.long], Type.void)),
348
+ Type.zclass)
349
+
350
+ assert_equal output, @type_checker.process(input)
351
+ end
352
+
353
+ def test_process_const
354
+ assert_raises NameError do
355
+ @type_checker.process s(:const, :NonExistant)
356
+ end
357
+ end
358
+
359
+ def test_process_cvar
360
+ input = s(:cvar, :name)
361
+ output = t(:cvar, :name, Type.unknown)
362
+
363
+ assert_equal output, @type_checker.process(input)
364
+ end
365
+
366
+ def test_process_cvasgn
367
+ input = s(:cvasgn, :name, s(:lit, 4))
368
+ output = t(:cvasgn, :name, t(:lit, 4, Type.long), Type.unknown)
369
+
370
+ assert_equal output, @type_checker.process(input)
371
+ end
372
+
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
+ def test_process_dasgn_curr
400
+ @type_checker.env.extend
401
+ input = t(:dasgn_curr, :x)
402
+ output = t(:dasgn_curr, :x, Type.unknown)
403
+
404
+ assert_equal output, @type_checker.process(input)
405
+ # HACK: is this a valid test??? it was in ruby_to_c:
406
+ # assert_equal Type.long, @type_checker.env.lookup(:x)
407
+ end
408
+
409
+ def test_process_defn
410
+ function_type = Type.function s(), Type.void
411
+ input = t(:defn,
412
+ :empty,
413
+ t(:args),
414
+ t(:scope))
415
+ output = t(:defn,
416
+ :empty,
417
+ t(:args),
418
+ t(:scope, Type.void),
419
+ function_type)
420
+
421
+ assert_equal output, @type_checker.process(input)
422
+ end
423
+
424
+ def test_process_dstr
425
+ add_fake_var :var, Type.str
426
+ input = t(:dstr,
427
+ "var is ",
428
+ t(:lvar, :var),
429
+ t(:str, ". So there."))
430
+ output = t(:dstr, "var is ",
431
+ t(:lvar, :var, Type.str),
432
+ t(:str, ". So there.", Type.str),
433
+ Type.str)
434
+
435
+ assert_equal output, @type_checker.process(input)
436
+ end
437
+
438
+ def test_process_dvar
439
+ add_fake_var :dvar, Type.long
440
+ input = t(:dvar, :dvar)
441
+ output = t(:dvar, :dvar, Type.long)
442
+
443
+ assert_equal output, @type_checker.process(input)
444
+ end
445
+
446
+ def test_process_false
447
+ input = t(:false)
448
+ output = t(:false, Type.bool)
449
+
450
+ assert_equal output, @type_checker.process(input)
451
+ end
452
+
453
+ def test_gasgn
454
+ input = s(:gasgn, :$blah, s(:lit, 42))
455
+ expected = t(:gasgn, :$blah, t(:lit, 42, Type.long), Type.long)
456
+
457
+ assert_equal expected, @type_checker.process(input)
458
+ end
459
+
460
+ def test_process_gvar_defined
461
+ add_fake_gvar :$arg, Type.long
462
+ input = t(:gvar, :$arg)
463
+ output = t(:gvar, :$arg, Type.long)
464
+
465
+ assert_equal output, @type_checker.process(input)
466
+ end
467
+
468
+ def test_process_gvar_undefined
469
+ input = t(:gvar, :$arg)
470
+ output = t(:gvar, :$arg, Type.unknown)
471
+
472
+ assert_equal output, @type_checker.process(input)
473
+ end
474
+
475
+ def test_process_iasgn
476
+ input = s(:iasgn, :@blah, s(:lit, 42))
477
+ expected = t(:iasgn, :@blah, t(:lit, 42, Type.long), Type.long)
478
+
479
+ assert_equal expected, @type_checker.process(input)
480
+ end
481
+
482
+ def test_process_if
483
+ input = t(:if,
484
+ t(:call,
485
+ t(:lit, 1),
486
+ :==,
487
+ t(:arglist, t(:lit, 2))),
488
+ t(:str, "not equal"),
489
+ nil)
490
+ output = t(:if,
491
+ t(:call,
492
+ t(:lit, 1, Type.long),
493
+ :==,
494
+ t(:arglist,
495
+ t(:lit, 2, Type.long)),
496
+ Type.bool),
497
+ t(:str, "not equal", Type.str),
498
+ nil,
499
+ Type.str)
500
+
501
+ assert_equal output, @type_checker.process(input)
502
+ end
503
+
504
+ def test_process_if_else
505
+ input = t(:if,
506
+ t(:call,
507
+ t(:lit, 1),
508
+ :==,
509
+ t(:arglist, t(:lit, 2))),
510
+ t(:str, "not equal"),
511
+ t(:str, "equal"))
512
+ output = t(:if,
513
+ t(:call,
514
+ t(:lit, 1, Type.long),
515
+ :==,
516
+ t(:arglist, t(:lit, 2, Type.long)),
517
+ Type.bool),
518
+ t(:str, "not equal", Type.str),
519
+ t(:str, "equal", Type.str),
520
+ Type.str)
521
+
522
+ assert_equal output, @type_checker.process(input)
523
+ end
524
+
525
+ def test_process_iter
526
+ @type_checker.env.extend
527
+ var_type = Type.long_list
528
+ add_fake_var :array, var_type
529
+ input = t(:iter,
530
+ t(:call,
531
+ t(:lvar, :array),
532
+ :each,
533
+ nil),
534
+ t(:dasgn_curr, :x),
535
+ t(:call,
536
+ nil,
537
+ :puts,
538
+ t(:arglist,
539
+ t(:call,
540
+ t(:dvar, :x),
541
+ :to_s,
542
+ nil))))
543
+ output = t(:iter,
544
+ t(:call,
545
+ t(:lvar, :array, var_type),
546
+ :each,
547
+ nil,
548
+ Type.unknown),
549
+ t(:dasgn_curr, :x, Type.long),
550
+ t(:call,
551
+ nil,
552
+ :puts,
553
+ t(:arglist,
554
+ t(:call,
555
+ t(:dvar, :x, Type.long),
556
+ :to_s,
557
+ nil,
558
+ Type.str)),
559
+ Type.void),
560
+ Type.void)
561
+
562
+ assert_equal output, @type_checker.process(input)
563
+ end
564
+
565
+ def test_process_ivar
566
+ @type_checker.env.add :@blah, Type.long
567
+ input = s(:ivar, :@blah)
568
+ expected = t(:ivar, :@blah, Type.long)
569
+
570
+ assert_equal expected, @type_checker.process(input)
571
+ end
572
+
573
+ def test_process_lasgn
574
+ @type_checker.env.extend # FIX: this is a design flaw... examine irb sess:
575
+ # require 'sexp_processor'
576
+ # require 'type_checker'
577
+ # tc = TypeChecker.new
578
+ # s = t(:lasgn, :var, t(:str, "foo"))
579
+ # tc.process(s)
580
+ # => raises
581
+ # tc.env.extend
582
+ # tc.process(s)
583
+ # => raises elsewhere... etc etc etc
584
+ # makes debugging very difficult
585
+ input = t(:lasgn, :var, t(:str, "foo"))
586
+ output = t(:lasgn, :var,
587
+ t(:str, "foo", Type.str),
588
+ Type.str)
589
+
590
+ assert_equal output, @type_checker.process(input)
591
+ end
592
+
593
+ def test_process_lasgn_array
594
+ @type_checker.env.extend
595
+ input = t(:lasgn,
596
+ :var,
597
+ t(:array,
598
+ t(:str, "foo"),
599
+ t(:str, "bar")))
600
+ output = t(:lasgn, :var,
601
+ t(:array,
602
+ t(:str, "foo", Type.str),
603
+ t(:str, "bar", Type.str)),
604
+ Type.str_list)
605
+
606
+ assert_equal output, @type_checker.process(input)
607
+ end
608
+
609
+ def test_process_lit_long
610
+ input = t(:lit, 1)
611
+ output = t(:lit, 1, Type.long)
612
+
613
+ assert_equal output, @type_checker.process(input)
614
+ end
615
+
616
+ def test_process_lit_sym
617
+ input = t(:lit, :sym)
618
+ output = t(:lit, :sym, Type.symbol)
619
+
620
+ assert_equal output, @type_checker.process(input)
621
+ end
622
+
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
+ def test_process_lvar
631
+ add_fake_var :arg, Type.long
632
+ input = t(:lvar, :arg)
633
+ output = t(:lvar, :arg, Type.long)
634
+
635
+ assert_equal output, @type_checker.process(input)
636
+ end
637
+
638
+ def test_process_nil
639
+ input = t(:nil)
640
+ output = t(:nil, Type.value)
641
+
642
+ assert_equal output, @type_checker.process(input)
643
+ end
644
+
645
+ def test_process_not
646
+ input = t(:not, t(:true))
647
+ output = t(:not, t(:true, Type.bool), Type.bool)
648
+
649
+ assert_equal output, @type_checker.process(input)
650
+ end
651
+
652
+ def test_process_or
653
+ input = t(:or, t(:true), t(:false))
654
+ output = t(:or, t(:true, Type.bool), t(:false, Type.bool), Type.bool)
655
+
656
+ assert_equal output, @type_checker.process(input)
657
+ end
658
+
659
+ def test_process_rescue
660
+ assert_raises RuntimeError do
661
+ @type_checker.process s(:rescue, s(:true), s(:true))
662
+ end
663
+ end
664
+
665
+ def test_process_return
666
+ input = t(:return, t(:nil))
667
+ output = t(:return, t(:nil, Type.value), Type.void)
668
+
669
+ assert_equal output, @type_checker.process(input)
670
+ end
671
+
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
+ def test_process_scope
688
+ input = t(:scope,
689
+ t(:block,
690
+ t(:return, t(:nil))))
691
+ output = t(:scope,
692
+ t(:block,
693
+ t(:return,
694
+ t(:nil, Type.value),
695
+ Type.void),
696
+ Type.unknown), # FIX ? do we care about block?
697
+ Type.void)
698
+
699
+ assert_equal output, @type_checker.process(input)
700
+ end
701
+
702
+ def test_process_scope_empty
703
+ input = t(:scope)
704
+ output = t(:scope, Type.void)
705
+
706
+ assert_equal output, @type_checker.process(input)
707
+ end
708
+
709
+ def test_process_true
710
+ input = t(:true)
711
+ output = t(:true, Type.bool)
712
+
713
+ assert_equal output, @type_checker.process(input)
714
+ end
715
+
716
+ def test_process_unless
717
+ input = t(:if,
718
+ t(:call,
719
+ t(:lit, 1),
720
+ :==,
721
+ t(:arglist, t(:lit, 2))),
722
+ nil,
723
+ t(:str, "equal"))
724
+ output = t(:if,
725
+ t(:call,
726
+ t(:lit, 1, Type.long),
727
+ :==,
728
+ t(:arglist,
729
+ t(:lit, 2, Type.long)),
730
+ Type.bool),
731
+ nil,
732
+ t(:str, "equal", Type.str),
733
+ Type.str)
734
+
735
+ assert_equal output, @type_checker.process(input)
736
+ end
737
+
738
+ def test_process_while
739
+ input = t(:while, t(:true), t(:call, t(:lit, 1), :to_s, nil), true)
740
+ expected = t(:while,
741
+ t(:true, Type.bool),
742
+ t(:call, t(:lit, 1, Type.long), :to_s, nil,
743
+ Type.str), true)
744
+
745
+ assert_equal expected, @type_checker.process(input)
746
+ end
747
+
748
+ def add_fake_function(name, reciever_type, return_type, *arg_types)
749
+ @type_checker.functions.add_function(name,
750
+ Type.function(reciever_type, arg_types, return_type))
751
+ end
752
+
753
+ def add_fake_var(name, type)
754
+ @type_checker.env.extend
755
+ @type_checker.env.add name, type
756
+ end
757
+
758
+ def add_fake_gvar(name, type)
759
+ @type_checker.genv.add name, type
760
+ end
761
+
762
+ # HACK: this needs to be set up w/ determine args in test_type_checker
763
+ # "unknown_args" => {
764
+ # "ParseTree" => [:defn, :unknown_args,
765
+ # [:scope, [:block, [:args, :arg1, :arg2], [:return, [:lvar, :arg1]]]]],
766
+ # "Rewriter" => s(:defn, :unknown_args,
767
+ # s(:args, :arg1, :arg2),
768
+ # s(:scope,
769
+ # s(:block,
770
+ # s(:return, s(:lvar, :arg1))))),
771
+ # "TypeChecker" => t(:defn, :unknown_args,
772
+ # t(:args,
773
+ # t(:arg1, Type.long),
774
+ # t(:arg2, Type.str)),
775
+ # t(:scope,
776
+ # t(:block,
777
+ # t(:return,
778
+ # t(:lvar,
779
+ # :arg1,
780
+ # Type.long),
781
+ # Type.void),
782
+ # Type.unknown),
783
+ # Type.void),
784
+ # Type.function(Type.unknown, [Type.long, Type.str], Type.long)),
785
+ # "R2CRewriter" => :same,
786
+ # "RubyToC" => "long
787
+ # unknown_args(long arg1, str arg2) {
788
+ # return arg1;
789
+ # }",
790
+ # },
791
+
792
+ # "determine_args" => {
793
+ # "ParseTree" => [:defn, :determine_args,
794
+ # [:scope, [:block,
795
+ # [:args],
796
+ # [:call, [:lit, 5], :==,
797
+ # [:array,
798
+ # [:fcall, :unknown_args,
799
+ # [:array, [:lit, 4], [:str, "known"]]]]]]]],
800
+ # "Rewriter" => s(:defn, :determine_args,
801
+ # s(:args),
802
+ # s(:scope,
803
+ # s(:block,
804
+ # s(:call,
805
+ # s(:lit, 5), :==,
806
+ # s(:arglist, s(:call, nil,
807
+ # :unknown_args,
808
+ # s(:arglist,
809
+ # s(:lit, 4),
810
+ # s(:str, "known")))))))),
811
+ # "TypeChecker" => t(:defn, :determine_args,
812
+ # t(:args),
813
+ # t(:scope,
814
+ # t(:block,
815
+ # t(:call,
816
+ # t(:lit,
817
+ # 5,
818
+ # Type.long),
819
+ # :==,
820
+ # t(:arglist,
821
+ # t(:call,
822
+ # nil,
823
+ # :unknown_args,
824
+ # t(:arglist,
825
+ # t(:lit, 4, Type.long),
826
+ # t(:str, "known", Type.str)),
827
+ # Type.long)),
828
+ # Type.bool),
829
+ # Type.unknown),
830
+ # Type.void),
831
+ # Type.function(Type.unknown, [], Type.void)),
832
+ # "R2CRewriter" => :same,
833
+ # "RubyToC" => "void\ndetermine_args() {\n5 == unknown_args(4, \"known\");\n}",
834
+ # },
835
+
836
+
837
+ end
838
+