]>
git.saurik.com Git - cycript.git/blob - Output.cpp
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 CYExternal::Output(CYOutput
&out
, CYFlags flags
) const {
456 out
<< "extern" << abi_
<< typed_
;
460 void CYFatArrow::Output(CYOutput
&out
, CYFlags flags
) const {
461 out
<< '(' << parameters_
<< ')' << ' ' << "=>" << ' ' << '{' << code_
<< '}';
464 void CYFinally::Output(CYOutput
&out
) const {
465 out
<< ' ' << "finally" << ' ';
473 void CYFor::Output(CYOutput
&out
, CYFlags flags
) const {
474 out
<< "for" << ' ' << '(';
475 if (initializer_
!= NULL
)
476 initializer_
->Output(out
, CYNoIn
);
482 if (increment_
!= NULL
)
486 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
489 void CYForLexical::Output(CYOutput
&out
, CYFlags flags
) const {
490 out
<< (constant_
? "const" : "let") << ' ';
491 binding_
->Output(out
, CYRight(flags
));
494 void CYForIn::Output(CYOutput
&out
, CYFlags flags
) const {
495 out
<< "for" << ' ' << '(';
496 initializer_
->Output(out
, CYNoIn
| CYNoRightHand
);
497 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
498 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
501 void CYForInitialized::Output(CYOutput
&out
, CYFlags flags
) const {
502 out
<< "for" << ' ' << '(' << "var" << ' ';
503 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
504 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
505 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
508 void CYForInComprehension::Output(CYOutput
&out
) const {
509 out
<< "for" << ' ' << '(';
510 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
511 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
514 void CYForOf::Output(CYOutput
&out
, CYFlags flags
) const {
515 out
<< "for" << ' ' << '(';
516 initializer_
->Output(out
, CYNoRightHand
);
517 out
<< ' ' << "of" << ' ' << *iterable_
<< ')';
518 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
521 void CYForOfComprehension::Output(CYOutput
&out
) const {
522 out
<< "for" << ' ' << '(';
523 binding_
->Output(out
, CYNoRightHand
);
524 out
<< ' ' << "of" << ' ' << *iterable_
<< ')' << next_
;
527 void CYForVariable::Output(CYOutput
&out
, CYFlags flags
) const {
529 binding_
->Output(out
, CYRight(flags
));
532 void CYFunction::Output(CYOutput
&out
) const {
533 out
<< '(' << parameters_
<< ')' << ' ';
541 void CYFunctionExpression::Output(CYOutput
&out
, CYFlags flags
) const {
542 // XXX: one could imagine using + here to save a byte
543 bool protect((flags
& CYNoFunction
) != 0);
548 out
<< ' ' << *name_
;
549 CYFunction::Output(out
);
554 void CYFunctionStatement::Output(CYOutput
&out
, CYFlags flags
) const {
555 out
<< "function" << ' ' << *name_
;
556 CYFunction::Output(out
);
559 void CYFunctionParameter::Output(CYOutput
&out
) const {
560 binding_
->Output(out
, CYNoFlags
);
562 out
<< ',' << ' ' << *next_
;
565 const char *CYIdentifier::Word() const {
566 return next_
== NULL
|| next_
== this ? CYWord::Word() : next_
->Word();
569 void CYIf::Output(CYOutput
&out
, CYFlags flags
) const {
571 if (false_
== NULL
&& (flags
& CYNoDangle
) != 0) {
576 out
<< "if" << ' ' << '(' << *test_
<< ')';
578 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
580 CYFlags
jacks(CYNoDangle
);
584 jacks
|= protect
? CYNoFlags
: CYCenter(flags
);
586 unsigned line(out
.position_
.line
);
587 unsigned indent(out
.indent_
);
588 true_
->Single(out
, jacks
, CYCompactShort
);
590 if (false_
!= NULL
) {
591 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
597 false_
->Single(out
, right
, CYCompactLong
);
604 void CYIfComprehension::Output(CYOutput
&out
) const {
605 out
<< "if" << ' ' << '(' << *test_
<< ')' << next_
;
608 void CYImport::Output(CYOutput
&out
, CYFlags flags
) const {
612 void CYImportDeclaration::Output(CYOutput
&out
, CYFlags flags
) const {
616 void CYIndirect::Output(CYOutput
&out
, CYFlags flags
) const {
618 rhs_
->Output(out
, Precedence(), CYRight(flags
));
621 void CYIndirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
622 object_
->Output(out
, Precedence(), CYLeft(flags
));
623 if (const char *word
= property_
->Word())
626 out
<< "->" << '[' << *property_
<< ']';
629 void CYInfix::Output(CYOutput
&out
, CYFlags flags
) const {
630 const char *name(Operator());
631 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in") == 0);
634 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
635 lhs_
->Output(out
, Precedence(), left
);
636 out
<< ' ' << name
<< ' ';
637 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
638 rhs_
->Output(out
, Precedence() - 1, right
);
643 void CYLabel::Output(CYOutput
&out
, CYFlags flags
) const {
644 out
<< *name_
<< ':';
645 statement_
->Single(out
, CYRight(flags
), CYCompactShort
);
648 void CYParenthetical::Output(CYOutput
&out
, CYFlags flags
) const {
650 expression_
->Output(out
, CYCompound::Precedence_
, CYNoFlags
);
654 void CYStatement::Output(CYOutput
&out
) const {
658 void CYTemplate::Output(CYOutput
&out
, CYFlags flags
) const {
662 void CYTypeArrayOf::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
663 next_
->Output(out
, Precedence(), identifier
);
669 void CYTypeBlockWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
671 next_
->Output(out
, Precedence(), identifier
);
672 out
<< ')' << '(' << parameters_
<< ')';
675 void CYTypeConstant::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
676 out
<< "const" << ' ';
677 next_
->Output(out
, Precedence(), identifier
);
680 void CYTypeFunctionWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
681 next_
->Output(out
, Precedence(), identifier
);
682 out
<< '(' << parameters_
;
684 if (parameters_
!= NULL
)
691 void CYTypePointerTo::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
693 next_
->Output(out
, Precedence(), identifier
);
696 void CYTypeVolatile::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
698 next_
->Output(out
, Precedence(), identifier
);
701 void CYTypeModifier::Output(CYOutput
&out
, int precedence
, CYIdentifier
*identifier
) const {
707 bool protect(precedence
> Precedence());
711 Output(out
, identifier
);
716 void CYTypedIdentifier::Output(CYOutput
&out
) const {
717 specifier_
->Output(out
);
718 modifier_
->Output(out
, 0, identifier_
);
721 void CYEncodedType::Output(CYOutput
&out
, CYFlags flags
) const {
722 out
<< "@encode(" << typed_
<< ")";
725 void CYTypedParameter::Output(CYOutput
&out
) const {
728 out
<< ',' << ' ' << next_
;
731 void CYLambda::Output(CYOutput
&out
, CYFlags flags
) const {
732 // XXX: this is seriously wrong
739 void CYTypeDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
740 out
<< "typedef" << ' ' << *typed_
;
744 void CYTypeExpression::Output(CYOutput
&out
, CYFlags flags
) const {
745 out
<< '(' << "typedef" << ' ' << *typed_
<< ')';
748 void CYLexical::Output(CYOutput
&out
, CYFlags flags
) const {
750 bindings_
->Output(out
, flags
); // XXX: flags
754 void CYModule::Output(CYOutput
&out
) const {
763 void New::Output(CYOutput
&out
, CYFlags flags
) const {
765 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
766 constructor_
->Output(out
, Precedence(), jacks
);
767 if (arguments_
!= NULL
)
768 out
<< '(' << *arguments_
<< ')';
773 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
777 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
778 std::ostringstream str
;
779 CYNumerify(str
, Value());
780 std::string
value(str
.str());
781 out
<< value
.c_str();
782 // XXX: this should probably also handle hex conversions and exponents
783 if ((flags
& CYNoInteger
) != 0 && value
.find('.') == std::string::npos
)
787 void CYNumber::PropertyName(CYOutput
&out
) const {
788 Output(out
, CYNoFlags
);
791 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
792 bool protect((flags
& CYNoBrace
) != 0);
804 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
805 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
809 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
810 const char *name(Operator());
814 rhs_
->Output(out
, Precedence(), CYRight(flags
));
817 void CYScript::Output(CYOutput
&out
) const {
821 void CYProperty::Output(CYOutput
&out
) const {
822 if (next_
!= NULL
|| out
.pretty_
)
824 out
<< '\n' << next_
;
827 void CYPropertyGetter::Output(CYOutput
&out
) const {
829 name_
->PropertyName(out
);
830 CYFunction::Output(out
);
831 CYProperty::Output(out
);
834 void CYPropertyMethod::Output(CYOutput
&out
) const {
835 name_
->PropertyName(out
);
836 CYFunction::Output(out
);
837 CYProperty::Output(out
);
840 void CYPropertySetter::Output(CYOutput
&out
) const {
842 name_
->PropertyName(out
);
843 CYFunction::Output(out
);
844 CYProperty::Output(out
);
847 void CYPropertyValue::Output(CYOutput
&out
) const {
849 name_
->PropertyName(out
);
851 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
852 CYProperty::Output(out
);
855 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
859 void CYResolveMember::Output(CYOutput
&out
, CYFlags flags
) const {
860 object_
->Output(out
, Precedence(), CYLeft(flags
));
861 if (const char *word
= property_
->Word())
864 out
<< "::" << '[' << *property_
<< ']';
867 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
870 out
<< ' ' << *value_
;
874 void CYRubyBlock::Output(CYOutput
&out
, CYFlags flags
) const {
875 call_
->Output(out
, CYLeft(flags
));
877 proc_
->Output(out
, CYRight(flags
));
880 void CYRubyProc::Output(CYOutput
&out
, CYFlags flags
) const {
881 out
<< '{' << ' ' << '|' << parameters_
<< '|' << '\n';
888 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
890 CYForEach (next
, this) {
891 bool last(next
->next_
== NULL
);
892 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYRight(flags
) : CYCenter(flags
));
895 next
->Output(out
, jacks
);
900 void CYStatement::Single(CYOutput
&out
, CYFlags flags
, CYCompactType request
) const {
902 return out
.Terminate();
904 _assert(next_
== NULL
);
906 CYCompactType
compact(Compact());
908 if (compact
>= request
)
918 if (compact
< request
)
922 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
923 std::ostringstream str
;
924 CYStringify(str
, value_
, size_
);
925 out
<< str
.str().c_str();
928 void CYString::PropertyName(CYOutput
&out
) const {
929 if (const char *word
= Word())
935 static const char *Reserved_
[] = {
936 "false", "null", "true",
938 "break", "case", "catch", "continue", "default",
939 "delete", "do", "else", "finally", "for", "function",
940 "if", "in", "instanceof", "new", "return", "switch",
941 "this", "throw", "try", "typeof", "var", "void",
946 "class", "enum", "export", "extends", "import", "super",
948 "abstract", "boolean", "byte", "char", "double", "final",
949 "float", "goto", "int", "long", "native", "short",
950 "synchronized", "throws", "transient", "volatile",
957 const char *CYString::Word() const {
958 if (size_
== 0 || !WordStartRange_
[value_
[0]])
960 for (size_t i(1); i
!= size_
; ++i
)
961 if (!WordEndRange_
[value_
[i
]])
963 const char *value(Value());
964 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
965 if (strcmp(*reserved
, value
) == 0)
970 void CYStructDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
971 out
<< "struct" << ' ' << *name_
<< *tail_
;
974 void CYStructTail::Output(CYOutput
&out
) const {
975 out
<< ' ' << '{' << '\n';
977 CYForEach (field
, fields_
) {
978 out
<< '\t' << *field
->typed_
;
986 void CYSuperAccess::Output(CYOutput
&out
, CYFlags flags
) const {
988 if (const char *word
= property_
->Word())
991 out
<< '[' << *property_
<< ']';
994 void CYSuperCall::Output(CYOutput
&out
, CYFlags flags
) const {
995 out
<< "super" << '(' << arguments_
<< ')';
998 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
999 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{' << '\n';
1006 void CYSymbol::Output(CYOutput
&out
, CYFlags flags
) const {
1007 bool protect((flags
& CYNoColon
) != 0);
1010 out
<< ':' << name_
;
1015 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
1022 void Throw::Output(CYOutput
&out
, CYFlags flags
) const {
1025 out
<< ' ' << *value_
;
1029 void Try::Output(CYOutput
&out
, CYFlags flags
) const {
1030 out
<< "try" << ' ';
1036 out
<< catch_
<< finally_
;
1041 void CYTypeCharacter::Output(CYOutput
&out
) const {
1043 case CYTypeNeutral
: break;
1044 case CYTypeSigned
: out
<< "signed" << ' '; break;
1045 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1051 void CYTypeError::Output(CYOutput
&out
) const {
1055 void CYTypeIntegral::Output(CYOutput
&out
) const {
1056 if (signing_
== CYTypeUnsigned
)
1057 out
<< "unsigned" << ' ';
1059 case 0: out
<< "short"; break;
1060 case 1: out
<< "int"; break;
1061 case 2: out
<< "long"; break;
1062 case 3: out
<< "long" << ' ' << "long"; break;
1063 default: _assert(false);
1067 void CYTypeStruct::Output(CYOutput
&out
) const {
1070 out
<< ' ' << *name_
;
1075 void CYTypeReference::Output(CYOutput
&out
) const {
1076 out
<< "struct" << ' ' << *name_
;
1079 void CYTypeVariable::Output(CYOutput
&out
) const {
1083 void CYTypeVoid::Output(CYOutput
&out
) const {
1087 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
1088 out
<< "var" << ' ';
1089 bindings_
->Output(out
, flags
); // XXX: flags
1093 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
1097 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
1098 out
<< "while" << ' ' << '(' << *test_
<< ')';
1099 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1102 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
1103 out
<< "with" << ' ' << '(' << *scope_
<< ')';
1104 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1107 void CYWord::Output(CYOutput
&out
) const {
1109 if (out
.options_
.verbose_
) {
1112 sprintf(number
, "%p", this);
1117 void CYWord::PropertyName(CYOutput
&out
) const {
1121 const char *CYWord::Word() const {