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