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