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.
- 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
|
-
|