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