ruby2c 1.0.0.9 → 1.1.0
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 +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
|
-
|