]>
Commit | Line | Data |
---|---|---|
5999c315 JF |
1 | #include "Parser.hpp" |
2 | ||
3 | #include <iostream> | |
4 | #include <iomanip> | |
5 | ||
4afefdd9 JF |
6 | #include <objc/runtime.h> |
7 | #include <sstream> | |
8 | ||
b09da87b JF |
9 | _finline CYFlags operator ~(CYFlags rhs) { |
10 | return static_cast<CYFlags>(~static_cast<unsigned>(rhs)); | |
11 | } | |
12 | ||
13 | _finline CYFlags operator &(CYFlags lhs, CYFlags rhs) { | |
14 | return static_cast<CYFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); | |
15 | } | |
16 | ||
17 | _finline CYFlags operator |(CYFlags lhs, CYFlags rhs) { | |
18 | return static_cast<CYFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); | |
19 | } | |
20 | ||
21 | _finline CYFlags &operator |=(CYFlags &lhs, CYFlags rhs) { | |
22 | return lhs = lhs | rhs; | |
23 | } | |
24 | ||
25 | _finline CYFlags CYLeft(CYFlags flags) { | |
26 | return flags & ~CYNoTrailer; | |
27 | } | |
28 | ||
29 | _finline CYFlags CYCenter(CYFlags flags) { | |
30 | return flags & CYNoIn; | |
31 | } | |
32 | ||
33 | _finline CYFlags CYRight(CYFlags flags) { | |
34 | return flags & (CYNoIn | CYNoTrailer); | |
35 | } | |
36 | ||
37 | bool CYFalse::Value() const { | |
38 | return false; | |
39 | } | |
40 | ||
41 | bool CYTrue::Value() const { | |
42 | return true; | |
43 | } | |
44 | ||
d35a3b07 JF |
45 | #define CYPA 16 |
46 | ||
b09da87b JF |
47 | void CYAddressOf::Output(std::ostream &out, CYFlags flags) const { |
48 | rhs_->Output(out, 1, CYLeft(flags)); | |
9b5527f0 | 49 | out << ".$cya()"; |
5999c315 JF |
50 | } |
51 | ||
d35a3b07 JF |
52 | void CYArgument::Output(std::ostream &out) const { |
53 | if (name_ != NULL) { | |
5999c315 JF |
54 | out << *name_; |
55 | if (value_ != NULL) | |
56 | out << ":"; | |
57 | } | |
d35a3b07 | 58 | if (value_ != NULL) |
b09da87b | 59 | value_->Output(out, CYPA, CYNoFlags); |
5999c315 | 60 | if (next_ != NULL) { |
d35a3b07 JF |
61 | if (next_->name_ == NULL) |
62 | out << ','; | |
63 | else | |
64 | out << ' '; | |
65 | next_->Output(out); | |
5999c315 JF |
66 | } |
67 | } | |
68 | ||
b09da87b | 69 | void CYArray::Output(std::ostream &out, CYFlags flags) const { |
5befe15e JF |
70 | out << '['; |
71 | if (elements_ != NULL) | |
72 | elements_->Output(out); | |
73 | out << ']'; | |
74 | } | |
75 | ||
b09da87b JF |
76 | void CYAssignment::Output(std::ostream &out, CYFlags flags) const { |
77 | lhs_->Output(out, Precedence() - 1, CYLeft(flags)); | |
d35a3b07 | 78 | out << Operator(); |
b09da87b | 79 | rhs_->Output(out, Precedence(), CYRight(flags)); |
d35a3b07 JF |
80 | } |
81 | ||
9e562cfc JF |
82 | void CYBlock::Output(std::ostream &out) const { |
83 | for (CYSource *statement(statements_); statement != NULL; statement = statement->next_) | |
84 | statement->Output(out); | |
85 | } | |
86 | ||
b09da87b JF |
87 | void CYBoolean::Output(std::ostream &out, CYFlags flags) const { |
88 | if ((flags & CYNoLeader) != 0) | |
89 | out << ' '; | |
5999c315 | 90 | out << (Value() ? "true" : "false"); |
b09da87b JF |
91 | if ((flags & CYNoTrailer) != 0) |
92 | out << ' '; | |
5999c315 JF |
93 | } |
94 | ||
95 | void CYBreak::Output(std::ostream &out) const { | |
96 | out << "break"; | |
97 | if (label_ != NULL) | |
98 | out << ' ' << *label_; | |
99 | out << ';'; | |
100 | } | |
101 | ||
b09da87b JF |
102 | void CYCall::Output(std::ostream &out, CYFlags flags) const { |
103 | function_->Output(out, Precedence(), CYLeft(flags)); | |
d35a3b07 | 104 | out << '('; |
5999c315 | 105 | if (arguments_ != NULL) |
d35a3b07 | 106 | arguments_->Output(out); |
5999c315 JF |
107 | out << ')'; |
108 | } | |
109 | ||
110 | void CYCatch::Output(std::ostream &out) const { | |
111 | out << "catch(" << *name_ << ')'; | |
112 | code_->Output(out, true); | |
113 | } | |
114 | ||
e5bc40db JF |
115 | void CYCategory::Output(std::ostream &out) const { |
116 | out << "(function($cys,$cyp,$cyc,$cyn,$cyt){"; | |
117 | out << "$cyp=object_getClass($cys);"; | |
118 | out << "$cyc=$cys;"; | |
119 | if (messages_ != NULL) | |
120 | messages_->Output(out, true); | |
121 | out << "})("; | |
367eebb1 | 122 | name_->ClassName(out, true); |
e5bc40db JF |
123 | out << ");"; |
124 | } | |
125 | ||
365abb0a JF |
126 | void CYClass::Output(std::ostream &out) const { |
127 | Output(out, CYNoBF); | |
128 | out << ";"; | |
129 | } | |
130 | ||
367eebb1 JF |
131 | void CYClass::Output(std::ostream &out, CYFlags flags) const { |
132 | // XXX: I don't necc. need the ()s | |
e5bc40db JF |
133 | out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){"; |
134 | out << "$cyp=object_getClass($cys);"; | |
367eebb1 JF |
135 | out << "$cyc=objc_allocateClassPair($cys,"; |
136 | if (name_ != NULL) | |
137 | name_->ClassName(out, false); | |
138 | else | |
139 | out << "$cyq(\"CY$\")"; | |
140 | out << ",0);"; | |
b09da87b JF |
141 | out << "$cym=object_getClass($cyc);"; |
142 | if (fields_ != NULL) | |
143 | fields_->Output(out); | |
144 | if (messages_ != NULL) | |
e5bc40db | 145 | messages_->Output(out, false); |
b09da87b | 146 | out << "objc_registerClassPair($cyc);"; |
367eebb1 JF |
147 | out << "return $cyc;"; |
148 | out << "}("; | |
b09da87b JF |
149 | if (super_ != NULL) |
150 | super_->Output(out, CYPA, CYNoFlags); | |
151 | else | |
152 | out << "null"; | |
367eebb1 | 153 | out << "))"; |
b09da87b JF |
154 | } |
155 | ||
e5bc40db JF |
156 | void CYCompound::Output(std::ostream &out, CYFlags flags) const { |
157 | if (CYExpression *expression = expressions_) | |
158 | if (CYExpression *next = expression->next_) { | |
159 | expression->Output(out, CYLeft(flags)); | |
160 | CYFlags center(CYCenter(flags)); | |
161 | while (next != NULL) { | |
162 | expression = next; | |
163 | out << ','; | |
164 | next = expression->next_; | |
165 | CYFlags right(next != NULL ? center : CYRight(flags)); | |
166 | expression->Output(out, right); | |
167 | } | |
168 | } else | |
169 | expression->Output(out, flags); | |
170 | } | |
171 | ||
b09da87b JF |
172 | void CYCondition::Output(std::ostream &out, CYFlags flags) const { |
173 | test_->Output(out, Precedence() - 1, CYLeft(flags)); | |
d35a3b07 | 174 | out << '?'; |
5999c315 | 175 | if (true_ != NULL) |
b09da87b | 176 | true_->Output(out, CYPA, CYNoFlags); |
d35a3b07 | 177 | out << ':'; |
b09da87b | 178 | false_->Output(out, CYPA, CYRight(flags)); |
5999c315 JF |
179 | } |
180 | ||
181 | void CYContinue::Output(std::ostream &out) const { | |
182 | out << "continue"; | |
183 | if (label_ != NULL) | |
184 | out << ' ' << *label_; | |
185 | out << ';'; | |
186 | } | |
187 | ||
188 | void CYClause::Output(std::ostream &out) const { | |
d35a3b07 JF |
189 | if (case_ != NULL) { |
190 | out << "case"; | |
b09da87b | 191 | case_->Output(out, CYNoFlags); |
d35a3b07 | 192 | } else |
5999c315 JF |
193 | out << "default"; |
194 | out << ':'; | |
195 | if (code_ != NULL) | |
196 | code_->Output(out, false); | |
197 | out << *next_; | |
198 | } | |
199 | ||
b09da87b | 200 | // XXX: deal with NoIn |
5999c315 JF |
201 | void CYDeclaration::Part(std::ostream &out) const { |
202 | out << "var "; | |
203 | Output(out); | |
204 | } | |
205 | ||
206 | void CYDeclaration::Output(std::ostream &out) const { | |
207 | out << *identifier_; | |
d35a3b07 JF |
208 | if (initialiser_ != NULL) { |
209 | out << '='; | |
b09da87b | 210 | initialiser_->Output(out, CYPA, CYNoFlags); |
d35a3b07 | 211 | } |
5999c315 JF |
212 | } |
213 | ||
b09da87b | 214 | // XXX: deal with NoIn |
5999c315 JF |
215 | void CYDeclarations::Part(std::ostream &out) const { |
216 | out << "var "; | |
d35a3b07 | 217 | |
5999c315 | 218 | const CYDeclarations *declaration(this); |
d35a3b07 JF |
219 | output: |
220 | out << *declaration->declaration_; | |
221 | declaration = declaration->next_; | |
222 | ||
223 | if (declaration != NULL) { | |
224 | out << ','; | |
225 | goto output; | |
226 | } | |
5999c315 JF |
227 | } |
228 | ||
229 | void CYDeclarations::Output(std::ostream &out) const { | |
230 | Part(out); | |
231 | out << ';'; | |
232 | } | |
233 | ||
9b5527f0 JF |
234 | void CYDirectMember::Output(std::ostream &out, CYFlags flags) const { |
235 | object_->Output(out, Precedence(), CYLeft(flags)); | |
236 | if (const char *word = property_->Word()) | |
237 | out << '.' << word; | |
238 | else { | |
239 | out << '['; | |
240 | property_->Output(out, CYNoFlags); | |
241 | out << ']'; | |
242 | } | |
243 | } | |
244 | ||
5999c315 | 245 | void CYDoWhile::Output(std::ostream &out) const { |
b09da87b | 246 | // XXX: extra space character! |
5999c315 JF |
247 | out << "do "; |
248 | code_->Output(out, false); | |
d35a3b07 | 249 | out << "while("; |
b09da87b JF |
250 | test_->Output(out, CYNoFlags); |
251 | out << ')'; | |
5999c315 JF |
252 | } |
253 | ||
5befe15e | 254 | void CYElement::Output(std::ostream &out) const { |
5999c315 | 255 | if (value_ != NULL) |
b09da87b | 256 | value_->Output(out, CYPA, CYNoFlags); |
5befe15e | 257 | if (next_ != NULL || value_ == NULL) |
5999c315 | 258 | out << ','; |
5befe15e JF |
259 | if (next_ != NULL) |
260 | next_->Output(out); | |
5999c315 JF |
261 | } |
262 | ||
263 | void CYEmpty::Output(std::ostream &out) const { | |
264 | out << ';'; | |
265 | } | |
266 | ||
267 | void CYEmpty::Output(std::ostream &out, bool block) const { | |
268 | if (next_ != NULL) | |
269 | CYSource::Output(out, block); | |
270 | else | |
271 | out << "{}"; | |
272 | } | |
273 | ||
274 | void CYExpress::Output(std::ostream &out) const { | |
365abb0a | 275 | expression_->Output(out, CYNoBF); |
5999c315 JF |
276 | out << ';'; |
277 | } | |
278 | ||
367eebb1 | 279 | void CYExpression::ClassName(std::ostream &out, bool object) const { |
e5bc40db JF |
280 | Output(out, CYPA, CYNoFlags); |
281 | } | |
282 | ||
5999c315 | 283 | void CYExpression::Part(std::ostream &out) const { |
d35a3b07 | 284 | // XXX: this should handle LeftHandSideExpression |
b09da87b | 285 | Output(out, CYNoIn); |
d35a3b07 JF |
286 | } |
287 | ||
b09da87b JF |
288 | void CYExpression::Output(std::ostream &out, unsigned precedence, CYFlags flags) const { |
289 | if (precedence < Precedence()) { | |
5999c315 | 290 | out << '('; |
b09da87b | 291 | Output(out, CYNoFlags); |
5999c315 | 292 | out << ')'; |
b09da87b JF |
293 | } else |
294 | Output(out, flags); | |
295 | } | |
296 | ||
297 | void CYField::Output(std::ostream &out) const { | |
298 | // XXX: implement! | |
5999c315 JF |
299 | } |
300 | ||
301 | void CYFor::Output(std::ostream &out) const { | |
302 | out << "for("; | |
303 | if (initialiser_ != NULL) | |
304 | initialiser_->Part(out); | |
305 | out << ';'; | |
306 | if (test_ != NULL) | |
b09da87b | 307 | test_->Output(out, CYNoFlags); |
5999c315 JF |
308 | out << ';'; |
309 | if (increment_ != NULL) | |
b09da87b | 310 | increment_->Output(out, CYNoFlags); |
5999c315 JF |
311 | out << ')'; |
312 | code_->Output(out, false); | |
313 | } | |
314 | ||
315 | void CYForIn::Output(std::ostream &out) const { | |
316 | out << "for("; | |
317 | initialiser_->Part(out); | |
b09da87b JF |
318 | // XXX: deal with this space character! |
319 | out << ' '; | |
320 | out << "in"; | |
321 | set_->Output(out, CYNoLeader); | |
5999c315 JF |
322 | out << ')'; |
323 | code_->Output(out, false); | |
324 | } | |
325 | ||
326 | void CYFunction::Output(std::ostream &out) const { | |
b09da87b JF |
327 | CYLambda::Output(out, CYNoFlags); |
328 | } | |
329 | ||
330 | void CYFunctionParameter::Output(std::ostream &out) const { | |
331 | out << *name_; | |
332 | if (next_ != NULL) { | |
333 | out << ','; | |
334 | out << *next_; | |
335 | } | |
5999c315 JF |
336 | } |
337 | ||
338 | void CYIf::Output(std::ostream &out) const { | |
d35a3b07 | 339 | out << "if("; |
b09da87b | 340 | test_->Output(out, CYNoFlags); |
d35a3b07 | 341 | out << ')'; |
5999c315 JF |
342 | true_->Output(out, true); |
343 | if (false_ != NULL) { | |
344 | out << "else "; | |
345 | false_->Output(out, false); | |
346 | } | |
347 | } | |
348 | ||
b09da87b JF |
349 | void CYIndirect::Output(std::ostream &out, CYFlags flags) const { |
350 | rhs_->Output(out, 1, CYLeft(flags)); | |
9b5527f0 JF |
351 | out << ".$cyi"; |
352 | } | |
353 | ||
354 | void CYIndirectMember::Output(std::ostream &out, CYFlags flags) const { | |
355 | object_->Output(out, Precedence(), CYLeft(flags)); | |
356 | out << ".$cyi"; | |
357 | if (const char *word = property_->Word()) | |
358 | out << '.' << word; | |
359 | else { | |
360 | out << '['; | |
361 | property_->Output(out, CYNoFlags); | |
362 | out << ']'; | |
363 | } | |
5999c315 JF |
364 | } |
365 | ||
b09da87b JF |
366 | void CYInfix::Output(std::ostream &out, CYFlags flags) const { |
367 | const char *name(Operator()); | |
368 | bool protect((flags & CYNoIn) != 0 && strcmp(name, "in")); | |
369 | if (protect) | |
370 | out << '('; | |
371 | bool alphabetic(Alphabetic()); | |
372 | CYFlags left(protect ? CYNoFlags : CYLeft(flags)); | |
373 | if (alphabetic) | |
374 | left |= CYNoTrailer; | |
375 | lhs_->Output(out, Precedence(), left); | |
376 | out << name; | |
377 | CYFlags right(protect ? CYNoFlags : CYRight(flags)); | |
378 | if (alphabetic) | |
379 | right |= CYNoLeader; | |
1ef7d061 JF |
380 | if (strcmp(name, "-") == 0) |
381 | right |= CYNoHyphen; | |
b09da87b JF |
382 | rhs_->Output(out, Precedence() - 1, right); |
383 | if (protect) | |
384 | out << ')'; | |
5999c315 JF |
385 | } |
386 | ||
b09da87b JF |
387 | void CYLambda::Output(std::ostream &out, CYFlags flags) const { |
388 | bool protect((flags & CYNoFunction) != 0); | |
389 | if (protect) | |
390 | out << '('; | |
83b5afe2 JF |
391 | else if ((flags & CYNoLeader) != 0) |
392 | out << ' '; | |
5999c315 JF |
393 | out << "function"; |
394 | if (name_ != NULL) | |
395 | out << ' ' << *name_; | |
396 | out << '('; | |
397 | if (parameters_ != NULL) | |
398 | out << *parameters_; | |
b09da87b JF |
399 | out << "){"; |
400 | if (body_ != NULL) | |
401 | body_->Show(out); | |
402 | out << '}'; | |
403 | if (protect) | |
404 | out << ')'; | |
5999c315 JF |
405 | } |
406 | ||
e5bc40db | 407 | void CYMessage::Output(std::ostream &out, bool replace) const { |
4e8c99fb | 408 | if (next_ != NULL) |
e5bc40db | 409 | next_->Output(out, replace); |
b09da87b JF |
410 | out << "$cyn=new Selector(\""; |
411 | for (CYMessageParameter *parameter(parameter_); parameter != NULL; parameter = parameter->next_) | |
412 | if (parameter->tag_ != NULL) { | |
413 | out << *parameter->tag_; | |
414 | if (parameter->name_ != NULL) | |
5999c315 JF |
415 | out << ':'; |
416 | } | |
b09da87b | 417 | out << "\");"; |
e5bc40db JF |
418 | out << "$cyt=$cyn.type($cy" << (instance_ ? 's' : 'p') << ");"; |
419 | out << "class_" << (replace ? "replace" : "add") << "Method($cy" << (instance_ ? 'c' : 'm') << ",$cyn,"; | |
478d4ed0 | 420 | out << "new Functor(function(self,_cmd"; |
b09da87b | 421 | for (CYMessageParameter *parameter(parameter_); parameter != NULL; parameter = parameter->next_) |
478d4ed0 JF |
422 | if (parameter->name_ != NULL) |
423 | out << ',' << *parameter->name_; | |
424 | out << "){return function(){"; | |
b09da87b JF |
425 | if (body_ != NULL) |
426 | body_->Show(out); | |
478d4ed0 | 427 | out << "}.call(self);},$cyt),$cyt);"; |
5999c315 JF |
428 | } |
429 | ||
b09da87b | 430 | void CYNew::Output(std::ostream &out, CYFlags flags) const { |
bce8339b JF |
431 | if ((flags & CYNoLeader) != 0) |
432 | out << ' '; | |
d35a3b07 | 433 | out << "new"; |
b09da87b | 434 | constructor_->Output(out, Precedence(), CYCenter(flags) | CYNoLeader); |
d35a3b07 | 435 | out << '('; |
5999c315 | 436 | if (arguments_ != NULL) |
d35a3b07 | 437 | arguments_->Output(out); |
5999c315 JF |
438 | out << ')'; |
439 | } | |
440 | ||
b09da87b JF |
441 | void CYNull::Output(std::ostream &out, CYFlags flags) const { |
442 | if ((flags & CYNoLeader) != 0) | |
443 | out << ' '; | |
5999c315 | 444 | CYWord::Output(out); |
b09da87b JF |
445 | if ((flags & CYNoTrailer) != 0) |
446 | out << ' '; | |
5999c315 JF |
447 | } |
448 | ||
b09da87b | 449 | void CYNumber::Output(std::ostream &out, CYFlags flags) const { |
1ef7d061 JF |
450 | double value(Value()); |
451 | if ((flags & CYNoLeader) != 0 || value < 0 && (flags & CYNoHyphen) != 0) | |
b09da87b | 452 | out << ' '; |
18401062 | 453 | // XXX: decide on correct precision |
1ef7d061 | 454 | out << std::setprecision(9) << value; |
b09da87b JF |
455 | if ((flags & CYNoTrailer) != 0) |
456 | out << ' '; | |
5999c315 JF |
457 | } |
458 | ||
e5bc40db JF |
459 | void CYNumber::PropertyName(std::ostream &out) const { |
460 | Output(out); | |
461 | } | |
462 | ||
b09da87b JF |
463 | void CYObject::Output(std::ostream &out, CYFlags flags) const { |
464 | bool protect((flags & CYNoBrace) != 0); | |
465 | if (protect) | |
466 | out << '('; | |
693d501b JF |
467 | out << '{'; |
468 | if (property_ != NULL) | |
469 | property_->Output(out); | |
470 | out << '}'; | |
b09da87b JF |
471 | if (protect) |
472 | out << ')'; | |
693d501b JF |
473 | } |
474 | ||
b09da87b JF |
475 | void CYPostfix::Output(std::ostream &out, CYFlags flags) const { |
476 | lhs_->Output(out, Precedence(), CYLeft(flags)); | |
d35a3b07 | 477 | out << Operator(); |
5999c315 JF |
478 | } |
479 | ||
b09da87b | 480 | void CYPrefix::Output(std::ostream &out, CYFlags flags) const { |
1ef7d061 | 481 | const char *name(Operator()); |
b09da87b | 482 | bool alphabetic(Alphabetic()); |
1ef7d061 JF |
483 | if (alphabetic && (flags & CYNoLeader) != 0 || name[0] == '-' && (flags & CYNoHyphen) != 0) |
484 | out << ' '; | |
485 | out << name; | |
b09da87b JF |
486 | CYFlags right(CYRight(flags)); |
487 | if (alphabetic) | |
488 | right |= CYNoLeader; | |
489 | rhs_->Output(out, Precedence(), right); | |
5999c315 JF |
490 | } |
491 | ||
693d501b | 492 | void CYProperty::Output(std::ostream &out) const { |
e5bc40db | 493 | name_->PropertyName(out); |
579ed526 | 494 | out << ':'; |
b09da87b | 495 | value_->Output(out, CYPA, CYNoFlags); |
5999c315 JF |
496 | if (next_ != NULL) { |
497 | out << ','; | |
693d501b | 498 | next_->Output(out); |
5999c315 | 499 | } |
5999c315 JF |
500 | } |
501 | ||
502 | void CYReturn::Output(std::ostream &out) const { | |
503 | out << "return"; | |
b09da87b JF |
504 | if (value_ != NULL) |
505 | value_->Output(out, CYNoLeader); | |
5999c315 JF |
506 | out << ';'; |
507 | } | |
508 | ||
b09da87b | 509 | void CYSelector::Output(std::ostream &out, CYFlags flags) const { |
bce8339b JF |
510 | if ((flags & CYNoLeader) != 0) |
511 | out << ' '; | |
b09da87b | 512 | out << "new Selector(\""; |
62014ea9 JF |
513 | if (name_ != NULL) |
514 | name_->Output(out); | |
dea834b0 | 515 | out << "\")"; |
e7ed5354 JF |
516 | } |
517 | ||
62014ea9 JF |
518 | void CYSelectorPart::Output(std::ostream &out) const { |
519 | if (name_ != NULL) | |
520 | out << *name_; | |
521 | if (value_) | |
522 | out << ':'; | |
523 | if (next_ != NULL) | |
524 | next_->Output(out); | |
525 | } | |
526 | ||
b09da87b | 527 | void CYSend::Output(std::ostream &out, CYFlags flags) const { |
c239b9f8 JF |
528 | if ((flags & CYNoLeader) != 0) |
529 | out << ' '; | |
b09da87b JF |
530 | out << "objc_msgSend("; |
531 | self_->Output(out, CYPA, CYNoFlags); | |
4afefdd9 JF |
532 | out << ","; |
533 | std::ostringstream name; | |
b09da87b JF |
534 | for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) |
535 | if (argument->name_ != NULL) { | |
4afefdd9 | 536 | name << *argument->name_; |
b09da87b | 537 | if (argument->value_ != NULL) |
4afefdd9 | 538 | name << ':'; |
b09da87b | 539 | } |
4afefdd9 | 540 | out << reinterpret_cast<void *>(sel_registerName(name.str().c_str())); |
b09da87b JF |
541 | for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) |
542 | if (argument->value_ != NULL) { | |
543 | out << ","; | |
544 | argument->value_->Output(out, CYPA, CYNoFlags); | |
545 | } | |
546 | out << ')'; | |
547 | } | |
548 | ||
b1ff2d78 | 549 | void CYSource::Show(std::ostream &out) const { |
5999c315 | 550 | for (const CYSource *next(this); next != NULL; next = next->next_) |
9e562cfc | 551 | next->Output_(out); |
5999c315 JF |
552 | } |
553 | ||
554 | void CYSource::Output(std::ostream &out, bool block) const { | |
9e562cfc | 555 | if (!block && !IsBlock()) |
5999c315 JF |
556 | Output(out); |
557 | else { | |
558 | out << '{'; | |
b1ff2d78 | 559 | Show(out); |
5999c315 JF |
560 | out << '}'; |
561 | } | |
562 | } | |
563 | ||
9e562cfc JF |
564 | void CYSource::Output_(std::ostream &out) const { |
565 | Output(out); | |
566 | } | |
567 | ||
568 | void CYStatement::Output_(std::ostream &out) const { | |
569 | for (CYLabel *label(labels_); label != NULL; label = label->next_) | |
570 | out << *label->name_ << ':'; | |
571 | Output(out); | |
572 | } | |
573 | ||
b09da87b | 574 | void CYString::Output(std::ostream &out, CYFlags flags) const { |
b4aa79af JF |
575 | unsigned quot(0), apos(0); |
576 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) | |
577 | if (*value == '"') | |
578 | ++quot; | |
579 | else if (*value == '\'') | |
580 | ++apos; | |
581 | ||
582 | bool single(quot > apos); | |
583 | ||
584 | out << (single ? '\'' : '"'); | |
5999c315 JF |
585 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) |
586 | switch (*value) { | |
5999c315 JF |
587 | case '\\': out << "\\\\"; break; |
588 | case '\b': out << "\\b"; break; | |
589 | case '\f': out << "\\f"; break; | |
590 | case '\n': out << "\\n"; break; | |
591 | case '\r': out << "\\r"; break; | |
592 | case '\t': out << "\\t"; break; | |
593 | case '\v': out << "\\v"; break; | |
594 | ||
b4aa79af JF |
595 | case '"': |
596 | if (!single) | |
597 | out << "\\\""; | |
598 | else goto simple; | |
599 | break; | |
600 | ||
601 | case '\'': | |
602 | if (single) | |
603 | out << "\\'"; | |
604 | else goto simple; | |
605 | break; | |
606 | ||
5999c315 JF |
607 | default: |
608 | if (*value < 0x20 || *value >= 0x7f) | |
609 | out << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value); | |
b4aa79af | 610 | else simple: |
5999c315 JF |
611 | out << *value; |
612 | } | |
b4aa79af | 613 | out << (single ? '\'' : '"'); |
5999c315 JF |
614 | } |
615 | ||
e5bc40db JF |
616 | void CYString::PropertyName(std::ostream &out) const { |
617 | if (const char *word = Word()) | |
618 | out << word; | |
619 | else | |
620 | Output(out); | |
621 | } | |
622 | ||
5999c315 | 623 | void CYSwitch::Output(std::ostream &out) const { |
d35a3b07 | 624 | out << "switch("; |
b09da87b | 625 | value_->Output(out, CYNoFlags); |
d35a3b07 | 626 | out << "){"; |
5999c315 JF |
627 | if (clauses_ != NULL) |
628 | out << *clauses_; | |
629 | out << '}'; | |
630 | } | |
631 | ||
b09da87b JF |
632 | void CYThis::Output(std::ostream &out, CYFlags flags) const { |
633 | if ((flags & CYNoLeader) != 0) | |
634 | out << ' '; | |
5999c315 | 635 | CYWord::Output(out); |
b09da87b JF |
636 | if ((flags & CYNoTrailer) != 0) |
637 | out << ' '; | |
5999c315 JF |
638 | } |
639 | ||
640 | void CYThrow::Output(std::ostream &out) const { | |
d35a3b07 | 641 | out << "throw"; |
b09da87b JF |
642 | if (value_ != NULL) |
643 | value_->Output(out, CYNoLeader); | |
5999c315 JF |
644 | out << ';'; |
645 | } | |
646 | ||
647 | void CYTry::Output(std::ostream &out) const { | |
648 | out << "try"; | |
649 | try_->Output(out, true); | |
650 | if (catch_ != NULL) | |
9b5527f0 | 651 | catch_->Output(out); |
5999c315 JF |
652 | if (finally_ != NULL) { |
653 | out << "finally"; | |
654 | finally_->Output(out, true); | |
655 | } | |
656 | } | |
657 | ||
b09da87b | 658 | void CYVariable::Output(std::ostream &out, CYFlags flags) const { |
478d4ed0 JF |
659 | if ((flags & CYNoLeader) != 0) |
660 | out << ' '; | |
5999c315 | 661 | out << *name_; |
478d4ed0 JF |
662 | if ((flags & CYNoTrailer) != 0) |
663 | out << ' '; | |
5999c315 JF |
664 | } |
665 | ||
666 | void CYWhile::Output(std::ostream &out) const { | |
d35a3b07 | 667 | out << "while("; |
b09da87b | 668 | test_->Output(out, CYNoFlags); |
d35a3b07 | 669 | out << ')'; |
5999c315 JF |
670 | code_->Output(out, false); |
671 | } | |
672 | ||
673 | void CYWith::Output(std::ostream &out) const { | |
d35a3b07 | 674 | out << "with("; |
b09da87b | 675 | scope_->Output(out, CYNoFlags); |
d35a3b07 | 676 | out << ')'; |
5999c315 JF |
677 | code_->Output(out, false); |
678 | } | |
679 | ||
367eebb1 JF |
680 | void CYWord::ClassName(std::ostream &out, bool object) const { |
681 | if (object) | |
682 | out << "objc_getClass("; | |
683 | out << '"' << Value() << '"'; | |
684 | if (object) | |
685 | out << ')'; | |
e5bc40db JF |
686 | } |
687 | ||
5999c315 JF |
688 | void CYWord::Output(std::ostream &out) const { |
689 | out << Value(); | |
690 | } | |
e5bc40db JF |
691 | |
692 | void CYWord::PropertyName(std::ostream &out) const { | |
693 | Output(out); | |
694 | } |