]>
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/>.
34 void CYStringify(std::ostringstream
&str
, const char *data
, size_t size
, CYStringifyMode mode
) {
40 unsigned quot(0), apos(0), tick(0), line(0);
41 for (const char *value(data
), *end(data
+ size
); value
!= end
; ++value
)
43 case '"': ++quot
; break;
44 case '\'': ++apos
; break;
45 case '`': ++tick
; break;
46 case '$': ++tick
; break;
47 case '\n': ++line
; break;
51 if (mode
!= CYStringifyModeCycript
)
54 double ratio(double(line
) / size
);
55 split
= size
> 10 && line
> 2 && ratio
> 0.005 && ratio
< 0.10;
59 if (mode
== CYStringifyModeNative
)
60 type
= CYStringTypeDouble
;
62 type
= CYStringTypeTemplate
;
64 type
= CYStringTypeSingle
;
66 type
= CYStringTypeDouble
;
68 bool parens(split
&& mode
!= CYStringifyModeNative
&& type
!= CYStringTypeTemplate
);
74 case CYStringTypeSingle
: border
= '\''; break;
75 case CYStringTypeDouble
: border
= '"'; break;
76 case CYStringTypeTemplate
: border
= '`'; break;
83 for (const char *value(data
), *end(data
+ size
); value
!= end
; ++value
)
87 } else { switch (uint8_t next
= *value
) {
88 case '\\': str
<< "\\\\"; break;
89 case '\b': str
<< "\\b"; break;
90 case '\f': str
<< "\\f"; break;
91 case '\r': str
<< "\\r"; break;
92 case '\t': str
<< "\\t"; break;
93 case '\v': str
<< "\\v"; break;
96 if (mode
== CYStringifyModeNative
)
104 /*else if (mode == CYStringifyModeNative)
105 str << border << "\\\n" << border;*/
106 else if (type
!= CYStringTypeTemplate
)
107 str
<< border
<< '+' << border
;
115 if (type
== CYStringTypeTemplate
)
121 if (type
== CYStringTypeTemplate
)
127 if (type
== CYStringTypeDouble
)
133 if (type
== CYStringTypeSingle
)
139 if (mode
!= CYStringifyModeNative
&& value
[1] >= '0' && value
[1] <= '9')
146 if (next
>= 0x20 && next
< 0x7f) simple
:
148 else if (mode
== CYStringifyModeNative
)
149 str
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
& 0xff);
152 if ((next
& 0x80) != 0)
153 while ((next
& 0x80 >> ++levels
) != 0);
155 unsigned point(next
& 0xff >> levels
);
156 while (--levels
!= 0)
157 point
= point
<< 6 | uint8_t(*++value
) & 0x3f;
160 str
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << point
;
161 else if (point
< 0x10000)
162 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << point
;
165 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xd800 | point
>> 0x0a);
166 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xdc00 | point
& 0x3ff);
177 void CYNumerify(std::ostringstream
&str
, double value
) {
178 if (std::isinf(value
)) {
186 // XXX: I want this to print 1e3 rather than 1000
187 sprintf(string
, "%.17g", value
);
191 void CYOutput::Terminate() {
196 CYOutput
&CYOutput::operator <<(char rhs
) {
197 if (rhs
== ' ' || rhs
== '\n')
201 else if (rhs
== '\t')
203 for (unsigned i(0); i
!= indent_
; ++i
)
206 else if (rhs
== '\r') {
218 if (mode_
== Terminated
&& rhs
!= '}') {
230 } else if (rhs
== '+') {
234 } else if (rhs
== '-') {
235 if (mode_
== NoHyphen
)
238 } else if (WordEndRange_
[rhs
]) {
239 if (mode_
== NoLetter
)
251 CYOutput
&CYOutput::operator <<(const char *rhs
) {
252 size_t size(strlen(rhs
));
255 return *this << *rhs
;
257 if (mode_
== Terminated
)
260 mode_
== NoPlus
&& *rhs
== '+' ||
261 mode_
== NoHyphen
&& *rhs
== '-' ||
262 mode_
== NoLetter
&& WordEndRange_
[*rhs
]
266 char last(rhs
[size
- 1]);
267 if (WordEndRange_
[last
] || last
== '/')
273 operator ()(rhs
, size
);
277 void CYArgument::Output(CYOutput
&out
) const {
284 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
287 out
<< ' ' << *next_
;
291 void CYArray::Output(CYOutput
&out
, CYFlags flags
) const {
292 out
<< '[' << elements_
<< ']';
295 void CYArrayComprehension::Output(CYOutput
&out
, CYFlags flags
) const {
296 out
<< '[' << *expression_
<< ' ' << *comprehensions_
<< ']';
299 void CYAssignment::Output(CYOutput
&out
, CYFlags flags
) const {
300 lhs_
->Output(out
, Precedence() - 1, CYLeft(flags
) | CYNoRightHand
);
301 out
<< ' ' << Operator() << ' ';
302 rhs_
->Output(out
, Precedence(), CYRight(flags
));
305 void CYAttemptMember::Output(CYOutput
&out
, CYFlags flags
) const {
306 object_
->Output(out
, Precedence(), CYLeft(flags
) | CYNoInteger
);
307 if (const char *word
= property_
->Word())
313 void CYBlock::Output(CYOutput
&out
, CYFlags flags
) const {
321 void CYBoolean::Output(CYOutput
&out
, CYFlags flags
) const {
322 out
<< '!' << (Value() ? "0" : "1");
323 if ((flags
& CYNoInteger
) != 0)
327 void CYBreak::Output(CYOutput
&out
, CYFlags flags
) const {
330 out
<< ' ' << *label_
;
334 void CYCall::Output(CYOutput
&out
, CYFlags flags
) const {
335 bool protect((flags
& CYNoCall
) != 0);
338 function_
->Output(out
, Precedence(), protect
? CYNoFlags
: flags
);
339 out
<< '(' << arguments_
<< ')';
347 void Catch::Output(CYOutput
&out
) const {
348 out
<< ' ' << "catch" << ' ' << '(' << *name_
<< ')' << ' ';
358 void CYClassExpression::Output(CYOutput
&out
, CYFlags flags
) const {
359 bool protect((flags
& CYNoClass
) != 0);
364 out
<< ' ' << *name_
;
370 void CYClassStatement::Output(CYOutput
&out
, CYFlags flags
) const {
371 out
<< "class" << ' ' << *name_
<< *tail_
;
374 void CYClassTail::Output(CYOutput
&out
) const {
375 if (extends_
== NULL
)
380 out
<< "extends" << ' ';
381 extends_
->Output(out
, CYAssign::Precedence_
- 1, CYNoFlags
);
393 void CYCompound::Output(CYOutput
&out
, CYFlags flags
) const {
395 expression_
->Output(out
, flags
);
397 expression_
->Output(out
, CYLeft(flags
));
399 next_
->Output(out
, CYRight(flags
));
403 void CYComputed::PropertyName(CYOutput
&out
) const {
405 expression_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
409 void CYCondition::Output(CYOutput
&out
, CYFlags flags
) const {
410 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
411 out
<< ' ' << '?' << ' ';
413 true_
->Output(out
, CYAssign::Precedence_
, CYNoColon
);
414 out
<< ' ' << ':' << ' ';
415 false_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
418 void CYContinue::Output(CYOutput
&out
, CYFlags flags
) const {
421 out
<< ' ' << *label_
;
425 void CYClause::Output(CYOutput
&out
) const {
430 out
<< "case" << ' ';
431 value_
->Output(out
, CYNoColon
);
440 void CYDebugger::Output(CYOutput
&out
, CYFlags flags
) const {
441 out
<< "debugger" << ';';
444 void CYBinding::Output(CYOutput
&out
, CYFlags flags
) const {
446 //out.out_ << ':' << identifier_->usage_ << '#' << identifier_->offset_;
447 if (initializer_
!= NULL
) {
448 out
<< ' ' << '=' << ' ';
449 initializer_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
453 void CYBindings::Output(CYOutput
&out
) const {
454 Output(out
, CYNoFlags
);
457 void CYBindings::Output(CYOutput
&out
, CYFlags flags
) const {
458 const CYBindings
*binding(this);
462 CYBindings
*next(binding
->next_
);
464 CYFlags
jacks(first
? CYLeft(flags
) : next
== NULL
? CYRight(flags
) : CYCenter(flags
));
466 binding
->binding_
->Output(out
, jacks
);
476 void CYDirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
477 object_
->Output(out
, Precedence(), CYLeft(flags
) | CYNoInteger
);
478 if (const char *word
= property_
->Word())
481 out
<< '[' << *property_
<< ']';
484 void CYDoWhile::Output(CYOutput
&out
, CYFlags flags
) const {
487 unsigned line(out
.position_
.line
);
488 unsigned indent(out
.indent_
);
489 code_
->Single(out
, CYCenter(flags
), CYCompactLong
);
491 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
496 out
<< "while" << ' ' << '(' << *test_
<< ')';
499 void CYElementSpread::Output(CYOutput
&out
) const {
500 out
<< "..." << value_
;
503 void CYElementValue::Output(CYOutput
&out
) const {
505 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
506 if (next_
!= NULL
|| value_
== NULL
) {
508 if (next_
!= NULL
&& !next_
->Elision())
515 void CYEmpty::Output(CYOutput
&out
, CYFlags flags
) const {
519 void CYEval::Output(CYOutput
&out
, CYFlags flags
) const {
523 void CYExpress::Output(CYOutput
&out
, CYFlags flags
) const {
524 expression_
->Output(out
, flags
| CYNoBFC
);
528 void CYExpression::Output(CYOutput
&out
) const {
529 Output(out
, CYNoFlags
);
532 void CYExpression::Output(CYOutput
&out
, int precedence
, CYFlags flags
) const {
533 if (precedence
< Precedence() || (flags
& CYNoRightHand
) != 0 && RightHand())
534 out
<< '(' << *this << ')';
539 void CYExtend::Output(CYOutput
&out
, CYFlags flags
) const {
540 lhs_
->Output(out
, CYLeft(flags
));
541 out
<< ' ' << object_
;
544 void CYExternalDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
545 out
<< "extern" << ' ' << abi_
<< ' ';
546 type_
->Output(out
, name_
);
550 void CYExternalExpression::Output(CYOutput
&out
, CYFlags flags
) const {
551 out
<< '(' << "extern" << ' ' << abi_
<< ' ';
552 type_
->Output(out
, name_
);
556 void CYFatArrow::Output(CYOutput
&out
, CYFlags flags
) const {
557 out
<< '(' << parameters_
<< ')' << ' ' << "=>" << ' ' << '{' << code_
<< '}';
560 void CYFinally::Output(CYOutput
&out
) const {
561 out
<< ' ' << "finally" << ' ';
569 void CYFor::Output(CYOutput
&out
, CYFlags flags
) const {
570 out
<< "for" << ' ' << '(';
571 if (initializer_
!= NULL
)
572 initializer_
->Output(out
, CYNoIn
);
578 if (increment_
!= NULL
)
582 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
585 void CYForLexical::Output(CYOutput
&out
, CYFlags flags
) const {
586 out
<< (constant_
? "const" : "let") << ' ';
587 binding_
->Output(out
, CYRight(flags
));
590 void CYForIn::Output(CYOutput
&out
, CYFlags flags
) const {
591 out
<< "for" << ' ' << '(';
592 initializer_
->Output(out
, CYNoIn
| CYNoRightHand
);
593 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
594 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
597 void CYForInitialized::Output(CYOutput
&out
, CYFlags flags
) const {
598 out
<< "for" << ' ' << '(' << "var" << ' ';
599 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
600 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
601 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
604 void CYForInComprehension::Output(CYOutput
&out
) const {
605 out
<< "for" << ' ' << '(';
606 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
607 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
610 void CYForOf::Output(CYOutput
&out
, CYFlags flags
) const {
611 out
<< "for" << ' ' << '(';
612 initializer_
->Output(out
, CYNoRightHand
);
613 out
<< ' ' << "of" << ' ' << *iterable_
<< ')';
614 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
617 void CYForOfComprehension::Output(CYOutput
&out
) const {
618 out
<< "for" << ' ' << '(';
619 binding_
->Output(out
, CYNoRightHand
);
620 out
<< ' ' << "of" << ' ' << *iterable_
<< ')' << next_
;
623 void CYForVariable::Output(CYOutput
&out
, CYFlags flags
) const {
625 binding_
->Output(out
, CYRight(flags
));
628 void CYFunction::Output(CYOutput
&out
) const {
629 out
<< '(' << parameters_
<< ')' << ' ';
637 void CYFunctionExpression::Output(CYOutput
&out
, CYFlags flags
) const {
638 // XXX: one could imagine using + here to save a byte
639 bool protect((flags
& CYNoFunction
) != 0);
644 out
<< ' ' << *name_
;
645 CYFunction::Output(out
);
650 void CYFunctionStatement::Output(CYOutput
&out
, CYFlags flags
) const {
651 out
<< "function" << ' ' << *name_
;
652 CYFunction::Output(out
);
655 void CYFunctionParameter::Output(CYOutput
&out
) const {
656 binding_
->Output(out
, CYNoFlags
);
658 out
<< ',' << ' ' << *next_
;
661 const char *CYIdentifier::Word() const {
662 return next_
== NULL
|| next_
== this ? CYWord::Word() : next_
->Word();
665 void CYIf::Output(CYOutput
&out
, CYFlags flags
) const {
667 if (false_
== NULL
&& (flags
& CYNoDangle
) != 0) {
672 out
<< "if" << ' ' << '(' << *test_
<< ')';
674 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
676 CYFlags
jacks(CYNoDangle
);
680 jacks
|= protect
? CYNoFlags
: CYCenter(flags
);
682 unsigned line(out
.position_
.line
);
683 unsigned indent(out
.indent_
);
684 true_
->Single(out
, jacks
, CYCompactShort
);
686 if (false_
!= NULL
) {
687 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
693 false_
->Single(out
, right
, CYCompactLong
);
700 void CYIfComprehension::Output(CYOutput
&out
) const {
701 out
<< "if" << ' ' << '(' << *test_
<< ')' << next_
;
704 void CYImport::Output(CYOutput
&out
, CYFlags flags
) const {
708 void CYImportDeclaration::Output(CYOutput
&out
, CYFlags flags
) const {
712 void CYIndirect::Output(CYOutput
&out
, CYFlags flags
) const {
714 rhs_
->Output(out
, Precedence(), CYRight(flags
));
717 void CYIndirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
718 object_
->Output(out
, Precedence(), CYLeft(flags
));
719 if (const char *word
= property_
->Word())
722 out
<< "->" << '[' << *property_
<< ']';
725 void CYInfix::Output(CYOutput
&out
, CYFlags flags
) const {
726 const char *name(Operator());
727 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in") == 0);
730 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
731 lhs_
->Output(out
, Precedence(), left
);
732 out
<< ' ' << name
<< ' ';
733 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
734 rhs_
->Output(out
, Precedence() - 1, right
);
739 void CYLabel::Output(CYOutput
&out
, CYFlags flags
) const {
740 out
<< *name_
<< ':';
741 statement_
->Single(out
, CYRight(flags
), CYCompactShort
);
744 void CYParenthetical::Output(CYOutput
&out
, CYFlags flags
) const {
746 expression_
->Output(out
, CYCompound::Precedence_
, CYNoFlags
);
750 void CYStatement::Output(CYOutput
&out
) const {
754 void CYTemplate::Output(CYOutput
&out
, CYFlags flags
) const {
758 void CYTypeArrayOf::Output(CYOutput
&out
, CYPropertyName
*name
) const {
759 next_
->Output(out
, Precedence(), name
, false);
765 void CYTypeBlockWith::Output(CYOutput
&out
, CYPropertyName
*name
) const {
767 next_
->Output(out
, Precedence(), name
, false);
768 out
<< ')' << '(' << parameters_
<< ')';
771 void CYTypeConstant::Output(CYOutput
&out
, CYPropertyName
*name
) const {
773 next_
->Output(out
, Precedence(), name
, false);
776 void CYTypeFunctionWith::Output(CYOutput
&out
, CYPropertyName
*name
) const {
777 next_
->Output(out
, Precedence(), name
, false);
778 out
<< '(' << parameters_
;
780 if (parameters_
!= NULL
)
787 void CYTypePointerTo::Output(CYOutput
&out
, CYPropertyName
*name
) const {
789 next_
->Output(out
, Precedence(), name
, false);
792 void CYTypeVolatile::Output(CYOutput
&out
, CYPropertyName
*name
) const {
794 next_
->Output(out
, Precedence(), name
, true);
797 void CYTypeModifier::Output(CYOutput
&out
, int precedence
, CYPropertyName
*name
, bool space
) const {
798 if (this == NULL
&& name
== NULL
)
804 name
->PropertyName(out
);
808 bool protect(precedence
> Precedence());
817 void CYType::Output(CYOutput
&out
, CYPropertyName
*name
) const {
819 modifier_
->Output(out
, 0, name
, true);
822 void CYType::Output(CYOutput
&out
) const {
826 void CYEncodedType::Output(CYOutput
&out
, CYFlags flags
) const {
827 out
<< "@encode(" << typed_
<< ")";
830 void CYTypedParameter::Output(CYOutput
&out
) const {
831 type_
->Output(out
, name_
);
833 out
<< ',' << ' ' << next_
;
836 void CYLambda::Output(CYOutput
&out
, CYFlags flags
) const {
837 // XXX: this is seriously wrong
844 void CYTypeDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
845 out
<< "typedef" << ' ';
846 type_
->Output(out
, name_
);
850 void CYTypeExpression::Output(CYOutput
&out
, CYFlags flags
) const {
851 out
<< '(' << "typedef" << ' ' << *typed_
<< ')';
854 void CYLexical::Output(CYOutput
&out
, CYFlags flags
) const {
856 bindings_
->Output(out
, flags
); // XXX: flags
860 void CYModule::Output(CYOutput
&out
) const {
869 void New::Output(CYOutput
&out
, CYFlags flags
) const {
871 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
872 constructor_
->Output(out
, Precedence(), jacks
);
873 if (arguments_
!= NULL
)
874 out
<< '(' << *arguments_
<< ')';
879 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
883 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
884 std::ostringstream str
;
885 CYNumerify(str
, Value());
886 std::string
value(str
.str());
887 out
<< value
.c_str();
888 // XXX: this should probably also handle hex conversions and exponents
889 if ((flags
& CYNoInteger
) != 0 && value
.find('.') == std::string::npos
)
893 void CYNumber::PropertyName(CYOutput
&out
) const {
894 Output(out
, CYNoFlags
);
897 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
898 bool protect((flags
& CYNoBrace
) != 0);
910 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
911 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
915 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
916 const char *name(Operator());
920 rhs_
->Output(out
, Precedence(), CYRight(flags
));
923 void CYScript::Output(CYOutput
&out
) const {
927 void CYProperty::Output(CYOutput
&out
) const {
928 if (next_
!= NULL
|| out
.pretty_
)
930 out
<< '\n' << next_
;
933 void CYPropertyGetter::Output(CYOutput
&out
) const {
935 name_
->PropertyName(out
);
936 CYFunction::Output(out
);
937 CYProperty::Output(out
);
940 void CYPropertyMethod::Output(CYOutput
&out
) const {
941 name_
->PropertyName(out
);
942 CYFunction::Output(out
);
943 CYProperty::Output(out
);
946 void CYPropertySetter::Output(CYOutput
&out
) const {
948 name_
->PropertyName(out
);
949 CYFunction::Output(out
);
950 CYProperty::Output(out
);
953 void CYPropertyValue::Output(CYOutput
&out
) const {
955 name_
->PropertyName(out
);
957 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
958 CYProperty::Output(out
);
961 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
965 void CYResolveMember::Output(CYOutput
&out
, CYFlags flags
) const {
966 object_
->Output(out
, Precedence(), CYLeft(flags
));
967 if (const char *word
= property_
->Word())
970 out
<< "::" << '[' << *property_
<< ']';
973 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
976 out
<< ' ' << *value_
;
980 void CYRubyBlock::Output(CYOutput
&out
, CYFlags flags
) const {
981 lhs_
->Output(out
, CYLeft(flags
));
983 proc_
->Output(out
, CYRight(flags
));
986 void CYRubyProc::Output(CYOutput
&out
, CYFlags flags
) const {
987 out
<< '{' << ' ' << '|' << parameters_
<< '|' << '\n';
994 void CYSubscriptMember::Output(CYOutput
&out
, CYFlags flags
) const {
995 object_
->Output(out
, Precedence(), CYLeft(flags
));
996 out
<< "." << '[' << *property_
<< ']';
999 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
1001 CYForEach (next
, this) {
1002 bool last(next
->next_
== NULL
);
1003 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYRight(flags
) : CYCenter(flags
));
1006 next
->Output(out
, jacks
);
1011 void CYStatement::Single(CYOutput
&out
, CYFlags flags
, CYCompactType request
) const {
1013 return out
.Terminate();
1015 _assert(next_
== NULL
);
1017 CYCompactType
compact(Compact());
1019 if (compact
>= request
)
1029 if (compact
< request
)
1033 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
1034 std::ostringstream str
;
1035 CYStringify(str
, value_
, size_
, CYStringifyModeLegacy
);
1036 out
<< str
.str().c_str();
1039 void CYString::PropertyName(CYOutput
&out
) const {
1040 if (const char *word
= Word())
1046 static const char *Reserved_
[] = {
1047 "false", "null", "true",
1049 "break", "case", "catch", "continue", "default",
1050 "delete", "do", "else", "finally", "for", "function",
1051 "if", "in", "instanceof", "new", "return", "switch",
1052 "this", "throw", "try", "typeof", "var", "void",
1055 "debugger", "const",
1057 "class", "enum", "export", "extends", "import", "super",
1059 "abstract", "boolean", "byte", "char", "double", "final",
1060 "float", "goto", "int", "long", "native", "short",
1061 "synchronized", "throws", "transient", "volatile",
1068 const char *CYString::Word() const {
1069 if (size_
== 0 || !WordStartRange_
[value_
[0]])
1071 for (size_t i(1); i
!= size_
; ++i
)
1072 if (!WordEndRange_
[value_
[i
]])
1074 const char *value(Value());
1075 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
1076 if (strcmp(*reserved
, value
) == 0)
1081 void CYStructDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
1082 out
<< "struct" << ' ' << *name_
<< *tail_
;
1085 void CYStructTail::Output(CYOutput
&out
) const {
1086 out
<< ' ' << '{' << '\n';
1088 CYForEach (field
, fields_
) {
1090 field
->type_
->Output(out
, field
->name_
);
1098 void CYSuperAccess::Output(CYOutput
&out
, CYFlags flags
) const {
1100 if (const char *word
= property_
->Word())
1103 out
<< '[' << *property_
<< ']';
1106 void CYSuperCall::Output(CYOutput
&out
, CYFlags flags
) const {
1107 out
<< "super" << '(' << arguments_
<< ')';
1110 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
1111 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{' << '\n';
1118 void CYSymbol::Output(CYOutput
&out
, CYFlags flags
) const {
1119 bool protect((flags
& CYNoColon
) != 0);
1122 out
<< ':' << name_
;
1127 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
1134 void Throw::Output(CYOutput
&out
, CYFlags flags
) const {
1137 out
<< ' ' << *value_
;
1141 void Try::Output(CYOutput
&out
, CYFlags flags
) const {
1142 out
<< "try" << ' ';
1148 out
<< catch_
<< finally_
;
1153 void CYTypeCharacter::Output(CYOutput
&out
) const {
1155 case CYTypeNeutral
: break;
1156 case CYTypeSigned
: out
<< "signed" << ' '; break;
1157 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1163 void CYTypeEnum::Output(CYOutput
&out
) const {
1164 out
<< "enum" << ' ';
1168 if (specifier_
!= NULL
)
1169 out
<< ':' << ' ' << *specifier_
<< ' ';
1175 CYForEach (constant
, constants_
) {
1180 out
<< '\t' << constant
->name_
;
1181 out
<< ' ' << '=' << ' ' << constant
->value_
;
1192 void CYTypeError::Output(CYOutput
&out
) const {
1196 void CYTypeFloating::Output(CYOutput
&out
) const {
1198 case 0: out
<< "float"; break;
1199 case 1: out
<< "double"; break;
1200 case 2: out
<< "long" << ' ' << "double"; break;
1201 default: _assert(false);
1205 void CYTypeInt128::Output(CYOutput
&out
) const {
1207 case CYTypeNeutral
: break;
1208 case CYTypeSigned
: out
<< "signed" << ' '; break;
1209 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1215 void CYTypeIntegral::Output(CYOutput
&out
) const {
1216 if (signing_
== CYTypeUnsigned
)
1217 out
<< "unsigned" << ' ';
1219 case 0: out
<< "short"; break;
1220 case 1: out
<< "int"; break;
1221 case 2: out
<< "long"; break;
1222 case 3: out
<< "long" << ' ' << "long"; break;
1223 default: _assert(false);
1227 void CYTypeStruct::Output(CYOutput
&out
) const {
1230 out
<< ' ' << *name_
;
1235 void CYTypeReference::Output(CYOutput
&out
) const {
1237 case CYTypeReferenceStruct
: out
<< "struct"; break;
1238 case CYTypeReferenceEnum
: out
<< "enum"; break;
1239 default: _assert(false);
1242 out
<< ' ' << *name_
;
1245 void CYTypeVariable::Output(CYOutput
&out
) const {
1249 void CYTypeVoid::Output(CYOutput
&out
) const {
1253 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
1254 out
<< "var" << ' ';
1255 bindings_
->Output(out
, flags
); // XXX: flags
1259 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
1263 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
1264 out
<< "while" << ' ' << '(' << *test_
<< ')';
1265 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1268 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
1269 out
<< "with" << ' ' << '(' << *scope_
<< ')';
1270 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1273 void CYWord::Output(CYOutput
&out
) const {
1275 if (out
.options_
.verbose_
) {
1278 sprintf(number
, "%p", this);
1283 void CYWord::PropertyName(CYOutput
&out
) const {
1287 const char *CYWord::Word() const {