]> git.saurik.com Git - cycript.git/blame - Output.cpp
Setup new objects in lexer to allocate into the correct pool.
[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 {
9e562cfc
JF
101 for (CYSource *statement(statements_); statement != NULL; statement = statement->next_)
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 {
5999c315
JF
129 out << "catch(" << *name_ << ')';
130 code_->Output(out, true);
131}
132
652ec1ba 133void CYCategory::Output(CYOutput &out) const {
e5bc40db
JF
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
652ec1ba 144void CYClass::Output(CYOutput &out) const {
365abb0a
JF
145 Output(out, CYNoBF);
146 out << ";";
147}
148
652ec1ba 149void CYClass::Output(CYOutput &out, CYFlags flags) const {
367eebb1 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
652ec1ba 174void CYCompound::Output(CYOutput &out, CYFlags flags) const {
e5bc40db
JF
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
652ec1ba 190void CYComprehension::Output(CYOutput &out) const {
75b0a457
JF
191 Begin_(out);
192 if (next_ != NULL)
193 next_->Output(out);
194}
195
652ec1ba 196void CYCondition::Output(CYOutput &out, CYFlags flags) const {
b09da87b 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
652ec1ba 205void CYContinue::Output(CYOutput &out) const {
5999c315
JF
206 out << "continue";
207 if (label_ != NULL)
208 out << ' ' << *label_;
209 out << ';';
210}
211
652ec1ba 212void CYClause::Output(CYOutput &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
652ec1ba 229void CYDeclaration::ForIn(CYOutput &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
652ec1ba 236void CYDeclaration::ForEachIn(CYOutput &out) const {
75b0a457 237 out << *identifier_;
5999c315
JF
238}
239
652ec1ba 240void CYDeclaration::Output(CYOutput &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
652ec1ba 249void CYDeclarations::For(CYOutput &out) const {
5999c315 250 out << "var ";
cac61857
JF
251 Output(out, CYNoIn);
252}
d35a3b07 253
652ec1ba 254void CYDeclarations::Output(CYOutput &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
652ec1ba 268void CYDirectMember::Output(CYOutput &out, CYFlags flags) const {
9b5527f0
JF
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
652ec1ba 279void CYDoWhile::Output(CYOutput &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
652ec1ba 288void CYElement::Output(CYOutput &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
652ec1ba 297void CYEmpty::Output(CYOutput &out) const {
5999c315
JF
298 out << ';';
299}
300
652ec1ba 301void CYEmpty::Output(CYOutput &out, bool block) const {
5999c315
JF
302 if (next_ != NULL)
303 CYSource::Output(out, block);
304 else
305 out << "{}";
306}
307
652ec1ba 308void CYExpress::Output(CYOutput &out) const {
365abb0a 309 expression_->Output(out, CYNoBF);
5999c315
JF
310 out << ';';
311}
312
652ec1ba 313void CYExpression::ClassName(CYOutput &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
652ec1ba 321void CYExpression::For(CYOutput &out) const {
cac61857
JF
322 Output(out, CYNoIn);
323}
324
652ec1ba 325void CYExpression::ForEachIn(CYOutput &out) const {
75b0a457
JF
326 // XXX: this should handle LeftHandSideExpression
327 Output(out, CYPA, CYNoFlags);
328}
329
652ec1ba 330void CYExpression::ForIn(CYOutput &out, CYFlags flags) const {
d35a3b07 331 // XXX: this should handle LeftHandSideExpression
75b0a457 332 Output(out, flags);
d35a3b07
JF
333}
334
652ec1ba 335void CYExpression::Output(CYOutput &out, unsigned precedence, CYFlags flags) const {
b09da87b 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
652ec1ba 344void CYField::Output(CYOutput &out) const {
b09da87b 345 // XXX: implement!
5999c315
JF
346}
347
652ec1ba 348void CYFor::Output(CYOutput &out) const {
5999c315
JF
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
652ec1ba 362void CYForEachIn::Output(CYOutput &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
652ec1ba 381void CYForEachInComprehension::Begin_(CYOutput &out) const {
75b0a457
JF
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
652ec1ba 391void CYForEachInComprehension::End_(CYOutput &out) const {
75b0a457
JF
392 out << "}}());";
393}
394
652ec1ba 395void CYForIn::Output(CYOutput &out) const {
5999c315 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
652ec1ba 404void CYForInComprehension::Begin_(CYOutput &out) const {
75b0a457
JF
405 out << "for(" << *name_ << " in";
406 set_->Output(out, CYNoLeader);
407 out << ')';
408}
409
652ec1ba 410void CYFunction::Output(CYOutput &out) const {
b09da87b
JF
411 CYLambda::Output(out, CYNoFlags);
412}
413
652ec1ba 414void CYFunctionParameter::Output(CYOutput &out) const {
b09da87b
JF
415 out << *name_;
416 if (next_ != NULL) {
417 out << ',';
418 out << *next_;
419 }
5999c315
JF
420}
421
652ec1ba 422void CYIf::Output(CYOutput &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
652ec1ba 433void CYIfComprehension::Begin_(CYOutput &out) const {
75b0a457
JF
434 out << "if(";
435 test_->Output(out, CYNoFlags);
436 out << ')';
437}
438
652ec1ba 439void CYIndirect::Output(CYOutput &out, CYFlags flags) const {
b09da87b 440 rhs_->Output(out, 1, CYLeft(flags));
9b5527f0
JF
441 out << ".$cyi";
442}
443
652ec1ba 444void CYIndirectMember::Output(CYOutput &out, CYFlags flags) const {
9b5527f0
JF
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
652ec1ba 456void CYInfix::Output(CYOutput &out, CYFlags flags) const {
b09da87b
JF
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
652ec1ba 477void CYLambda::Output(CYOutput &out, CYFlags flags) const {
b09da87b
JF
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
652ec1ba 497void CYLet::Output(CYOutput &out) const {
cac61857
JF
498 out << "let(";
499 declarations_->Output(out, CYNoFlags);
500 out << "){";
501 if (statements_ != NULL)
502 statements_->Show(out);
503 out << "}";
504}
505
652ec1ba 506void CYMessage::Output(CYOutput &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
652ec1ba 529void CYNew::Output(CYOutput &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
652ec1ba 540void CYNull::Output(CYOutput &out, CYFlags flags) const {
b09da87b
JF
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
652ec1ba 548void CYNumber::Output(CYOutput &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
652ec1ba 553 out.out_ << std::setprecision(9) << value;
b09da87b
JF
554 if ((flags & CYNoTrailer) != 0)
555 out << ' ';
5999c315
JF
556}
557
652ec1ba 558void CYNumber::PropertyName(CYOutput &out) const {
e5bc40db
JF
559 Output(out);
560}
561
652ec1ba 562void CYObject::Output(CYOutput &out, CYFlags flags) const {
b09da87b
JF
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
652ec1ba 574void CYPostfix::Output(CYOutput &out, CYFlags flags) const {
b09da87b 575 lhs_->Output(out, Precedence(), CYLeft(flags));
d35a3b07 576 out << Operator();
5999c315
JF
577}
578
652ec1ba 579void CYPrefix::Output(CYOutput &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
652ec1ba 591void CYProperty::Output(CYOutput &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
63cd45c9
JF
601void CYRegEx::Output(CYOutput &out, CYFlags flags) const {
602 out << Value();
603 if ((flags & CYNoTrailer) != 0)
604 out << ' ';
605}
606
652ec1ba 607void CYReturn::Output(CYOutput &out) const {
5999c315 608 out << "return";
b09da87b
JF
609 if (value_ != NULL)
610 value_->Output(out, CYNoLeader);
5999c315
JF
611 out << ';';
612}
613
652ec1ba 614void CYSelector::Output(CYOutput &out, CYFlags flags) const {
bce8339b
JF
615 if ((flags & CYNoLeader) != 0)
616 out << ' ';
b09da87b 617 out << "new Selector(\"";
62014ea9
JF
618 if (name_ != NULL)
619 name_->Output(out);
dea834b0 620 out << "\")";
e7ed5354
JF
621}
622
652ec1ba 623void CYSelectorPart::Output(CYOutput &out) const {
62014ea9
JF
624 if (name_ != NULL)
625 out << *name_;
626 if (value_)
627 out << ':';
628 if (next_ != NULL)
629 next_->Output(out);
630}
631
652ec1ba 632void CYSend::Output(CYOutput &out, CYFlags flags) const {
c239b9f8
JF
633 if ((flags & CYNoLeader) != 0)
634 out << ' ';
b09da87b
JF
635 out << "objc_msgSend(";
636 self_->Output(out, CYPA, CYNoFlags);
4afefdd9
JF
637 out << ",";
638 std::ostringstream name;
b09da87b
JF
639 for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_)
640 if (argument->name_ != NULL) {
4afefdd9 641 name << *argument->name_;
b09da87b 642 if (argument->value_ != NULL)
4afefdd9 643 name << ':';
b09da87b 644 }
652ec1ba 645 out.out_ << reinterpret_cast<void *>(sel_registerName(name.str().c_str()));
b09da87b
JF
646 for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_)
647 if (argument->value_ != NULL) {
648 out << ",";
649 argument->value_->Output(out, CYPA, CYNoFlags);
650 }
651 out << ')';
652}
653
652ec1ba 654void CYSource::Show(CYOutput &out) const {
5999c315 655 for (const CYSource *next(this); next != NULL; next = next->next_)
9e562cfc 656 next->Output_(out);
5999c315
JF
657}
658
652ec1ba 659void CYSource::Output(CYOutput &out, bool block) const {
9e562cfc 660 if (!block && !IsBlock())
5999c315
JF
661 Output(out);
662 else {
663 out << '{';
b1ff2d78 664 Show(out);
5999c315
JF
665 out << '}';
666 }
667}
668
652ec1ba 669void CYSource::Output_(CYOutput &out) const {
9e562cfc
JF
670 Output(out);
671}
672
652ec1ba 673void CYStatement::Output_(CYOutput &out) const {
9e562cfc
JF
674 for (CYLabel *label(labels_); label != NULL; label = label->next_)
675 out << *label->name_ << ':';
676 Output(out);
677}
678
652ec1ba 679void CYString::Output(CYOutput &out, CYFlags flags) const {
b4aa79af
JF
680 unsigned quot(0), apos(0);
681 for (const char *value(value_), *end(value_ + size_); value != end; ++value)
682 if (*value == '"')
683 ++quot;
684 else if (*value == '\'')
685 ++apos;
686
687 bool single(quot > apos);
688
689 out << (single ? '\'' : '"');
5999c315
JF
690 for (const char *value(value_), *end(value_ + size_); value != end; ++value)
691 switch (*value) {
5999c315
JF
692 case '\\': out << "\\\\"; break;
693 case '\b': out << "\\b"; break;
694 case '\f': out << "\\f"; break;
695 case '\n': out << "\\n"; break;
696 case '\r': out << "\\r"; break;
697 case '\t': out << "\\t"; break;
698 case '\v': out << "\\v"; break;
699
b4aa79af
JF
700 case '"':
701 if (!single)
702 out << "\\\"";
703 else goto simple;
704 break;
705
706 case '\'':
707 if (single)
708 out << "\\'";
709 else goto simple;
710 break;
711
5999c315
JF
712 default:
713 if (*value < 0x20 || *value >= 0x7f)
652ec1ba 714 out.out_ << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value);
b4aa79af 715 else simple:
5999c315
JF
716 out << *value;
717 }
b4aa79af 718 out << (single ? '\'' : '"');
5999c315
JF
719}
720
652ec1ba 721void CYString::PropertyName(CYOutput &out) const {
e5bc40db
JF
722 if (const char *word = Word())
723 out << word;
724 else
725 Output(out);
726}
727
652ec1ba 728void CYSwitch::Output(CYOutput &out) const {
d35a3b07 729 out << "switch(";
b09da87b 730 value_->Output(out, CYNoFlags);
d35a3b07 731 out << "){";
5999c315
JF
732 if (clauses_ != NULL)
733 out << *clauses_;
734 out << '}';
735}
736
652ec1ba 737void CYThis::Output(CYOutput &out, CYFlags flags) const {
b09da87b
JF
738 if ((flags & CYNoLeader) != 0)
739 out << ' ';
5999c315 740 CYWord::Output(out);
b09da87b
JF
741 if ((flags & CYNoTrailer) != 0)
742 out << ' ';
5999c315
JF
743}
744
652ec1ba 745void CYThrow::Output(CYOutput &out) const {
d35a3b07 746 out << "throw";
b09da87b
JF
747 if (value_ != NULL)
748 value_->Output(out, CYNoLeader);
5999c315
JF
749 out << ';';
750}
751
652ec1ba 752void CYTry::Output(CYOutput &out) const {
5999c315
JF
753 out << "try";
754 try_->Output(out, true);
755 if (catch_ != NULL)
9b5527f0 756 catch_->Output(out);
5999c315
JF
757 if (finally_ != NULL) {
758 out << "finally";
759 finally_->Output(out, true);
760 }
761}
762
652ec1ba 763void CYVar::Output(CYOutput &out) const {
cac61857
JF
764 out << "var ";
765 declarations_->Output(out, CYNoFlags);
766 out << ';';
767}
768
652ec1ba 769void CYVariable::Output(CYOutput &out, CYFlags flags) const {
478d4ed0
JF
770 if ((flags & CYNoLeader) != 0)
771 out << ' ';
5999c315 772 out << *name_;
478d4ed0
JF
773 if ((flags & CYNoTrailer) != 0)
774 out << ' ';
5999c315
JF
775}
776
652ec1ba 777void CYWhile::Output(CYOutput &out) const {
d35a3b07 778 out << "while(";
b09da87b 779 test_->Output(out, CYNoFlags);
d35a3b07 780 out << ')';
5999c315
JF
781 code_->Output(out, false);
782}
783
652ec1ba 784void CYWith::Output(CYOutput &out) const {
d35a3b07 785 out << "with(";
b09da87b 786 scope_->Output(out, CYNoFlags);
d35a3b07 787 out << ')';
5999c315
JF
788 code_->Output(out, false);
789}
790
652ec1ba 791void CYWord::ClassName(CYOutput &out, bool object) const {
367eebb1
JF
792 if (object)
793 out << "objc_getClass(";
794 out << '"' << Value() << '"';
795 if (object)
796 out << ')';
e5bc40db
JF
797}
798
652ec1ba 799void CYWord::Output(CYOutput &out) const {
5999c315
JF
800 out << Value();
801}
e5bc40db 802
652ec1ba 803void CYWord::PropertyName(CYOutput &out) const {
e5bc40db
JF
804 Output(out);
805}