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