]>
git.saurik.com Git - cycript.git/blob - Output.cpp
987abf61c8c6fc791ab878140c4aa060354daeaa
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2015 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
);
674 void CYTypeBlockWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
676 next_
->Output(out
, Precedence(), identifier
);
677 out
<< ')' << '(' << parameters_
<< ')';
680 void CYTypeConstant::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
681 out
<< "const" << ' ';
682 next_
->Output(out
, Precedence(), identifier
);
685 void CYTypeFunctionWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
686 next_
->Output(out
, Precedence(), identifier
);
687 out
<< '(' << parameters_
;
689 if (parameters_
!= NULL
)
696 void CYTypePointerTo::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
698 next_
->Output(out
, Precedence(), identifier
);
701 void CYTypeVolatile::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
703 next_
->Output(out
, Precedence(), identifier
);
706 void CYTypeModifier::Output(CYOutput
&out
, int precedence
, CYIdentifier
*identifier
) const {
712 bool protect(precedence
> Precedence());
716 Output(out
, identifier
);
721 void CYTypedIdentifier::Output(CYOutput
&out
) const {
722 specifier_
->Output(out
);
723 modifier_
->Output(out
, 0, identifier_
);
726 void CYEncodedType::Output(CYOutput
&out
, CYFlags flags
) const {
727 out
<< "@encode(" << typed_
<< ")";
730 void CYTypedParameter::Output(CYOutput
&out
) const {
733 out
<< ',' << ' ' << next_
;
736 void CYLambda::Output(CYOutput
&out
, CYFlags flags
) const {
737 // XXX: this is seriously wrong
744 void CYTypeDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
745 out
<< "typedef" << ' ' << *typed_
;
749 void CYTypeExpression::Output(CYOutput
&out
, CYFlags flags
) const {
750 out
<< '(' << "typedef" << ' ' << *typed_
<< ')';
753 void CYLexical::Output(CYOutput
&out
, CYFlags flags
) const {
755 bindings_
->Output(out
, flags
); // XXX: flags
759 void CYModule::Output(CYOutput
&out
) const {
768 void New::Output(CYOutput
&out
, CYFlags flags
) const {
770 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
771 constructor_
->Output(out
, Precedence(), jacks
);
772 if (arguments_
!= NULL
)
773 out
<< '(' << *arguments_
<< ')';
778 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
782 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
783 std::ostringstream str
;
784 CYNumerify(str
, Value());
785 std::string
value(str
.str());
786 out
<< value
.c_str();
787 // XXX: this should probably also handle hex conversions and exponents
788 if ((flags
& CYNoInteger
) != 0 && value
.find('.') == std::string::npos
)
792 void CYNumber::PropertyName(CYOutput
&out
) const {
793 Output(out
, CYNoFlags
);
796 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
797 bool protect((flags
& CYNoBrace
) != 0);
809 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
810 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
814 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
815 const char *name(Operator());
819 rhs_
->Output(out
, Precedence(), CYRight(flags
));
822 void CYScript::Output(CYOutput
&out
) const {
826 void CYProperty::Output(CYOutput
&out
) const {
827 if (next_
!= NULL
|| out
.pretty_
)
829 out
<< '\n' << next_
;
832 void CYPropertyGetter::Output(CYOutput
&out
) const {
834 name_
->PropertyName(out
);
835 CYFunction::Output(out
);
836 CYProperty::Output(out
);
839 void CYPropertyMethod::Output(CYOutput
&out
) const {
840 name_
->PropertyName(out
);
841 CYFunction::Output(out
);
842 CYProperty::Output(out
);
845 void CYPropertySetter::Output(CYOutput
&out
) const {
847 name_
->PropertyName(out
);
848 CYFunction::Output(out
);
849 CYProperty::Output(out
);
852 void CYPropertyValue::Output(CYOutput
&out
) const {
854 name_
->PropertyName(out
);
856 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
857 CYProperty::Output(out
);
860 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
864 void CYResolveMember::Output(CYOutput
&out
, CYFlags flags
) const {
865 object_
->Output(out
, Precedence(), CYLeft(flags
));
866 if (const char *word
= property_
->Word())
869 out
<< "::" << '[' << *property_
<< ']';
872 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
875 out
<< ' ' << *value_
;
879 void CYRubyBlock::Output(CYOutput
&out
, CYFlags flags
) const {
880 lhs_
->Output(out
, CYLeft(flags
));
882 proc_
->Output(out
, CYRight(flags
));
885 void CYRubyProc::Output(CYOutput
&out
, CYFlags flags
) const {
886 out
<< '{' << ' ' << '|' << parameters_
<< '|' << '\n';
893 void CYSubscriptMember::Output(CYOutput
&out
, CYFlags flags
) const {
894 object_
->Output(out
, Precedence(), CYLeft(flags
));
895 out
<< "." << '[' << *property_
<< ']';
898 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
900 CYForEach (next
, this) {
901 bool last(next
->next_
== NULL
);
902 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYRight(flags
) : CYCenter(flags
));
905 next
->Output(out
, jacks
);
910 void CYStatement::Single(CYOutput
&out
, CYFlags flags
, CYCompactType request
) const {
912 return out
.Terminate();
914 _assert(next_
== NULL
);
916 CYCompactType
compact(Compact());
918 if (compact
>= request
)
928 if (compact
< request
)
932 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
933 std::ostringstream str
;
934 CYStringify(str
, value_
, size_
);
935 out
<< str
.str().c_str();
938 void CYString::PropertyName(CYOutput
&out
) const {
939 if (const char *word
= Word())
945 static const char *Reserved_
[] = {
946 "false", "null", "true",
948 "break", "case", "catch", "continue", "default",
949 "delete", "do", "else", "finally", "for", "function",
950 "if", "in", "instanceof", "new", "return", "switch",
951 "this", "throw", "try", "typeof", "var", "void",
956 "class", "enum", "export", "extends", "import", "super",
958 "abstract", "boolean", "byte", "char", "double", "final",
959 "float", "goto", "int", "long", "native", "short",
960 "synchronized", "throws", "transient", "volatile",
967 const char *CYString::Word() const {
968 if (size_
== 0 || !WordStartRange_
[value_
[0]])
970 for (size_t i(1); i
!= size_
; ++i
)
971 if (!WordEndRange_
[value_
[i
]])
973 const char *value(Value());
974 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
975 if (strcmp(*reserved
, value
) == 0)
980 void CYStructDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
981 out
<< "struct" << ' ' << *name_
<< *tail_
;
984 void CYStructTail::Output(CYOutput
&out
) const {
985 out
<< ' ' << '{' << '\n';
987 CYForEach (field
, fields_
) {
988 out
<< '\t' << *field
->typed_
;
996 void CYSuperAccess::Output(CYOutput
&out
, CYFlags flags
) const {
998 if (const char *word
= property_
->Word())
1001 out
<< '[' << *property_
<< ']';
1004 void CYSuperCall::Output(CYOutput
&out
, CYFlags flags
) const {
1005 out
<< "super" << '(' << arguments_
<< ')';
1008 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
1009 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{' << '\n';
1016 void CYSymbol::Output(CYOutput
&out
, CYFlags flags
) const {
1017 bool protect((flags
& CYNoColon
) != 0);
1020 out
<< ':' << name_
;
1025 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
1032 void Throw::Output(CYOutput
&out
, CYFlags flags
) const {
1035 out
<< ' ' << *value_
;
1039 void Try::Output(CYOutput
&out
, CYFlags flags
) const {
1040 out
<< "try" << ' ';
1046 out
<< catch_
<< finally_
;
1051 void CYTypeCharacter::Output(CYOutput
&out
) const {
1053 case CYTypeNeutral
: break;
1054 case CYTypeSigned
: out
<< "signed" << ' '; break;
1055 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1061 void CYTypeError::Output(CYOutput
&out
) const {
1065 void CYTypeIntegral::Output(CYOutput
&out
) const {
1066 if (signing_
== CYTypeUnsigned
)
1067 out
<< "unsigned" << ' ';
1069 case 0: out
<< "short"; break;
1070 case 1: out
<< "int"; break;
1071 case 2: out
<< "long"; break;
1072 case 3: out
<< "long" << ' ' << "long"; break;
1073 default: _assert(false);
1077 void CYTypeStruct::Output(CYOutput
&out
) const {
1080 out
<< ' ' << *name_
;
1085 void CYTypeReference::Output(CYOutput
&out
) const {
1086 out
<< "struct" << ' ' << *name_
;
1089 void CYTypeVariable::Output(CYOutput
&out
) const {
1093 void CYTypeVoid::Output(CYOutput
&out
) const {
1097 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
1098 out
<< "var" << ' ';
1099 bindings_
->Output(out
, flags
); // XXX: flags
1103 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
1107 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
1108 out
<< "while" << ' ' << '(' << *test_
<< ')';
1109 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1112 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
1113 out
<< "with" << ' ' << '(' << *scope_
<< ')';
1114 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1117 void CYWord::Output(CYOutput
&out
) const {
1119 if (out
.options_
.verbose_
) {
1122 sprintf(number
, "%p", this);
1127 void CYWord::PropertyName(CYOutput
&out
) const {
1131 const char *CYWord::Word() const {