]>
git.saurik.com Git - cycript.git/blob - Output.cpp
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 CYExternalDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
461 out
<< "extern" << ' ' << abi_
<< ' ' << typed_
;
465 void CYExternalExpression::Output(CYOutput
&out
, CYFlags flags
) const {
466 out
<< '(' << "extern" << ' ' << abi_
<< ' ' << typed_
<< ')';
469 void CYFatArrow::Output(CYOutput
&out
, CYFlags flags
) const {
470 out
<< '(' << parameters_
<< ')' << ' ' << "=>" << ' ' << '{' << code_
<< '}';
473 void CYFinally::Output(CYOutput
&out
) const {
474 out
<< ' ' << "finally" << ' ';
482 void CYFor::Output(CYOutput
&out
, CYFlags flags
) const {
483 out
<< "for" << ' ' << '(';
484 if (initializer_
!= NULL
)
485 initializer_
->Output(out
, CYNoIn
);
491 if (increment_
!= NULL
)
495 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
498 void CYForLexical::Output(CYOutput
&out
, CYFlags flags
) const {
499 out
<< (constant_
? "const" : "let") << ' ';
500 binding_
->Output(out
, CYRight(flags
));
503 void CYForIn::Output(CYOutput
&out
, CYFlags flags
) const {
504 out
<< "for" << ' ' << '(';
505 initializer_
->Output(out
, CYNoIn
| CYNoRightHand
);
506 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
507 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
510 void CYForInitialized::Output(CYOutput
&out
, CYFlags flags
) const {
511 out
<< "for" << ' ' << '(' << "var" << ' ';
512 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
513 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
514 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
517 void CYForInComprehension::Output(CYOutput
&out
) const {
518 out
<< "for" << ' ' << '(';
519 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
520 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
523 void CYForOf::Output(CYOutput
&out
, CYFlags flags
) const {
524 out
<< "for" << ' ' << '(';
525 initializer_
->Output(out
, CYNoRightHand
);
526 out
<< ' ' << "of" << ' ' << *iterable_
<< ')';
527 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
530 void CYForOfComprehension::Output(CYOutput
&out
) const {
531 out
<< "for" << ' ' << '(';
532 binding_
->Output(out
, CYNoRightHand
);
533 out
<< ' ' << "of" << ' ' << *iterable_
<< ')' << next_
;
536 void CYForVariable::Output(CYOutput
&out
, CYFlags flags
) const {
538 binding_
->Output(out
, CYRight(flags
));
541 void CYFunction::Output(CYOutput
&out
) const {
542 out
<< '(' << parameters_
<< ')' << ' ';
550 void CYFunctionExpression::Output(CYOutput
&out
, CYFlags flags
) const {
551 // XXX: one could imagine using + here to save a byte
552 bool protect((flags
& CYNoFunction
) != 0);
557 out
<< ' ' << *name_
;
558 CYFunction::Output(out
);
563 void CYFunctionStatement::Output(CYOutput
&out
, CYFlags flags
) const {
564 out
<< "function" << ' ' << *name_
;
565 CYFunction::Output(out
);
568 void CYFunctionParameter::Output(CYOutput
&out
) const {
569 binding_
->Output(out
, CYNoFlags
);
571 out
<< ',' << ' ' << *next_
;
574 const char *CYIdentifier::Word() const {
575 return next_
== NULL
|| next_
== this ? CYWord::Word() : next_
->Word();
578 void CYIf::Output(CYOutput
&out
, CYFlags flags
) const {
580 if (false_
== NULL
&& (flags
& CYNoDangle
) != 0) {
585 out
<< "if" << ' ' << '(' << *test_
<< ')';
587 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
589 CYFlags
jacks(CYNoDangle
);
593 jacks
|= protect
? CYNoFlags
: CYCenter(flags
);
595 unsigned line(out
.position_
.line
);
596 unsigned indent(out
.indent_
);
597 true_
->Single(out
, jacks
, CYCompactShort
);
599 if (false_
!= NULL
) {
600 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
606 false_
->Single(out
, right
, CYCompactLong
);
613 void CYIfComprehension::Output(CYOutput
&out
) const {
614 out
<< "if" << ' ' << '(' << *test_
<< ')' << next_
;
617 void CYImport::Output(CYOutput
&out
, CYFlags flags
) const {
621 void CYImportDeclaration::Output(CYOutput
&out
, CYFlags flags
) const {
625 void CYIndirect::Output(CYOutput
&out
, CYFlags flags
) const {
627 rhs_
->Output(out
, Precedence(), CYRight(flags
));
630 void CYIndirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
631 object_
->Output(out
, Precedence(), CYLeft(flags
));
632 if (const char *word
= property_
->Word())
635 out
<< "->" << '[' << *property_
<< ']';
638 void CYInfix::Output(CYOutput
&out
, CYFlags flags
) const {
639 const char *name(Operator());
640 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in") == 0);
643 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
644 lhs_
->Output(out
, Precedence(), left
);
645 out
<< ' ' << name
<< ' ';
646 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
647 rhs_
->Output(out
, Precedence() - 1, right
);
652 void CYLabel::Output(CYOutput
&out
, CYFlags flags
) const {
653 out
<< *name_
<< ':';
654 statement_
->Single(out
, CYRight(flags
), CYCompactShort
);
657 void CYParenthetical::Output(CYOutput
&out
, CYFlags flags
) const {
659 expression_
->Output(out
, CYCompound::Precedence_
, CYNoFlags
);
663 void CYStatement::Output(CYOutput
&out
) const {
667 void CYTemplate::Output(CYOutput
&out
, CYFlags flags
) const {
671 void CYTypeArrayOf::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
672 next_
->Output(out
, Precedence(), identifier
, false);
678 void CYTypeBlockWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
680 next_
->Output(out
, Precedence(), identifier
, false);
681 out
<< ')' << '(' << parameters_
<< ')';
684 void CYTypeConstant::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
686 next_
->Output(out
, Precedence(), identifier
, false);
689 void CYTypeFunctionWith::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
690 next_
->Output(out
, Precedence(), identifier
, false);
691 out
<< '(' << parameters_
;
693 if (parameters_
!= NULL
)
700 void CYTypePointerTo::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
702 next_
->Output(out
, Precedence(), identifier
, false);
705 void CYTypeVolatile::Output(CYOutput
&out
, CYIdentifier
*identifier
) const {
707 next_
->Output(out
, Precedence(), identifier
, true);
710 void CYTypeModifier::Output(CYOutput
&out
, int precedence
, CYIdentifier
*identifier
, bool space
) const {
711 if (this == NULL
&& identifier
== NULL
)
721 bool protect(precedence
> Precedence());
725 Output(out
, identifier
);
730 void CYTypedIdentifier::Output(CYOutput
&out
) const {
732 modifier_
->Output(out
, 0, identifier_
, true);
735 void CYEncodedType::Output(CYOutput
&out
, CYFlags flags
) const {
736 out
<< "@encode(" << typed_
<< ")";
739 void CYTypedParameter::Output(CYOutput
&out
) const {
742 out
<< ',' << ' ' << next_
;
745 void CYLambda::Output(CYOutput
&out
, CYFlags flags
) const {
746 // XXX: this is seriously wrong
753 void CYTypeDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
754 out
<< "typedef" << ' ' << *typed_
;
758 void CYTypeExpression::Output(CYOutput
&out
, CYFlags flags
) const {
759 out
<< '(' << "typedef" << ' ' << *typed_
<< ')';
762 void CYLexical::Output(CYOutput
&out
, CYFlags flags
) const {
764 bindings_
->Output(out
, flags
); // XXX: flags
768 void CYModule::Output(CYOutput
&out
) const {
777 void New::Output(CYOutput
&out
, CYFlags flags
) const {
779 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
780 constructor_
->Output(out
, Precedence(), jacks
);
781 if (arguments_
!= NULL
)
782 out
<< '(' << *arguments_
<< ')';
787 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
791 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
792 std::ostringstream str
;
793 CYNumerify(str
, Value());
794 std::string
value(str
.str());
795 out
<< value
.c_str();
796 // XXX: this should probably also handle hex conversions and exponents
797 if ((flags
& CYNoInteger
) != 0 && value
.find('.') == std::string::npos
)
801 void CYNumber::PropertyName(CYOutput
&out
) const {
802 Output(out
, CYNoFlags
);
805 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
806 bool protect((flags
& CYNoBrace
) != 0);
818 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
819 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
823 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
824 const char *name(Operator());
828 rhs_
->Output(out
, Precedence(), CYRight(flags
));
831 void CYScript::Output(CYOutput
&out
) const {
835 void CYProperty::Output(CYOutput
&out
) const {
836 if (next_
!= NULL
|| out
.pretty_
)
838 out
<< '\n' << next_
;
841 void CYPropertyGetter::Output(CYOutput
&out
) const {
843 name_
->PropertyName(out
);
844 CYFunction::Output(out
);
845 CYProperty::Output(out
);
848 void CYPropertyMethod::Output(CYOutput
&out
) const {
849 name_
->PropertyName(out
);
850 CYFunction::Output(out
);
851 CYProperty::Output(out
);
854 void CYPropertySetter::Output(CYOutput
&out
) const {
856 name_
->PropertyName(out
);
857 CYFunction::Output(out
);
858 CYProperty::Output(out
);
861 void CYPropertyValue::Output(CYOutput
&out
) const {
863 name_
->PropertyName(out
);
865 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
866 CYProperty::Output(out
);
869 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
873 void CYResolveMember::Output(CYOutput
&out
, CYFlags flags
) const {
874 object_
->Output(out
, Precedence(), CYLeft(flags
));
875 if (const char *word
= property_
->Word())
878 out
<< "::" << '[' << *property_
<< ']';
881 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
884 out
<< ' ' << *value_
;
888 void CYRubyBlock::Output(CYOutput
&out
, CYFlags flags
) const {
889 lhs_
->Output(out
, CYLeft(flags
));
891 proc_
->Output(out
, CYRight(flags
));
894 void CYRubyProc::Output(CYOutput
&out
, CYFlags flags
) const {
895 out
<< '{' << ' ' << '|' << parameters_
<< '|' << '\n';
902 void CYSubscriptMember::Output(CYOutput
&out
, CYFlags flags
) const {
903 object_
->Output(out
, Precedence(), CYLeft(flags
));
904 out
<< "." << '[' << *property_
<< ']';
907 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
909 CYForEach (next
, this) {
910 bool last(next
->next_
== NULL
);
911 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYRight(flags
) : CYCenter(flags
));
914 next
->Output(out
, jacks
);
919 void CYStatement::Single(CYOutput
&out
, CYFlags flags
, CYCompactType request
) const {
921 return out
.Terminate();
923 _assert(next_
== NULL
);
925 CYCompactType
compact(Compact());
927 if (compact
>= request
)
937 if (compact
< request
)
941 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
942 std::ostringstream str
;
943 CYStringify(str
, value_
, size_
);
944 out
<< str
.str().c_str();
947 void CYString::PropertyName(CYOutput
&out
) const {
948 if (const char *word
= Word())
954 static const char *Reserved_
[] = {
955 "false", "null", "true",
957 "break", "case", "catch", "continue", "default",
958 "delete", "do", "else", "finally", "for", "function",
959 "if", "in", "instanceof", "new", "return", "switch",
960 "this", "throw", "try", "typeof", "var", "void",
965 "class", "enum", "export", "extends", "import", "super",
967 "abstract", "boolean", "byte", "char", "double", "final",
968 "float", "goto", "int", "long", "native", "short",
969 "synchronized", "throws", "transient", "volatile",
976 const char *CYString::Word() const {
977 if (size_
== 0 || !WordStartRange_
[value_
[0]])
979 for (size_t i(1); i
!= size_
; ++i
)
980 if (!WordEndRange_
[value_
[i
]])
982 const char *value(Value());
983 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
984 if (strcmp(*reserved
, value
) == 0)
989 void CYStructDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
990 out
<< "struct" << ' ' << *name_
<< *tail_
;
993 void CYStructTail::Output(CYOutput
&out
) const {
994 out
<< ' ' << '{' << '\n';
996 CYForEach (field
, fields_
) {
997 out
<< '\t' << *field
->typed_
;
1005 void CYSuperAccess::Output(CYOutput
&out
, CYFlags flags
) const {
1007 if (const char *word
= property_
->Word())
1010 out
<< '[' << *property_
<< ']';
1013 void CYSuperCall::Output(CYOutput
&out
, CYFlags flags
) const {
1014 out
<< "super" << '(' << arguments_
<< ')';
1017 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
1018 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{' << '\n';
1025 void CYSymbol::Output(CYOutput
&out
, CYFlags flags
) const {
1026 bool protect((flags
& CYNoColon
) != 0);
1029 out
<< ':' << name_
;
1034 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
1041 void Throw::Output(CYOutput
&out
, CYFlags flags
) const {
1044 out
<< ' ' << *value_
;
1048 void Try::Output(CYOutput
&out
, CYFlags flags
) const {
1049 out
<< "try" << ' ';
1055 out
<< catch_
<< finally_
;
1060 void CYTypeCharacter::Output(CYOutput
&out
) const {
1062 case CYTypeNeutral
: break;
1063 case CYTypeSigned
: out
<< "signed" << ' '; break;
1064 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1070 void CYTypeEnum::Output(CYOutput
&out
) const {
1071 out
<< "enum" << ' ';
1075 if (specifier_
!= NULL
)
1076 out
<< ':' << ' ' << *specifier_
<< ' ';
1082 CYForEach (constant
, constants_
) {
1087 out
<< '\t' << constant
->name_
;
1088 out
<< ' ' << '=' << ' ' << constant
->value_
;
1099 void CYTypeError::Output(CYOutput
&out
) const {
1103 void CYTypeInt128::Output(CYOutput
&out
) const {
1105 case CYTypeNeutral
: break;
1106 case CYTypeSigned
: out
<< "signed" << ' '; break;
1107 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1113 void CYTypeIntegral::Output(CYOutput
&out
) const {
1114 if (signing_
== CYTypeUnsigned
)
1115 out
<< "unsigned" << ' ';
1117 case 0: out
<< "short"; break;
1118 case 1: out
<< "int"; break;
1119 case 2: out
<< "long"; break;
1120 case 3: out
<< "long" << ' ' << "long"; break;
1121 default: _assert(false);
1125 void CYTypeStruct::Output(CYOutput
&out
) const {
1128 out
<< ' ' << *name_
;
1133 void CYTypeReference::Output(CYOutput
&out
) const {
1135 case CYTypeReferenceStruct
: out
<< "struct"; break;
1136 case CYTypeReferenceEnum
: out
<< "enum"; break;
1137 default: _assert(false);
1140 out
<< ' ' << *name_
;
1143 void CYTypeVariable::Output(CYOutput
&out
) const {
1147 void CYTypeVoid::Output(CYOutput
&out
) const {
1151 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
1152 out
<< "var" << ' ';
1153 bindings_
->Output(out
, flags
); // XXX: flags
1157 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
1161 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
1162 out
<< "while" << ' ' << '(' << *test_
<< ')';
1163 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1166 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
1167 out
<< "with" << ' ' << '(' << *scope_
<< ')';
1168 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1171 void CYWord::Output(CYOutput
&out
) const {
1173 if (out
.options_
.verbose_
) {
1176 sprintf(number
, "%p", this);
1181 void CYWord::PropertyName(CYOutput
&out
) const {
1185 const char *CYWord::Word() const {