]>
git.saurik.com Git - cycript.git/blob - Output.cpp
6 _finline CYFlags
operator ~(CYFlags rhs
) {
7 return static_cast<CYFlags
>(~static_cast<unsigned>(rhs
));
10 _finline CYFlags
operator &(CYFlags lhs
, CYFlags rhs
) {
11 return static_cast<CYFlags
>(static_cast<unsigned>(lhs
) & static_cast<unsigned>(rhs
));
14 _finline CYFlags
operator |(CYFlags lhs
, CYFlags rhs
) {
15 return static_cast<CYFlags
>(static_cast<unsigned>(lhs
) | static_cast<unsigned>(rhs
));
18 _finline CYFlags
&operator |=(CYFlags
&lhs
, CYFlags rhs
) {
19 return lhs
= lhs
| rhs
;
22 _finline CYFlags
CYLeft(CYFlags flags
) {
23 return flags
& ~CYNoDangle
;
26 _finline CYFlags
CYRight(CYFlags flags
) {
27 return flags
& ~CYNoBF
;
30 _finline CYFlags
CYCenter(CYFlags flags
) {
31 return CYLeft(CYRight(flags
));
34 void CYOutput::Terminate() {
39 CYOutput
&CYOutput::operator <<(char rhs
) {
40 if (rhs
== ' ' || rhs
== '\n')
46 for (unsigned i(0); i
!= indent_
; ++i
)
55 if (mode_
== Terminated
&& rhs
!= '}')
65 } else if (rhs
== '+') {
69 } else if (rhs
== '-') {
70 if (mode_
== NoHyphen
)
73 } else if (WordEndRange_
[rhs
]) {
74 if (mode_
== NoLetter
)
85 CYOutput
&CYOutput::operator <<(const char *rhs
) {
86 size_t size(strlen(rhs
));
91 if (mode_
== Terminated
)
94 mode_
== NoPlus
&& *rhs
== '+' ||
95 mode_
== NoHyphen
&& *rhs
== '-' ||
96 mode_
== NoLetter
&& WordEndRange_
[*rhs
]
100 if (WordEndRange_
[rhs
[size
- 1]])
109 void CYArgument::Output(CYOutput
&out
) const {
116 value_
->Output(out
, CYPA
, CYNoFlags
);
118 if (next_
->name_
== NULL
)
120 out
<< ' ' << *next_
;
124 void CYArray::Output(CYOutput
&out
, CYFlags flags
) const {
125 out
<< '[' << elements_
<< ']';
128 void CYArrayComprehension::Output(CYOutput
&out
, CYFlags flags
) const {
129 // XXX: I don't necc. need the ()s
130 out
<< "(function($cyv";
131 for (CYComprehension
*comprehension(comprehensions_
); comprehension
!= NULL
; comprehension
= comprehension
->next_
)
132 if (const char *name
= comprehension
->Name())
136 comprehensions_
->Output(out
);
138 expression_
->Output(out
, CYPA
, CYNoFlags
);
140 for (CYComprehension
*comprehension(comprehensions_
); comprehension
!= NULL
; comprehension
= comprehension
->next_
)
141 comprehension
->End_(out
);
142 out
<< "return $cyv;";
146 void CYAssignment::Output(CYOutput
&out
, CYFlags flags
) const {
147 lhs_
->Output(out
, Precedence() - 1, CYLeft(flags
) | CYNoRightHand
);
148 out
<< ' ' << Operator() << ' ';
149 rhs_
->Output(out
, Precedence(), CYRight(flags
));
152 void CYBlock::Output(CYOutput
&out
) const {
155 if (statements_
!= NULL
)
156 statements_
->Multiple(out
);
161 void CYBlock::Output(CYOutput
&out
, CYFlags flags
) const {
162 if (statements_
== NULL
)
164 else if (statements_
->next_
== NULL
)
165 statements_
->Single(out
, flags
);
170 void CYBoolean::Output(CYOutput
&out
, CYFlags flags
) const {
171 out
<< (Value() ? "true" : "false");
174 void CYBreak::Output(CYOutput
&out
, CYFlags flags
) const {
177 out
<< ' ' << *label_
;
181 void CYCall::Output(CYOutput
&out
, CYFlags flags
) const {
182 bool protect((flags
& CYNoCall
) != 0);
185 function_
->Output(out
, Precedence(), protect
? CYNoFlags
: flags
);
186 out
<< '(' << arguments_
<< ')';
191 void CYCatch::Output(CYOutput
&out
) const {
192 out
<< ' ' << "catch" << ' ' << '(' << *name_
<< ')' << ' ' << code_
;
195 void CYCompound::Output(CYOutput
&out
, CYFlags flags
) const {
196 if (CYExpression
*expression
= expressions_
)
197 if (CYExpression
*next
= expression
->next_
) {
198 expression
->Output(out
, CYLeft(flags
));
199 CYFlags
center(CYCenter(flags
));
200 while (next
!= NULL
) {
203 next
= expression
->next_
;
204 CYFlags
right(next
!= NULL
? center
: CYRight(flags
));
205 expression
->Output(out
, right
);
208 expression
->Output(out
, flags
);
211 void CYComprehension::Output(CYOutput
&out
) const {
216 void CYCondition::Output(CYOutput
&out
, CYFlags flags
) const {
217 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
218 out
<< ' ' << '?' << ' ';
220 true_
->Output(out
, CYPA
, CYNoFlags
);
221 out
<< ' ' << ':' << ' ';
222 false_
->Output(out
, CYPA
, CYRight(flags
));
225 void CYContinue::Output(CYOutput
&out
, CYFlags flags
) const {
228 out
<< ' ' << *label_
;
232 void CYClause::Output(CYOutput
&out
) const {
234 out
<< "case" << ' ' << *case_
;
238 if (statements_
!= NULL
)
239 statements_
->Multiple(out
);
243 const char *CYDeclaration::ForEachIn() const {
244 return identifier_
->Value();
247 void CYDeclaration::ForIn(CYOutput
&out
, CYFlags flags
) const {
249 Output(out
, CYRight(flags
));
252 void CYDeclaration::ForEachIn(CYOutput
&out
) const {
256 void CYDeclaration::Output(CYOutput
&out
, CYFlags flags
) const {
258 if (initialiser_
!= NULL
) {
259 out
<< ' ' << '=' << ' ';
260 initialiser_
->Output(out
, CYPA
, CYRight(flags
));
264 void CYDeclarations::For(CYOutput
&out
) const {
269 void CYDeclarations::Output(CYOutput
&out
) const {
270 Output(out
, CYNoFlags
);
273 void CYDeclarations::Output(CYOutput
&out
, CYFlags flags
) const {
274 const CYDeclarations
*declaration(this);
277 CYDeclarations
*next(declaration
->next_
);
278 CYFlags
jacks(first
? CYLeft(flags
) : next
== NULL
? CYRight(flags
) : CYCenter(flags
));
280 declaration
->declaration_
->Output(out
, jacks
);
289 void CYDirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
290 object_
->Output(out
, Precedence(), CYLeft(flags
));
291 if (const char *word
= property_
->Word())
294 out
<< '[' << *property_
<< ']';
297 void CYDoWhile::Output(CYOutput
&out
, CYFlags flags
) const {
299 code_
->Single(out
, CYCenter(flags
));
300 out
<< "while" << ' ' << '(' << *test_
<< ')';
303 void CYElement::Output(CYOutput
&out
) const {
305 value_
->Output(out
, CYPA
, CYNoFlags
);
306 if (next_
!= NULL
|| value_
== NULL
) {
308 if (next_
!= NULL
&& next_
->value_
!= NULL
)
315 void CYEmpty::Output(CYOutput
&out
, CYFlags flags
) const {
319 void CYExpress::Output(CYOutput
&out
, CYFlags flags
) const {
320 expression_
->Output(out
, flags
| CYNoBF
);
324 void CYExpression::ClassName(CYOutput
&out
, bool object
) const {
325 Output(out
, CYPA
, CYNoFlags
);
328 const char *CYExpression::ForEachIn() const {
332 void CYExpression::For(CYOutput
&out
) const {
336 void CYExpression::ForEachIn(CYOutput
&out
) const {
337 Output(out
, CYPA
, CYNoRightHand
);
340 void CYExpression::ForIn(CYOutput
&out
, CYFlags flags
) const {
341 Output(out
, flags
| CYNoRightHand
);
344 void CYExpression::Output(CYOutput
&out
) const {
345 Output(out
, CYNoFlags
);
348 void CYExpression::Output(CYOutput
&out
, unsigned precedence
, CYFlags flags
) const {
349 if (precedence
< Precedence() || (flags
& CYNoRightHand
) != 0 && RightHand())
350 out
<< '(' << *this << ')';
355 void CYFinally::Output(CYOutput
&out
) const {
356 out
<< ' ' << "finally" << ' ' << code_
;
359 void CYFor::Output(CYOutput
&out
, CYFlags flags
) const {
360 out
<< "for" << ' ' << '(';
361 if (initialiser_
!= NULL
)
362 initialiser_
->For(out
);
368 code_
->Single(out
, CYRight(flags
));
371 void CYForEachIn::Output(CYOutput
&out
, CYFlags flags
) const {
372 out
<< "with({$cys:0,$cyt:0}){";
375 set_
->Output(out
, CYPA
, CYNoFlags
);
378 out
<< "for($cyt in $cys){";
380 initialiser_
->ForEachIn(out
);
381 out
<< "=$cys[$cyt];";
383 code_
->Multiple(out
);
390 void CYForEachInComprehension::Begin_(CYOutput
&out
) const {
391 out
<< "(function($cys){";
393 set_
->Output(out
, CYPA
, CYNoFlags
);
396 out
<< "for(" << *name_
<< " in $cys){";
397 out
<< *name_
<< "=$cys[" << *name_
<< "];";
400 void CYForEachInComprehension::End_(CYOutput
&out
) const {
404 void CYForIn::Output(CYOutput
&out
, CYFlags flags
) const {
405 out
<< "for" << ' ' << '(';
406 initialiser_
->ForIn(out
, CYNoIn
);
407 out
<< "in" << *set_
<< ')';
408 code_
->Single(out
, CYRight(flags
));
411 void CYForInComprehension::Begin_(CYOutput
&out
) const {
412 out
<< "for" << ' ' << '(' << *name_
<< "in" << *set_
<< ')';
415 void CYFunction::Output(CYOutput
&out
, CYFlags flags
) const {
416 // XXX: one could imagine using + here to save a byte
417 bool protect((flags
& CYNoFunction
) != 0);
422 out
<< ' ' << *name_
;
423 out
<< '(' << parameters_
<< ')';
429 void CYFunctionExpression::Output(CYOutput
&out
, CYFlags flags
) const {
430 CYFunction::Output(out
, flags
);
433 void CYFunctionStatement::Output(CYOutput
&out
, CYFlags flags
) const {
434 CYFunction::Output(out
, flags
);
437 void CYFunctionParameter::Output(CYOutput
&out
) const {
440 out
<< ',' << ' ' << *next_
;
443 void CYIf::Output(CYOutput
&out
, CYFlags flags
) const {
445 if (false_
== NULL
&& (flags
& CYNoDangle
) != 0) {
450 out
<< "if" << ' ' << '(' << *test_
<< ')';
452 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
454 CYFlags
jacks(CYNoDangle
);
458 jacks
|= protect
? CYNoFlags
: CYCenter(flags
);
460 true_
->Single(out
, jacks
);
462 if (false_
!= NULL
) {
464 false_
->Single(out
, right
);
471 void CYIfComprehension::Begin_(CYOutput
&out
) const {
472 out
<< "if" << '(' << *test_
<< ')';
475 void CYIndirectMember::Output(CYOutput
&out
, CYFlags flags
) const {
476 object_
->Output(out
, Precedence(), CYLeft(flags
));
477 if (const char *word
= property_
->Word())
480 out
<< "->" << '[' << *property_
<< ']';
483 void CYInfix::Output(CYOutput
&out
, CYFlags flags
) const {
484 const char *name(Operator());
485 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in") == 0);
488 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
489 lhs_
->Output(out
, Precedence(), left
);
490 out
<< ' ' << name
<< ' ';
491 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
492 rhs_
->Output(out
, Precedence() - 1, right
);
497 void CYLabel::Output(CYOutput
&out
, CYFlags flags
) const {
498 out
<< *name_
<< ':' << ' ';
499 statement_
->Single(out
, CYRight(flags
));
502 void CYLet::Output(CYOutput
&out
, CYFlags flags
) const {
503 out
<< "let" << ' ' << '(' << *declarations_
<< ')' << ' ' << code_
;
506 void CYNew::Output(CYOutput
&out
, CYFlags flags
) const {
508 CYFlags
jacks(CYNoCall
| CYCenter(flags
));
509 constructor_
->Output(out
, Precedence(), jacks
);
510 if (arguments_
!= NULL
)
511 out
<< '(' << *arguments_
<< ')';
514 void CYNull::Output(CYOutput
&out
, CYFlags flags
) const {
518 void CYNumber::Output(CYOutput
&out
, CYFlags flags
) const {
520 sprintf(value
, "%.17g", Value());
524 void CYNumber::PropertyName(CYOutput
&out
) const {
525 Output(out
, CYNoFlags
);
528 void CYObject::Output(CYOutput
&out
, CYFlags flags
) const {
529 bool protect((flags
& CYNoBrace
) != 0);
541 void CYPostfix::Output(CYOutput
&out
, CYFlags flags
) const {
542 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
546 void CYPrefix::Output(CYOutput
&out
, CYFlags flags
) const {
547 const char *name(Operator());
551 rhs_
->Output(out
, Precedence(), CYRight(flags
));
554 void CYProgram::Output(CYOutput
&out
) const {
555 if (statements_
!= NULL
)
556 statements_
->Multiple(out
);
559 void CYProperty::Output(CYOutput
&out
) const {
561 name_
->PropertyName(out
);
563 value_
->Output(out
, CYPA
, CYNoFlags
);
565 out
<< ',' << '\n' << *next_
;
570 void CYRegEx::Output(CYOutput
&out
, CYFlags flags
) const {
574 void CYReturn::Output(CYOutput
&out
, CYFlags flags
) const {
577 out
<< ' ' << *value_
;
581 void CYStatement::Multiple(CYOutput
&out
, CYFlags flags
) const {
583 for (const CYStatement
*next(this); next
!= NULL
; next
= next
->next_
) {
584 bool last(next
->next_
== NULL
);
585 CYFlags
jacks(first
? last
? flags
: CYLeft(flags
) : last
? CYCenter(flags
) : CYRight(flags
));
588 next
->Output(out
, jacks
);
593 void CYStatement::Single(CYOutput
&out
, CYFlags flags
) const {
594 _assert(next_
== NULL
);
603 void CYString::Output(CYOutput
&out
, CYFlags flags
) const {
604 unsigned quot(0), apos(0);
605 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
608 else if (*value
== '\'')
611 bool single(quot
> apos
);
613 std::ostringstream str
;
615 str
<< (single
? '\'' : '"');
616 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
618 case '\\': str
<< "\\\\"; break;
619 case '\b': str
<< "\\b"; break;
620 case '\f': str
<< "\\f"; break;
621 case '\n': str
<< "\\n"; break;
622 case '\r': str
<< "\\r"; break;
623 case '\t': str
<< "\\t"; break;
624 case '\v': str
<< "\\v"; break;
639 if (*value
< 0x20 || *value
>= 0x7f)
640 str
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
);
644 str
<< (single
? '\'' : '"');
646 out
<< str
.str().c_str();
649 void CYString::PropertyName(CYOutput
&out
) const {
650 if (const char *word
= Word())
656 static const char *Reserved_
[] = {
657 "false", "null", "true",
659 "break", "case", "catch", "continue", "default",
660 "delete", "do", "else", "finally", "for", "function",
661 "if", "in", "instanceof", "new", "return", "switch",
662 "this", "throw", "try", "typeof", "var", "void",
667 "class", "enum", "export", "extends", "import", "super",
669 "abstract", "boolean", "byte", "char", "double", "final",
670 "float", "goto", "int", "long", "native", "short",
671 "synchronized", "throws", "transient", "volatile",
680 const char *CYString::Word() const {
681 if (size_
== 0 || !WordStartRange_
[value_
[0]])
683 for (size_t i(1); i
!= size_
; ++i
)
684 if (!WordEndRange_
[value_
[i
]])
686 const char *value(Value());
687 for (const char **reserved(Reserved_
); *reserved
!= NULL
; ++reserved
)
688 if (strcmp(*reserved
, value
) == 0)
693 void CYSwitch::Output(CYOutput
&out
, CYFlags flags
) const {
694 out
<< "switch" << ' ' << '(' << *value_
<< ')' << ' ' << '{';
699 void CYThis::Output(CYOutput
&out
, CYFlags flags
) const {
703 void CYThrow::Output(CYOutput
&out
, CYFlags flags
) const {
706 out
<< ' ' << *value_
;
710 void CYTry::Output(CYOutput
&out
, CYFlags flags
) const {
711 out
<< "try" << ' ' << code_
<< catch_
<< finally_
;
714 void CYVar::Output(CYOutput
&out
, CYFlags flags
) const {
716 declarations_
->Output(out
, flags
);
720 void CYVariable::Output(CYOutput
&out
, CYFlags flags
) const {
724 void CYWhile::Output(CYOutput
&out
, CYFlags flags
) const {
725 out
<< "while" << '(' << *test_
<< ')';
726 code_
->Single(out
, CYRight(flags
));
729 void CYWith::Output(CYOutput
&out
, CYFlags flags
) const {
730 out
<< "with" << '(' << *scope_
<< ')';
731 code_
->Single(out
, CYRight(flags
));
734 void CYWord::ClassName(CYOutput
&out
, bool object
) const {
736 out
<< "objc_getClass(";
737 out
<< '"' << Value() << '"';
742 void CYWord::Output(CYOutput
&out
) const {
746 void CYWord::PropertyName(CYOutput
&out
) const {