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