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