ruby2c 1.0.0.9 → 1.1.0
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 +2 -0
- data.tar.gz.sig +1 -1
- data/History.txt +71 -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 +2 -2
- data/lib/ruby_to_ansi_c.rb +14 -18
- data/lib/ruby_to_ruby_c.rb +3 -3
- data/lib/type.rb +3 -3
- data/lib/type_checker.rb +97 -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
- metadata +97 -150
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
data/lib/ruby_to_ruby_c.rb
CHANGED
@@ -181,17 +181,17 @@ class RubyToRubyC < RubyToAnsiC
|
|
181
181
|
arg_count = value.length - 1 if value.first == :array
|
182
182
|
args = value
|
183
183
|
|
184
|
-
exp_type = exp.
|
184
|
+
exp_type = exp.c_type
|
185
185
|
@env.add var.to_sym, exp_type
|
186
186
|
|
187
187
|
if exp_type.list? then
|
188
188
|
assert_type args, :array
|
189
189
|
|
190
|
-
raise "array must be of one type" unless args.
|
190
|
+
raise "array must be of one type" unless args.c_type == CType.homo
|
191
191
|
|
192
192
|
args.shift # :arglist
|
193
193
|
# REFACTOR: this (here down) is the only diff w/ super
|
194
|
-
out << "#{var} = rb_ary_new2(#{
|
194
|
+
out << "#{var} = rb_ary_new2(#{arg_count});\n"
|
195
195
|
args.each_with_index do |o,i|
|
196
196
|
out << "rb_ary_store(#{var}, #{i}, #{process o});\n"
|
197
197
|
end
|
data/lib/type.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
require 'handle'
|
3
3
|
require 'function_type'
|
4
4
|
|
5
|
-
class
|
5
|
+
class CType
|
6
6
|
|
7
7
|
# REFACTOR: nuke this
|
8
8
|
KNOWN_TYPES = {
|
@@ -40,7 +40,7 @@ class Type
|
|
40
40
|
# TODO: gross, maybe go back to the *args version from method_missing
|
41
41
|
return_type = arg_types
|
42
42
|
arg_types = lhs_type
|
43
|
-
lhs_type =
|
43
|
+
lhs_type = CType.unknown
|
44
44
|
end
|
45
45
|
|
46
46
|
self.new FunctionType.new(lhs_type, arg_types, return_type)
|
@@ -52,7 +52,7 @@ class Type
|
|
52
52
|
|
53
53
|
def self.method_missing(type, *args)
|
54
54
|
raise "Unknown type Type.#{type} (#{type.inspect})" unless
|
55
|
-
|
55
|
+
KNOWN_TYPES.has_key?(type)
|
56
56
|
|
57
57
|
if type.to_s =~ /(.*)_list$/ then
|
58
58
|
TYPES[type] = self.new($1.intern, true) unless TYPES.has_key?(type)
|
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,17 +104,17 @@ 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
|
@@ -127,13 +126,13 @@ class TypeChecker < SexpProcessor
|
|
127
126
|
rhs = process exp.shift
|
128
127
|
lhs = process exp.shift
|
129
128
|
|
130
|
-
rhs_type = rhs.
|
131
|
-
lhs_type = lhs.
|
129
|
+
rhs_type = rhs.c_type
|
130
|
+
lhs_type = lhs.c_type
|
132
131
|
|
133
132
|
rhs_type.unify lhs_type
|
134
|
-
rhs_type.unify
|
133
|
+
rhs_type.unify CType.bool
|
135
134
|
|
136
|
-
return t(:and, rhs, lhs,
|
135
|
+
return t(:and, rhs, lhs, CType.bool)
|
137
136
|
end
|
138
137
|
|
139
138
|
##
|
@@ -146,7 +145,7 @@ class TypeChecker < SexpProcessor
|
|
146
145
|
|
147
146
|
until exp.empty? do
|
148
147
|
arg = exp.shift
|
149
|
-
type =
|
148
|
+
type = CType.unknown
|
150
149
|
@env.add arg, type
|
151
150
|
formals << t(arg, type)
|
152
151
|
types << type
|
@@ -173,7 +172,7 @@ class TypeChecker < SexpProcessor
|
|
173
172
|
until exp.empty? do
|
174
173
|
var = process exp.shift
|
175
174
|
vars << var
|
176
|
-
types << var.
|
175
|
+
types << var.c_type
|
177
176
|
end
|
178
177
|
vars
|
179
178
|
end
|
@@ -214,7 +213,7 @@ class TypeChecker < SexpProcessor
|
|
214
213
|
# sexp.
|
215
214
|
|
216
215
|
def process_block(exp)
|
217
|
-
nodes = t(:block,
|
216
|
+
nodes = t(:block, CType.unknown)
|
218
217
|
until exp.empty? do
|
219
218
|
nodes << process(exp.shift)
|
220
219
|
end
|
@@ -228,7 +227,7 @@ class TypeChecker < SexpProcessor
|
|
228
227
|
# TODO do something more sensible
|
229
228
|
|
230
229
|
def process_block_arg(exp)
|
231
|
-
t(:block_arg, exp.shift,
|
230
|
+
t(:block_arg, exp.shift, CType.fucked)
|
232
231
|
end
|
233
232
|
|
234
233
|
##
|
@@ -275,9 +274,9 @@ class TypeChecker < SexpProcessor
|
|
275
274
|
[]
|
276
275
|
else
|
277
276
|
if args.first == :arglist then
|
278
|
-
args.
|
277
|
+
args.c_types
|
279
278
|
elsif args.first == :splat then
|
280
|
-
[args.
|
279
|
+
[args.c_type]
|
281
280
|
else
|
282
281
|
raise "That's not a Ruby Sexp you handed me, I'm freaking out on: #{args.inspect}"
|
283
282
|
end
|
@@ -288,15 +287,15 @@ class TypeChecker < SexpProcessor
|
|
288
287
|
raise "lhs of === may not be nil" if lhs.nil?
|
289
288
|
raise "rhs of === may not be nil" if rhs.nil?
|
290
289
|
raise "Help! I can't figure out what kind of #=== comparison to use" if
|
291
|
-
lhs.
|
292
|
-
equal_type = lhs.
|
290
|
+
lhs.c_type.unknown? and rhs.c_type.unknown?
|
291
|
+
equal_type = lhs.c_type.unknown? ? rhs.c_type : lhs.c_type
|
293
292
|
name = "case_equal_#{equal_type.list_type}".intern
|
294
293
|
end
|
295
294
|
|
296
|
-
return_type =
|
297
|
-
lhs_type = lhs.nil? ?
|
295
|
+
return_type = CType.unknown
|
296
|
+
lhs_type = lhs.nil? ? CType.unknown : lhs.c_type # TODO: maybe void instead of unknown
|
298
297
|
|
299
|
-
function_type =
|
298
|
+
function_type = CType.function(lhs_type, arg_types, return_type)
|
300
299
|
@functions.unify(name, function_type) do
|
301
300
|
@functions.add_function(name, function_type)
|
302
301
|
$stderr.puts "\nWARNING: function #{name} called w/o being defined. Registering #{function_type.inspect}" if $DEBUG
|
@@ -314,9 +313,9 @@ class TypeChecker < SexpProcessor
|
|
314
313
|
name = exp.shift
|
315
314
|
superclass = exp.shift
|
316
315
|
|
317
|
-
@genv.add name,
|
316
|
+
@genv.add name, CType.zclass
|
318
317
|
|
319
|
-
result = t(:class,
|
318
|
+
result = t(:class, CType.zclass)
|
320
319
|
result << name
|
321
320
|
result << superclass
|
322
321
|
|
@@ -325,12 +324,12 @@ class TypeChecker < SexpProcessor
|
|
325
324
|
klass = eval(name.to_s) # HACK do proper lookup - ugh
|
326
325
|
klass.constants.each do |c|
|
327
326
|
const_type = case klass.const_get(c)
|
328
|
-
when
|
329
|
-
|
327
|
+
when Integer then
|
328
|
+
CType.long
|
330
329
|
when String then
|
331
|
-
|
330
|
+
CType.str
|
332
331
|
else
|
333
|
-
|
332
|
+
CType.unknown
|
334
333
|
end
|
335
334
|
@env.add c.intern, const_type
|
336
335
|
end
|
@@ -348,7 +347,7 @@ class TypeChecker < SexpProcessor
|
|
348
347
|
|
349
348
|
def process_colon2(exp) # (Module::Class/Module)
|
350
349
|
name = process(exp.shift)
|
351
|
-
return t(:colon2, name, exp.shift,
|
350
|
+
return t(:colon2, name, exp.shift, CType.zclass)
|
352
351
|
end
|
353
352
|
|
354
353
|
##
|
@@ -356,7 +355,7 @@ class TypeChecker < SexpProcessor
|
|
356
355
|
|
357
356
|
def process_colon3(exp) # (::OUTER_CONST)
|
358
357
|
name = exp.shift
|
359
|
-
return t(:colon3, name,
|
358
|
+
return t(:colon3, name, CType.const)
|
360
359
|
end
|
361
360
|
|
362
361
|
##
|
@@ -387,7 +386,7 @@ class TypeChecker < SexpProcessor
|
|
387
386
|
def process_cvar(exp)
|
388
387
|
# TODO: we should treat these as globals and have them in the top scope
|
389
388
|
name = exp.shift
|
390
|
-
return t(:cvar, name,
|
389
|
+
return t(:cvar, name, CType.unknown)
|
391
390
|
end
|
392
391
|
|
393
392
|
##
|
@@ -398,7 +397,7 @@ class TypeChecker < SexpProcessor
|
|
398
397
|
def process_cvasgn(exp)
|
399
398
|
name = exp.shift
|
400
399
|
val = process exp.shift
|
401
|
-
return t(:cvasgn, name, val,
|
400
|
+
return t(:cvasgn, name, val, CType.unknown)
|
402
401
|
end
|
403
402
|
|
404
403
|
##
|
@@ -407,7 +406,7 @@ class TypeChecker < SexpProcessor
|
|
407
406
|
|
408
407
|
def process_dasgn_curr(exp)
|
409
408
|
name = exp.shift
|
410
|
-
type =
|
409
|
+
type = CType.unknown
|
411
410
|
@env.add name, type # HACK lookup before adding like lasgn
|
412
411
|
|
413
412
|
return t(:dasgn_curr, name, type)
|
@@ -418,7 +417,7 @@ class TypeChecker < SexpProcessor
|
|
418
417
|
|
419
418
|
def process_defined(exp)
|
420
419
|
thing = process exp.shift
|
421
|
-
return t(:defined, thing,
|
420
|
+
return t(:defined, thing, CType.bool)
|
422
421
|
end
|
423
422
|
|
424
423
|
def rewrite_defn(exp)
|
@@ -448,7 +447,7 @@ class TypeChecker < SexpProcessor
|
|
448
447
|
|
449
448
|
# Function might already have been defined by a :call node.
|
450
449
|
# TODO: figure out the receiver type? Is that possible at this stage?
|
451
|
-
function_type =
|
450
|
+
function_type = CType.function CType.unknown, args.c_types, CType.unknown
|
452
451
|
@functions.unify(name, function_type) do
|
453
452
|
@functions.add_function(name, function_type)
|
454
453
|
$stderr.puts "\nWARNING: Registering function #{name}: #{function_type.inspect}" if $DEBUG
|
@@ -465,15 +464,15 @@ class TypeChecker < SexpProcessor
|
|
465
464
|
|
466
465
|
return_count = 0
|
467
466
|
body.each_of_type(:return) do |sub_exp|
|
468
|
-
return_type.unify sub_exp[1].
|
467
|
+
return_type.unify sub_exp[1].c_type
|
469
468
|
return_count += 1
|
470
469
|
end
|
471
|
-
return_type.unify
|
470
|
+
return_type.unify CType.void if return_count == 0
|
472
471
|
|
473
472
|
# TODO: bad API, clean
|
474
473
|
raise "wrong" if
|
475
|
-
args.
|
476
|
-
args.
|
474
|
+
args.c_types.size != function_type.list_type.formal_types.size
|
475
|
+
args.c_types.each_with_index do |type, i|
|
477
476
|
type.unify function_type.list_type.formal_types[i]
|
478
477
|
end
|
479
478
|
|
@@ -485,7 +484,7 @@ class TypeChecker < SexpProcessor
|
|
485
484
|
# string-typed sexp.
|
486
485
|
|
487
486
|
def process_dstr(exp)
|
488
|
-
out = t(:dstr, exp.shift,
|
487
|
+
out = t(:dstr, exp.shift, CType.str)
|
489
488
|
until exp.empty? do
|
490
489
|
result = process exp.shift
|
491
490
|
out << result
|
@@ -524,7 +523,7 @@ class TypeChecker < SexpProcessor
|
|
524
523
|
# False returns a bool-typed sexp.
|
525
524
|
|
526
525
|
def process_false(exp)
|
527
|
-
return t(:false,
|
526
|
+
return t(:false, CType.bool)
|
528
527
|
end
|
529
528
|
|
530
529
|
##
|
@@ -536,12 +535,12 @@ class TypeChecker < SexpProcessor
|
|
536
535
|
|
537
536
|
var_type = @genv.lookup var rescue nil
|
538
537
|
if var_type.nil? then
|
539
|
-
@genv.add var, val.
|
538
|
+
@genv.add var, val.c_type
|
540
539
|
else
|
541
|
-
val.
|
540
|
+
val.c_type.unify var_type
|
542
541
|
end
|
543
542
|
|
544
|
-
return t(:gasgn, var, val, val.
|
543
|
+
return t(:gasgn, var, val, val.c_type)
|
545
544
|
end
|
546
545
|
|
547
546
|
##
|
@@ -553,7 +552,7 @@ class TypeChecker < SexpProcessor
|
|
553
552
|
name = exp.shift
|
554
553
|
type = @genv.lookup name rescue nil
|
555
554
|
if type.nil? then
|
556
|
-
type =
|
555
|
+
type = CType.unknown
|
557
556
|
@genv.add name, type
|
558
557
|
end
|
559
558
|
return t(:gvar, name, type)
|
@@ -566,7 +565,7 @@ class TypeChecker < SexpProcessor
|
|
566
565
|
# TODO support inline hashes
|
567
566
|
|
568
567
|
def process_hash(exp)
|
569
|
-
result = t(:hash,
|
568
|
+
result = t(:hash, CType.fucked)
|
570
569
|
until exp.empty? do
|
571
570
|
result << process(exp.shift)
|
572
571
|
end
|
@@ -583,12 +582,12 @@ class TypeChecker < SexpProcessor
|
|
583
582
|
|
584
583
|
var_type = @env.lookup var rescue nil
|
585
584
|
if var_type.nil? then
|
586
|
-
@env.add var, val.
|
585
|
+
@env.add var, val.c_type
|
587
586
|
else
|
588
|
-
val.
|
587
|
+
val.c_type.unify var_type
|
589
588
|
end
|
590
589
|
|
591
|
-
return t(:iasgn, var, val, val.
|
590
|
+
return t(:iasgn, var, val, val.c_type)
|
592
591
|
end
|
593
592
|
|
594
593
|
##
|
@@ -601,17 +600,17 @@ class TypeChecker < SexpProcessor
|
|
601
600
|
then_exp = process exp.shift
|
602
601
|
else_exp = process exp.shift rescue nil # might be empty
|
603
602
|
|
604
|
-
cond_exp.
|
603
|
+
cond_exp.c_type.unify CType.bool
|
605
604
|
begin
|
606
|
-
then_exp.
|
605
|
+
then_exp.c_type.unify else_exp.c_type unless then_exp.nil? or else_exp.nil?
|
607
606
|
rescue TypeError
|
608
607
|
puts "Error unifying #{then_exp.inspect} with #{else_exp.inspect}"
|
609
608
|
raise
|
610
609
|
end
|
611
610
|
|
612
611
|
# FIX: at least document this
|
613
|
-
type = then_exp.
|
614
|
-
type = else_exp.
|
612
|
+
type = then_exp.c_type unless then_exp.nil?
|
613
|
+
type = else_exp.c_type unless else_exp.nil?
|
615
614
|
|
616
615
|
return t(:if, cond_exp, then_exp, else_exp, type)
|
617
616
|
end
|
@@ -648,15 +647,15 @@ class TypeChecker < SexpProcessor
|
|
648
647
|
lhs = call_exp[1] # FIX
|
649
648
|
if lhs.nil? then
|
650
649
|
# We're an fcall getting passed a block.
|
651
|
-
return t(:iter, call_exp, dargs_exp, body_exp, call_exp.
|
650
|
+
return t(:iter, call_exp, dargs_exp, body_exp, call_exp.c_type)
|
652
651
|
else
|
653
|
-
|
652
|
+
CType.unknown_list.unify lhs.c_type # force a list type, lhs must be Enum
|
654
653
|
|
655
654
|
dargs_exp.sexp_body.each do |subexp|
|
656
|
-
|
655
|
+
CType.new(lhs.c_type.list_type).unify subexp.c_type
|
657
656
|
end
|
658
657
|
|
659
|
-
return t(:iter, call_exp, dargs_exp, body_exp,
|
658
|
+
return t(:iter, call_exp, dargs_exp, body_exp, CType.void)
|
660
659
|
end
|
661
660
|
end
|
662
661
|
|
@@ -671,7 +670,7 @@ class TypeChecker < SexpProcessor
|
|
671
670
|
|
672
671
|
var_type = @env.lookup name rescue nil
|
673
672
|
if var_type.nil? then
|
674
|
-
var_type =
|
673
|
+
var_type = CType.unknown
|
675
674
|
@env.add name, var_type
|
676
675
|
end
|
677
676
|
|
@@ -690,7 +689,7 @@ class TypeChecker < SexpProcessor
|
|
690
689
|
def process_lasgn(exp)
|
691
690
|
name = exp.shift
|
692
691
|
arg_exp = nil
|
693
|
-
arg_type =
|
692
|
+
arg_type = CType.unknown
|
694
693
|
var_type = @env.lookup name rescue nil
|
695
694
|
|
696
695
|
unless exp.empty? then
|
@@ -700,14 +699,14 @@ class TypeChecker < SexpProcessor
|
|
700
699
|
|
701
700
|
# if we've got an array in there, unify everything in it.
|
702
701
|
if sub_exp_type == :array then
|
703
|
-
arg_type = arg_exp.
|
704
|
-
arg_type = arg_type.inject(
|
702
|
+
arg_type = arg_exp.c_types
|
703
|
+
arg_type = arg_type.inject(CType.unknown) do |t1, t2|
|
705
704
|
t1.unify t2
|
706
705
|
end
|
707
706
|
arg_type = arg_type.dup # singleton type
|
708
707
|
arg_type.list = true
|
709
708
|
else
|
710
|
-
arg_type = arg_exp.
|
709
|
+
arg_type = arg_exp.c_type
|
711
710
|
end
|
712
711
|
end
|
713
712
|
|
@@ -729,18 +728,18 @@ class TypeChecker < SexpProcessor
|
|
729
728
|
type = nil
|
730
729
|
|
731
730
|
case value
|
732
|
-
when
|
733
|
-
type =
|
731
|
+
when Integer then
|
732
|
+
type = CType.long
|
734
733
|
when Float then
|
735
|
-
type =
|
734
|
+
type = CType.float
|
736
735
|
when Symbol then
|
737
|
-
type =
|
736
|
+
type = CType.symbol
|
738
737
|
when Regexp then
|
739
|
-
type =
|
738
|
+
type = CType.regexp
|
740
739
|
when Range then
|
741
|
-
type =
|
740
|
+
type = CType.range
|
742
741
|
when Const then
|
743
|
-
type =
|
742
|
+
type = CType.const
|
744
743
|
else
|
745
744
|
raise "Bug! no: Unknown literal #{value}:#{value.class}"
|
746
745
|
end
|
@@ -770,15 +769,15 @@ class TypeChecker < SexpProcessor
|
|
770
769
|
|
771
770
|
mlhs_values.zip(mrhs_values) do |lasgn, value|
|
772
771
|
if value.nil? then
|
773
|
-
lasgn.
|
772
|
+
lasgn.c_type.unify CType.value # nil
|
774
773
|
else
|
775
|
-
lasgn.
|
774
|
+
lasgn.c_type.unify value.c_type
|
776
775
|
end
|
777
776
|
end
|
778
777
|
|
779
778
|
if mlhs_values.length < mrhs_values.length then
|
780
779
|
last_lasgn = mlhs_values.last
|
781
|
-
last_lasgn.
|
780
|
+
last_lasgn.c_type.list = true
|
782
781
|
end
|
783
782
|
|
784
783
|
return t(:masgn, mlhs, mrhs)
|
@@ -790,7 +789,7 @@ class TypeChecker < SexpProcessor
|
|
790
789
|
def process_nil(exp)
|
791
790
|
# don't do a fucking thing until... we have something to do
|
792
791
|
# HACK: wtf to do here? (what type is nil?!?!)
|
793
|
-
return t(:nil,
|
792
|
+
return t(:nil, CType.value)
|
794
793
|
end
|
795
794
|
|
796
795
|
##
|
@@ -799,8 +798,8 @@ class TypeChecker < SexpProcessor
|
|
799
798
|
|
800
799
|
def process_not(exp)
|
801
800
|
thing = process exp.shift
|
802
|
-
thing.
|
803
|
-
return t(:not, thing,
|
801
|
+
thing.c_type.unify CType.bool
|
802
|
+
return t(:not, thing, CType.bool)
|
804
803
|
end
|
805
804
|
|
806
805
|
##
|
@@ -821,13 +820,13 @@ class TypeChecker < SexpProcessor
|
|
821
820
|
rhs = process exp.shift
|
822
821
|
lhs = process exp.shift
|
823
822
|
|
824
|
-
rhs_type = rhs.
|
825
|
-
lhs_type = lhs.
|
823
|
+
rhs_type = rhs.c_type
|
824
|
+
lhs_type = lhs.c_type
|
826
825
|
|
827
826
|
rhs_type.unify lhs_type
|
828
|
-
rhs_type.unify
|
827
|
+
rhs_type.unify CType.bool
|
829
828
|
|
830
|
-
return t(:or, rhs, lhs,
|
829
|
+
return t(:or, rhs, lhs, CType.bool)
|
831
830
|
end
|
832
831
|
|
833
832
|
##
|
@@ -838,7 +837,7 @@ class TypeChecker < SexpProcessor
|
|
838
837
|
o2 = exp.empty? ? nil : process(exp.shift)
|
839
838
|
o3 = exp.empty? ? nil : process(exp.shift)
|
840
839
|
|
841
|
-
result = t(:resbody,
|
840
|
+
result = t(:resbody, CType.unknown) # void?
|
842
841
|
result << o1
|
843
842
|
result << o2 unless o2.nil?
|
844
843
|
result << o3 unless o3.nil?
|
@@ -855,9 +854,9 @@ class TypeChecker < SexpProcessor
|
|
855
854
|
rescue_block = process exp.shift
|
856
855
|
els = exp.empty? ? nil : process(exp.shift)
|
857
856
|
|
858
|
-
try_type = try_block.
|
859
|
-
rescue_type = rescue_block.
|
860
|
-
# ensure_type = els.
|
857
|
+
try_type = try_block.c_type
|
858
|
+
rescue_type = rescue_block.c_type
|
859
|
+
# ensure_type = els.c_type # HACK/FIX: not sure if I should unify
|
861
860
|
|
862
861
|
try_type.unify rescue_type
|
863
862
|
# try_type.unify ensure_type
|
@@ -869,7 +868,7 @@ class TypeChecker < SexpProcessor
|
|
869
868
|
# Return returns a void typed sexp.
|
870
869
|
|
871
870
|
def process_return(exp)
|
872
|
-
result = t(:return,
|
871
|
+
result = t(:return, CType.void) # TODO why void - cuz this is a keyword
|
873
872
|
result << process(exp.shift) unless exp.empty?
|
874
873
|
return result
|
875
874
|
end
|
@@ -878,11 +877,11 @@ class TypeChecker < SexpProcessor
|
|
878
877
|
# Scope returns a void-typed sexp.
|
879
878
|
|
880
879
|
def process_scope(exp)
|
881
|
-
return t(:scope,
|
880
|
+
return t(:scope, CType.void) if exp.empty?
|
882
881
|
|
883
882
|
body = process exp.shift
|
884
883
|
|
885
|
-
return t(:scope, body,
|
884
|
+
return t(:scope, body, CType.void)
|
886
885
|
end
|
887
886
|
|
888
887
|
##
|
@@ -891,7 +890,7 @@ class TypeChecker < SexpProcessor
|
|
891
890
|
# TODO support self
|
892
891
|
|
893
892
|
def process_self(exp)
|
894
|
-
return t(:self,
|
893
|
+
return t(:self, CType.unknown)
|
895
894
|
end
|
896
895
|
|
897
896
|
##
|
@@ -901,14 +900,14 @@ class TypeChecker < SexpProcessor
|
|
901
900
|
|
902
901
|
def process_splat(exp)
|
903
902
|
value = process exp.shift
|
904
|
-
return t(:splat, value,
|
903
|
+
return t(:splat, value, CType.unknown) # TODO: probably value_list?
|
905
904
|
end
|
906
905
|
|
907
906
|
##
|
908
907
|
# String literal returns a string-typed sexp.
|
909
908
|
|
910
909
|
def process_str(exp)
|
911
|
-
return t(:str, exp.shift,
|
910
|
+
return t(:str, exp.shift, CType.str)
|
912
911
|
end
|
913
912
|
|
914
913
|
##
|
@@ -919,7 +918,7 @@ class TypeChecker < SexpProcessor
|
|
919
918
|
def process_super(exp)
|
920
919
|
args = process exp.shift
|
921
920
|
# TODO try to look up the method in our superclass?
|
922
|
-
return t(:super, args,
|
921
|
+
return t(:super, args, CType.unknown)
|
923
922
|
end
|
924
923
|
|
925
924
|
##
|
@@ -932,8 +931,8 @@ class TypeChecker < SexpProcessor
|
|
932
931
|
to_ary << process(exp.shift)
|
933
932
|
end
|
934
933
|
|
935
|
-
to_ary.
|
936
|
-
to_ary.
|
934
|
+
to_ary.c_type = to_ary[1].c_type.dup
|
935
|
+
to_ary.c_type.list = true
|
937
936
|
|
938
937
|
return to_ary
|
939
938
|
end
|
@@ -942,7 +941,7 @@ class TypeChecker < SexpProcessor
|
|
942
941
|
# True returns a bool-typed sexp.
|
943
942
|
|
944
943
|
def process_true(exp)
|
945
|
-
return t(:true,
|
944
|
+
return t(:true, CType.bool)
|
946
945
|
end
|
947
946
|
|
948
947
|
##
|
@@ -952,7 +951,7 @@ class TypeChecker < SexpProcessor
|
|
952
951
|
cond = process exp.shift
|
953
952
|
body = process exp.shift
|
954
953
|
is_precondition = exp.shift
|
955
|
-
|
954
|
+
CType.bool.unify cond.c_type
|
956
955
|
return t(:while, cond, body, is_precondition)
|
957
956
|
end
|
958
957
|
|
@@ -960,11 +959,10 @@ class TypeChecker < SexpProcessor
|
|
960
959
|
# Yield is currently unsupported. Returns a unmentionably-typed sexp.
|
961
960
|
|
962
961
|
def process_yield(exp)
|
963
|
-
result = t(:yield,
|
962
|
+
result = t(:yield, CType.fucked)
|
964
963
|
until exp.empty? do
|
965
964
|
result << process(exp.shift)
|
966
965
|
end
|
967
966
|
return result
|
968
967
|
end
|
969
968
|
end
|
970
|
-
|