]> git.saurik.com Git - cycript.git/blob - Output.cpp
a5d97430c3e2b0cc9a2601099082b5374ecc1e56
[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 out << "with({$cys:0,$cyt:0}){";
364
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
376 out << '}';
377
378 out << '}';
379 }
380
381 void 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
391 void CYForEachInComprehension::End_(std::ostream &out) const {
392 out << "}}());";
393 }
394
395 void CYForIn::Output(std::ostream &out) const {
396 out << "for(";
397 initialiser_->ForIn(out, CYNoIn | CYNoTrailer);
398 out << "in";
399 set_->Output(out, CYNoLeader);
400 out << ')';
401 code_->Output(out, false);
402 }
403
404 void CYForInComprehension::Begin_(std::ostream &out) const {
405 out << "for(" << *name_ << " in";
406 set_->Output(out, CYNoLeader);
407 out << ')';
408 }
409
410 void CYFunction::Output(std::ostream &out) const {
411 CYLambda::Output(out, CYNoFlags);
412 }
413
414 void CYFunctionParameter::Output(std::ostream &out) const {
415 out << *name_;
416 if (next_ != NULL) {
417 out << ',';
418 out << *next_;
419 }
420 }
421
422 void CYIf::Output(std::ostream &out) const {
423 out << "if(";
424 test_->Output(out, CYNoFlags);
425 out << ')';
426 true_->Output(out, true);
427 if (false_ != NULL) {
428 out << "else ";
429 false_->Output(out, false);
430 }
431 }
432
433 void CYIfComprehension::Begin_(std::ostream &out) const {
434 out << "if(";
435 test_->Output(out, CYNoFlags);
436 out << ')';
437 }
438
439 void CYIndirect::Output(std::ostream &out, CYFlags flags) const {
440 rhs_->Output(out, 1, CYLeft(flags));
441 out << ".$cyi";
442 }
443
444 void 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 }
454 }
455
456 void 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;
470 if (strcmp(name, "-") == 0)
471 right |= CYNoHyphen;
472 rhs_->Output(out, Precedence() - 1, right);
473 if (protect)
474 out << ')';
475 }
476
477 void CYLambda::Output(std::ostream &out, CYFlags flags) const {
478 bool protect((flags & CYNoFunction) != 0);
479 if (protect)
480 out << '(';
481 else if ((flags & CYNoLeader) != 0)
482 out << ' ';
483 out << "function";
484 if (name_ != NULL)
485 out << ' ' << *name_;
486 out << '(';
487 if (parameters_ != NULL)
488 out << *parameters_;
489 out << "){";
490 if (body_ != NULL)
491 body_->Show(out);
492 out << '}';
493 if (protect)
494 out << ')';
495 }
496
497 void 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
506 void CYMessage::Output(std::ostream &out, bool replace) const {
507 if (next_ != NULL)
508 next_->Output(out, replace);
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)
514 out << ':';
515 }
516 out << "\");";
517 out << "$cyt=$cyn.type($cy" << (instance_ ? 's' : 'p') << ");";
518 out << "class_" << (replace ? "replace" : "add") << "Method($cy" << (instance_ ? 'c' : 'm') << ",$cyn,";
519 out << "new Functor(function(self,_cmd";
520 for (CYMessageParameter *parameter(parameter_); parameter != NULL; parameter = parameter->next_)
521 if (parameter->name_ != NULL)
522 out << ',' << *parameter->name_;
523 out << "){return function(){";
524 if (body_ != NULL)
525 body_->Show(out);
526 out << "}.call(self);},$cyt),$cyt);";
527 }
528
529 void CYNew::Output(std::ostream &out, CYFlags flags) const {
530 if ((flags & CYNoLeader) != 0)
531 out << ' ';
532 out << "new";
533 constructor_->Output(out, Precedence(), CYCenter(flags) | CYNoLeader);
534 out << '(';
535 if (arguments_ != NULL)
536 arguments_->Output(out);
537 out << ')';
538 }
539
540 void CYNull::Output(std::ostream &out, CYFlags flags) const {
541 if ((flags & CYNoLeader) != 0)
542 out << ' ';
543 CYWord::Output(out);
544 if ((flags & CYNoTrailer) != 0)
545 out << ' ';
546 }
547
548 void CYNumber::Output(std::ostream &out, CYFlags flags) const {
549 double value(Value());
550 if ((flags & CYNoLeader) != 0 || value < 0 && (flags & CYNoHyphen) != 0)
551 out << ' ';
552 // XXX: decide on correct precision
553 out << std::setprecision(9) << value;
554 if ((flags & CYNoTrailer) != 0)
555 out << ' ';
556 }
557
558 void CYNumber::PropertyName(std::ostream &out) const {
559 Output(out);
560 }
561
562 void CYObject::Output(std::ostream &out, CYFlags flags) const {
563 bool protect((flags & CYNoBrace) != 0);
564 if (protect)
565 out << '(';
566 out << '{';
567 if (property_ != NULL)
568 property_->Output(out);
569 out << '}';
570 if (protect)
571 out << ')';
572 }
573
574 void CYPostfix::Output(std::ostream &out, CYFlags flags) const {
575 lhs_->Output(out, Precedence(), CYLeft(flags));
576 out << Operator();
577 }
578
579 void CYPrefix::Output(std::ostream &out, CYFlags flags) const {
580 const char *name(Operator());
581 bool alphabetic(Alphabetic());
582 if (alphabetic && (flags & CYNoLeader) != 0 || name[0] == '-' && (flags & CYNoHyphen) != 0)
583 out << ' ';
584 out << name;
585 CYFlags right(CYRight(flags));
586 if (alphabetic)
587 right |= CYNoLeader;
588 rhs_->Output(out, Precedence(), right);
589 }
590
591 void CYProperty::Output(std::ostream &out) const {
592 name_->PropertyName(out);
593 out << ':';
594 value_->Output(out, CYPA, CYNoFlags);
595 if (next_ != NULL) {
596 out << ',';
597 next_->Output(out);
598 }
599 }
600
601 void CYReturn::Output(std::ostream &out) const {
602 out << "return";
603 if (value_ != NULL)
604 value_->Output(out, CYNoLeader);
605 out << ';';
606 }
607
608 void CYSelector::Output(std::ostream &out, CYFlags flags) const {
609 if ((flags & CYNoLeader) != 0)
610 out << ' ';
611 out << "new Selector(\"";
612 if (name_ != NULL)
613 name_->Output(out);
614 out << "\")";
615 }
616
617 void 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
626 void CYSend::Output(std::ostream &out, CYFlags flags) const {
627 if ((flags & CYNoLeader) != 0)
628 out << ' ';
629 out << "objc_msgSend(";
630 self_->Output(out, CYPA, CYNoFlags);
631 out << ",";
632 std::ostringstream name;
633 for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_)
634 if (argument->name_ != NULL) {
635 name << *argument->name_;
636 if (argument->value_ != NULL)
637 name << ':';
638 }
639 out << reinterpret_cast<void *>(sel_registerName(name.str().c_str()));
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
648 void CYSource::Show(std::ostream &out) const {
649 for (const CYSource *next(this); next != NULL; next = next->next_)
650 next->Output_(out);
651 }
652
653 void CYSource::Output(std::ostream &out, bool block) const {
654 if (!block && !IsBlock())
655 Output(out);
656 else {
657 out << '{';
658 Show(out);
659 out << '}';
660 }
661 }
662
663 void CYSource::Output_(std::ostream &out) const {
664 Output(out);
665 }
666
667 void 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
673 void CYString::Output(std::ostream &out, CYFlags flags) const {
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 ? '\'' : '"');
684 for (const char *value(value_), *end(value_ + size_); value != end; ++value)
685 switch (*value) {
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
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
706 default:
707 if (*value < 0x20 || *value >= 0x7f)
708 out << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value);
709 else simple:
710 out << *value;
711 }
712 out << (single ? '\'' : '"');
713 }
714
715 void CYString::PropertyName(std::ostream &out) const {
716 if (const char *word = Word())
717 out << word;
718 else
719 Output(out);
720 }
721
722 void CYSwitch::Output(std::ostream &out) const {
723 out << "switch(";
724 value_->Output(out, CYNoFlags);
725 out << "){";
726 if (clauses_ != NULL)
727 out << *clauses_;
728 out << '}';
729 }
730
731 void CYThis::Output(std::ostream &out, CYFlags flags) const {
732 if ((flags & CYNoLeader) != 0)
733 out << ' ';
734 CYWord::Output(out);
735 if ((flags & CYNoTrailer) != 0)
736 out << ' ';
737 }
738
739 void CYThrow::Output(std::ostream &out) const {
740 out << "throw";
741 if (value_ != NULL)
742 value_->Output(out, CYNoLeader);
743 out << ';';
744 }
745
746 void CYTry::Output(std::ostream &out) const {
747 out << "try";
748 try_->Output(out, true);
749 if (catch_ != NULL)
750 catch_->Output(out);
751 if (finally_ != NULL) {
752 out << "finally";
753 finally_->Output(out, true);
754 }
755 }
756
757 void CYVar::Output(std::ostream &out) const {
758 out << "var ";
759 declarations_->Output(out, CYNoFlags);
760 out << ';';
761 }
762
763 void CYVariable::Output(std::ostream &out, CYFlags flags) const {
764 if ((flags & CYNoLeader) != 0)
765 out << ' ';
766 out << *name_;
767 if ((flags & CYNoTrailer) != 0)
768 out << ' ';
769 }
770
771 void CYWhile::Output(std::ostream &out) const {
772 out << "while(";
773 test_->Output(out, CYNoFlags);
774 out << ')';
775 code_->Output(out, false);
776 }
777
778 void CYWith::Output(std::ostream &out) const {
779 out << "with(";
780 scope_->Output(out, CYNoFlags);
781 out << ')';
782 code_->Output(out, false);
783 }
784
785 void CYWord::ClassName(std::ostream &out, bool object) const {
786 if (object)
787 out << "objc_getClass(";
788 out << '"' << Value() << '"';
789 if (object)
790 out << ')';
791 }
792
793 void CYWord::Output(std::ostream &out) const {
794 out << Value();
795 }
796
797 void CYWord::PropertyName(std::ostream &out) const {
798 Output(out);
799 }