]>
git.saurik.com Git - cycript.git/blob - Output.cpp
0bc11727f29c47ed99bc86ce772bc51c2357d1b7
1 /* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
5 /* GNU Affero General Public License, Version 3 {{{ */
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.
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.
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/>.
28 void CYStringify(std::ostringstream
&str
, const char *data
, size_t size
, bool c
) {
33 unsigned quot(0), apos(0);
34 for (const char *value(data
), *end(data
+ size
); value
!= end
; ++value
)
37 else if (*value
== '\'')
43 str
<< (single
? '\'' : '"');
45 for (const char *value(data
), *end(data
+ size
); value
!= end
; ++value
)
46 switch (uint8_t next
= *value
) {
47 case '\\': str
<< "\\\\"; break;
48 case '\b': str
<< "\\b"; break;
49 case '\f': str
<< "\\f"; break;
50 case '\n': str
<< "\\n"; break;
51 case '\r': str
<< "\\r"; break;
52 case '\t': str
<< "\\t"; break;
53 case '\v': str
<< "\\v"; break;
68 if (value
[1] >= '0' && value
[1] <= '9')
75 if (next
>= 0x20 && next
< 0x7f) simple
:
79 if ((next
& 0x80) != 0)
80 while ((next
& 0x80 >> ++levels
) != 0);
82 unsigned point(next
& 0xff >> levels
);
84 point
= point
<< 6 | uint8_t(*++value
) & 0x3f;
87 str
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << point
;
88 else if (point
< 0x10000)
89 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << point
;
92 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xd800 | point
>> 0x0a);
93 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xdc00 | point
& 0x3ff);
98 str
<< (single
? '\'' : '"');
101 void CYNumerify(std::ostringstream
&str
, double value
) {
102 if (std::isinf(value
)) {
110 // XXX: I want this to print 1e3 rather than 1000
111 sprintf(string
, "%.17g", value
);
115 void CYOutput::Terminate() {
120 CYOutput
&CYOutput::operator <<(char rhs
) {
121 if (rhs
== ' ' || rhs
== '\n')
125 else if (rhs
== '\t')
127 for (unsigned i(0); i
!= indent_
; ++i
)
130 else if (rhs
== '\r') {
142 if (mode_
== Terminated
&& rhs
!= '}') {
154 } else if (rhs
== '+') {
158 } else if (rhs
== '-') {
159 if (mode_
== NoHyphen
)
162 } else if (WordEndRange_
[rhs
]) {
163 if (mode_
== NoLetter
)
175 CYOutput
&CYOutput::operator <<(const char *rhs
) {
176 size_t size(strlen(rhs
));
179 return *this << *rhs
;
181 if (mode_
== Terminated
)
184 mode_
== NoPlus
&& *rhs
== '+' ||
185 mode_
== NoHyphen
&& *rhs
== '-' ||
186 mode_
== NoLetter
&& WordEndRange_
[*rhs
]
190 char last(rhs
[size
- 1]);
191 if (WordEndRange_
[last
] || last
== '/')
197 operator ()(rhs
, size
);
201 void CYArgument::Output(CYOutput
&out
) const {
208 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
211 out
<< ' ' << *next_
;
215 void CYArray::Output(CYOutput
&out
, CYFlags flags
) const {
216 out
<< '[' << elements_
<< ']';
219 void CYArrayComprehension::Output(CYOutput
&out
, CYFlags flags
) const {
220 out
<< '[' << *expression_
<< ' ' << *comprehensions_
<< ']';
223 void CYAssignment::Output(CYOutput
&out
, CYFlags flags
) const {
224 lhs_
->Output(out
, Precedence() - 1, CYLeft(flags
) | CYNoRightHand
);
225 out
<< ' ' << Operator() << ' ';
226 rhs_
->Output(out
, Precedence(), CYRight(flags
));
229 void CYBlock::Output(CYOutput
&out
, CYFlags flags
) const {
237 void CYBoolean::Output(CYOutput
&out
, CYFlags flags
) const {
238 out
<< '!' << (Value() ? "0" : "1");
239 if ((flags
& CYNoInteger
) != 0)
243 void CYBreak::Output(CYOutput
&out
, CYFlags flags
) const {
246 out
<< ' ' << *label_
;
250 void CYCall::Output(CYOutput
&out
, CYFlags flags
) const {
251 bool protect((flags
& CYNoCall
) != 0);
254 function_
->Output(out
, Precedence(), protect
? CYNoFlags
: flags
);
255 out
<< '(' << arguments_
<< ')';
263 void Catch::Output(CYOutput
&out
) const {
264 out
<< ' ' << "catch" << ' ' << '(' << *name_
<< ')' << ' ';
274 void CYClassExpression::Output(CYOutput
&out
, CYFlags flags
) const {
275 bool protect((flags
& CYNoClass
) != 0);
280 out
<< ' ' << *name_
;
286 void CYClassStatement::Output(CYOutput
&out
, CYFlags flags
) const {
287 out
<< "class" << ' ' << *name_
<< *tail_
;
290 void CYClassTail::Output(CYOutput
&out
) const {
291 if (extends_
== NULL
)
296 out
<< "extends" << ' ';
297 extends_
->Output(out
, CYAssign::Precedence_
- 1, CYNoFlags
);
309 void CYCompound::Output(CYOutput
&out
, CYFlags flags
) const {
311 expression_
->Output(out
, flags
);
313 expression_
->Output(out
, CYLeft(flags
));
315 next_
->Output(out
, CYRight(flags
));
319 void CYComputed::PropertyName(CYOutput
&out
) const {
321 expression_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
325 void CYCondition::Output(CYOutput
&out
, CYFlags flags
) const {
326 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
327 out
<< ' ' << '?' << ' ';
329 true_
->Output(out
, CYAssign::Precedence_
, CYNoColon
);
330 out
<< ' ' << ':' << ' ';
331 false_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
334 void CYContinue::Output(CYOutput
&out
, CYFlags flags
) const {
337 out
<< ' ' << *label_
;
341 void CYClause::Output(CYOutput
&out
) const {
346 out
<< "case" << ' ';
347 value_
->Output(out
, CYNoColon
);
356 void CYDebugger::Output(CYOutput
&out
, CYFlags flags
) const {
357 out
<< "debugger" << ';';
360 void CYBinding::Output(CYOutput
&out
, CYFlags flags
) const {
362 //out.out_ << ':' << identifier_->usage_ << '#' << identifier_->offset_;
363 if (initializer_
!= NULL
) {
364 out
<< ' ' << '=' << ' ';
365 initializer_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
369 void CYBindings::Output(CYOutput
&out
) const {
370 Output(out
, CYNoFlags
);
373 void CYBindings::Output(CYOutput
&out
, CYFlags flags
) const {
374 const CYBindings
*binding(this);
378 CYBindings
*next(binding
->next_
);
380 CYFlags
jacks(first
? CYLeft(flags
) : next
== NULL
? CYRight(flags
) : CYCenter(flags
));
382 binding
->binding_
->Output(out
, jacks
);
392 void CYDirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
393 object_
->Output(out
, Precedence(), CYLeft(flags
) | CYNoInteger
);
394 if (const char *word
= property_
->Word())
397 out
<< '[' << *property_
<< ']';
400 void CYDoWhile::Output(CYOutput
&out
, CYFlags flags
) const {
403 unsigned line(out
.position_
.line
);
404 unsigned indent(out
.indent_
);
405 code_
->Single(out
, CYCenter(flags
), CYCompactLong
);
407 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
412 out
<< "while" << ' ' << '(' << *test_
<< ')';
415 void CYElementSpread::Output(CYOutput
&out
) const {
416 out
<< "..." << value_
;
419 void CYElementValue::Output(CYOutput
&out
) const {
421 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
422 if (next_
!= NULL
|| value_
== NULL
) {
424 if (next_
!= NULL
&& !next_
->Elision())
431 void CYEmpty::Output(CYOutput
&out
, CYFlags flags
) const {
435 void CYEval::Output(CYOutput
&out
, CYFlags flags
) const {
439 void CYExpress::Output(CYOutput
&out
, CYFlags flags
) const {
440 expression_
->Output(out
, flags
| CYNoBFC
);
444 void CYExpression::Output(CYOutput
&out
) const {
445 Output(out
, CYNoFlags
);
448 void CYExpression::Output(CYOutput
&out
, int precedence
, CYFlags flags
) const {
449 if (precedence
< Precedence() || (flags
& CYNoRightHand
) != 0 && RightHand())
450 out
<< '(' << *this << ')';
455 void CYExtend::Output(CYOutput
&out
, CYFlags flags
) const {
456 lhs_
->Output(out
, CYLeft(flags
));
457 out
<< ' ' << object_
;
460 void CYExternal::Output(CYOutput
&out
, CYFlags flags
) const {
461 out
<< "extern" << ' ' << abi_
<< ' ' << typed_
;
465 void CYFatArrow::Output(CYOutput
&out
, CYFlags flags
) const {
466 out
<< '(' << parameters_
<< ')' << ' ' << "=>" << ' ' << '{' << code_
<< '}';
469 void CYFinally::Output(CYOutput
&out
) const {
470 out
<< ' ' << "finally" << ' ';
478 void CYFor::Output(CYOutput
&out
, CYFlags flags
) const {
479 out
<< "for" << ' ' << '(';
480 if (initializer_
!= NULL
)
481 initializer_
->Output(out
, CYNoIn
);
487 if (increment_
!= NULL
)
491 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
494 void CYForLexical::Output(CYOutput
&out
, CYFlags flags
) const {
495 out
<< (constant_
? "const" : "let") << ' ';
496 binding_
->Output(out
, CYRight(flags
));
499 void CYForIn::Output(CYOutput
&out
, CYFlags flags
) const {
500 out
<< "for" << ' ' << '(';
501 initializer_
->Output(out
, CYNoIn
| CYNoRightHand
);
502 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
503 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
506 void CYForInitialized::Output(CYOutput
&out
, CYFlags flags
) const {
507 out
<< "for" << ' ' << '(' << "var" << ' ';
508 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
509 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
510 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
513 void CYForInComprehension::Output(CYOutput
&out
) const {
514 out
<< "for" << ' ' << '(';
515 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
516 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
519 void CYForOf::Output(CYOutput
&out
, CYFlags flags
) const {
520 out
<< "for" << ' ' << '(';
521 initializer_
->Output(out
, CYNoRightHand
);
522 out
<< ' ' << "of" << ' ' << *iterable_
<< ')';
523 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
526 void CYForOfComprehension::Output(CYOutput
&out
) const {
527 out
<< "for" << ' ' << '(';
528 binding_
->Output(out
, CYNoRightHand
);
529 out
<< ' ' << "of" << ' ' << *iterable_
<< ')' << next_
;
532 void CYForVariable::Output(CYOutput
&out
, CYFlags flags
) const {
534 binding_
->Output(out
, CYRight(flags
));
537 void CYFunction::Output(CYOutput
&out
) const {
538 out
<< '(' << parameters_
<< ')' << ' ';
546 void CYFunctionExpression::Output(CYOutput
&out
, CYFlags flags
) const {
547 // XXX: one could imagine using + here to save a byte
548 bool protect((flags
& CYNoFunction
) != 0);
553 out
<< ' ' << *name_
;
554 CYFunction::Output(out
);
559 void CYFunctionStatement::Output(CYOutput
&out
, CYFlags flags
) const {
560 out
<< "function" << ' ' << *name_
;
561 CYFunction::Output(out
);
564 void CYFunctionParameter::Output(CYOutput
&out
) const {
565 binding_
->Output(out
, CYNoFlags
);
567 out
<< ',' << ' ' << *next_
;
570 const char *CYIdentifier::Word() const {
571 return next_
== NULL
|| next_
== this ? CYWord::Word() : next_
->Word();
574 void CYIf::Output(CYOutput
&out
, CYFlags flags
) const {
576 if (false_
== NULL
&& (flags
& CYNoDangle
) != 0) {
581 out
<< "if" << ' ' << '(' << *test_
<< ')';
583 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
585 CYFlags
jacks(CYNoDangle
);
589 jacks
|= protect
? CYNoFlags
: CYCenter(flags
);
591 unsigned line(out
.position_
.line
);
592 unsigned indent(out
.indent_
);
593 true_
->Single(out
, jacks
, CYCompactShort
);
595 if (false_
!= NULL
) {
596 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
602 false_
->Single(out
, right
, CYCompactLong
);
609 void CYIfComprehension::Output(CYOutput
&out
) const {
610 out
<< "if" << ' ' << '(' << *test_
<< ')' << next_
;
613 void CYImport::Output(CYOutput
&out
, CYFlags flags
) const {
617 void CYImportDeclaration::Output(CYOutput
&out
, CYFlags flags
) const {
621 void CYIndirect::Output(CYOutput
&out
, CYFlags flags
) const {
623 rhs_
->Output(out
, Precedence(), CYRight(flags
));
626 void CYIndirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
627 object_
->Output(out
, Precedence(), CYLeft(flags
));
628 if (const char *word
= property_
->Word())
631 out
<< "->" << '[' << *property_
<< ']';
634 void CYInfix::Output(CYOutput
&out
, CYFlags flags
) const {
635 const char *name(Operator());
636 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in") == 0);
639 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
640 lhs_
->Output(out
, Precedence(), left
);
641 out
<< ' ' << name
<< ' ';
642 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
643 rhs_
->Output(out
, Precedence() - 1, right
);
648 void CYLabel::Output(CYOutput
&out
, CYFlags flags
) const {
649 out
<< *name_
<< ':';
650 statement_
->Single(out
, CYRight(flags
), CYCompactShort
);
653 void CYParenthetical::Output(CYOutput
&out
, CYFlags flags
) const {
655 expression_
->Output(out
, CYCompound::Precedence_
, CYNoFlags
);
659 void CYStatement::Output(CYOutput
&out
) const {
663 void CYTemplate::Output(CYOutput
&out
, CYFlags flags
) const {
667 void CYTypeArrayOf::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
668 next_
->Output(out
, Precedence(), identifier
, false);
674 void CYTypeBlockWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
676 next_
->Output(out
, Precedence(), identifier
, false);
677 out
<< ')' << '(' << parameters_
<< ')';
680 void CYTypeConstant::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
682 next_
->Output(out
, Precedence(), identifier
, false);
685 void CYTypeFunctionWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
686 next_
->Output(out
, Precedence(), identifier
, false);
687 out
<< '(' << parameters_
;
689 if (parameters_
!= NULL
)
696 void CYTypePointerTo::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
698 next_
->Output(out
, Precedence(), identifier
, false);
701 void CYTypeVolatile::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
703 next_
->Output(out
, Precedence(), identifier
, true);
706 void CYTypeModifier::Output(CYOutput
&out
, int precedence
, CYIdentifier
*identifier
, bool space
) const {
707 if (this == NULL
&& identifier
== NULL
)
717 bool protect(precedence
> Precedence());
721 Output(out
, identifier
);
726 void CYTypedIdentifier::Output(CYOutput
&out
) const {
727 specifier_
->Output(out
);
728 modifier_
->Output(out
, 0, identifier_
, true);
731 void CYEncodedType::Output(CYOutput
&out
, CYFlags flags
) const {
732 out
<< "@encode(" << typed_
<< ")";
735 void CYTypedParameter::Output(CYOutput
&out
) const {
738 out
<< ',' << ' ' << next_
;
741 void CYLambda::Output(CYOutput
&out
, CYFlags flags
) const {
742 // XXX: this is seriously wrong
749 void CYTypeDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
750 out
<< "typedef" << ' ' << *typed_
;
754 void CYTypeExpression::Output(CYOutput
&out
, CYFlags flags
) const {
755 out
<< '(' << "typedef" << ' ' << *typed_
<< ')';
758 void CYLexical::Output(CYOutput
&out
, CYFlags flags
) const {
760 bindings_
->Output(out
, flags
); // XXX: flags
764 void CYModule::Output(CYOutput
&out
) const {
773 void New::Output(CYOutput
&out
, CYFlags flags
) const {
775 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
776 constructor_
->Output(out
, Precedence(), jacks
);
777 if (arguments_
!= NULL
)
778 out
<< '(' << *arguments_
<< ')';
783 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
787 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
788 std::ostringstream str
;
789 CYNumerify(str
, Value());
790 std::string
value(str
.str());
791 out
<< value
.c_str();
792 // XXX: this should probably also handle hex conversions and exponents
793 if ((flags
& CYNoInteger
) != 0 && value
.find('.') == std::string::npos
)
797 void CYNumber::PropertyName(CYOutput
&out
) const {
798 Output(out
, CYNoFlags
);
801 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
802 bool protect((flags
& CYNoBrace
) != 0);
814 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
815 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
819 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
820 const char *name(Operator());
824 rhs_
->Output(out
, Precedence(), CYRight(flags
));
827 void CYScript::Output(CYOutput
&out
) const {
831 void CYProperty::Output(CYOutput
&out
) const {
832 if (next_
!= NULL
|| out
.pretty_
)
834 out
<< '\n' << next_
;
837 void CYPropertyGetter::Output(CYOutput
&out
) const {
839 name_
->PropertyName(out
);
840 CYFunction::Output(out
);
841 CYProperty::Output(out
);
844 void CYPropertyMethod::Output(CYOutput
&out
) const {
845 name_
->PropertyName(out
);
846 CYFunction::Output(out
);
847 CYProperty::Output(out
);
850 void CYPropertySetter::Output(CYOutput
&out
) const {
852 name_
->PropertyName(out
);
853 CYFunction::Output(out
);
854 CYProperty::Output(out
);
857 void CYPropertyValue::Output(CYOutput
&out
) const {
859 name_
->PropertyName(out
);
861 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
862 CYProperty::Output(out
);
865 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
869 void CYResolveMember::Output(CYOutput
&out
, CYFlags flags
) const {
870 object_
->Output(out
, Precedence(), CYLeft(flags
));
871 if (const char *word
= property_
->Word())
874 out
<< "::" << '[' << *property_
<< ']';
877 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
880 out
<< ' ' << *value_
;
884 void CYRubyBlock::Output(CYOutput
&out
, CYFlags flags
) const {
885 lhs_
->Output(out
, CYLeft(flags
));
887 proc_
->Output(out
, CYRight(flags
));
890 void CYRubyProc::Output(CYOutput
&out
, CYFlags flags
) const {
891 out
<< '{' << ' ' << '|' << parameters_
<< '|' << '\n';
898 void CYSubscriptMember::Output(CYOutput
&out
, CYFlags flags
) const {
899 object_
->Output(out
, Precedence(), CYLeft(flags
));
900 out
<< "." << '[' << *property_
<< ']';
903 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
905 CYForEach (next
, this) {
906 bool last(next
->next_
== NULL
);
907 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYRight(flags
) : CYCenter(flags
));
910 next
->Output(out
, jacks
);
915 void CYStatement::Single(CYOutput
&out
, CYFlags flags
, CYCompactType request
) const {
917 return out
.Terminate();
919 _assert(next_
== NULL
);
921 CYCompactType
compact(Compact());
923 if (compact
>= request
)
933 if (compact
< request
)
937 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
938 std::ostringstream str
;
939 CYStringify(str
, value_
, size_
);
940 out
<< str
.str().c_str();
943 void CYString::PropertyName(CYOutput
&out
) const {
944 if (const char *word
= Word())
950 static const char *Reserved_
[] = {
951 "false", "null", "true",
953 "break", "case", "catch", "continue", "default",
954 "delete", "do", "else", "finally", "for", "function",
955 "if", "in", "instanceof", "new", "return", "switch",
956 "this", "throw", "try", "typeof", "var", "void",
961 "class", "enum", "export", "extends", "import", "super",
963 "abstract", "boolean", "byte", "char", "double", "final",
964 "float", "goto", "int", "long", "native", "short",
965 "synchronized", "throws", "transient", "volatile",
972 const char *CYString::Word() const {
973 if (size_
== 0 || !WordStartRange_
[value_
[0]])
975 for (size_t i(1); i
!= size_
; ++i
)
976 if (!WordEndRange_
[value_
[i
]])
978 const char *value(Value());
979 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
980 if (strcmp(*reserved
, value
) == 0)
985 void CYStructDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
986 out
<< "struct" << ' ' << *name_
<< *tail_
;
989 void CYStructTail::Output(CYOutput
&out
) const {
990 out
<< ' ' << '{' << '\n';
992 CYForEach (field
, fields_
) {
993 out
<< '\t' << *field
->typed_
;
1001 void CYSuperAccess::Output(CYOutput
&out
, CYFlags flags
) const {
1003 if (const char *word
= property_
->Word())
1006 out
<< '[' << *property_
<< ']';
1009 void CYSuperCall::Output(CYOutput
&out
, CYFlags flags
) const {
1010 out
<< "super" << '(' << arguments_
<< ')';
1013 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
1014 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{' << '\n';
1021 void CYSymbol::Output(CYOutput
&out
, CYFlags flags
) const {
1022 bool protect((flags
& CYNoColon
) != 0);
1025 out
<< ':' << name_
;
1030 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
1037 void Throw::Output(CYOutput
&out
, CYFlags flags
) const {
1040 out
<< ' ' << *value_
;
1044 void Try::Output(CYOutput
&out
, CYFlags flags
) const {
1045 out
<< "try" << ' ';
1051 out
<< catch_
<< finally_
;
1056 void CYTypeCharacter::Output(CYOutput
&out
) const {
1058 case CYTypeNeutral
: break;
1059 case CYTypeSigned
: out
<< "signed" << ' '; break;
1060 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1066 void CYTypeError::Output(CYOutput
&out
) const {
1070 void CYTypeIntegral::Output(CYOutput
&out
) const {
1071 if (signing_
== CYTypeUnsigned
)
1072 out
<< "unsigned" << ' ';
1074 case 0: out
<< "short"; break;
1075 case 1: out
<< "int"; break;
1076 case 2: out
<< "long"; break;
1077 case 3: out
<< "long" << ' ' << "long"; break;
1078 default: _assert(false);
1082 void CYTypeStruct::Output(CYOutput
&out
) const {
1085 out
<< ' ' << *name_
;
1090 void CYTypeReference::Output(CYOutput
&out
) const {
1091 out
<< "struct" << ' ' << *name_
;
1094 void CYTypeVariable::Output(CYOutput
&out
) const {
1098 void CYTypeVoid::Output(CYOutput
&out
) const {
1102 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
1103 out
<< "var" << ' ';
1104 bindings_
->Output(out
, flags
); // XXX: flags
1108 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
1112 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
1113 out
<< "while" << ' ' << '(' << *test_
<< ')';
1114 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1117 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
1118 out
<< "with" << ' ' << '(' << *scope_
<< ')';
1119 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1122 void CYWord::Output(CYOutput
&out
) const {
1124 if (out
.options_
.verbose_
) {
1127 sprintf(number
, "%p", this);
1132 void CYWord::PropertyName(CYOutput
&out
) const {
1136 const char *CYWord::Word() const {