]>
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 CYBlock::Output(CYOutput
&out
, CYFlags flags
) const {
313 void CYBoolean::Output(CYOutput
&out
, CYFlags flags
) const {
314 out
<< '!' << (Value() ? "0" : "1");
315 if ((flags
& CYNoInteger
) != 0)
319 void CYBreak::Output(CYOutput
&out
, CYFlags flags
) const {
322 out
<< ' ' << *label_
;
326 void CYCall::Output(CYOutput
&out
, CYFlags flags
) const {
327 bool protect((flags
& CYNoCall
) != 0);
330 function_
->Output(out
, Precedence(), protect
? CYNoFlags
: flags
);
331 out
<< '(' << arguments_
<< ')';
339 void Catch::Output(CYOutput
&out
) const {
340 out
<< ' ' << "catch" << ' ' << '(' << *name_
<< ')' << ' ';
350 void CYClassExpression::Output(CYOutput
&out
, CYFlags flags
) const {
351 bool protect((flags
& CYNoClass
) != 0);
356 out
<< ' ' << *name_
;
362 void CYClassStatement::Output(CYOutput
&out
, CYFlags flags
) const {
363 out
<< "class" << ' ' << *name_
<< *tail_
;
366 void CYClassTail::Output(CYOutput
&out
) const {
367 if (extends_
== NULL
)
372 out
<< "extends" << ' ';
373 extends_
->Output(out
, CYAssign::Precedence_
- 1, CYNoFlags
);
385 void CYCompound::Output(CYOutput
&out
, CYFlags flags
) const {
387 expression_
->Output(out
, flags
);
389 expression_
->Output(out
, CYLeft(flags
));
391 next_
->Output(out
, CYRight(flags
));
395 void CYComputed::PropertyName(CYOutput
&out
) const {
397 expression_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
401 void CYCondition::Output(CYOutput
&out
, CYFlags flags
) const {
402 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
403 out
<< ' ' << '?' << ' ';
405 true_
->Output(out
, CYAssign::Precedence_
, CYNoColon
);
406 out
<< ' ' << ':' << ' ';
407 false_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
410 void CYContinue::Output(CYOutput
&out
, CYFlags flags
) const {
413 out
<< ' ' << *label_
;
417 void CYClause::Output(CYOutput
&out
) const {
422 out
<< "case" << ' ';
423 value_
->Output(out
, CYNoColon
);
432 void CYDebugger::Output(CYOutput
&out
, CYFlags flags
) const {
433 out
<< "debugger" << ';';
436 void CYBinding::Output(CYOutput
&out
, CYFlags flags
) const {
438 //out.out_ << ':' << identifier_->usage_ << '#' << identifier_->offset_;
439 if (initializer_
!= NULL
) {
440 out
<< ' ' << '=' << ' ';
441 initializer_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
445 void CYBindings::Output(CYOutput
&out
) const {
446 Output(out
, CYNoFlags
);
449 void CYBindings::Output(CYOutput
&out
, CYFlags flags
) const {
450 const CYBindings
*binding(this);
454 CYBindings
*next(binding
->next_
);
456 CYFlags
jacks(first
? CYLeft(flags
) : next
== NULL
? CYRight(flags
) : CYCenter(flags
));
458 binding
->binding_
->Output(out
, jacks
);
468 void CYDirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
469 object_
->Output(out
, Precedence(), CYLeft(flags
) | CYNoInteger
);
470 if (const char *word
= property_
->Word())
473 out
<< '[' << *property_
<< ']';
476 void CYDoWhile::Output(CYOutput
&out
, CYFlags flags
) const {
479 unsigned line(out
.position_
.line
);
480 unsigned indent(out
.indent_
);
481 code_
->Single(out
, CYCenter(flags
), CYCompactLong
);
483 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
488 out
<< "while" << ' ' << '(' << *test_
<< ')';
491 void CYElementSpread::Output(CYOutput
&out
) const {
492 out
<< "..." << value_
;
495 void CYElementValue::Output(CYOutput
&out
) const {
497 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
498 if (next_
!= NULL
|| value_
== NULL
) {
500 if (next_
!= NULL
&& !next_
->Elision())
507 void CYEmpty::Output(CYOutput
&out
, CYFlags flags
) const {
511 void CYEval::Output(CYOutput
&out
, CYFlags flags
) const {
515 void CYExpress::Output(CYOutput
&out
, CYFlags flags
) const {
516 expression_
->Output(out
, flags
| CYNoBFC
);
520 void CYExpression::Output(CYOutput
&out
) const {
521 Output(out
, CYNoFlags
);
524 void CYExpression::Output(CYOutput
&out
, int precedence
, CYFlags flags
) const {
525 if (precedence
< Precedence() || (flags
& CYNoRightHand
) != 0 && RightHand())
526 out
<< '(' << *this << ')';
531 void CYExtend::Output(CYOutput
&out
, CYFlags flags
) const {
532 lhs_
->Output(out
, CYLeft(flags
));
533 out
<< ' ' << object_
;
536 void CYExternalDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
537 out
<< "extern" << ' ' << abi_
<< ' ';
538 type_
->Output(out
, name_
);
542 void CYExternalExpression::Output(CYOutput
&out
, CYFlags flags
) const {
543 out
<< '(' << "extern" << ' ' << abi_
<< ' ';
544 type_
->Output(out
, name_
);
548 void CYFatArrow::Output(CYOutput
&out
, CYFlags flags
) const {
549 out
<< '(' << parameters_
<< ')' << ' ' << "=>" << ' ' << '{' << code_
<< '}';
552 void CYFinally::Output(CYOutput
&out
) const {
553 out
<< ' ' << "finally" << ' ';
561 void CYFor::Output(CYOutput
&out
, CYFlags flags
) const {
562 out
<< "for" << ' ' << '(';
563 if (initializer_
!= NULL
)
564 initializer_
->Output(out
, CYNoIn
);
570 if (increment_
!= NULL
)
574 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
577 void CYForLexical::Output(CYOutput
&out
, CYFlags flags
) const {
578 out
<< (constant_
? "const" : "let") << ' ';
579 binding_
->Output(out
, CYRight(flags
));
582 void CYForIn::Output(CYOutput
&out
, CYFlags flags
) const {
583 out
<< "for" << ' ' << '(';
584 initializer_
->Output(out
, CYNoIn
| CYNoRightHand
);
585 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
586 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
589 void CYForInitialized::Output(CYOutput
&out
, CYFlags flags
) const {
590 out
<< "for" << ' ' << '(' << "var" << ' ';
591 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
592 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
593 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
596 void CYForInComprehension::Output(CYOutput
&out
) const {
597 out
<< "for" << ' ' << '(';
598 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
599 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
602 void CYForOf::Output(CYOutput
&out
, CYFlags flags
) const {
603 out
<< "for" << ' ' << '(';
604 initializer_
->Output(out
, CYNoRightHand
);
605 out
<< ' ' << "of" << ' ' << *iterable_
<< ')';
606 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
609 void CYForOfComprehension::Output(CYOutput
&out
) const {
610 out
<< "for" << ' ' << '(';
611 binding_
->Output(out
, CYNoRightHand
);
612 out
<< ' ' << "of" << ' ' << *iterable_
<< ')' << next_
;
615 void CYForVariable::Output(CYOutput
&out
, CYFlags flags
) const {
617 binding_
->Output(out
, CYRight(flags
));
620 void CYFunction::Output(CYOutput
&out
) const {
621 out
<< '(' << parameters_
<< ')' << ' ';
629 void CYFunctionExpression::Output(CYOutput
&out
, CYFlags flags
) const {
630 // XXX: one could imagine using + here to save a byte
631 bool protect((flags
& CYNoFunction
) != 0);
636 out
<< ' ' << *name_
;
637 CYFunction::Output(out
);
642 void CYFunctionStatement::Output(CYOutput
&out
, CYFlags flags
) const {
643 out
<< "function" << ' ' << *name_
;
644 CYFunction::Output(out
);
647 void CYFunctionParameter::Output(CYOutput
&out
) const {
648 binding_
->Output(out
, CYNoFlags
);
650 out
<< ',' << ' ' << *next_
;
653 const char *CYIdentifier::Word() const {
654 return next_
== NULL
|| next_
== this ? CYWord::Word() : next_
->Word();
657 void CYIf::Output(CYOutput
&out
, CYFlags flags
) const {
659 if (false_
== NULL
&& (flags
& CYNoDangle
) != 0) {
664 out
<< "if" << ' ' << '(' << *test_
<< ')';
666 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
668 CYFlags
jacks(CYNoDangle
);
672 jacks
|= protect
? CYNoFlags
: CYCenter(flags
);
674 unsigned line(out
.position_
.line
);
675 unsigned indent(out
.indent_
);
676 true_
->Single(out
, jacks
, CYCompactShort
);
678 if (false_
!= NULL
) {
679 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
685 false_
->Single(out
, right
, CYCompactLong
);
692 void CYIfComprehension::Output(CYOutput
&out
) const {
693 out
<< "if" << ' ' << '(' << *test_
<< ')' << next_
;
696 void CYImport::Output(CYOutput
&out
, CYFlags flags
) const {
700 void CYImportDeclaration::Output(CYOutput
&out
, CYFlags flags
) const {
704 void CYIndirect::Output(CYOutput
&out
, CYFlags flags
) const {
706 rhs_
->Output(out
, Precedence(), CYRight(flags
));
709 void CYIndirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
710 object_
->Output(out
, Precedence(), CYLeft(flags
));
711 if (const char *word
= property_
->Word())
714 out
<< "->" << '[' << *property_
<< ']';
717 void CYInfix::Output(CYOutput
&out
, CYFlags flags
) const {
718 const char *name(Operator());
719 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in") == 0);
722 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
723 lhs_
->Output(out
, Precedence(), left
);
724 out
<< ' ' << name
<< ' ';
725 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
726 rhs_
->Output(out
, Precedence() - 1, right
);
731 void CYLabel::Output(CYOutput
&out
, CYFlags flags
) const {
732 out
<< *name_
<< ':';
733 statement_
->Single(out
, CYRight(flags
), CYCompactShort
);
736 void CYParenthetical::Output(CYOutput
&out
, CYFlags flags
) const {
738 expression_
->Output(out
, CYCompound::Precedence_
, CYNoFlags
);
742 void CYStatement::Output(CYOutput
&out
) const {
746 void CYTemplate::Output(CYOutput
&out
, CYFlags flags
) const {
750 void CYTypeArrayOf::Output(CYOutput
&out
, CYPropertyName
*name
) const {
751 next_
->Output(out
, Precedence(), name
, false);
757 void CYTypeBlockWith::Output(CYOutput
&out
, CYPropertyName
*name
) const {
759 next_
->Output(out
, Precedence(), name
, false);
760 out
<< ')' << '(' << parameters_
<< ')';
763 void CYTypeConstant::Output(CYOutput
&out
, CYPropertyName
*name
) const {
765 next_
->Output(out
, Precedence(), name
, false);
768 void CYTypeFunctionWith::Output(CYOutput
&out
, CYPropertyName
*name
) const {
769 next_
->Output(out
, Precedence(), name
, false);
770 out
<< '(' << parameters_
;
772 if (parameters_
!= NULL
)
779 void CYTypePointerTo::Output(CYOutput
&out
, CYPropertyName
*name
) const {
781 next_
->Output(out
, Precedence(), name
, false);
784 void CYTypeVolatile::Output(CYOutput
&out
, CYPropertyName
*name
) const {
786 next_
->Output(out
, Precedence(), name
, true);
789 void CYTypeModifier::Output(CYOutput
&out
, int precedence
, CYPropertyName
*name
, bool space
) const {
790 if (this == NULL
&& name
== NULL
)
796 name
->PropertyName(out
);
800 bool protect(precedence
> Precedence());
809 void CYType::Output(CYOutput
&out
, CYPropertyName
*name
) const {
811 modifier_
->Output(out
, 0, name
, true);
814 void CYType::Output(CYOutput
&out
) const {
818 void CYEncodedType::Output(CYOutput
&out
, CYFlags flags
) const {
819 out
<< "@encode(" << typed_
<< ")";
822 void CYTypedParameter::Output(CYOutput
&out
) const {
823 type_
->Output(out
, name_
);
825 out
<< ',' << ' ' << next_
;
828 void CYLambda::Output(CYOutput
&out
, CYFlags flags
) const {
829 // XXX: this is seriously wrong
836 void CYTypeDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
837 out
<< "typedef" << ' ';
838 type_
->Output(out
, name_
);
842 void CYTypeExpression::Output(CYOutput
&out
, CYFlags flags
) const {
843 out
<< '(' << "typedef" << ' ' << *typed_
<< ')';
846 void CYLexical::Output(CYOutput
&out
, CYFlags flags
) const {
848 bindings_
->Output(out
, flags
); // XXX: flags
852 void CYModule::Output(CYOutput
&out
) const {
861 void New::Output(CYOutput
&out
, CYFlags flags
) const {
863 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
864 constructor_
->Output(out
, Precedence(), jacks
);
865 if (arguments_
!= NULL
)
866 out
<< '(' << *arguments_
<< ')';
871 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
875 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
876 std::ostringstream str
;
877 CYNumerify(str
, Value());
878 std::string
value(str
.str());
879 out
<< value
.c_str();
880 // XXX: this should probably also handle hex conversions and exponents
881 if ((flags
& CYNoInteger
) != 0 && value
.find('.') == std::string::npos
)
885 void CYNumber::PropertyName(CYOutput
&out
) const {
886 Output(out
, CYNoFlags
);
889 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
890 bool protect((flags
& CYNoBrace
) != 0);
902 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
903 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
907 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
908 const char *name(Operator());
912 rhs_
->Output(out
, Precedence(), CYRight(flags
));
915 void CYScript::Output(CYOutput
&out
) const {
919 void CYProperty::Output(CYOutput
&out
) const {
920 if (next_
!= NULL
|| out
.pretty_
)
922 out
<< '\n' << next_
;
925 void CYPropertyGetter::Output(CYOutput
&out
) const {
927 name_
->PropertyName(out
);
928 CYFunction::Output(out
);
929 CYProperty::Output(out
);
932 void CYPropertyMethod::Output(CYOutput
&out
) const {
933 name_
->PropertyName(out
);
934 CYFunction::Output(out
);
935 CYProperty::Output(out
);
938 void CYPropertySetter::Output(CYOutput
&out
) const {
940 name_
->PropertyName(out
);
941 CYFunction::Output(out
);
942 CYProperty::Output(out
);
945 void CYPropertyValue::Output(CYOutput
&out
) const {
947 name_
->PropertyName(out
);
949 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
950 CYProperty::Output(out
);
953 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
957 void CYResolveMember::Output(CYOutput
&out
, CYFlags flags
) const {
958 object_
->Output(out
, Precedence(), CYLeft(flags
));
959 if (const char *word
= property_
->Word())
962 out
<< "::" << '[' << *property_
<< ']';
965 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
968 out
<< ' ' << *value_
;
972 void CYRubyBlock::Output(CYOutput
&out
, CYFlags flags
) const {
973 lhs_
->Output(out
, CYLeft(flags
));
975 proc_
->Output(out
, CYRight(flags
));
978 void CYRubyProc::Output(CYOutput
&out
, CYFlags flags
) const {
979 out
<< '{' << ' ' << '|' << parameters_
<< '|' << '\n';
986 void CYSubscriptMember::Output(CYOutput
&out
, CYFlags flags
) const {
987 object_
->Output(out
, Precedence(), CYLeft(flags
));
988 out
<< "." << '[' << *property_
<< ']';
991 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
993 CYForEach (next
, this) {
994 bool last(next
->next_
== NULL
);
995 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYRight(flags
) : CYCenter(flags
));
998 next
->Output(out
, jacks
);
1003 void CYStatement::Single(CYOutput
&out
, CYFlags flags
, CYCompactType request
) const {
1005 return out
.Terminate();
1007 _assert(next_
== NULL
);
1009 CYCompactType
compact(Compact());
1011 if (compact
>= request
)
1021 if (compact
< request
)
1025 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
1026 std::ostringstream str
;
1027 CYStringify(str
, value_
, size_
, CYStringifyModeLegacy
);
1028 out
<< str
.str().c_str();
1031 void CYString::PropertyName(CYOutput
&out
) const {
1032 if (const char *word
= Word())
1038 static const char *Reserved_
[] = {
1039 "false", "null", "true",
1041 "break", "case", "catch", "continue", "default",
1042 "delete", "do", "else", "finally", "for", "function",
1043 "if", "in", "instanceof", "new", "return", "switch",
1044 "this", "throw", "try", "typeof", "var", "void",
1047 "debugger", "const",
1049 "class", "enum", "export", "extends", "import", "super",
1051 "abstract", "boolean", "byte", "char", "double", "final",
1052 "float", "goto", "int", "long", "native", "short",
1053 "synchronized", "throws", "transient", "volatile",
1060 const char *CYString::Word() const {
1061 if (size_
== 0 || !WordStartRange_
[value_
[0]])
1063 for (size_t i(1); i
!= size_
; ++i
)
1064 if (!WordEndRange_
[value_
[i
]])
1066 const char *value(Value());
1067 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
1068 if (strcmp(*reserved
, value
) == 0)
1073 void CYStructDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
1074 out
<< "struct" << ' ' << *name_
<< *tail_
;
1077 void CYStructTail::Output(CYOutput
&out
) const {
1078 out
<< ' ' << '{' << '\n';
1080 CYForEach (field
, fields_
) {
1082 field
->type_
->Output(out
, field
->name_
);
1090 void CYSuperAccess::Output(CYOutput
&out
, CYFlags flags
) const {
1092 if (const char *word
= property_
->Word())
1095 out
<< '[' << *property_
<< ']';
1098 void CYSuperCall::Output(CYOutput
&out
, CYFlags flags
) const {
1099 out
<< "super" << '(' << arguments_
<< ')';
1102 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
1103 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{' << '\n';
1110 void CYSymbol::Output(CYOutput
&out
, CYFlags flags
) const {
1111 bool protect((flags
& CYNoColon
) != 0);
1114 out
<< ':' << name_
;
1119 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
1126 void Throw::Output(CYOutput
&out
, CYFlags flags
) const {
1129 out
<< ' ' << *value_
;
1133 void Try::Output(CYOutput
&out
, CYFlags flags
) const {
1134 out
<< "try" << ' ';
1140 out
<< catch_
<< finally_
;
1145 void CYTypeCharacter::Output(CYOutput
&out
) const {
1147 case CYTypeNeutral
: break;
1148 case CYTypeSigned
: out
<< "signed" << ' '; break;
1149 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1155 void CYTypeEnum::Output(CYOutput
&out
) const {
1156 out
<< "enum" << ' ';
1160 if (specifier_
!= NULL
)
1161 out
<< ':' << ' ' << *specifier_
<< ' ';
1167 CYForEach (constant
, constants_
) {
1172 out
<< '\t' << constant
->name_
;
1173 out
<< ' ' << '=' << ' ' << constant
->value_
;
1184 void CYTypeError::Output(CYOutput
&out
) const {
1188 void CYTypeFloating::Output(CYOutput
&out
) const {
1190 case 0: out
<< "float"; break;
1191 case 1: out
<< "double"; break;
1192 case 2: out
<< "long" << ' ' << "double"; break;
1193 default: _assert(false);
1197 void CYTypeInt128::Output(CYOutput
&out
) const {
1199 case CYTypeNeutral
: break;
1200 case CYTypeSigned
: out
<< "signed" << ' '; break;
1201 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1207 void CYTypeIntegral::Output(CYOutput
&out
) const {
1208 if (signing_
== CYTypeUnsigned
)
1209 out
<< "unsigned" << ' ';
1211 case 0: out
<< "short"; break;
1212 case 1: out
<< "int"; break;
1213 case 2: out
<< "long"; break;
1214 case 3: out
<< "long" << ' ' << "long"; break;
1215 default: _assert(false);
1219 void CYTypeStruct::Output(CYOutput
&out
) const {
1222 out
<< ' ' << *name_
;
1227 void CYTypeReference::Output(CYOutput
&out
) const {
1229 case CYTypeReferenceStruct
: out
<< "struct"; break;
1230 case CYTypeReferenceEnum
: out
<< "enum"; break;
1231 default: _assert(false);
1234 out
<< ' ' << *name_
;
1237 void CYTypeVariable::Output(CYOutput
&out
) const {
1241 void CYTypeVoid::Output(CYOutput
&out
) const {
1245 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
1246 out
<< "var" << ' ';
1247 bindings_
->Output(out
, flags
); // XXX: flags
1251 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
1255 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
1256 out
<< "while" << ' ' << '(' << *test_
<< ')';
1257 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1260 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
1261 out
<< "with" << ' ' << '(' << *scope_
<< ')';
1262 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1265 void CYWord::Output(CYOutput
&out
) const {
1267 if (out
.options_
.verbose_
) {
1270 sprintf(number
, "%p", this);
1275 void CYWord::PropertyName(CYOutput
&out
) const {
1279 const char *CYWord::Word() const {