]> git.saurik.com Git - cycript.git/blob - Output.cpp
Support extern "C" syntax to FFI via C prototypes.
[cycript.git] / Output.cpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2014 Jay Freeman (saurik)
3 */
4
5 /* GNU Affero General Public License, Version 3 {{{ */
6 /*
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20 /* }}} */
21
22 #include "cycript.hpp"
23 #include "Parser.hpp"
24
25 #include <sstream>
26
27 void CYOutput::Terminate() {
28 out_ << ';';
29 mode_ = NoMode;
30 }
31
32 CYOutput &CYOutput::operator <<(char rhs) {
33 if (rhs == ' ' || rhs == '\n')
34 if (pretty_)
35 out_ << rhs;
36 else goto done;
37 else if (rhs == '\t')
38 if (pretty_)
39 for (unsigned i(0); i != indent_; ++i)
40 out_ << " ";
41 else goto done;
42 else if (rhs == '\r') {
43 if (right_) {
44 out_ << '\n';
45 right_ = false;
46 } goto done;
47 } else goto work;
48
49 right_ = true;
50 mode_ = NoMode;
51 goto done;
52
53 work:
54 if (mode_ == Terminated && rhs != '}') {
55 right_ = true;
56 out_ << ';';
57 }
58
59 if (rhs == ';') {
60 if (pretty_)
61 goto none;
62 else {
63 mode_ = Terminated;
64 goto done;
65 }
66 } else if (rhs == '+') {
67 if (mode_ == NoPlus)
68 out_ << ' ';
69 mode_ = NoPlus;
70 } else if (rhs == '-') {
71 if (mode_ == NoHyphen)
72 out_ << ' ';
73 mode_ = NoHyphen;
74 } else if (WordEndRange_[rhs]) {
75 if (mode_ == NoLetter)
76 out_ << ' ';
77 mode_ = NoLetter;
78 } else none:
79 mode_ = NoMode;
80
81 right_ = true;
82 out_ << rhs;
83 done:
84 return *this;
85 }
86
87 CYOutput &CYOutput::operator <<(const char *rhs) {
88 size_t size(strlen(rhs));
89
90 if (size == 1)
91 return *this << *rhs;
92
93 if (mode_ == Terminated)
94 out_ << ';';
95 else if (
96 mode_ == NoPlus && *rhs == '+' ||
97 mode_ == NoHyphen && *rhs == '-' ||
98 mode_ == NoLetter && WordEndRange_[*rhs]
99 )
100 out_ << ' ';
101
102 if (WordEndRange_[rhs[size - 1]])
103 mode_ = NoLetter;
104 else
105 mode_ = NoMode;
106
107 right_ = true;
108 out_ << rhs;
109 return *this;
110 }
111
112 void CYArgument::Output(CYOutput &out) const {
113 if (name_ != NULL) {
114 out << *name_;
115 if (value_ != NULL)
116 out << ':' << ' ';
117 }
118 if (value_ != NULL)
119 value_->Output(out, CYAssign::Precedence_, CYNoFlags);
120 if (next_ != NULL) {
121 out << ',';
122 out << ' ' << *next_;
123 }
124 }
125
126 void CYArray::Output(CYOutput &out, CYFlags flags) const {
127 out << '[' << elements_ << ']';
128 }
129
130 void CYArrayComprehension::Output(CYOutput &out, CYFlags flags) const {
131 out << '[' << *expression_ << ' ' << *comprehensions_ << ']';
132 }
133
134 void CYAssignment::Output(CYOutput &out, CYFlags flags) const {
135 lhs_->Output(out, Precedence() - 1, CYLeft(flags) | CYNoRightHand);
136 out << ' ' << Operator() << ' ';
137 rhs_->Output(out, Precedence(), CYRight(flags));
138 }
139
140 void CYBlock::Output(CYOutput &out) const {
141 out << '{' << '\n';
142 ++out.indent_;
143 if (statements_ != NULL)
144 statements_->Multiple(out);
145 --out.indent_;
146 out << '\t' << '}';
147 }
148
149 void CYBlock::Output(CYOutput &out, CYFlags flags) const {
150 if (statements_ == NULL)
151 out.Terminate();
152 else if (statements_->next_ == NULL)
153 statements_->Single(out, flags);
154 else
155 Output(out);
156 }
157
158 void CYBoolean::Output(CYOutput &out, CYFlags flags) const {
159 out << (Value() ? "true" : "false");
160 }
161
162 void CYBreak::Output(CYOutput &out, CYFlags flags) const {
163 out << "break";
164 if (label_ != NULL)
165 out << ' ' << *label_;
166 out << ';';
167 }
168
169 void CYCall::Output(CYOutput &out, CYFlags flags) const {
170 bool protect((flags & CYNoCall) != 0);
171 if (protect)
172 out << '(';
173 function_->Output(out, Precedence(), protect ? CYNoFlags : flags);
174 out << '(' << arguments_ << ')';
175 if (protect)
176 out << ')';
177 }
178
179 namespace cy {
180 namespace Syntax {
181
182 void Catch::Output(CYOutput &out) const {
183 out << ' ' << "catch" << ' ' << '(' << *name_ << ')' << ' ' << code_;
184 }
185
186 } }
187
188 void CYComment::Output(CYOutput &out, CYFlags flags) const {
189 out << '\r';
190 out.out_ << value_;
191 out.right_ = true;
192 out << '\r';
193 }
194
195 void CYCompound::Output(CYOutput &out, CYFlags flags) const {
196 if (next_ == NULL)
197 expression_->Output(out, flags);
198 else {
199 expression_->Output(out, CYLeft(flags));
200 out << ',' << ' ';
201 next_->Output(out, CYRight(flags));
202 }
203 }
204
205 void CYCondition::Output(CYOutput &out, CYFlags flags) const {
206 test_->Output(out, Precedence() - 1, CYLeft(flags));
207 out << ' ' << '?' << ' ';
208 if (true_ != NULL)
209 true_->Output(out, CYAssign::Precedence_, CYNoFlags);
210 out << ' ' << ':' << ' ';
211 false_->Output(out, CYAssign::Precedence_, CYRight(flags));
212 }
213
214 void CYContinue::Output(CYOutput &out, CYFlags flags) const {
215 out << "continue";
216 if (label_ != NULL)
217 out << ' ' << *label_;
218 out << ';';
219 }
220
221 void CYClause::Output(CYOutput &out) const {
222 if (case_ != NULL)
223 out << "case" << ' ' << *case_;
224 else
225 out << "default";
226 out << ':' << '\n';
227 if (statements_ != NULL)
228 statements_->Multiple(out);
229 out << next_;
230 }
231
232 void CYDebugger::Output(CYOutput &out, CYFlags flags) const {
233 out << "debugger" << ';';
234 }
235
236 void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const {
237 out << "var";
238 Output(out, CYRight(flags));
239 }
240
241 void CYDeclaration::Output(CYOutput &out, CYFlags flags) const {
242 out << *identifier_;
243 //out.out_ << ':' << identifier_->usage_ << '#' << identifier_->offset_;
244 if (initialiser_ != NULL) {
245 out << ' ' << '=' << ' ';
246 initialiser_->Output(out, CYAssign::Precedence_, CYRight(flags));
247 }
248 }
249
250 void CYForDeclarations::Output(CYOutput &out, CYFlags flags) const {
251 out << "var";
252 Output(out, CYRight(flags));
253 }
254
255 void CYDeclarations::Output(CYOutput &out) const {
256 Output(out, CYNoFlags);
257 }
258
259 void CYDeclarations::Output(CYOutput &out, CYFlags flags) const {
260 const CYDeclarations *declaration(this);
261 bool first(true);
262
263 for (;;) {
264 CYDeclarations *next(declaration->next_);
265
266 CYFlags jacks(first ? CYLeft(flags) : next == NULL ? CYRight(flags) : CYCenter(flags));
267 first = false;
268 declaration->declaration_->Output(out, jacks);
269
270 if (next == NULL)
271 break;
272
273 out << ',' << ' ';
274 declaration = next;
275 }
276 }
277
278 void CYDirectMember::Output(CYOutput &out, CYFlags flags) const {
279 object_->Output(out, Precedence(), CYLeft(flags) | CYNoInteger);
280 if (const char *word = property_->Word())
281 out << '.' << word;
282 else
283 out << '[' << *property_ << ']';
284 }
285
286 void CYDoWhile::Output(CYOutput &out, CYFlags flags) const {
287 out << "do";
288 code_->Single(out, CYCenter(flags));
289 out << "while" << ' ' << '(' << *test_ << ')';
290 }
291
292 void CYElement::Output(CYOutput &out) const {
293 if (value_ != NULL)
294 value_->Output(out, CYAssign::Precedence_, CYNoFlags);
295 if (next_ != NULL || value_ == NULL) {
296 out << ',';
297 if (next_ != NULL && next_->value_ != NULL)
298 out << ' ';
299 }
300 if (next_ != NULL)
301 next_->Output(out);
302 }
303
304 void CYEmpty::Output(CYOutput &out, CYFlags flags) const {
305 out.Terminate();
306 }
307
308 void CYExpress::Output(CYOutput &out, CYFlags flags) const {
309 expression_->Output(out, flags | CYNoBF);
310 out << ';';
311 }
312
313 void CYExpression::ClassName(CYOutput &out, bool object) const {
314 Output(out, CYAssign::Precedence_, CYNoFlags);
315 }
316
317 void CYExpression::ForIn(CYOutput &out, CYFlags flags) const {
318 Output(out, flags | CYNoRightHand);
319 }
320
321 void CYExpression::Output(CYOutput &out) const {
322 Output(out, CYNoFlags);
323 }
324
325 void CYExpression::Output(CYOutput &out, int precedence, CYFlags flags) const {
326 if (precedence < Precedence() || (flags & CYNoRightHand) != 0 && RightHand())
327 out << '(' << *this << ')';
328 else
329 Output(out, flags);
330 }
331
332 void CYExternal::Output(CYOutput &out, CYFlags flags) const {
333 out << "extern" << abi_ << typed_ << ';';
334 }
335
336 void CYFatArrow::Output(CYOutput &out, CYFlags flags) const {
337 out << '(' << parameters_ << ')' << ' ' << "=>" << ' ' << code_;
338 }
339
340 void CYFinally::Output(CYOutput &out) const {
341 out << ' ' << "finally" << ' ' << code_;
342 }
343
344 void CYFor::Output(CYOutput &out, CYFlags flags) const {
345 out << "for" << ' ' << '(';
346 if (initialiser_ != NULL)
347 initialiser_->Output(out, CYNoIn);
348 out.Terminate();
349 if (test_ != NULL)
350 out << ' ';
351 out << test_;
352 out.Terminate();
353 if (increment_ != NULL)
354 out << ' ';
355 out << increment_;
356 out << ')';
357 code_->Single(out, CYRight(flags));
358 }
359
360 void CYForOf::Output(CYOutput &out, CYFlags flags) const {
361 out << "for" << ' ' << "each" << ' ' << '(';
362 initialiser_->ForIn(out, CYNoIn);
363 out << "in" << *set_ << ')';
364 code_->Single(out, CYRight(flags));
365 }
366
367 void CYForOfComprehension::Output(CYOutput &out) const {
368 out << "for" << ' ' << "each" << ' ' << '(' << *name_ << ' ' << "in" << ' ' << *set_ << ')' << next_;
369 }
370
371 void CYForIn::Output(CYOutput &out, CYFlags flags) const {
372 out << "for" << ' ' << '(';
373 if (initialiser_ != NULL)
374 initialiser_->ForIn(out, CYNoIn);
375 out << "in" << *set_ << ')';
376 code_->Single(out, CYRight(flags));
377 }
378
379 void CYForInComprehension::Output(CYOutput &out) const {
380 out << "for" << ' ' << '(' << *name_ << ' ' << "in" << ' ' << *set_ << ')';
381 }
382
383 void CYFunction::Output(CYOutput &out, CYFlags flags) const {
384 // XXX: one could imagine using + here to save a byte
385 bool protect((flags & CYNoFunction) != 0);
386 if (protect)
387 out << '(';
388 out << "function";
389 if (name_ != NULL)
390 out << ' ' << *name_;
391 out << '(' << parameters_ << ')';
392 out << ' ' << code_;
393 if (protect)
394 out << ')';
395 }
396
397 void CYFunctionExpression::Output(CYOutput &out, CYFlags flags) const {
398 CYFunction::Output(out, flags);
399 }
400
401 void CYFunctionStatement::Output(CYOutput &out, CYFlags flags) const {
402 CYFunction::Output(out, flags);
403 }
404
405 void CYFunctionParameter::Output(CYOutput &out) const {
406 initialiser_->Output(out, CYNoFlags);
407 if (next_ != NULL)
408 out << ',' << ' ' << *next_;
409 }
410
411 const char *CYIdentifier::Word() const {
412 return replace_ == NULL || replace_ == this ? CYWord::Word() : replace_->Word();
413 }
414
415 void CYIf::Output(CYOutput &out, CYFlags flags) const {
416 bool protect(false);
417 if (false_ == NULL && (flags & CYNoDangle) != 0) {
418 protect = true;
419 out << '{';
420 }
421
422 out << "if" << ' ' << '(' << *test_ << ')';
423
424 CYFlags right(protect ? CYNoFlags : CYRight(flags));
425
426 CYFlags jacks(CYNoDangle);
427 if (false_ == NULL)
428 jacks |= right;
429 else
430 jacks |= protect ? CYNoFlags : CYCenter(flags);
431
432 true_->Single(out, jacks);
433
434 if (false_ != NULL) {
435 out << '\t' << "else";
436 false_->Single(out, right);
437 }
438
439 if (protect)
440 out << '}';
441 }
442
443 void CYIfComprehension::Output(CYOutput &out) const {
444 out << "if" << ' ' << '(' << *test_ << ')' << next_;
445 }
446
447 void CYImport::Output(CYOutput &out, CYFlags flags) const {
448 out << "@import";
449 }
450
451 void CYIndirectMember::Output(CYOutput &out, CYFlags flags) const {
452 object_->Output(out, Precedence(), CYLeft(flags));
453 if (const char *word = property_->Word())
454 out << "->" << word;
455 else
456 out << "->" << '[' << *property_ << ']';
457 }
458
459 void CYInfix::Output(CYOutput &out, CYFlags flags) const {
460 const char *name(Operator());
461 bool protect((flags & CYNoIn) != 0 && strcmp(name, "in") == 0);
462 if (protect)
463 out << '(';
464 CYFlags left(protect ? CYNoFlags : CYLeft(flags));
465 lhs_->Output(out, Precedence(), left);
466 out << ' ' << name << ' ';
467 CYFlags right(protect ? CYNoFlags : CYRight(flags));
468 rhs_->Output(out, Precedence() - 1, right);
469 if (protect)
470 out << ')';
471 }
472
473 void CYLabel::Output(CYOutput &out, CYFlags flags) const {
474 out << *name_ << ':' << ' ';
475 statement_->Single(out, CYRight(flags));
476 }
477
478 void CYTypeArrayOf::Output(CYOutput &out, CYIdentifier *identifier) const {
479 next_->Output(out, Precedence(), identifier);
480 out << '[';
481 out << size_;
482 out << ']';
483 }
484
485 void CYTypeBlockWith::Output(CYOutput &out, CYIdentifier *identifier) const {
486 out << '(' << '^';
487 next_->Output(out, Precedence(), identifier);
488 out << ')' << '(' << parameters_ << ')';
489 }
490
491 void CYTypeConstant::Output(CYOutput &out, CYIdentifier *identifier) const {
492 out << "const";
493 next_->Output(out, Precedence(), identifier);
494 }
495
496 void CYTypeFunctionWith::Output(CYOutput &out, CYIdentifier *identifier) const {
497 next_->Output(out, Precedence(), identifier);
498 out << '(' << parameters_ << ')';
499 }
500
501 void CYTypePointerTo::Output(CYOutput &out, CYIdentifier *identifier) const {
502 out << '*';
503 next_->Output(out, Precedence(), identifier);
504 }
505
506 void CYTypeVolatile::Output(CYOutput &out, CYIdentifier *identifier) const {
507 out << "volatile";
508 next_->Output(out, Precedence(), identifier);
509 }
510
511 void CYTypeModifier::Output(CYOutput &out, int precedence, CYIdentifier *identifier) const {
512 if (this == NULL) {
513 out << identifier;
514 return;
515 }
516
517 bool protect(precedence > Precedence());
518
519 if (protect)
520 out << '(';
521 Output(out, identifier);
522 if (protect)
523 out << ')';
524 }
525
526 void CYTypedIdentifier::Output(CYOutput &out) const {
527 specifier_->Output(out);
528 modifier_->Output(out, 0, identifier_);
529 }
530
531 void CYEncodedType::Output(CYOutput &out, CYFlags flags) const {
532 out << "@encode(" << typed_ << ")";
533 }
534
535 void CYTypedParameter::Output(CYOutput &out) const {
536 out << typed_;
537 if (next_ != NULL)
538 out << ',' << ' ' << next_;
539 }
540
541 void CYLambda::Output(CYOutput &out, CYFlags flags) const {
542 // XXX: this is seriously wrong
543 out << "[](";
544 out << ")->";
545 out << "{";
546 out << "}";
547 }
548
549 void CYTypeDefinition::Output(CYOutput &out, CYFlags flags) const {
550 out << "typedef" << *typed_;
551 }
552
553 void CYLetStatement::Output(CYOutput &out, CYFlags flags) const {
554 out << "let" << ' ' << '(' << *declarations_ << ')';
555 code_->Single(out, CYRight(flags));
556 }
557
558 void CYModule::Output(CYOutput &out) const {
559 out << part_;
560 if (next_ != NULL)
561 out << '.' << next_;
562 }
563
564 namespace cy {
565 namespace Syntax {
566
567 void New::Output(CYOutput &out, CYFlags flags) const {
568 out << "new" << ' ';
569 CYFlags jacks(CYNoCall | CYCenter(flags));
570 constructor_->Output(out, Precedence(), jacks);
571 if (arguments_ != NULL)
572 out << '(' << *arguments_ << ')';
573 }
574
575 } }
576
577 void CYNull::Output(CYOutput &out, CYFlags flags) const {
578 CYWord::Output(out);
579 }
580
581 void CYNumber::Output(CYOutput &out, CYFlags flags) const {
582 std::ostringstream str;
583 CYNumerify(str, Value());
584 std::string value(str.str());
585 out << value.c_str();
586 // XXX: this should probably also handle hex conversions and exponents
587 if ((flags & CYNoInteger) != 0 && value.find('.') == std::string::npos)
588 out << '.';
589 }
590
591 void CYNumber::PropertyName(CYOutput &out) const {
592 Output(out, CYNoFlags);
593 }
594
595 void CYObject::Output(CYOutput &out, CYFlags flags) const {
596 bool protect((flags & CYNoBrace) != 0);
597 if (protect)
598 out << '(';
599 out << '{' << '\n';
600 ++out.indent_;
601 out << properties_;
602 --out.indent_;
603 out << '\t' << '}';
604 if (protect)
605 out << ')';
606 }
607
608 void CYPostfix::Output(CYOutput &out, CYFlags flags) const {
609 lhs_->Output(out, Precedence(), CYLeft(flags));
610 out << Operator();
611 }
612
613 void CYPrefix::Output(CYOutput &out, CYFlags flags) const {
614 const char *name(Operator());
615 out << name;
616 if (Alphabetic())
617 out << ' ';
618 rhs_->Output(out, Precedence(), CYRight(flags));
619 }
620
621 void CYProgram::Output(CYOutput &out) const {
622 if (statements_ != NULL)
623 statements_->Multiple(out);
624 }
625
626 void CYProperty::Output(CYOutput &out) const {
627 out << '\t';
628 name_->PropertyName(out);
629 out << ':' << ' ';
630 value_->Output(out, CYAssign::Precedence_, CYNoFlags);
631 if (next_ != NULL)
632 out << ',' << '\n' << *next_;
633 else
634 out << '\n';
635 }
636
637 void CYRegEx::Output(CYOutput &out, CYFlags flags) const {
638 out << Value();
639 }
640
641 void CYReturn::Output(CYOutput &out, CYFlags flags) const {
642 out << "return";
643 if (value_ != NULL)
644 out << ' ' << *value_;
645 out << ';';
646 }
647
648 void CYRubyBlock::Output(CYOutput &out, CYFlags flags) const {
649 call_->Output(out, CYLeft(flags));
650 out << ' ';
651 proc_->Output(out, CYRight(flags));
652 }
653
654 void CYRubyProc::Output(CYOutput &out, CYFlags flags) const {
655 // XXX: this is not outputting the parameters
656 out << code_;
657 }
658
659 void CYStatement::Multiple(CYOutput &out, CYFlags flags) const {
660 bool first(true);
661 CYForEach (next, this) {
662 bool last(next->next_ == NULL);
663 CYFlags jacks(first ? last ? flags : CYLeft(flags) : last ? CYRight(flags) : CYCenter(flags));
664 first = false;
665 out << '\t';
666 next->Output(out, jacks);
667 out << '\n';
668 }
669 }
670
671 void CYStatement::Single(CYOutput &out, CYFlags flags) const {
672 if (this == NULL)
673 return out.Terminate();
674
675 _assert(next_ == NULL);
676 out << '\n';
677 ++out.indent_;
678 out << '\t';
679 Output(out, flags);
680 out << '\n';
681 --out.indent_;
682 }
683
684 void CYString::Output(CYOutput &out, CYFlags flags) const {
685 std::ostringstream str;
686 CYStringify(str, value_, size_);
687 out << str.str().c_str();
688 }
689
690 void CYString::PropertyName(CYOutput &out) const {
691 if (const char *word = Word())
692 out << word;
693 else
694 out << *this;
695 }
696
697 static const char *Reserved_[] = {
698 "false", "null", "true",
699
700 "break", "case", "catch", "continue", "default",
701 "delete", "do", "else", "finally", "for", "function",
702 "if", "in", "instanceof", "new", "return", "switch",
703 "this", "throw", "try", "typeof", "var", "void",
704 "while", "with",
705
706 "debugger", "const",
707
708 "class", "enum", "export", "extends", "import", "super",
709
710 "abstract", "boolean", "byte", "char", "double", "final",
711 "float", "goto", "int", "long", "native", "short",
712 "synchronized", "throws", "transient", "volatile",
713
714 "let", "yield",
715
716 NULL
717 };
718
719 const char *CYString::Word() const {
720 if (size_ == 0 || !WordStartRange_[value_[0]])
721 return NULL;
722 for (size_t i(1); i != size_; ++i)
723 if (!WordEndRange_[value_[i]])
724 return NULL;
725 const char *value(Value());
726 for (const char **reserved(Reserved_); *reserved != NULL; ++reserved)
727 if (strcmp(*reserved, value) == 0)
728 return NULL;
729 return value;
730 }
731
732 void CYSwitch::Output(CYOutput &out, CYFlags flags) const {
733 out << "switch" << ' ' << '(' << *value_ << ')' << ' ' << '{';
734 out << clauses_;
735 out << '}';
736 }
737
738 void CYThis::Output(CYOutput &out, CYFlags flags) const {
739 CYWord::Output(out);
740 }
741
742 namespace cy {
743 namespace Syntax {
744
745 void Throw::Output(CYOutput &out, CYFlags flags) const {
746 out << "throw";
747 if (value_ != NULL)
748 out << ' ' << *value_;
749 out << ';';
750 }
751
752 void Try::Output(CYOutput &out, CYFlags flags) const {
753 out << "try" << ' ' << code_ << catch_ << finally_;
754 }
755
756 } }
757
758 void CYTypeError::Output(CYOutput &out) const {
759 out << "@error";
760 }
761
762 void CYTypeLong::Output(CYOutput &out) const {
763 out << "long" << specifier_;
764 }
765
766 void CYTypeShort::Output(CYOutput &out) const {
767 out << "short" << specifier_;
768 }
769
770 void CYTypeSigned::Output(CYOutput &out) const {
771 out << "signed" << specifier_;
772 }
773
774 void CYTypeUnsigned::Output(CYOutput &out) const {
775 out << "unsigned" << specifier_;
776 }
777
778 void CYTypeVariable::Output(CYOutput &out) const {
779 out << *name_;
780 }
781
782 void CYTypeVoid::Output(CYOutput &out) const {
783 out << "void";
784 }
785
786 void CYVar::Output(CYOutput &out, CYFlags flags) const {
787 out << "var";
788 declarations_->Output(out, flags);
789 out << ';';
790 }
791
792 void CYVariable::Output(CYOutput &out, CYFlags flags) const {
793 out << *name_;
794 }
795
796 void CYWhile::Output(CYOutput &out, CYFlags flags) const {
797 out << "while" << '(' << *test_ << ')';
798 code_->Single(out, CYRight(flags));
799 }
800
801 void CYWith::Output(CYOutput &out, CYFlags flags) const {
802 out << "with" << '(' << *scope_ << ')';
803 code_->Single(out, CYRight(flags));
804 }
805
806 void CYWord::ClassName(CYOutput &out, bool object) const {
807 if (object)
808 out << "objc_getClass(";
809 out << '"' << Word() << '"';
810 if (object)
811 out << ')';
812 }
813
814 void CYWord::Output(CYOutput &out) const {
815 out << Word();
816 if (out.options_.verbose_)
817 out.out_ << '@' << this;
818 }
819
820 void CYWord::PropertyName(CYOutput &out) const {
821 Output(out);
822 }
823
824 const char *CYWord::Word() const {
825 return word_;
826 }