ruby2c 1.0.0.9 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/type_checker.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  require 'pp'
3
2
  begin require 'rubygems'; rescue LoadError; end
4
3
  require 'ruby_parser'
@@ -9,7 +8,7 @@ require 'r2cenvironment'
9
8
  require 'type'
10
9
  require 'typed_sexp'
11
10
 
12
- # TODO: calls to sexp_type should probably be replaced w/ better Sexp API
11
+ # TODO: calls to c_type should probably be replaced w/ better Sexp API
13
12
 
14
13
  ##
15
14
  # TypeChecker bootstrap table.
@@ -105,21 +104,25 @@ class TypeChecker < SexpProcessor
105
104
  # for lower level types (in C) comes from.
106
105
 
107
106
  def bootstrap
108
- # @genv.add :$stdin, Type.file
109
- # @genv.add :$stdout, Type.file
110
- # @genv.add :$stderr, Type.file
107
+ # @genv.add :$stdin, CType.file
108
+ # @genv.add :$stdout, CType.file
109
+ # @genv.add :$stderr, CType.file
111
110
 
112
111
  $bootstrap.each do |name,signatures|
113
- # FIX: Using Type.send because it must go through method_missing, not new
112
+ # FIX: Using CType.send because it must go through method_missing, not new
114
113
  signatures.each do |signature|
115
- lhs_type = Type.send(signature[0])
116
- return_type = Type.send(signature[-1])
117
- arg_types = signature[1..-2].map { |t| Type.send(t) }
118
- @functions.add_function(name, Type.function(lhs_type, arg_types, return_type))
114
+ lhs_type = CType.send(signature[0])
115
+ return_type = CType.send(signature[-1])
116
+ arg_types = signature[1..-2].map { |t| CType.send(t) }
117
+ @functions.add_function(name, CType.function(lhs_type, arg_types, return_type))
119
118
  end
120
119
  end
121
120
  end
122
121
 
122
+ def process exp, _src = nil, _timeout = nil
123
+ super(exp)
124
+ end
125
+
123
126
  ##
124
127
  # Logical and unifies its two arguments, then returns a bool sexp.
125
128
 
@@ -127,13 +130,13 @@ class TypeChecker < SexpProcessor
127
130
  rhs = process exp.shift
128
131
  lhs = process exp.shift
129
132
 
130
- rhs_type = rhs.sexp_type
131
- lhs_type = lhs.sexp_type
133
+ rhs_type = rhs.c_type
134
+ lhs_type = lhs.c_type
132
135
 
133
136
  rhs_type.unify lhs_type
134
- rhs_type.unify Type.bool
137
+ rhs_type.unify CType.bool
135
138
 
136
- return t(:and, rhs, lhs, Type.bool)
139
+ return t(:and, rhs, lhs, CType.bool)
137
140
  end
138
141
 
139
142
  ##
@@ -146,7 +149,7 @@ class TypeChecker < SexpProcessor
146
149
 
147
150
  until exp.empty? do
148
151
  arg = exp.shift
149
- type = Type.unknown
152
+ type = CType.unknown
150
153
  @env.add arg, type
151
154
  formals << t(arg, type)
152
155
  types << type
@@ -173,7 +176,7 @@ class TypeChecker < SexpProcessor
173
176
  until exp.empty? do
174
177
  var = process exp.shift
175
178
  vars << var
176
- types << var.sexp_type
179
+ types << var.c_type
177
180
  end
178
181
  vars
179
182
  end
@@ -214,7 +217,7 @@ class TypeChecker < SexpProcessor
214
217
  # sexp.
215
218
 
216
219
  def process_block(exp)
217
- nodes = t(:block, Type.unknown)
220
+ nodes = t(:block, CType.unknown)
218
221
  until exp.empty? do
219
222
  nodes << process(exp.shift)
220
223
  end
@@ -228,7 +231,7 @@ class TypeChecker < SexpProcessor
228
231
  # TODO do something more sensible
229
232
 
230
233
  def process_block_arg(exp)
231
- t(:block_arg, exp.shift, Type.fucked)
234
+ t(:block_arg, exp.shift, CType.fucked)
232
235
  end
233
236
 
234
237
  ##
@@ -275,9 +278,9 @@ class TypeChecker < SexpProcessor
275
278
  []
276
279
  else
277
280
  if args.first == :arglist then
278
- args.sexp_types
281
+ args.c_types
279
282
  elsif args.first == :splat then
280
- [args.sexp_type]
283
+ [args.c_type]
281
284
  else
282
285
  raise "That's not a Ruby Sexp you handed me, I'm freaking out on: #{args.inspect}"
283
286
  end
@@ -288,15 +291,15 @@ class TypeChecker < SexpProcessor
288
291
  raise "lhs of === may not be nil" if lhs.nil?
289
292
  raise "rhs of === may not be nil" if rhs.nil?
290
293
  raise "Help! I can't figure out what kind of #=== comparison to use" if
291
- lhs.sexp_type.unknown? and rhs.sexp_type.unknown?
292
- equal_type = lhs.sexp_type.unknown? ? rhs.sexp_type : lhs.sexp_type
294
+ lhs.c_type.unknown? and rhs.c_type.unknown?
295
+ equal_type = lhs.c_type.unknown? ? rhs.c_type : lhs.c_type
293
296
  name = "case_equal_#{equal_type.list_type}".intern
294
297
  end
295
298
 
296
- return_type = Type.unknown
297
- lhs_type = lhs.nil? ? Type.unknown : lhs.sexp_type # TODO: maybe void instead of unknown
299
+ return_type = CType.unknown
300
+ lhs_type = lhs.nil? ? CType.unknown : lhs.c_type # TODO: maybe void instead of unknown
298
301
 
299
- function_type = Type.function(lhs_type, arg_types, return_type)
302
+ function_type = CType.function(lhs_type, arg_types, return_type)
300
303
  @functions.unify(name, function_type) do
301
304
  @functions.add_function(name, function_type)
302
305
  $stderr.puts "\nWARNING: function #{name} called w/o being defined. Registering #{function_type.inspect}" if $DEBUG
@@ -314,9 +317,9 @@ class TypeChecker < SexpProcessor
314
317
  name = exp.shift
315
318
  superclass = exp.shift
316
319
 
317
- @genv.add name, Type.zclass
320
+ @genv.add name, CType.zclass
318
321
 
319
- result = t(:class, Type.zclass)
322
+ result = t(:class, CType.zclass)
320
323
  result << name
321
324
  result << superclass
322
325
 
@@ -325,12 +328,12 @@ class TypeChecker < SexpProcessor
325
328
  klass = eval(name.to_s) # HACK do proper lookup - ugh
326
329
  klass.constants.each do |c|
327
330
  const_type = case klass.const_get(c)
328
- when Fixnum then
329
- Type.long
331
+ when Integer then
332
+ CType.long
330
333
  when String then
331
- Type.str
334
+ CType.str
332
335
  else
333
- Type.unknown
336
+ CType.unknown
334
337
  end
335
338
  @env.add c.intern, const_type
336
339
  end
@@ -348,7 +351,7 @@ class TypeChecker < SexpProcessor
348
351
 
349
352
  def process_colon2(exp) # (Module::Class/Module)
350
353
  name = process(exp.shift)
351
- return t(:colon2, name, exp.shift, Type.zclass)
354
+ return t(:colon2, name, exp.shift, CType.zclass)
352
355
  end
353
356
 
354
357
  ##
@@ -356,7 +359,7 @@ class TypeChecker < SexpProcessor
356
359
 
357
360
  def process_colon3(exp) # (::OUTER_CONST)
358
361
  name = exp.shift
359
- return t(:colon3, name, Type.const)
362
+ return t(:colon3, name, CType.const)
360
363
  end
361
364
 
362
365
  ##
@@ -387,7 +390,7 @@ class TypeChecker < SexpProcessor
387
390
  def process_cvar(exp)
388
391
  # TODO: we should treat these as globals and have them in the top scope
389
392
  name = exp.shift
390
- return t(:cvar, name, Type.unknown)
393
+ return t(:cvar, name, CType.unknown)
391
394
  end
392
395
 
393
396
  ##
@@ -398,7 +401,7 @@ class TypeChecker < SexpProcessor
398
401
  def process_cvasgn(exp)
399
402
  name = exp.shift
400
403
  val = process exp.shift
401
- return t(:cvasgn, name, val, Type.unknown)
404
+ return t(:cvasgn, name, val, CType.unknown)
402
405
  end
403
406
 
404
407
  ##
@@ -407,7 +410,7 @@ class TypeChecker < SexpProcessor
407
410
 
408
411
  def process_dasgn_curr(exp)
409
412
  name = exp.shift
410
- type = Type.unknown
413
+ type = CType.unknown
411
414
  @env.add name, type # HACK lookup before adding like lasgn
412
415
 
413
416
  return t(:dasgn_curr, name, type)
@@ -418,7 +421,7 @@ class TypeChecker < SexpProcessor
418
421
 
419
422
  def process_defined(exp)
420
423
  thing = process exp.shift
421
- return t(:defined, thing, Type.bool)
424
+ return t(:defined, thing, CType.bool)
422
425
  end
423
426
 
424
427
  def rewrite_defn(exp)
@@ -448,7 +451,7 @@ class TypeChecker < SexpProcessor
448
451
 
449
452
  # Function might already have been defined by a :call node.
450
453
  # TODO: figure out the receiver type? Is that possible at this stage?
451
- function_type = Type.function Type.unknown, args.sexp_types, Type.unknown
454
+ function_type = CType.function CType.unknown, args.c_types, CType.unknown
452
455
  @functions.unify(name, function_type) do
453
456
  @functions.add_function(name, function_type)
454
457
  $stderr.puts "\nWARNING: Registering function #{name}: #{function_type.inspect}" if $DEBUG
@@ -465,15 +468,15 @@ class TypeChecker < SexpProcessor
465
468
 
466
469
  return_count = 0
467
470
  body.each_of_type(:return) do |sub_exp|
468
- return_type.unify sub_exp[1].sexp_type
471
+ return_type.unify sub_exp[1].c_type
469
472
  return_count += 1
470
473
  end
471
- return_type.unify Type.void if return_count == 0
474
+ return_type.unify CType.void if return_count == 0
472
475
 
473
476
  # TODO: bad API, clean
474
477
  raise "wrong" if
475
- args.sexp_types.size != function_type.list_type.formal_types.size
476
- args.sexp_types.each_with_index do |type, i|
478
+ args.c_types.size != function_type.list_type.formal_types.size
479
+ args.c_types.each_with_index do |type, i|
477
480
  type.unify function_type.list_type.formal_types[i]
478
481
  end
479
482
 
@@ -485,7 +488,7 @@ class TypeChecker < SexpProcessor
485
488
  # string-typed sexp.
486
489
 
487
490
  def process_dstr(exp)
488
- out = t(:dstr, exp.shift, Type.str)
491
+ out = t(:dstr, exp.shift, CType.str)
489
492
  until exp.empty? do
490
493
  result = process exp.shift
491
494
  out << result
@@ -524,7 +527,7 @@ class TypeChecker < SexpProcessor
524
527
  # False returns a bool-typed sexp.
525
528
 
526
529
  def process_false(exp)
527
- return t(:false, Type.bool)
530
+ return t(:false, CType.bool)
528
531
  end
529
532
 
530
533
  ##
@@ -536,12 +539,12 @@ class TypeChecker < SexpProcessor
536
539
 
537
540
  var_type = @genv.lookup var rescue nil
538
541
  if var_type.nil? then
539
- @genv.add var, val.sexp_type
542
+ @genv.add var, val.c_type
540
543
  else
541
- val.sexp_type.unify var_type
544
+ val.c_type.unify var_type
542
545
  end
543
546
 
544
- return t(:gasgn, var, val, val.sexp_type)
547
+ return t(:gasgn, var, val, val.c_type)
545
548
  end
546
549
 
547
550
  ##
@@ -553,7 +556,7 @@ class TypeChecker < SexpProcessor
553
556
  name = exp.shift
554
557
  type = @genv.lookup name rescue nil
555
558
  if type.nil? then
556
- type = Type.unknown
559
+ type = CType.unknown
557
560
  @genv.add name, type
558
561
  end
559
562
  return t(:gvar, name, type)
@@ -566,7 +569,7 @@ class TypeChecker < SexpProcessor
566
569
  # TODO support inline hashes
567
570
 
568
571
  def process_hash(exp)
569
- result = t(:hash, Type.fucked)
572
+ result = t(:hash, CType.fucked)
570
573
  until exp.empty? do
571
574
  result << process(exp.shift)
572
575
  end
@@ -583,12 +586,12 @@ class TypeChecker < SexpProcessor
583
586
 
584
587
  var_type = @env.lookup var rescue nil
585
588
  if var_type.nil? then
586
- @env.add var, val.sexp_type
589
+ @env.add var, val.c_type
587
590
  else
588
- val.sexp_type.unify var_type
591
+ val.c_type.unify var_type
589
592
  end
590
593
 
591
- return t(:iasgn, var, val, val.sexp_type)
594
+ return t(:iasgn, var, val, val.c_type)
592
595
  end
593
596
 
594
597
  ##
@@ -601,17 +604,17 @@ class TypeChecker < SexpProcessor
601
604
  then_exp = process exp.shift
602
605
  else_exp = process exp.shift rescue nil # might be empty
603
606
 
604
- cond_exp.sexp_type.unify Type.bool
607
+ cond_exp.c_type.unify CType.bool
605
608
  begin
606
- then_exp.sexp_type.unify else_exp.sexp_type unless then_exp.nil? or else_exp.nil?
609
+ then_exp.c_type.unify else_exp.c_type unless then_exp.nil? or else_exp.nil?
607
610
  rescue TypeError
608
611
  puts "Error unifying #{then_exp.inspect} with #{else_exp.inspect}"
609
612
  raise
610
613
  end
611
614
 
612
615
  # FIX: at least document this
613
- type = then_exp.sexp_type unless then_exp.nil?
614
- type = else_exp.sexp_type unless else_exp.nil?
616
+ type = then_exp.c_type unless then_exp.nil?
617
+ type = else_exp.c_type unless else_exp.nil?
615
618
 
616
619
  return t(:if, cond_exp, then_exp, else_exp, type)
617
620
  end
@@ -648,15 +651,15 @@ class TypeChecker < SexpProcessor
648
651
  lhs = call_exp[1] # FIX
649
652
  if lhs.nil? then
650
653
  # We're an fcall getting passed a block.
651
- return t(:iter, call_exp, dargs_exp, body_exp, call_exp.sexp_type)
654
+ return t(:iter, call_exp, dargs_exp, body_exp, call_exp.c_type)
652
655
  else
653
- Type.unknown_list.unify lhs.sexp_type # force a list type, lhs must be Enum
656
+ CType.unknown_list.unify lhs.c_type # force a list type, lhs must be Enum
654
657
 
655
658
  dargs_exp.sexp_body.each do |subexp|
656
- Type.new(lhs.sexp_type.list_type).unify subexp.sexp_type
659
+ CType.new(lhs.c_type.list_type).unify subexp.c_type
657
660
  end
658
661
 
659
- return t(:iter, call_exp, dargs_exp, body_exp, Type.void)
662
+ return t(:iter, call_exp, dargs_exp, body_exp, CType.void)
660
663
  end
661
664
  end
662
665
 
@@ -671,7 +674,7 @@ class TypeChecker < SexpProcessor
671
674
 
672
675
  var_type = @env.lookup name rescue nil
673
676
  if var_type.nil? then
674
- var_type = Type.unknown
677
+ var_type = CType.unknown
675
678
  @env.add name, var_type
676
679
  end
677
680
 
@@ -690,7 +693,7 @@ class TypeChecker < SexpProcessor
690
693
  def process_lasgn(exp)
691
694
  name = exp.shift
692
695
  arg_exp = nil
693
- arg_type = Type.unknown
696
+ arg_type = CType.unknown
694
697
  var_type = @env.lookup name rescue nil
695
698
 
696
699
  unless exp.empty? then
@@ -700,14 +703,14 @@ class TypeChecker < SexpProcessor
700
703
 
701
704
  # if we've got an array in there, unify everything in it.
702
705
  if sub_exp_type == :array then
703
- arg_type = arg_exp.sexp_types
704
- arg_type = arg_type.inject(Type.unknown) do |t1, t2|
706
+ arg_type = arg_exp.c_types
707
+ arg_type = arg_type.inject(CType.unknown) do |t1, t2|
705
708
  t1.unify t2
706
709
  end
707
710
  arg_type = arg_type.dup # singleton type
708
711
  arg_type.list = true
709
712
  else
710
- arg_type = arg_exp.sexp_type
713
+ arg_type = arg_exp.c_type
711
714
  end
712
715
  end
713
716
 
@@ -729,18 +732,18 @@ class TypeChecker < SexpProcessor
729
732
  type = nil
730
733
 
731
734
  case value
732
- when Fixnum then
733
- type = Type.long
735
+ when Integer then
736
+ type = CType.long
734
737
  when Float then
735
- type = Type.float
738
+ type = CType.float
736
739
  when Symbol then
737
- type = Type.symbol
740
+ type = CType.symbol
738
741
  when Regexp then
739
- type = Type.regexp
742
+ type = CType.regexp
740
743
  when Range then
741
- type = Type.range
744
+ type = CType.range
742
745
  when Const then
743
- type = Type.const
746
+ type = CType.const
744
747
  else
745
748
  raise "Bug! no: Unknown literal #{value}:#{value.class}"
746
749
  end
@@ -770,15 +773,15 @@ class TypeChecker < SexpProcessor
770
773
 
771
774
  mlhs_values.zip(mrhs_values) do |lasgn, value|
772
775
  if value.nil? then
773
- lasgn.sexp_type.unify Type.value # nil
776
+ lasgn.c_type.unify CType.value # nil
774
777
  else
775
- lasgn.sexp_type.unify value.sexp_type
778
+ lasgn.c_type.unify value.c_type
776
779
  end
777
780
  end
778
781
 
779
782
  if mlhs_values.length < mrhs_values.length then
780
783
  last_lasgn = mlhs_values.last
781
- last_lasgn.sexp_type.list = true
784
+ last_lasgn.c_type.list = true
782
785
  end
783
786
 
784
787
  return t(:masgn, mlhs, mrhs)
@@ -790,7 +793,7 @@ class TypeChecker < SexpProcessor
790
793
  def process_nil(exp)
791
794
  # don't do a fucking thing until... we have something to do
792
795
  # HACK: wtf to do here? (what type is nil?!?!)
793
- return t(:nil, Type.value)
796
+ return t(:nil, CType.value)
794
797
  end
795
798
 
796
799
  ##
@@ -799,8 +802,8 @@ class TypeChecker < SexpProcessor
799
802
 
800
803
  def process_not(exp)
801
804
  thing = process exp.shift
802
- thing.sexp_type.unify Type.bool
803
- return t(:not, thing, Type.bool)
805
+ thing.c_type.unify CType.bool
806
+ return t(:not, thing, CType.bool)
804
807
  end
805
808
 
806
809
  ##
@@ -821,13 +824,13 @@ class TypeChecker < SexpProcessor
821
824
  rhs = process exp.shift
822
825
  lhs = process exp.shift
823
826
 
824
- rhs_type = rhs.sexp_type
825
- lhs_type = lhs.sexp_type
827
+ rhs_type = rhs.c_type
828
+ lhs_type = lhs.c_type
826
829
 
827
830
  rhs_type.unify lhs_type
828
- rhs_type.unify Type.bool
831
+ rhs_type.unify CType.bool
829
832
 
830
- return t(:or, rhs, lhs, Type.bool)
833
+ return t(:or, rhs, lhs, CType.bool)
831
834
  end
832
835
 
833
836
  ##
@@ -838,7 +841,7 @@ class TypeChecker < SexpProcessor
838
841
  o2 = exp.empty? ? nil : process(exp.shift)
839
842
  o3 = exp.empty? ? nil : process(exp.shift)
840
843
 
841
- result = t(:resbody, Type.unknown) # void?
844
+ result = t(:resbody, CType.unknown) # void?
842
845
  result << o1
843
846
  result << o2 unless o2.nil?
844
847
  result << o3 unless o3.nil?
@@ -855,9 +858,9 @@ class TypeChecker < SexpProcessor
855
858
  rescue_block = process exp.shift
856
859
  els = exp.empty? ? nil : process(exp.shift)
857
860
 
858
- try_type = try_block.sexp_type
859
- rescue_type = rescue_block.sexp_type
860
- # ensure_type = els.sexp_type # HACK/FIX: not sure if I should unify
861
+ try_type = try_block.c_type
862
+ rescue_type = rescue_block.c_type
863
+ # ensure_type = els.c_type # HACK/FIX: not sure if I should unify
861
864
 
862
865
  try_type.unify rescue_type
863
866
  # try_type.unify ensure_type
@@ -869,7 +872,7 @@ class TypeChecker < SexpProcessor
869
872
  # Return returns a void typed sexp.
870
873
 
871
874
  def process_return(exp)
872
- result = t(:return, Type.void) # TODO why void - cuz this is a keyword
875
+ result = t(:return, CType.void) # TODO why void - cuz this is a keyword
873
876
  result << process(exp.shift) unless exp.empty?
874
877
  return result
875
878
  end
@@ -878,11 +881,11 @@ class TypeChecker < SexpProcessor
878
881
  # Scope returns a void-typed sexp.
879
882
 
880
883
  def process_scope(exp)
881
- return t(:scope, Type.void) if exp.empty?
884
+ return t(:scope, CType.void) if exp.empty?
882
885
 
883
886
  body = process exp.shift
884
887
 
885
- return t(:scope, body, Type.void)
888
+ return t(:scope, body, CType.void)
886
889
  end
887
890
 
888
891
  ##
@@ -891,7 +894,7 @@ class TypeChecker < SexpProcessor
891
894
  # TODO support self
892
895
 
893
896
  def process_self(exp)
894
- return t(:self, Type.unknown)
897
+ return t(:self, CType.unknown)
895
898
  end
896
899
 
897
900
  ##
@@ -901,14 +904,14 @@ class TypeChecker < SexpProcessor
901
904
 
902
905
  def process_splat(exp)
903
906
  value = process exp.shift
904
- return t(:splat, value, Type.unknown) # TODO: probably value_list?
907
+ return t(:splat, value, CType.unknown) # TODO: probably value_list?
905
908
  end
906
909
 
907
910
  ##
908
911
  # String literal returns a string-typed sexp.
909
912
 
910
913
  def process_str(exp)
911
- return t(:str, exp.shift, Type.str)
914
+ return t(:str, exp.shift, CType.str)
912
915
  end
913
916
 
914
917
  ##
@@ -919,7 +922,7 @@ class TypeChecker < SexpProcessor
919
922
  def process_super(exp)
920
923
  args = process exp.shift
921
924
  # TODO try to look up the method in our superclass?
922
- return t(:super, args, Type.unknown)
925
+ return t(:super, args, CType.unknown)
923
926
  end
924
927
 
925
928
  ##
@@ -932,8 +935,8 @@ class TypeChecker < SexpProcessor
932
935
  to_ary << process(exp.shift)
933
936
  end
934
937
 
935
- to_ary.sexp_type = to_ary[1].sexp_type.dup
936
- to_ary.sexp_type.list = true
938
+ to_ary.c_type = to_ary[1].c_type.dup
939
+ to_ary.c_type.list = true
937
940
 
938
941
  return to_ary
939
942
  end
@@ -942,7 +945,7 @@ class TypeChecker < SexpProcessor
942
945
  # True returns a bool-typed sexp.
943
946
 
944
947
  def process_true(exp)
945
- return t(:true, Type.bool)
948
+ return t(:true, CType.bool)
946
949
  end
947
950
 
948
951
  ##
@@ -952,7 +955,7 @@ class TypeChecker < SexpProcessor
952
955
  cond = process exp.shift
953
956
  body = process exp.shift
954
957
  is_precondition = exp.shift
955
- Type.bool.unify cond.sexp_type
958
+ CType.bool.unify cond.c_type
956
959
  return t(:while, cond, body, is_precondition)
957
960
  end
958
961
 
@@ -960,11 +963,10 @@ class TypeChecker < SexpProcessor
960
963
  # Yield is currently unsupported. Returns a unmentionably-typed sexp.
961
964
 
962
965
  def process_yield(exp)
963
- result = t(:yield, Type.fucked)
966
+ result = t(:yield, CType.fucked)
964
967
  until exp.empty? do
965
968
  result << process(exp.shift)
966
969
  end
967
970
  return result
968
971
  end
969
972
  end
970
-