]>
git.saurik.com Git - cycript.git/blob - Output.cpp
a2e32130d91ade2a05606bd5ed562722a92c6caa
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;
98 /*else if (mode == CYStringifyModeNative)
99 str << border << "\\\n" << border;*/
100 else if (type
!= CYStringTypeTemplate
)
101 str
<< border
<< '+' << border
;
109 if (type
== CYStringTypeTemplate
)
115 if (type
== CYStringTypeTemplate
)
121 if (type
== CYStringTypeDouble
)
127 if (type
== CYStringTypeSingle
)
133 if (value
[1] >= '0' && value
[1] <= '9')
140 if (next
>= 0x20 && next
< 0x7f) simple
:
144 if ((next
& 0x80) != 0)
145 while ((next
& 0x80 >> ++levels
) != 0);
147 unsigned point(next
& 0xff >> levels
);
148 while (--levels
!= 0)
149 point
= point
<< 6 | uint8_t(*++value
) & 0x3f;
152 str
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << point
;
153 else if (point
< 0x10000)
154 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << point
;
157 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xd800 | point
>> 0x0a);
158 str
<< "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xdc00 | point
& 0x3ff);
169 void CYNumerify(std::ostringstream
&str
, double value
) {
170 if (std::isinf(value
)) {
178 // XXX: I want this to print 1e3 rather than 1000
179 sprintf(string
, "%.17g", value
);
183 void CYOutput::Terminate() {
188 CYOutput
&CYOutput::operator <<(char rhs
) {
189 if (rhs
== ' ' || rhs
== '\n')
193 else if (rhs
== '\t')
195 for (unsigned i(0); i
!= indent_
; ++i
)
198 else if (rhs
== '\r') {
210 if (mode_
== Terminated
&& rhs
!= '}') {
222 } else if (rhs
== '+') {
226 } else if (rhs
== '-') {
227 if (mode_
== NoHyphen
)
230 } else if (WordEndRange_
[rhs
]) {
231 if (mode_
== NoLetter
)
243 CYOutput
&CYOutput::operator <<(const char *rhs
) {
244 size_t size(strlen(rhs
));
247 return *this << *rhs
;
249 if (mode_
== Terminated
)
252 mode_
== NoPlus
&& *rhs
== '+' ||
253 mode_
== NoHyphen
&& *rhs
== '-' ||
254 mode_
== NoLetter
&& WordEndRange_
[*rhs
]
258 char last(rhs
[size
- 1]);
259 if (WordEndRange_
[last
] || last
== '/')
265 operator ()(rhs
, size
);
269 void CYArgument::Output(CYOutput
&out
) const {
276 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
279 out
<< ' ' << *next_
;
283 void CYArray::Output(CYOutput
&out
, CYFlags flags
) const {
284 out
<< '[' << elements_
<< ']';
287 void CYArrayComprehension::Output(CYOutput
&out
, CYFlags flags
) const {
288 out
<< '[' << *expression_
<< ' ' << *comprehensions_
<< ']';
291 void CYAssignment::Output(CYOutput
&out
, CYFlags flags
) const {
292 lhs_
->Output(out
, Precedence() - 1, CYLeft(flags
) | CYNoRightHand
);
293 out
<< ' ' << Operator() << ' ';
294 rhs_
->Output(out
, Precedence(), CYRight(flags
));
297 void CYBlock::Output(CYOutput
&out
, CYFlags flags
) const {
305 void CYBoolean::Output(CYOutput
&out
, CYFlags flags
) const {
306 out
<< '!' << (Value() ? "0" : "1");
307 if ((flags
& CYNoInteger
) != 0)
311 void CYBreak::Output(CYOutput
&out
, CYFlags flags
) const {
314 out
<< ' ' << *label_
;
318 void CYCall::Output(CYOutput
&out
, CYFlags flags
) const {
319 bool protect((flags
& CYNoCall
) != 0);
322 function_
->Output(out
, Precedence(), protect
? CYNoFlags
: flags
);
323 out
<< '(' << arguments_
<< ')';
331 void Catch::Output(CYOutput
&out
) const {
332 out
<< ' ' << "catch" << ' ' << '(' << *name_
<< ')' << ' ';
342 void CYClassExpression::Output(CYOutput
&out
, CYFlags flags
) const {
343 bool protect((flags
& CYNoClass
) != 0);
348 out
<< ' ' << *name_
;
354 void CYClassStatement::Output(CYOutput
&out
, CYFlags flags
) const {
355 out
<< "class" << ' ' << *name_
<< *tail_
;
358 void CYClassTail::Output(CYOutput
&out
) const {
359 if (extends_
== NULL
)
364 out
<< "extends" << ' ';
365 extends_
->Output(out
, CYAssign::Precedence_
- 1, CYNoFlags
);
377 void CYCompound::Output(CYOutput
&out
, CYFlags flags
) const {
379 expression_
->Output(out
, flags
);
381 expression_
->Output(out
, CYLeft(flags
));
383 next_
->Output(out
, CYRight(flags
));
387 void CYComputed::PropertyName(CYOutput
&out
) const {
389 expression_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
393 void CYCondition::Output(CYOutput
&out
, CYFlags flags
) const {
394 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
395 out
<< ' ' << '?' << ' ';
397 true_
->Output(out
, CYAssign::Precedence_
, CYNoColon
);
398 out
<< ' ' << ':' << ' ';
399 false_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
402 void CYContinue::Output(CYOutput
&out
, CYFlags flags
) const {
405 out
<< ' ' << *label_
;
409 void CYClause::Output(CYOutput
&out
) const {
414 out
<< "case" << ' ';
415 value_
->Output(out
, CYNoColon
);
424 void CYDebugger::Output(CYOutput
&out
, CYFlags flags
) const {
425 out
<< "debugger" << ';';
428 void CYBinding::Output(CYOutput
&out
, CYFlags flags
) const {
430 //out.out_ << ':' << identifier_->usage_ << '#' << identifier_->offset_;
431 if (initializer_
!= NULL
) {
432 out
<< ' ' << '=' << ' ';
433 initializer_
->Output(out
, CYAssign::Precedence_
, CYRight(flags
));
437 void CYBindings::Output(CYOutput
&out
) const {
438 Output(out
, CYNoFlags
);
441 void CYBindings::Output(CYOutput
&out
, CYFlags flags
) const {
442 const CYBindings
*binding(this);
446 CYBindings
*next(binding
->next_
);
448 CYFlags
jacks(first
? CYLeft(flags
) : next
== NULL
? CYRight(flags
) : CYCenter(flags
));
450 binding
->binding_
->Output(out
, jacks
);
460 void CYDirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
461 object_
->Output(out
, Precedence(), CYLeft(flags
) | CYNoInteger
);
462 if (const char *word
= property_
->Word())
465 out
<< '[' << *property_
<< ']';
468 void CYDoWhile::Output(CYOutput
&out
, CYFlags flags
) const {
471 unsigned line(out
.position_
.line
);
472 unsigned indent(out
.indent_
);
473 code_
->Single(out
, CYCenter(flags
), CYCompactLong
);
475 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
480 out
<< "while" << ' ' << '(' << *test_
<< ')';
483 void CYElementSpread::Output(CYOutput
&out
) const {
484 out
<< "..." << value_
;
487 void CYElementValue::Output(CYOutput
&out
) const {
489 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
490 if (next_
!= NULL
|| value_
== NULL
) {
492 if (next_
!= NULL
&& !next_
->Elision())
499 void CYEmpty::Output(CYOutput
&out
, CYFlags flags
) const {
503 void CYEval::Output(CYOutput
&out
, CYFlags flags
) const {
507 void CYExpress::Output(CYOutput
&out
, CYFlags flags
) const {
508 expression_
->Output(out
, flags
| CYNoBFC
);
512 void CYExpression::Output(CYOutput
&out
) const {
513 Output(out
, CYNoFlags
);
516 void CYExpression::Output(CYOutput
&out
, int precedence
, CYFlags flags
) const {
517 if (precedence
< Precedence() || (flags
& CYNoRightHand
) != 0 && RightHand())
518 out
<< '(' << *this << ')';
523 void CYExtend::Output(CYOutput
&out
, CYFlags flags
) const {
524 lhs_
->Output(out
, CYLeft(flags
));
525 out
<< ' ' << object_
;
528 void CYExternalDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
529 out
<< "extern" << ' ' << abi_
<< ' ';
530 type_
->Output(out
, name_
);
534 void CYExternalExpression::Output(CYOutput
&out
, CYFlags flags
) const {
535 out
<< '(' << "extern" << ' ' << abi_
<< ' ';
536 type_
->Output(out
, name_
);
540 void CYFatArrow::Output(CYOutput
&out
, CYFlags flags
) const {
541 out
<< '(' << parameters_
<< ')' << ' ' << "=>" << ' ' << '{' << code_
<< '}';
544 void CYFinally::Output(CYOutput
&out
) const {
545 out
<< ' ' << "finally" << ' ';
553 void CYFor::Output(CYOutput
&out
, CYFlags flags
) const {
554 out
<< "for" << ' ' << '(';
555 if (initializer_
!= NULL
)
556 initializer_
->Output(out
, CYNoIn
);
562 if (increment_
!= NULL
)
566 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
569 void CYForLexical::Output(CYOutput
&out
, CYFlags flags
) const {
570 out
<< (constant_
? "const" : "let") << ' ';
571 binding_
->Output(out
, CYRight(flags
));
574 void CYForIn::Output(CYOutput
&out
, CYFlags flags
) const {
575 out
<< "for" << ' ' << '(';
576 initializer_
->Output(out
, CYNoIn
| CYNoRightHand
);
577 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
578 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
581 void CYForInitialized::Output(CYOutput
&out
, CYFlags flags
) const {
582 out
<< "for" << ' ' << '(' << "var" << ' ';
583 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
584 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
585 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
588 void CYForInComprehension::Output(CYOutput
&out
) const {
589 out
<< "for" << ' ' << '(';
590 binding_
->Output(out
, CYNoIn
| CYNoRightHand
);
591 out
<< ' ' << "in" << ' ' << *iterable_
<< ')';
594 void CYForOf::Output(CYOutput
&out
, CYFlags flags
) const {
595 out
<< "for" << ' ' << '(';
596 initializer_
->Output(out
, CYNoRightHand
);
597 out
<< ' ' << "of" << ' ' << *iterable_
<< ')';
598 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
601 void CYForOfComprehension::Output(CYOutput
&out
) const {
602 out
<< "for" << ' ' << '(';
603 binding_
->Output(out
, CYNoRightHand
);
604 out
<< ' ' << "of" << ' ' << *iterable_
<< ')' << next_
;
607 void CYForVariable::Output(CYOutput
&out
, CYFlags flags
) const {
609 binding_
->Output(out
, CYRight(flags
));
612 void CYFunction::Output(CYOutput
&out
) const {
613 out
<< '(' << parameters_
<< ')' << ' ';
621 void CYFunctionExpression::Output(CYOutput
&out
, CYFlags flags
) const {
622 // XXX: one could imagine using + here to save a byte
623 bool protect((flags
& CYNoFunction
) != 0);
628 out
<< ' ' << *name_
;
629 CYFunction::Output(out
);
634 void CYFunctionStatement::Output(CYOutput
&out
, CYFlags flags
) const {
635 out
<< "function" << ' ' << *name_
;
636 CYFunction::Output(out
);
639 void CYFunctionParameter::Output(CYOutput
&out
) const {
640 binding_
->Output(out
, CYNoFlags
);
642 out
<< ',' << ' ' << *next_
;
645 const char *CYIdentifier::Word() const {
646 return next_
== NULL
|| next_
== this ? CYWord::Word() : next_
->Word();
649 void CYIf::Output(CYOutput
&out
, CYFlags flags
) const {
651 if (false_
== NULL
&& (flags
& CYNoDangle
) != 0) {
656 out
<< "if" << ' ' << '(' << *test_
<< ')';
658 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
660 CYFlags
jacks(CYNoDangle
);
664 jacks
|= protect
? CYNoFlags
: CYCenter(flags
);
666 unsigned line(out
.position_
.line
);
667 unsigned indent(out
.indent_
);
668 true_
->Single(out
, jacks
, CYCompactShort
);
670 if (false_
!= NULL
) {
671 if (out
.position_
.line
!= line
&& out
.recent_
== indent
)
677 false_
->Single(out
, right
, CYCompactLong
);
684 void CYIfComprehension::Output(CYOutput
&out
) const {
685 out
<< "if" << ' ' << '(' << *test_
<< ')' << next_
;
688 void CYImport::Output(CYOutput
&out
, CYFlags flags
) const {
692 void CYImportDeclaration::Output(CYOutput
&out
, CYFlags flags
) const {
696 void CYIndirect::Output(CYOutput
&out
, CYFlags flags
) const {
698 rhs_
->Output(out
, Precedence(), CYRight(flags
));
701 void CYIndirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
702 object_
->Output(out
, Precedence(), CYLeft(flags
));
703 if (const char *word
= property_
->Word())
706 out
<< "->" << '[' << *property_
<< ']';
709 void CYInfix::Output(CYOutput
&out
, CYFlags flags
) const {
710 const char *name(Operator());
711 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in") == 0);
714 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
715 lhs_
->Output(out
, Precedence(), left
);
716 out
<< ' ' << name
<< ' ';
717 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
718 rhs_
->Output(out
, Precedence() - 1, right
);
723 void CYLabel::Output(CYOutput
&out
, CYFlags flags
) const {
724 out
<< *name_
<< ':';
725 statement_
->Single(out
, CYRight(flags
), CYCompactShort
);
728 void CYParenthetical::Output(CYOutput
&out
, CYFlags flags
) const {
730 expression_
->Output(out
, CYCompound::Precedence_
, CYNoFlags
);
734 void CYStatement::Output(CYOutput
&out
) const {
738 void CYTemplate::Output(CYOutput
&out
, CYFlags flags
) const {
742 void CYTypeArrayOf::Output(CYOutput
&out
, CYPropertyName
*name
) const {
743 next_
->Output(out
, Precedence(), name
, false);
749 void CYTypeBlockWith::Output(CYOutput
&out
, CYPropertyName
*name
) const {
751 next_
->Output(out
, Precedence(), name
, false);
752 out
<< ')' << '(' << parameters_
<< ')';
755 void CYTypeConstant::Output(CYOutput
&out
, CYPropertyName
*name
) const {
757 next_
->Output(out
, Precedence(), name
, false);
760 void CYTypeFunctionWith::Output(CYOutput
&out
, CYPropertyName
*name
) const {
761 next_
->Output(out
, Precedence(), name
, false);
762 out
<< '(' << parameters_
;
764 if (parameters_
!= NULL
)
771 void CYTypePointerTo::Output(CYOutput
&out
, CYPropertyName
*name
) const {
773 next_
->Output(out
, Precedence(), name
, false);
776 void CYTypeVolatile::Output(CYOutput
&out
, CYPropertyName
*name
) const {
778 next_
->Output(out
, Precedence(), name
, true);
781 void CYTypeModifier::Output(CYOutput
&out
, int precedence
, CYPropertyName
*name
, bool space
) const {
782 if (this == NULL
&& name
== NULL
)
788 name
->PropertyName(out
);
792 bool protect(precedence
> Precedence());
801 void CYType::Output(CYOutput
&out
, CYPropertyName
*name
) const {
803 modifier_
->Output(out
, 0, name
, true);
806 void CYType::Output(CYOutput
&out
) const {
810 void CYEncodedType::Output(CYOutput
&out
, CYFlags flags
) const {
811 out
<< "@encode(" << typed_
<< ")";
814 void CYTypedParameter::Output(CYOutput
&out
) const {
815 type_
->Output(out
, name_
);
817 out
<< ',' << ' ' << next_
;
820 void CYLambda::Output(CYOutput
&out
, CYFlags flags
) const {
821 // XXX: this is seriously wrong
828 void CYTypeDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
829 out
<< "typedef" << ' ';
830 type_
->Output(out
, name_
);
834 void CYTypeExpression::Output(CYOutput
&out
, CYFlags flags
) const {
835 out
<< '(' << "typedef" << ' ' << *typed_
<< ')';
838 void CYLexical::Output(CYOutput
&out
, CYFlags flags
) const {
840 bindings_
->Output(out
, flags
); // XXX: flags
844 void CYModule::Output(CYOutput
&out
) const {
853 void New::Output(CYOutput
&out
, CYFlags flags
) const {
855 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
856 constructor_
->Output(out
, Precedence(), jacks
);
857 if (arguments_
!= NULL
)
858 out
<< '(' << *arguments_
<< ')';
863 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
867 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
868 std::ostringstream str
;
869 CYNumerify(str
, Value());
870 std::string
value(str
.str());
871 out
<< value
.c_str();
872 // XXX: this should probably also handle hex conversions and exponents
873 if ((flags
& CYNoInteger
) != 0 && value
.find('.') == std::string::npos
)
877 void CYNumber::PropertyName(CYOutput
&out
) const {
878 Output(out
, CYNoFlags
);
881 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
882 bool protect((flags
& CYNoBrace
) != 0);
894 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
895 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
899 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
900 const char *name(Operator());
904 rhs_
->Output(out
, Precedence(), CYRight(flags
));
907 void CYScript::Output(CYOutput
&out
) const {
911 void CYProperty::Output(CYOutput
&out
) const {
912 if (next_
!= NULL
|| out
.pretty_
)
914 out
<< '\n' << next_
;
917 void CYPropertyGetter::Output(CYOutput
&out
) const {
919 name_
->PropertyName(out
);
920 CYFunction::Output(out
);
921 CYProperty::Output(out
);
924 void CYPropertyMethod::Output(CYOutput
&out
) const {
925 name_
->PropertyName(out
);
926 CYFunction::Output(out
);
927 CYProperty::Output(out
);
930 void CYPropertySetter::Output(CYOutput
&out
) const {
932 name_
->PropertyName(out
);
933 CYFunction::Output(out
);
934 CYProperty::Output(out
);
937 void CYPropertyValue::Output(CYOutput
&out
) const {
939 name_
->PropertyName(out
);
941 value_
->Output(out
, CYAssign::Precedence_
, CYNoFlags
);
942 CYProperty::Output(out
);
945 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
949 void CYResolveMember::Output(CYOutput
&out
, CYFlags flags
) const {
950 object_
->Output(out
, Precedence(), CYLeft(flags
));
951 if (const char *word
= property_
->Word())
954 out
<< "::" << '[' << *property_
<< ']';
957 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
960 out
<< ' ' << *value_
;
964 void CYRubyBlock::Output(CYOutput
&out
, CYFlags flags
) const {
965 lhs_
->Output(out
, CYLeft(flags
));
967 proc_
->Output(out
, CYRight(flags
));
970 void CYRubyProc::Output(CYOutput
&out
, CYFlags flags
) const {
971 out
<< '{' << ' ' << '|' << parameters_
<< '|' << '\n';
978 void CYSubscriptMember::Output(CYOutput
&out
, CYFlags flags
) const {
979 object_
->Output(out
, Precedence(), CYLeft(flags
));
980 out
<< "." << '[' << *property_
<< ']';
983 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
985 CYForEach (next
, this) {
986 bool last(next
->next_
== NULL
);
987 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYRight(flags
) : CYCenter(flags
));
990 next
->Output(out
, jacks
);
995 void CYStatement::Single(CYOutput
&out
, CYFlags flags
, CYCompactType request
) const {
997 return out
.Terminate();
999 _assert(next_
== NULL
);
1001 CYCompactType
compact(Compact());
1003 if (compact
>= request
)
1013 if (compact
< request
)
1017 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
1018 std::ostringstream str
;
1019 CYStringify(str
, value_
, size_
, CYStringifyModeLegacy
);
1020 out
<< str
.str().c_str();
1023 void CYString::PropertyName(CYOutput
&out
) const {
1024 if (const char *word
= Word())
1030 static const char *Reserved_
[] = {
1031 "false", "null", "true",
1033 "break", "case", "catch", "continue", "default",
1034 "delete", "do", "else", "finally", "for", "function",
1035 "if", "in", "instanceof", "new", "return", "switch",
1036 "this", "throw", "try", "typeof", "var", "void",
1039 "debugger", "const",
1041 "class", "enum", "export", "extends", "import", "super",
1043 "abstract", "boolean", "byte", "char", "double", "final",
1044 "float", "goto", "int", "long", "native", "short",
1045 "synchronized", "throws", "transient", "volatile",
1052 const char *CYString::Word() const {
1053 if (size_
== 0 || !WordStartRange_
[value_
[0]])
1055 for (size_t i(1); i
!= size_
; ++i
)
1056 if (!WordEndRange_
[value_
[i
]])
1058 const char *value(Value());
1059 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
1060 if (strcmp(*reserved
, value
) == 0)
1065 void CYStructDefinition::Output(CYOutput
&out
, CYFlags flags
) const {
1066 out
<< "struct" << ' ' << *name_
<< *tail_
;
1069 void CYStructTail::Output(CYOutput
&out
) const {
1070 out
<< ' ' << '{' << '\n';
1072 CYForEach (field
, fields_
) {
1074 field
->type_
->Output(out
, field
->name_
);
1082 void CYSuperAccess::Output(CYOutput
&out
, CYFlags flags
) const {
1084 if (const char *word
= property_
->Word())
1087 out
<< '[' << *property_
<< ']';
1090 void CYSuperCall::Output(CYOutput
&out
, CYFlags flags
) const {
1091 out
<< "super" << '(' << arguments_
<< ')';
1094 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
1095 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{' << '\n';
1102 void CYSymbol::Output(CYOutput
&out
, CYFlags flags
) const {
1103 bool protect((flags
& CYNoColon
) != 0);
1106 out
<< ':' << name_
;
1111 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
1118 void Throw::Output(CYOutput
&out
, CYFlags flags
) const {
1121 out
<< ' ' << *value_
;
1125 void Try::Output(CYOutput
&out
, CYFlags flags
) const {
1126 out
<< "try" << ' ';
1132 out
<< catch_
<< finally_
;
1137 void CYTypeCharacter::Output(CYOutput
&out
) const {
1139 case CYTypeNeutral
: break;
1140 case CYTypeSigned
: out
<< "signed" << ' '; break;
1141 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1147 void CYTypeEnum::Output(CYOutput
&out
) const {
1148 out
<< "enum" << ' ';
1152 if (specifier_
!= NULL
)
1153 out
<< ':' << ' ' << *specifier_
<< ' ';
1159 CYForEach (constant
, constants_
) {
1164 out
<< '\t' << constant
->name_
;
1165 out
<< ' ' << '=' << ' ' << constant
->value_
;
1176 void CYTypeError::Output(CYOutput
&out
) const {
1180 void CYTypeInt128::Output(CYOutput
&out
) const {
1182 case CYTypeNeutral
: break;
1183 case CYTypeSigned
: out
<< "signed" << ' '; break;
1184 case CYTypeUnsigned
: out
<< "unsigned" << ' '; break;
1190 void CYTypeIntegral::Output(CYOutput
&out
) const {
1191 if (signing_
== CYTypeUnsigned
)
1192 out
<< "unsigned" << ' ';
1194 case 0: out
<< "short"; break;
1195 case 1: out
<< "int"; break;
1196 case 2: out
<< "long"; break;
1197 case 3: out
<< "long" << ' ' << "long"; break;
1198 default: _assert(false);
1202 void CYTypeStruct::Output(CYOutput
&out
) const {
1205 out
<< ' ' << *name_
;
1210 void CYTypeReference::Output(CYOutput
&out
) const {
1212 case CYTypeReferenceStruct
: out
<< "struct"; break;
1213 case CYTypeReferenceEnum
: out
<< "enum"; break;
1214 default: _assert(false);
1217 out
<< ' ' << *name_
;
1220 void CYTypeVariable::Output(CYOutput
&out
) const {
1224 void CYTypeVoid::Output(CYOutput
&out
) const {
1228 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
1229 out
<< "var" << ' ';
1230 bindings_
->Output(out
, flags
); // XXX: flags
1234 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
1238 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
1239 out
<< "while" << ' ' << '(' << *test_
<< ')';
1240 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1243 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
1244 out
<< "with" << ' ' << '(' << *scope_
<< ')';
1245 code_
->Single(out
, CYRight(flags
), CYCompactShort
);
1248 void CYWord::Output(CYOutput
&out
) const {
1250 if (out
.options_
.verbose_
) {
1253 sprintf(number
, "%p", this);
1258 void CYWord::PropertyName(CYOutput
&out
) const {
1262 const char *CYWord::Word() const {