ruby2c 1.0.0.9 → 1.1.1
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +1 -0
- data/History.txt +78 -53
- data/README.txt +1 -1
- data/Rakefile +2 -0
- data/lib/crewriter.rb +35 -23
- data/lib/r2cenvironment.rb +3 -3
- data/lib/rewriter.rb +6 -2
- data/lib/ruby_to_ansi_c.rb +18 -18
- data/lib/ruby_to_ruby_c.rb +3 -3
- data/lib/type.rb +3 -3
- data/lib/type_checker.rb +101 -99
- data/lib/typed_sexp.rb +49 -25
- data/test/r2ctestcase.rb +321 -288
- data/test/test_crewriter.rb +127 -128
- data/test/test_extras.rb +4 -4
- data/test/test_function_table.rb +23 -23
- data/test/test_function_type.rb +39 -40
- data/test/test_handle.rb +2 -2
- data/test/test_r2cenvironment.rb +38 -38
- data/test/test_ruby_to_ansi_c.rb +58 -58
- data/test/test_ruby_to_ruby_c.rb +26 -26
- data/test/test_type.rb +38 -38
- data/test/test_type_checker.rb +165 -165
- data/test/test_typed_sexp.rb +62 -54
- data.tar.gz.sig +2 -1
- metadata +101 -153
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
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
|
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,
|
109
|
-
# @genv.add :$stdout,
|
110
|
-
# @genv.add :$stderr,
|
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
|
112
|
+
# FIX: Using CType.send because it must go through method_missing, not new
|
114
113
|
signatures.each do |signature|
|
115
|
-
lhs_type =
|
116
|
-
return_type =
|
117
|
-
arg_types = signature[1..-2].map { |t|
|
118
|
-
@functions.add_function(name,
|
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.
|
131
|
-
lhs_type = lhs.
|
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
|
137
|
+
rhs_type.unify CType.bool
|
135
138
|
|
136
|
-
return t(:and, rhs, lhs,
|
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 =
|
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.
|
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,
|
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,
|
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.
|
281
|
+
args.c_types
|
279
282
|
elsif args.first == :splat then
|
280
|
-
[args.
|
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.
|
292
|
-
equal_type = lhs.
|
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 =
|
297
|
-
lhs_type = lhs.nil? ?
|
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 =
|
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,
|
320
|
+
@genv.add name, CType.zclass
|
318
321
|
|
319
|
-
result = t(:class,
|
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
|
329
|
-
|
331
|
+
when Integer then
|
332
|
+
CType.long
|
330
333
|
when String then
|
331
|
-
|
334
|
+
CType.str
|
332
335
|
else
|
333
|
-
|
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,
|
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,
|
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,
|
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,
|
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 =
|
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,
|
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 =
|
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].
|
471
|
+
return_type.unify sub_exp[1].c_type
|
469
472
|
return_count += 1
|
470
473
|
end
|
471
|
-
return_type.unify
|
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.
|
476
|
-
args.
|
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,
|
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,
|
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.
|
542
|
+
@genv.add var, val.c_type
|
540
543
|
else
|
541
|
-
val.
|
544
|
+
val.c_type.unify var_type
|
542
545
|
end
|
543
546
|
|
544
|
-
return t(:gasgn, var, val, val.
|
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 =
|
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,
|
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.
|
589
|
+
@env.add var, val.c_type
|
587
590
|
else
|
588
|
-
val.
|
591
|
+
val.c_type.unify var_type
|
589
592
|
end
|
590
593
|
|
591
|
-
return t(:iasgn, var, val, val.
|
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.
|
607
|
+
cond_exp.c_type.unify CType.bool
|
605
608
|
begin
|
606
|
-
then_exp.
|
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.
|
614
|
-
type = else_exp.
|
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.
|
654
|
+
return t(:iter, call_exp, dargs_exp, body_exp, call_exp.c_type)
|
652
655
|
else
|
653
|
-
|
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
|
-
|
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,
|
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 =
|
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 =
|
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.
|
704
|
-
arg_type = arg_type.inject(
|
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.
|
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
|
733
|
-
type =
|
735
|
+
when Integer then
|
736
|
+
type = CType.long
|
734
737
|
when Float then
|
735
|
-
type =
|
738
|
+
type = CType.float
|
736
739
|
when Symbol then
|
737
|
-
type =
|
740
|
+
type = CType.symbol
|
738
741
|
when Regexp then
|
739
|
-
type =
|
742
|
+
type = CType.regexp
|
740
743
|
when Range then
|
741
|
-
type =
|
744
|
+
type = CType.range
|
742
745
|
when Const then
|
743
|
-
type =
|
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.
|
776
|
+
lasgn.c_type.unify CType.value # nil
|
774
777
|
else
|
775
|
-
lasgn.
|
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.
|
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,
|
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.
|
803
|
-
return t(:not, thing,
|
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.
|
825
|
-
lhs_type = lhs.
|
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
|
831
|
+
rhs_type.unify CType.bool
|
829
832
|
|
830
|
-
return t(:or, rhs, lhs,
|
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,
|
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.
|
859
|
-
rescue_type = rescue_block.
|
860
|
-
# ensure_type = els.
|
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,
|
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,
|
884
|
+
return t(:scope, CType.void) if exp.empty?
|
882
885
|
|
883
886
|
body = process exp.shift
|
884
887
|
|
885
|
-
return t(:scope, body,
|
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,
|
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,
|
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,
|
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,
|
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.
|
936
|
-
to_ary.
|
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,
|
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
|
-
|
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,
|
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
|
-
|