cast 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,233 @@
1
+ ###
2
+ ### ##################################################################
3
+ ###
4
+ ### C.default_parser and the parse_* methods.
5
+ ###
6
+ ### Yeah, this could be so much faster.
7
+ ###
8
+ ### ##################################################################
9
+ ###
10
+
11
+ module C
12
+ @@default_parser = Parser.new
13
+ def self.default_parser
14
+ @@default_parser
15
+ end
16
+ def self.default_parser= val
17
+ @@default_parser = val
18
+ end
19
+
20
+ class Node
21
+ ###
22
+ ### Return true if `str' is parsed to something `==' to this Node.
23
+ ### str is first converted to a String using #to_s, then given to
24
+ ### self.class.parse (along with the optional `parser').
25
+ ###
26
+ def match? str, parser=nil
27
+ node = self.class.parse(str.to_s, parser) rescue (return false)
28
+ self == node
29
+ end
30
+ ###
31
+ ### Same as #match?.
32
+ ###
33
+ def =~ *args
34
+ match? *args
35
+ end
36
+ private
37
+ end
38
+ class NodeList
39
+ ###
40
+ ### As defined in Node.
41
+ ###
42
+ def match? arr, parser=nil
43
+ arr = arr.to_a
44
+ return false if arr.length != self.length
45
+ each_with_index do |node, i|
46
+ node.match?(arr[i], parser) or return false
47
+ end
48
+ return true
49
+ end
50
+ end
51
+
52
+ def self.parse s, parser=nil
53
+ TranslationUnit.parse(s, parser)
54
+ end
55
+
56
+ class TranslationUnit
57
+ def self.parse s, parser=nil
58
+ parser ||= C.default_parser
59
+ parser.parse(s)
60
+ end
61
+ end
62
+
63
+ class Declaration
64
+ def self.parse s, parser=nil
65
+ parser ||= C.default_parser
66
+ ents = parser.parse(s).entities
67
+ if ents.length == 1 && # int i; int j;
68
+ ents[0].is_a?(Declaration) # void f() {}
69
+ return ents[0].detach
70
+ else
71
+ raise ParseError, "invalid Declaration"
72
+ end
73
+ end
74
+ end
75
+
76
+ class Parameter
77
+ def self.parse s, parser=nil
78
+ parser ||= C.default_parser
79
+ ents = parser.parse("void f(#{s}) {}").entities
80
+ if ents.length == 1 && # ) {} void (
81
+ ents[0].is_a?(FunctionDef) && # ); void(
82
+ ents[0].type.params && #
83
+ ents[0].type.params.length <= 1 # x,y
84
+ param = ents[0].type.params[0]
85
+ if param.nil?
86
+ return Parameter.new(Void.new)
87
+ else
88
+ return param.detach
89
+ end
90
+ else
91
+ raise ParseError, "invalid Parameter"
92
+ end
93
+ end
94
+ end
95
+
96
+ class Declarator
97
+ def self.parse s, parser=nil
98
+ parser ||= C.default_parser
99
+ ents = parser.parse("int #{s};").entities
100
+ if ents.length == 1 && # f; int f;
101
+ ents[0].declarators.length == 1 # i,j
102
+ return ents[0].declarators[0].detach
103
+ else
104
+ raise ParseError, "invalid Declarator"
105
+ end
106
+ end
107
+ end
108
+
109
+ class FunctionDef
110
+ def self.parse s, parser=nil
111
+ parser ||= C.default_parser
112
+ ents = parser.parse(s).entities
113
+ if ents.length == 1 && # void f(); void g();
114
+ ents[0].is_a?(FunctionDef) # int i;
115
+ return ents[0].detach
116
+ else
117
+ raise ParseError, "invalid FunctionDef"
118
+ end
119
+ end
120
+ end
121
+
122
+ class Enumerator
123
+ def self.parse s, parser=nil
124
+ parser ||= C.default_parser
125
+ ents = parser.parse("enum {#{s}};").entities
126
+ if ents.length == 1 && # } enum {
127
+ ents[0].is_a?(Declaration) && # } f() {
128
+ ents[0].type.members.length == 1 # X, Y
129
+ return ents[0].type.members[0].detach
130
+ else
131
+ raise ParseError, "invalid Enumerator"
132
+ end
133
+ end
134
+ end
135
+
136
+ class MemberInit
137
+ def self.parse s, parser=nil
138
+ parser ||= C.default_parser
139
+ ents = parser.parse("int f() {struct s x = {#{s}};}").entities
140
+ if ents.length == 1 && # } int f() {
141
+ ents[0].def.stmts.length == 1 && # }} f() {{
142
+ ents[0].def.stmts[0].declarators.length == 1 && # 1}, y
143
+ ents[0].def.stmts[0].declarators[0].init.member_inits.length == 1 # 1, 2
144
+ return ents[0].def.stmts[0].declarators[0].init.member_inits[0].detach
145
+ else
146
+ raise ParseError, "invalid MemberInit"
147
+ end
148
+ end
149
+ end
150
+
151
+ class Member
152
+ def self.parse s, parser=nil
153
+ parser ||= C.default_parser
154
+ ents = parser.parse("int f() {struct s x = {#{s} = 1;};}").entities
155
+ if ents.length == 1 && # };} int f() {struct s x = {a
156
+ ents[0].def.stmts.length == 1 && # }; x
157
+ #ents[0].def.stmts[0].length == 1 && # 1}, x = {.a
158
+ ents[0].def.stmts[0].declarators.length == 1 && # 1}, x = {.a
159
+ ents[0].def.stmts[0].declarators[0].init.member_inits.length == 1 && # x = 1, y
160
+ ents[0].def.stmts[0].declarators[0].init.member_inits[0].member.length == 1 && # .a .b
161
+ ents[0].def.stmts[0].declarators[0].init.member_inits[0].member[0].is_a?(C::Member) # [0]
162
+ return ents[0].def.stmts[0].declarators[0].init.member_inits[0].member[0].detach
163
+ else
164
+ raise ParseError, "invalid Member"
165
+ end
166
+ end
167
+ end
168
+
169
+ class Statement
170
+ def self.parse s, parser=nil
171
+ parser ||= C.default_parser
172
+ ents = parser.parse("void f() {#{s}}").entities
173
+ if ents.length == 1 && # } void f() {
174
+ ents[0].def.stmts.length == 1 && # ;;
175
+ ents[0].def.stmts[0].is_a?(self) # int i;
176
+ return ents[0].def.stmts[0].detach
177
+ else
178
+ raise ParseError, "invalid #{self}"
179
+ end
180
+ end
181
+ end
182
+
183
+ class Label
184
+ def self.parse s, parser=nil
185
+ parser ||= C.default_parser
186
+ ents = parser.parse("void f() {switch (0) #{s};}").entities
187
+ if ents.length == 1 && # } void f() {
188
+ ents[0].def.stmts.length == 1 && # ;
189
+ ents[0].def.stmts[0].stmt && #
190
+ ents[0].def.stmts[0].stmt.labels.length == 1 && # x
191
+ ents[0].def.stmts[0].stmt.labels[0].is_a?(self)
192
+ return ents[0].def.stmts[0].stmt.labels[0].detach
193
+ else
194
+ raise ParseError, "invalid #{self}"
195
+ end
196
+ end
197
+ end
198
+
199
+ class Expression
200
+ def self.parse s, parser=nil
201
+ parser ||= C.default_parser
202
+ ents = parser.parse("void f() {#{s};}").entities
203
+ if ents.length == 1 && # } void f() {
204
+ ents[0].def.stmts.length == 1 && # ;
205
+ ents[0].def.stmts[0].is_a?(ExpressionStatement) && # int i
206
+ ents[0].def.stmts[0].expr.is_a?(self)
207
+ return ents[0].def.stmts[0].expr.detach
208
+ else
209
+ raise ParseError, "invalid #{self}"
210
+ end
211
+ end
212
+ end
213
+
214
+ class Type
215
+ def self.parse s, parser=nil
216
+ parser ||= C.default_parser
217
+ ents = parser.parse("void f() {(#{s})x;}").entities
218
+ if ents.length == 1 && # 1);} void f() {(int
219
+ ents[0].def.stmts.length == 1 && # 1); (int
220
+ ents[0].def.stmts[0].expr.type.is_a?(self)
221
+ return ents[0].def.stmts[0].expr.type.detach
222
+ else
223
+ raise ParseError, "invalid #{self}"
224
+ end
225
+ end
226
+ end
227
+
228
+ #### Make sure we didn't miss any
229
+ CORE_C_NODE_CLASSES.each do |c|
230
+ c.methods.include? 'parse' or
231
+ raise "#{c}#parse not defined"
232
+ end
233
+ end
@@ -0,0 +1,59 @@
1
+ ###
2
+ ### ##################################################################
3
+ ###
4
+ ### Node#to_debug.
5
+ ###
6
+ ### ##################################################################
7
+ ###
8
+
9
+ module C
10
+ class Node
11
+ TO_DEBUG_TAB = ' '
12
+ def to_debug
13
+ return Node.to_debug1(self)
14
+ end
15
+
16
+ def Node.to_debug1 x, prefix='', indent=0, is_child=true
17
+ case x
18
+ when NodeList
19
+ if x.empty?
20
+ return "#{TO_DEBUG_TAB*indent}#{prefix}[]\n"
21
+ else
22
+ str = "#{TO_DEBUG_TAB*indent}#{prefix}\n"
23
+ x.each do |el|
24
+ str << to_debug1(el, "- ", indent+1)
25
+ end
26
+ return str
27
+ end
28
+ when Node
29
+ classname = x.class.name.gsub(/^C::/, '')
30
+ str = "#{TO_DEBUG_TAB*indent}#{prefix}#{classname}"
31
+
32
+ fields = x.fields
33
+ bools, others = fields.partition{|field| field.reader.to_s[-1] == ??}
34
+ bools.delete_if{|field| !x.send(field.reader)}
35
+ bools.map!{|field| field.init_key}
36
+
37
+ unless bools == []
38
+ str << " (#{bools.join(' ')})"
39
+ end
40
+ str << "\n"
41
+
42
+ others.each do |field|
43
+ val = x.send(field.reader)
44
+ next if val == field.make_default ||
45
+ ## don't bother with non-child Nodes, since they may cause
46
+ ## loops in the tree
47
+ (val.is_a?(Node) && !field.child?)
48
+ str << to_debug1(val, "#{field.reader}: ", indent+1, field.child?)
49
+ end
50
+ return str
51
+ when Symbol
52
+ return "#{TO_DEBUG_TAB*indent}#{prefix}#{x}\n"
53
+ else
54
+ return "#{TO_DEBUG_TAB*indent}#{prefix}#{x.inspect}\n"
55
+ end
56
+ return s.string
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,538 @@
1
+ ###
2
+ ### ##################################################################
3
+ ###
4
+ ### The Node#to_s methods.
5
+ ###
6
+ ### Yeah, this could be so so *SO* much faster.
7
+ ###
8
+ ### ##################################################################
9
+ ###
10
+
11
+ module C
12
+ ## undef the #to_s methods so we can check that we didn't forget to
13
+ ## define any
14
+ Node.send(:undef_method, :to_s)
15
+
16
+ INDENT = ' '
17
+ class Node
18
+ private
19
+ def indent s, levels=1
20
+ s.gsub(/^/, INDENT*levels)
21
+ end
22
+ def hang stmt, cont=false
23
+ if stmt.is_a? Block
24
+ return " #{stmt.to_s(:hanging)}" << (cont ? ' ' : '')
25
+ else
26
+ return "\n#{stmt.to_s}" << (cont ? "\n" : '')
27
+ end
28
+ end
29
+ end
30
+
31
+ class TranslationUnit
32
+ def to_s
33
+ entities.map{|n| n.to_s}.join("\n\n")
34
+ end
35
+ end
36
+ class Declaration
37
+ def to_s
38
+ str = ''
39
+ inline? and str << "inline "
40
+ storage and str << "#{storage} "
41
+ if declarators.empty?
42
+ return str << "#{type};"
43
+ else
44
+ return str << "#{type} " << declarators.join(', ') << ';'
45
+ end
46
+ end
47
+ end
48
+ class Declarator
49
+ def to_s
50
+ (indirect_type ? indirect_type.to_s(name) : name.dup) <<
51
+ (init ? " = #{init}" : '') <<
52
+ (num_bits ? " : #{num_bits}" : '')
53
+ end
54
+ end
55
+ class FunctionDef
56
+ def to_s
57
+ str = ''
58
+ static? and str << 'static '
59
+ inline? and str << 'inline '
60
+ if no_prototype?
61
+ str << "#{type.to_s(name)}\n"
62
+ type.params.each do |p|
63
+ str << indent("#{p.to_s};\n")
64
+ end
65
+ str << "#{self.def.to_s(:hanging)}"
66
+ else
67
+ str << "#{type.to_s(name)}#{hang(self.def)}"
68
+ end
69
+ end
70
+ end
71
+
72
+ ### Statements
73
+ class Statement
74
+ def label str
75
+ labels.map{|s| "#{s}:\n"}.join + indent(str)
76
+ end
77
+ end
78
+ class Block
79
+ def to_s hanging=false
80
+ str = stmts.map do |s|
81
+ if s.is_a? Statement
82
+ s.to_s
83
+ else
84
+ indent(s.to_s)
85
+ end
86
+ end.join("\n")
87
+ str << "\n" unless str == ''
88
+ str = "{\n" << str << "}"
89
+ if hanging
90
+ if labels.empty?
91
+ return str
92
+ else
93
+ return "\n" << label(str)
94
+ end
95
+ else
96
+ return label(str)
97
+ end
98
+ end
99
+ end
100
+ class If
101
+ def to_s
102
+ str = "if (#{cond})"
103
+ if self.else.nil?
104
+ str << hang(self.then)
105
+ else
106
+ str << hang(self.then, :cont) << 'else' << hang(self.else)
107
+ end
108
+ return label(str)
109
+ end
110
+ end
111
+ class Switch
112
+ def to_s
113
+ label("switch (#{cond})" << hang(stmt))
114
+ end
115
+ end
116
+ class While
117
+ def to_s
118
+ if do?
119
+ label('do' << hang(stmt, :cont) << "while (#{cond});")
120
+ else
121
+ label("while (#{cond})" << hang(stmt))
122
+ end
123
+ end
124
+ end
125
+ class For
126
+ def to_s
127
+ initstr =
128
+ case init
129
+ when nil
130
+ ';'
131
+ when Declaration
132
+ "#{init}"
133
+ else
134
+ "#{init};"
135
+ end
136
+ condstr = cond ? " #{cond};" : ';'
137
+ iterstr = iter ? " #{iter}" : ''
138
+ label("for (#{initstr}#{condstr}#{iterstr})" << hang(stmt))
139
+ end
140
+ end
141
+ class Goto
142
+ def to_s
143
+ label("goto #{target};")
144
+ end
145
+ end
146
+ class Continue
147
+ def to_s
148
+ label("continue;")
149
+ end
150
+ end
151
+ class Break
152
+ def to_s
153
+ label("break;")
154
+ end
155
+ end
156
+ class Return
157
+ def to_s
158
+ label("return#{expr ? ' '+expr.to_s : ''};")
159
+ end
160
+ end
161
+ class ExpressionStatement
162
+ def to_s
163
+ label("#{expr};")
164
+ end
165
+ end
166
+
167
+ class PlainLabel
168
+ def to_s
169
+ name.to_s
170
+ end
171
+ end
172
+ class Default
173
+ def to_s
174
+ 'default'
175
+ end
176
+ end
177
+ class Case
178
+ def to_s
179
+ "case #{expr}"
180
+ end
181
+ end
182
+
183
+ ### Expressions
184
+ precedence_table = {}
185
+ [[Comma],
186
+ [Assign, MultiplyAssign, DivideAssign, ModAssign, AddAssign,
187
+ SubtractAssign, ShiftLeftAssign, ShiftRightAssign, BitAndAssign,
188
+ BitXorAssign, BitOrAssign],
189
+ [Conditional],
190
+ [Or],
191
+ [And],
192
+ [BitOr],
193
+ [BitXor],
194
+ [BitAnd],
195
+ [Equal, NotEqual],
196
+ [Less, More, LessOrEqual, MoreOrEqual],
197
+ [ShiftLeft, ShiftRight],
198
+ [Add, Subtract],
199
+ [Multiply, Divide, Mod],
200
+ [PreInc, PreDec, Sizeof, Cast, Address, Dereference, Positive, Negative,
201
+ BitNot, Not],
202
+ [Index, Call, Arrow, Dot, PostInc, PostDec],
203
+ [Literal, Variable]
204
+ ].each_with_index do |klasses, prec|
205
+ klasses.each do |klass|
206
+ klass.send(:define_method, :to_s_precedence){|| prec}
207
+ end
208
+ end
209
+ ## check all Expression classes have a precedence
210
+ C::Expression.subclasses_recursive do |c|
211
+ next if !C::Node.subclasses_recursive.include? c
212
+ c.instance_methods.include? 'to_s_precedence' or
213
+ raise "#{c}#to_s_precedence not defined"
214
+ end
215
+
216
+ ## PrefixExpressions
217
+ [ [Cast , lambda{"(#{self.type})"}],
218
+ [Address , lambda{"&" }],
219
+ [Dereference, lambda{"*" }],
220
+ [Positive , lambda{"+" }],
221
+ [Negative , lambda{"-" }],
222
+ [PreInc , lambda{"++" }],
223
+ [PreDec , lambda{"--" }],
224
+ [BitNot , lambda{"~" }],
225
+ [Not , lambda{"!" }]
226
+ ].each do |c, proc|
227
+ c.send(:define_method, :to_s) do | |
228
+ if expr.to_s_precedence < self.to_s_precedence
229
+ return "#{instance_eval(&proc)}(#{expr})"
230
+ else
231
+ return "#{instance_eval(&proc)}#{expr}"
232
+ end
233
+ end
234
+ end
235
+ ## PostfixExpressions
236
+ [ [Arrow , lambda{"->#{member}"}],
237
+ [Dot , lambda{".#{member}" }],
238
+ [Index , lambda{"[#{index}]" }],
239
+ [PostInc , lambda{"++" }],
240
+ [PostDec , lambda{"--" }]
241
+ ].each do |c, proc|
242
+ c.send(:define_method, :to_s) do | |
243
+ if expr.to_s_precedence < self.to_s_precedence
244
+ return "(#{expr})#{instance_eval(&proc)}"
245
+ else
246
+ return "#{expr}#{instance_eval(&proc)}"
247
+ end
248
+ end
249
+ end
250
+ ## BinaryExpressions
251
+ [ [Add , '+' ],
252
+ [Subtract , '-' ],
253
+ [Multiply , '*' ],
254
+ [Divide , '/' ],
255
+ [Mod , '%' ],
256
+ [Equal , '=='],
257
+ [NotEqual , '!='],
258
+ [Less , '<' ],
259
+ [More , '>' ],
260
+ [LessOrEqual, '<='],
261
+ [MoreOrEqual, '>='],
262
+ [BitAnd , '&' ],
263
+ [BitOr , '|' ],
264
+ [BitXor , '^' ],
265
+ [ShiftLeft , '<<'],
266
+ [ShiftRight , '>>'],
267
+ [And , '&&'],
268
+ [Or , '||'],
269
+ ].each do |c, op|
270
+ c.send(:define_method, :to_s) do | |
271
+ if expr1.to_s_precedence < self.to_s_precedence
272
+ str1 = "(#{expr1})"
273
+ else
274
+ str1 = "#{expr1}"
275
+ end
276
+ ## all binary expressions are left associative
277
+ if expr2.to_s_precedence <= self.to_s_precedence
278
+ str2 = "(#{expr2})"
279
+ else
280
+ str2 = "#{expr2}"
281
+ end
282
+ "#{str1} #{op} #{str2}"
283
+ end
284
+ end
285
+ ## AssignmentExpressions
286
+ [ [Assign , '' ],
287
+ [MultiplyAssign , '*' ],
288
+ [DivideAssign , '/' ],
289
+ [ModAssign , '%' ],
290
+ [AddAssign , '+' ],
291
+ [SubtractAssign , '-' ],
292
+ [ShiftLeftAssign , '<<'],
293
+ [ShiftRightAssign, '>>'],
294
+ [BitAndAssign , '&' ],
295
+ [BitXorAssign , '^' ],
296
+ [BitOrAssign , '|' ]
297
+ ].each do |c, op|
298
+ c.send(:define_method, :to_s) do | |
299
+ if rval.to_s_precedence < self.to_s_precedence
300
+ rvalstr = "(#{rval})"
301
+ else
302
+ rvalstr = "#{rval}"
303
+ end
304
+ "#{lval} #{op}= #{rvalstr}"
305
+ end
306
+ end
307
+ ## Other Expressions
308
+ class Sizeof
309
+ def to_s
310
+ if expr.is_a? Expression
311
+ if expr.to_s_precedence < self.to_s_precedence
312
+ return "sizeof(#{expr})"
313
+ else
314
+ return "sizeof #{expr}"
315
+ end
316
+ else
317
+ return "sizeof(#{expr})"
318
+ end
319
+ end
320
+ end
321
+ ## DirectTypes
322
+ int_longnesses = ['short ', '', 'long ', 'long long ']
323
+ float_longnesses = ['float', 'double', 'long double']
324
+ [ [Struct, lambda do
325
+ str = 'struct'
326
+ name and str << " #{name}"
327
+ members and str << " {\n" << indent(members.join("\n")) << "\n}"
328
+ str
329
+ end],
330
+ [Union, lambda do
331
+ str = 'union'
332
+ name and str << " #{name}"
333
+ members and str << " {\n" << indent(members.join("\n")) << "\n}"
334
+ str
335
+ end],
336
+ [Enum, lambda do
337
+ str = 'enum'
338
+ name and str << " #{name}"
339
+ members and str << " {\n" << indent(members.join(",\n")) << "\n}"
340
+ str
341
+ end],
342
+ [CustomType, lambda{name.dup }],
343
+ [Void , lambda{'void' }],
344
+ [Int , lambda do
345
+ longness_str = int_longnesses[longness+1].dup
346
+ "#{unsigned? ? 'unsigned ' : ''}#{longness_str}int"
347
+ end],
348
+ [Float , lambda{float_longnesses[longness].dup}],
349
+ [Char , lambda{"#{unsigned? ? 'unsigned ' : ''}char"}],
350
+ [Bool , lambda{'_Bool' }],
351
+ [Complex , lambda{'_Complex' }],
352
+ [Imaginary , lambda{'_Imaginary'}]
353
+ ].each do |c, x|
354
+ c.send(:define_method, :to_s) do |*args|
355
+ case args.length
356
+ when 0
357
+ namestr = nil
358
+ when 1
359
+ namestr = args[0]
360
+ namestr = nil if namestr == ''
361
+ else
362
+ raise ArgumentError, "wrong number of args (#{args.length} for 1)"
363
+ end
364
+ str = ''
365
+ const? and str << 'const '
366
+ restrict? and str << 'restrict '
367
+ volatile? and str << 'volatile '
368
+ str << instance_eval(&x) << (namestr ? " #{namestr}" : '')
369
+ end
370
+ end
371
+
372
+ class Enumerator
373
+ def to_s
374
+ if val
375
+ "#{name} = #{val}"
376
+ else
377
+ "#{name}"
378
+ end
379
+ end
380
+ end
381
+
382
+ class Comma
383
+ def to_s
384
+ exprs.join(', ')
385
+ end
386
+ end
387
+
388
+ class Conditional
389
+ def to_s
390
+ strs = [:cond, :then, :else].map do |child|
391
+ val = send(child)
392
+ if val.to_s_precedence < self.to_s_precedence
393
+ "(#{val})"
394
+ else
395
+ "#{val}"
396
+ end
397
+ end
398
+ "#{strs[0]} ? #{strs[1]} : #{strs[2]}"
399
+ end
400
+ end
401
+
402
+ class Call
403
+ def to_s
404
+ argstrs = args.map do |arg|
405
+ if arg.is_a? Comma
406
+ "(#{arg})"
407
+ else
408
+ "#{arg}"
409
+ end
410
+ end
411
+ if expr.to_s_precedence < self.to_s_precedence
412
+ exprstr = "(#{expr})"
413
+ else
414
+ exprstr = "#{expr}"
415
+ end
416
+ "#{exprstr}(#{argstrs.join(', ')})"
417
+ end
418
+ end
419
+
420
+ ### IndirectTypes
421
+ class Pointer
422
+ def to_s name=nil
423
+ str = '*'
424
+ const? and str << 'const '
425
+ restrict? and str << 'restrict '
426
+ volatile? and str << 'volatile '
427
+ str =
428
+ case type
429
+ when Function, Array
430
+ "(#{str}#{name})"
431
+ else
432
+ "#{str}#{name}"
433
+ end
434
+ if type
435
+ type.to_s(str)
436
+ else
437
+ str
438
+ end
439
+ end
440
+ end
441
+ class Array
442
+ def to_s name=nil
443
+ str = "#{name}[#{length}]"
444
+ if type
445
+ type.to_s(str)
446
+ else
447
+ str
448
+ end
449
+ end
450
+ end
451
+ class Function
452
+ def to_s name=nil
453
+ str =
454
+ if params.nil?
455
+ paramstr = ''
456
+ elsif params.empty?
457
+ paramstr = 'void'
458
+ else
459
+ paramstr = params.join(', ')
460
+ end
461
+ var_args? and paramstr << ', ...'
462
+ str = "#{name}(#{paramstr})"
463
+ if type
464
+ type.to_s(str)
465
+ else
466
+ str
467
+ end
468
+ end
469
+ end
470
+ class Parameter
471
+ def to_s
472
+ str = register? ? 'register ' : ''
473
+ str << type.to_s(name)
474
+ end
475
+ end
476
+
477
+ ### Literals
478
+ class StringLiteral
479
+ def to_s
480
+ "\"#{val}\""
481
+ end
482
+ end
483
+ class CharLiteral
484
+ def to_s
485
+ "'#{val}'"
486
+ end
487
+ end
488
+ class CompoundLiteral
489
+ def to_s
490
+ str = ''
491
+ type and
492
+ str << "(#{type}) "
493
+ str << "{\n" << indent(inits.join(",\n")) << "\n}"
494
+ end
495
+ end
496
+ class MemberInit
497
+ def to_s
498
+ str = ''
499
+ if member
500
+ memberstr = member.map do |m|
501
+ if m.is_a? Expression
502
+ "[#{m}]"
503
+ else
504
+ ".#{m}"
505
+ end
506
+ end
507
+ str << member.join(' ') << ' = '
508
+ end
509
+ return str << init.to_s
510
+ end
511
+ end
512
+ class Member
513
+ def to_s
514
+ name.dup
515
+ end
516
+ end
517
+ class IntLiteral
518
+ def to_s
519
+ val.to_s
520
+ end
521
+ end
522
+ class FloatLiteral
523
+ def to_s
524
+ val.to_s
525
+ end
526
+ end
527
+ class Variable
528
+ def to_s
529
+ name.dup
530
+ end
531
+ end
532
+
533
+ ## check we didn't miss any
534
+ CORE_C_NODE_CLASSES.each do |c|
535
+ c.method_defined? :to_s or
536
+ raise "#{c}#to_s not defined"
537
+ end
538
+ end