ruby2c 1.0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +1 -0
- data/.autotest +21 -0
- data/History.txt +173 -0
- data/Manifest.txt +35 -0
- data/README.txt +76 -0
- data/Rakefile +21 -0
- data/demo/char.rb +13 -0
- data/demo/factorial.rb +11 -0
- data/demo/hello.rb +11 -0
- data/demo/misc.rb +25 -0
- data/demo/newarray.rb +11 -0
- data/demo/strcat.rb +12 -0
- data/lib/crewriter.rb +199 -0
- data/lib/function_table.rb +45 -0
- data/lib/function_type.rb +46 -0
- data/lib/handle.rb +14 -0
- data/lib/r2cenvironment.rb +59 -0
- data/lib/rewriter.rb +35 -0
- data/lib/ruby_to_ansi_c.rb +673 -0
- data/lib/ruby_to_ruby_c.rb +382 -0
- data/lib/type.rb +148 -0
- data/lib/type_checker.rb +920 -0
- data/lib/typed_sexp.rb +88 -0
- data/test/r2ctestcase.rb +1196 -0
- data/test/test_crewriter.rb +328 -0
- data/test/test_extras.rb +68 -0
- data/test/test_function_table.rb +90 -0
- data/test/test_function_type.rb +125 -0
- data/test/test_handle.rb +39 -0
- data/test/test_r2cenvironment.rb +191 -0
- data/test/test_rewriter.rb +16 -0
- data/test/test_ruby_to_ansi_c.rb +487 -0
- data/test/test_ruby_to_ruby_c.rb +161 -0
- data/test/test_type.rb +193 -0
- data/test/test_type_checker.rb +805 -0
- data/test/test_typed_sexp.rb +138 -0
- metadata +164 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'minitest/autorun' if $0 == __FILE__
|
6
|
+
require 'minitest/unit'
|
7
|
+
require 'function_type'
|
8
|
+
require 'type'
|
9
|
+
|
10
|
+
class TestFunctionType < MiniTest::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@function_type = FunctionType.new Type.void, [Type.long, Type.str], Type.value
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_formal_types
|
16
|
+
assert_equal [Type.long, Type.str], @function_type.formal_types
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_formal_types=
|
20
|
+
@function_type.formal_types = [Type.str, Type.long]
|
21
|
+
assert_equal [Type.str, Type.long], @function_type.formal_types
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_receiver_type
|
25
|
+
assert_equal Type.void, @function_type.receiver_type
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_receiver_type=
|
29
|
+
@function_type.receiver_type = Type.str
|
30
|
+
assert_equal Type.str, @function_type.receiver_type
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_return_type
|
34
|
+
assert_equal Type.value, @function_type.return_type
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_return_type=
|
38
|
+
@function_type.return_type = Type.long
|
39
|
+
assert_equal Type.long, @function_type.return_type
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_equals
|
43
|
+
funs = []
|
44
|
+
funs << FunctionType.new(Type.unknown, [], Type.unknown)
|
45
|
+
funs << FunctionType.new(Type.unknown, [Type.unknown], Type.unknown)
|
46
|
+
funs << FunctionType.new(Type.unknown, [], Type.long)
|
47
|
+
funs << FunctionType.new(Type.unknown, [Type.long], Type.unknown)
|
48
|
+
funs << FunctionType.new(Type.unknown, [Type.long], Type.long)
|
49
|
+
funs << FunctionType.new(Type.unknown, [Type.unknown, Type.unknown], Type.unknown)
|
50
|
+
funs << FunctionType.new(Type.unknown, [Type.long, Type.unknown], Type.unknown)
|
51
|
+
funs << FunctionType.new(Type.unknown, [Type.long, Type.long], Type.long)
|
52
|
+
#funs << FunctionType.new(Type.unknown, [], Type.long)
|
53
|
+
|
54
|
+
funs.each_with_index do |fun1, i|
|
55
|
+
funs.each_with_index do |fun2, j|
|
56
|
+
if i == j then
|
57
|
+
assert_equal fun1, fun2
|
58
|
+
else
|
59
|
+
refute_equal fun1, fun2
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_unify_components
|
66
|
+
fun1 = FunctionType.new(Type.unknown, [Type.unknown], Type.unknown)
|
67
|
+
fun2 = FunctionType.new(Type.long, [Type.long], Type.long)
|
68
|
+
fun1.unify_components fun2
|
69
|
+
assert_equal fun2, fun1
|
70
|
+
|
71
|
+
fun3 = FunctionType.new(Type.unknown, [Type.long], Type.unknown)
|
72
|
+
fun4 = FunctionType.new(Type.long, [Type.unknown], Type.long)
|
73
|
+
fun3.unify_components fun4
|
74
|
+
assert_equal fun4, fun3
|
75
|
+
|
76
|
+
fun5 = FunctionType.new(Type.unknown, [], Type.unknown)
|
77
|
+
fun6 = FunctionType.new(Type.long, [], Type.long)
|
78
|
+
fun5.unify_components fun6
|
79
|
+
assert_equal fun6, fun5
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_initialize_fail
|
83
|
+
assert_raises(RuntimeError) do
|
84
|
+
FunctionType.new(Type.unknown, nil, Type.long)
|
85
|
+
end
|
86
|
+
|
87
|
+
assert_raises(RuntimeError)do
|
88
|
+
FunctionType.new(Type.unknown, [], nil)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_unify_components_fail
|
93
|
+
fun1 = FunctionType.new(Type.long, [Type.str], Type.unknown)
|
94
|
+
fun2 = FunctionType.new(Type.unknown, [Type.long], Type.long)
|
95
|
+
assert_raises(TypeError) do
|
96
|
+
fun1.unify_components fun2
|
97
|
+
end
|
98
|
+
|
99
|
+
fun3 = FunctionType.new(Type.long, [], Type.unknown)
|
100
|
+
fun4 = FunctionType.new(Type.unknown, [Type.unknown], Type.long)
|
101
|
+
assert_raises(TypeError) do
|
102
|
+
fun3.unify_components fun4
|
103
|
+
end
|
104
|
+
|
105
|
+
fun5 = FunctionType.new(Type.long, [Type.unknown], Type.unknown)
|
106
|
+
fun6 = FunctionType.new(Type.unknown, [], Type.long)
|
107
|
+
assert_raises(TypeError) do
|
108
|
+
fun5.unify_components fun6
|
109
|
+
end
|
110
|
+
|
111
|
+
fun7 = FunctionType.new(Type.long, [], Type.str)
|
112
|
+
fun8 = FunctionType.new(Type.unknown, [], Type.long)
|
113
|
+
assert_raises(TypeError) do
|
114
|
+
fun7.unify_components fun8
|
115
|
+
end
|
116
|
+
|
117
|
+
fun9 = FunctionType.new(Type.long, [], Type.str)
|
118
|
+
funa = FunctionType.new(Type.str, [], Type.unknown)
|
119
|
+
assert_raises(TypeError) do
|
120
|
+
fun7.unify_components fun8
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
data/test/test_handle.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'minitest/autorun' if $0 == __FILE__
|
6
|
+
require 'minitest/unit'
|
7
|
+
require 'handle'
|
8
|
+
|
9
|
+
class TestHandle < MiniTest::Unit::TestCase
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@handle = Handle.new("text")
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_contents
|
16
|
+
assert_equal "text", @handle.contents
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_contents=
|
20
|
+
@handle.contents = "new text"
|
21
|
+
assert_equal "new text", @handle.contents
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_equals
|
25
|
+
obj = "foo"
|
26
|
+
handle1 = Handle.new obj
|
27
|
+
handle2 = Handle.new obj
|
28
|
+
assert_equal handle1, handle2
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_equals_reassign
|
32
|
+
obj = "foo"
|
33
|
+
handle2 = Handle.new obj
|
34
|
+
@handle.contents = obj
|
35
|
+
assert_equal @handle, handle2
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,191 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'minitest/autorun' if $0 == __FILE__
|
6
|
+
require 'minitest/unit'
|
7
|
+
require 'r2cenvironment'
|
8
|
+
require 'type'
|
9
|
+
|
10
|
+
class TestR2CEnvironment < MiniTest::Unit::TestCase
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@env = R2CEnvironment.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_add
|
17
|
+
assert_equal Type.long, @env.add(:var, Type.long)
|
18
|
+
assert_equal Type.long, @env.lookup(:var)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_add_depth
|
22
|
+
@env.scope do
|
23
|
+
assert_equal Type.long, @env.add(:var, Type.long, 1)
|
24
|
+
end
|
25
|
+
assert_equal Type.long, @env.lookup(:var)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_add_raises_on_illegal
|
29
|
+
assert_raises RuntimeError do
|
30
|
+
@env.add nil, Type.long
|
31
|
+
end
|
32
|
+
|
33
|
+
assert_raises RuntimeError do
|
34
|
+
@env.add 1, :foo
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_add_segmented
|
39
|
+
@env.scope do
|
40
|
+
@env.add :var, Type.long
|
41
|
+
assert_equal Type.long, @env.lookup(:var)
|
42
|
+
end
|
43
|
+
|
44
|
+
assert_raises NameError do
|
45
|
+
@env.lookup(:var)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_current
|
50
|
+
@env.add :var, Type.long
|
51
|
+
@env.set_val :var, 42
|
52
|
+
|
53
|
+
expected = { :var => [Type.long, 42] }
|
54
|
+
assert_equal expected, @env.current
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_all
|
58
|
+
@env.scope do
|
59
|
+
@env.add :x, Type.long
|
60
|
+
|
61
|
+
@env.scope do
|
62
|
+
@env.add :y, Type.str
|
63
|
+
@env.add :x, Type.float
|
64
|
+
|
65
|
+
expected = { :x => [Type.float], :y => [Type.str] }
|
66
|
+
assert_equal expected, @env.all
|
67
|
+
end
|
68
|
+
|
69
|
+
expected = { :x => [Type.long] }
|
70
|
+
assert_equal expected, @env.all
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_depth
|
75
|
+
assert_equal 1, @env.depth
|
76
|
+
|
77
|
+
@env.scope do
|
78
|
+
assert_equal 2, @env.depth
|
79
|
+
end
|
80
|
+
|
81
|
+
assert_equal 1, @env.depth
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_env
|
85
|
+
assert_equal [{}], @env.env
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_get_val
|
89
|
+
@env.add :var, Type.long
|
90
|
+
@env.set_val :var, 42
|
91
|
+
|
92
|
+
assert_equal 42, @env.get_val(:var)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_set_val
|
96
|
+
@env.add :var, Type.long
|
97
|
+
assert_equal 42, @env.set_val(:var, 42)
|
98
|
+
|
99
|
+
assert_equal 42, @env.get_val(:var)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_set_val_static_array
|
103
|
+
@env.add :var, Type.long
|
104
|
+
assert_equal "[2]", @env.set_val(:var, "[2]")
|
105
|
+
|
106
|
+
assert_equal "[2]", @env.get_val(:var)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_get_val_unset
|
110
|
+
@env.add :var, Type.long
|
111
|
+
|
112
|
+
assert_nil @env.get_val(:var)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_get_val_unknown
|
116
|
+
assert_raises(NameError) do
|
117
|
+
@env.get_val(:unknown)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_extend
|
122
|
+
assert_equal [{}], @env.env
|
123
|
+
|
124
|
+
@env.extend
|
125
|
+
assert_equal [{}, {}], @env.env
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_lookup
|
129
|
+
@env.add :var, Type.long
|
130
|
+
assert_equal Type.long, @env.lookup(:var)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_lookup_raises
|
134
|
+
assert_raises NameError do
|
135
|
+
@env.lookup(:var)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_lookup_scope
|
140
|
+
@env.add :var, Type.long
|
141
|
+
assert_equal Type.long, @env.lookup(:var)
|
142
|
+
|
143
|
+
@env.scope do
|
144
|
+
assert_equal Type.long, @env.lookup(:var)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_scope
|
149
|
+
@env.add :var, Type.long
|
150
|
+
assert_equal Type.long, @env.lookup(:var)
|
151
|
+
|
152
|
+
@env.scope do
|
153
|
+
@env.add :var, Type.float
|
154
|
+
assert_equal Type.float, @env.lookup(:var)
|
155
|
+
end
|
156
|
+
|
157
|
+
assert_equal Type.long, @env.lookup(:var)
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_scope_raise
|
161
|
+
@env.add :a, Type.float
|
162
|
+
|
163
|
+
begin
|
164
|
+
@env.scope do
|
165
|
+
@env.add :a, Type.long
|
166
|
+
@env.add :b, Type.long
|
167
|
+
raise "woo"
|
168
|
+
end
|
169
|
+
rescue
|
170
|
+
# should replicate baddies
|
171
|
+
end
|
172
|
+
|
173
|
+
expected = { :a => [Type.float] }
|
174
|
+
assert_equal expected, @env.all
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_unextend
|
178
|
+
@env.extend
|
179
|
+
|
180
|
+
@env.add :var, Type.long
|
181
|
+
|
182
|
+
assert_equal Type.long, @env.lookup(:var)
|
183
|
+
|
184
|
+
@env.unextend
|
185
|
+
|
186
|
+
assert_raises NameError do
|
187
|
+
@env.lookup :var
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'minitest/autorun' if $0 == __FILE__
|
6
|
+
require 'rewriter'
|
7
|
+
require 'r2ctestcase'
|
8
|
+
|
9
|
+
ParseTreeTestCase.testcase_order << "Rewriter"
|
10
|
+
|
11
|
+
class TestRewriter < R2CTestCase
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
@processor = Rewriter.new
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,487 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
|
5
|
+
require 'minitest/autorun' if $0 == __FILE__
|
6
|
+
require 'ruby_to_ansi_c'
|
7
|
+
require 'r2ctestcase'
|
8
|
+
|
9
|
+
class TestRubyToAnsiC < R2CTestCase
|
10
|
+
def setup
|
11
|
+
@ruby_to_c = RubyToAnsiC.new
|
12
|
+
@ruby_to_c.env.extend
|
13
|
+
@processor = @ruby_to_c
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_c_type_bool
|
17
|
+
assert_equal "bool", @ruby_to_c.class.c_type(Type.bool)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_c_type_float
|
21
|
+
assert_equal "double", @ruby_to_c.class.c_type(Type.float)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_c_type_long
|
25
|
+
assert_equal "long", @ruby_to_c.class.c_type(Type.long)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_c_type_long_list
|
29
|
+
assert_equal "long *", @ruby_to_c.class.c_type(Type.long_list)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_c_type_str
|
33
|
+
assert_equal "str", @ruby_to_c.class.c_type(Type.str)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_c_type_str_list
|
37
|
+
assert_equal "str *", @ruby_to_c.class.c_type(Type.str_list)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_c_type_symbol
|
41
|
+
assert_equal "symbol", @ruby_to_c.class.c_type(Type.symbol)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_c_type_unknown
|
45
|
+
assert_equal "void *", @ruby_to_c.class.c_type(Type.unknown)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_c_type_value
|
49
|
+
assert_equal "void *", @ruby_to_c.class.c_type(Type.value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_c_type_void
|
53
|
+
assert_equal "void", @ruby_to_c.class.c_type(Type.void)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_env
|
57
|
+
refute_nil @ruby_to_c.env
|
58
|
+
assert_kind_of Environment, @ruby_to_c.env
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_process_and
|
62
|
+
input = t(:and, t(:lit, 1, Type.long), t(:lit, 2, Type.long))
|
63
|
+
output = "1 && 2"
|
64
|
+
|
65
|
+
assert_equal output, @ruby_to_c.process(input)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_process_args_empty
|
69
|
+
input = t(:args)
|
70
|
+
output = "()"
|
71
|
+
|
72
|
+
assert_equal output, @ruby_to_c.process(input)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_process_args_normal
|
76
|
+
input = t(:args,
|
77
|
+
t(:foo, Type.long),
|
78
|
+
t(:bar, Type.long))
|
79
|
+
output = "(long foo, long bar)"
|
80
|
+
|
81
|
+
assert_equal output, @ruby_to_c.process(input)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_process_array_empty
|
85
|
+
input = t(:array)
|
86
|
+
output = "rb_ary_new()"
|
87
|
+
|
88
|
+
assert_equal output, @ruby_to_c.process(input)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_process_array_multiple
|
92
|
+
input = t(:array,
|
93
|
+
t(:lvar, :arg1, Type.long),
|
94
|
+
t(:lvar, :arg2, Type.long))
|
95
|
+
output = "arg1, arg2"
|
96
|
+
|
97
|
+
assert_equal output, @ruby_to_c.process(input)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_process_array_single
|
101
|
+
input = t(:array,
|
102
|
+
t(:lvar, :arg1, Type.long))
|
103
|
+
output = "arg1"
|
104
|
+
|
105
|
+
assert_equal output, @ruby_to_c.process(input)
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_process_block
|
109
|
+
input = t(:block, t(:return, t(:nil)))
|
110
|
+
output = "return NULL;\n"
|
111
|
+
|
112
|
+
assert_equal output, @ruby_to_c.process(input)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_process_block_multiple
|
116
|
+
input = t(:block,
|
117
|
+
t(:str, "foo"),
|
118
|
+
t(:return, t(:nil)))
|
119
|
+
output = "\"foo\";\nreturn NULL;\n"
|
120
|
+
|
121
|
+
assert_equal output, @ruby_to_c.process(input)
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_process_call
|
125
|
+
input = t(:call, nil, :name, nil)
|
126
|
+
output = "name()"
|
127
|
+
|
128
|
+
assert_equal output, @ruby_to_c.process(input)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_process_call_lhs
|
132
|
+
input = t(:call, t(:lit, 1, Type.long), :name, nil)
|
133
|
+
output = "name(1)"
|
134
|
+
|
135
|
+
assert_equal output, @ruby_to_c.process(input)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_process_call_lhs_rhs
|
139
|
+
input = t(:call,
|
140
|
+
t(:lit, 1, Type.long),
|
141
|
+
:name,
|
142
|
+
t(:array, t(:str, "foo")))
|
143
|
+
output = "name(1, \"foo\")"
|
144
|
+
|
145
|
+
assert_equal output, @ruby_to_c.process(input)
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_process_call_nil?
|
149
|
+
input = t(:call,
|
150
|
+
t(:lvar, :arg, Type.long),
|
151
|
+
:nil?,
|
152
|
+
nil)
|
153
|
+
output = "arg"
|
154
|
+
|
155
|
+
assert_equal output, @ruby_to_c.process(input)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_process_call_operator
|
159
|
+
methods = t(:==, :<, :>, :-, :+, :*, :/, :%, :<=, :>=)
|
160
|
+
|
161
|
+
methods.each do |method|
|
162
|
+
input = t(:call,
|
163
|
+
t(:lit, 1, Type.long),
|
164
|
+
method,
|
165
|
+
t(:array, t(:lit, 2, Type.long)))
|
166
|
+
output = "1 #{method} 2"
|
167
|
+
|
168
|
+
assert_equal output, @ruby_to_c.process(input)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_process_call_rhs
|
173
|
+
input = t(:call,
|
174
|
+
nil,
|
175
|
+
:name,
|
176
|
+
t(:array,
|
177
|
+
t(:str, "foo")))
|
178
|
+
output = "name(\"foo\")"
|
179
|
+
|
180
|
+
assert_equal output, @ruby_to_c.process(input)
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_process_dasgn_curr
|
184
|
+
input = t(:dasgn_curr, :x, Type.long)
|
185
|
+
output = "x"
|
186
|
+
|
187
|
+
assert_equal output, @ruby_to_c.process(input)
|
188
|
+
# HACK - see test_type_checker equivalent test
|
189
|
+
# assert_equal Type.long, @ruby_to_c.env.lookup("x")
|
190
|
+
end
|
191
|
+
|
192
|
+
# TODO: fix for 1.8.2
|
193
|
+
def test_process_defn
|
194
|
+
input = t(:defn,
|
195
|
+
:empty,
|
196
|
+
t(:args),
|
197
|
+
t(:scope),
|
198
|
+
Type.function([], Type.void))
|
199
|
+
output = "void\nempty() {\n}"
|
200
|
+
assert_equal output, @ruby_to_c.process(input)
|
201
|
+
|
202
|
+
assert_equal ["void empty();\n"], @ruby_to_c.prototypes
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_process_defn_with_args_and_body
|
207
|
+
input = t(:defn, :empty,
|
208
|
+
t(:args,
|
209
|
+
t(:foo, Type.long),
|
210
|
+
t(:bar, Type.long)),
|
211
|
+
t(:scope,
|
212
|
+
t(:block,
|
213
|
+
t(:lit, 5, Type.long))),
|
214
|
+
Type.function([], Type.void))
|
215
|
+
output = "void\nempty(long foo, long bar) {\n5;\n}"
|
216
|
+
|
217
|
+
assert_equal output, @ruby_to_c.process(input)
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_process_dvar
|
221
|
+
input = t(:dvar, :dvar, Type.long)
|
222
|
+
output = "dvar"
|
223
|
+
|
224
|
+
assert_equal output, @ruby_to_c.process(input)
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_process_false
|
228
|
+
input = t(:false)
|
229
|
+
output = "0"
|
230
|
+
|
231
|
+
assert_equal output, @ruby_to_c.process(input)
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_process_gvar
|
235
|
+
input = t(:gvar, :$stderr, Type.long)
|
236
|
+
output = "stderr"
|
237
|
+
|
238
|
+
assert_equal output, @ruby_to_c.process(input)
|
239
|
+
assert_raises RuntimeError do
|
240
|
+
@ruby_to_c.process t(:gvar, :$some_gvar, Type.long)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_process_iasgn
|
245
|
+
input = t(:iasgn, :@blah, t(:lit, 42, Type.long), Type.long)
|
246
|
+
expected = "self->blah = 42"
|
247
|
+
|
248
|
+
assert_equal expected, @ruby_to_c.process(input)
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_process_if
|
252
|
+
input = t(:if,
|
253
|
+
t(:call,
|
254
|
+
t(:lit, 1, Type.long),
|
255
|
+
:==,
|
256
|
+
t(:array, t(:lit, 2, Type.long))),
|
257
|
+
t(:str, "not equal"),
|
258
|
+
nil)
|
259
|
+
output = "if (1 == 2) {\n\"not equal\";\n}"
|
260
|
+
|
261
|
+
assert_equal output, @ruby_to_c.process(input)
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_process_if_block
|
265
|
+
input = t(:if,
|
266
|
+
t(:call,
|
267
|
+
t(:lit, 1, Type.long),
|
268
|
+
:==,
|
269
|
+
t(:array, t(:lit, 2, Type.long))),
|
270
|
+
t(:block,
|
271
|
+
t(:lit, 5, Type.long),
|
272
|
+
t(:str, "not equal")),
|
273
|
+
nil)
|
274
|
+
output = "if (1 == 2) {\n5;\n\"not equal\";\n}"
|
275
|
+
|
276
|
+
assert_equal output, @ruby_to_c.process(input)
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_process_if_else
|
280
|
+
input = t(:if,
|
281
|
+
t(:call,
|
282
|
+
t(:lit, 1, Type.long),
|
283
|
+
:==,
|
284
|
+
t(:array, t(:lit, 2, Type.long))),
|
285
|
+
t(:str, "not equal"),
|
286
|
+
t(:str, "equal"))
|
287
|
+
output = "if (1 == 2) {\n\"not equal\";\n} else {\n\"equal\";\n}"
|
288
|
+
|
289
|
+
assert_equal output, @ruby_to_c.process(input)
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_process_ivar
|
293
|
+
@ruby_to_c.env.add :@blah, Type.long
|
294
|
+
input = t(:ivar, :@blah, Type.long)
|
295
|
+
expected = "self->blah"
|
296
|
+
|
297
|
+
assert_equal expected, @ruby_to_c.process(input)
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_process_lasgn
|
301
|
+
input = t(:lasgn, :var, t(:str, "foo"), Type.str)
|
302
|
+
output = "var = \"foo\""
|
303
|
+
|
304
|
+
assert_equal output, @ruby_to_c.process(input)
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_process_lit_float
|
308
|
+
input = t(:lit, 1.0, Type.float)
|
309
|
+
output = "1.0"
|
310
|
+
|
311
|
+
assert_equal output, @ruby_to_c.process(input)
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_process_lit_long
|
315
|
+
input = t(:lit, 1, Type.long)
|
316
|
+
output = "1"
|
317
|
+
|
318
|
+
assert_equal output, @ruby_to_c.process(input)
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_process_lit_sym
|
322
|
+
input = t(:lit, :sym, Type.symbol)
|
323
|
+
output = "\"sym\""
|
324
|
+
|
325
|
+
assert_equal output, @ruby_to_c.process(input)
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_process_lvar
|
329
|
+
input = t(:lvar, :arg, Type.long)
|
330
|
+
output = "arg"
|
331
|
+
|
332
|
+
assert_equal output, @ruby_to_c.process(input)
|
333
|
+
end
|
334
|
+
|
335
|
+
def test_process_nil
|
336
|
+
input = t(:nil)
|
337
|
+
output = "NULL"
|
338
|
+
|
339
|
+
assert_equal output, @ruby_to_c.process(input)
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_process_not
|
343
|
+
input = t(:not, t(:true, Type.bool), Type.bool)
|
344
|
+
output = "!(1)"
|
345
|
+
|
346
|
+
assert_equal output, @ruby_to_c.process(input)
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_process_or
|
350
|
+
input = t(:or, t(:lit, 1, Type.long), t(:lit, 2, Type.long))
|
351
|
+
output = "1 || 2"
|
352
|
+
|
353
|
+
assert_equal output, @ruby_to_c.process(input)
|
354
|
+
end
|
355
|
+
|
356
|
+
def test_process_return
|
357
|
+
input = t(:return, t(:nil))
|
358
|
+
output = "return NULL"
|
359
|
+
|
360
|
+
assert_equal output, @ruby_to_c.process(input)
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_process_scope
|
364
|
+
input = t(:scope,
|
365
|
+
t(:block,
|
366
|
+
t(:return, t(:nil))))
|
367
|
+
output = "{\nreturn NULL;\n}"
|
368
|
+
|
369
|
+
assert_equal output, @ruby_to_c.process(input)
|
370
|
+
end
|
371
|
+
|
372
|
+
def test_process_scope_empty
|
373
|
+
input = t(:scope)
|
374
|
+
output = "{\n}"
|
375
|
+
|
376
|
+
assert_equal output, @ruby_to_c.process(input)
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_process_scope_var_set
|
380
|
+
input = t(:scope, t(:block,
|
381
|
+
t(:lasgn, :arg,
|
382
|
+
t(:str, "declare me"),
|
383
|
+
Type.str),
|
384
|
+
t(:return, t(:nil))))
|
385
|
+
output = "{\nstr arg;\narg = \"declare me\";\nreturn NULL;\n}"
|
386
|
+
|
387
|
+
assert_equal output, @ruby_to_c.process(input)
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_process_str
|
391
|
+
input = t(:str, "foo", Type.str)
|
392
|
+
output = "\"foo\""
|
393
|
+
|
394
|
+
assert_equal output, @ruby_to_c.process(input)
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_process_str_backslashed
|
398
|
+
input = t(:str, "foo\nbar", Type.str)
|
399
|
+
output = "\"foo\\nbar\""
|
400
|
+
|
401
|
+
assert_equal output, @ruby_to_c.process(input)
|
402
|
+
end
|
403
|
+
|
404
|
+
def test_process_str_multi
|
405
|
+
input = t(:str, "foo
|
406
|
+
bar", Type.str)
|
407
|
+
output = "\"foo\\nbar\""
|
408
|
+
|
409
|
+
assert_equal output, @ruby_to_c.process(input)
|
410
|
+
end
|
411
|
+
|
412
|
+
def test_process_true
|
413
|
+
input = t(:true)
|
414
|
+
output = "1"
|
415
|
+
|
416
|
+
assert_equal output, @ruby_to_c.process(input)
|
417
|
+
end
|
418
|
+
|
419
|
+
def test_process_unless
|
420
|
+
input = t(:if,
|
421
|
+
t(:call,
|
422
|
+
t(:lit, 1, Type.long),
|
423
|
+
:==,
|
424
|
+
t(:array, t(:lit, 2, Type.long))),
|
425
|
+
nil,
|
426
|
+
t(:str, "equal"))
|
427
|
+
output = "if (1 == 2) {\n;\n} else {\n\"equal\";\n}"
|
428
|
+
|
429
|
+
assert_equal output, @ruby_to_c.process(input)
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_process_while
|
433
|
+
input = t(:while,
|
434
|
+
t(:call, t(:lvar, :n), :<=, t(:array, t(:lit, 3, Type.long))),
|
435
|
+
t(:block,
|
436
|
+
t(:call,
|
437
|
+
nil,
|
438
|
+
:puts,
|
439
|
+
t(:array,
|
440
|
+
t(:call,
|
441
|
+
t(:lvar, :n),
|
442
|
+
:to_s,
|
443
|
+
nil))),
|
444
|
+
t(:lasgn, :n,
|
445
|
+
t(:call,
|
446
|
+
t(:lvar, :n),
|
447
|
+
:+,
|
448
|
+
t(:array,
|
449
|
+
t(:lit, 1, Type.long))),
|
450
|
+
Type.long)), true) # NOTE Type.long needed but not used
|
451
|
+
|
452
|
+
expected = "while (n <= 3) {\nputs(to_s(n));\nn = n + 1;\n}"
|
453
|
+
|
454
|
+
assert_equal expected, @ruby_to_c.process(input)
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_prototypes
|
458
|
+
assert_equal [], @ruby_to_c.prototypes
|
459
|
+
@ruby_to_c.process t(:defn,
|
460
|
+
:empty,
|
461
|
+
t(:args),
|
462
|
+
t(:scope),
|
463
|
+
Type.function([], Type.void))
|
464
|
+
|
465
|
+
assert_equal "void empty();\n", @ruby_to_c.prototypes.first
|
466
|
+
end
|
467
|
+
|
468
|
+
# def test_translator
|
469
|
+
# Object.class_eval "class Suck; end"
|
470
|
+
# input = [:class, :Suck, :Object,
|
471
|
+
# [:defn, :something, [:scope, [:block, [:args], [:fcall, :"whaaa\?"]]]],
|
472
|
+
# [:defn, :foo, [:scope, [:block, [:args], [:vcall, :something]]]]]
|
473
|
+
# expected = "// class Suck < Object\n\nvoid\nsomething() {\nwhaaa?();\n}\n\nvoid\nfoo() {\nsomething();\n}"
|
474
|
+
# assert_equal expected, RubyToAnsiC.translator.process(input)
|
475
|
+
# end
|
476
|
+
|
477
|
+
def disabled_test_dstr
|
478
|
+
input = t(:dstr,
|
479
|
+
"var is ",
|
480
|
+
t(:lvar, :var),
|
481
|
+
t(:str, ". So there."))
|
482
|
+
output = "sprintf stuff goes here"
|
483
|
+
|
484
|
+
flunk "Way too hard right now"
|
485
|
+
assert_equal output, @ruby_to_c.process(input)
|
486
|
+
end
|
487
|
+
end
|