]>
git.saurik.com Git - cycript.git/blob - Output.cpp
75802883eeafa85f0f250cb32963c4b0f0e69feb
6 #include <objc/runtime.h>
9 _finline CYFlags
operator ~(CYFlags rhs
) {
10 return static_cast<CYFlags
>(~static_cast<unsigned>(rhs
));
13 _finline CYFlags
operator &(CYFlags lhs
, CYFlags rhs
) {
14 return static_cast<CYFlags
>(static_cast<unsigned>(lhs
) & static_cast<unsigned>(rhs
));
17 _finline CYFlags
operator |(CYFlags lhs
, CYFlags rhs
) {
18 return static_cast<CYFlags
>(static_cast<unsigned>(lhs
) | static_cast<unsigned>(rhs
));
21 _finline CYFlags
&operator |=(CYFlags
&lhs
, CYFlags rhs
) {
22 return lhs
= lhs
| rhs
;
25 _finline CYFlags
CYLeft(CYFlags flags
) {
26 return flags
& ~CYNoTrailer
;
29 _finline CYFlags
CYCenter(CYFlags flags
) {
30 return flags
& CYNoIn
;
33 _finline CYFlags
CYRight(CYFlags flags
) {
34 return flags
& (CYNoIn
| CYNoTrailer
);
37 bool CYFalse::Value() const {
41 bool CYTrue::Value() const {
47 void CYAddressOf::Output(std::ostream
&out
, CYFlags flags
) const {
48 rhs_
->Output(out
, 1, CYLeft(flags
));
52 void CYArgument::Output(std::ostream
&out
) const {
59 value_
->Output(out
, CYPA
, CYNoFlags
);
61 if (next_
->name_
== NULL
)
69 void CYArray::Output(std::ostream
&out
, CYFlags flags
) const {
71 if (elements_
!= NULL
)
72 elements_
->Output(out
);
76 void CYArrayComprehension::Output(std::ostream
&out
, CYFlags flags
) const {
77 // XXX: I don't necc. need the ()s
78 out
<< "(function($cyv";
79 for (CYComprehension
*comprehension(comprehensions_
); comprehension
!= NULL
; comprehension
= comprehension
->next_
)
80 if (const char *name
= comprehension
->Name())
84 comprehensions_
->Output(out
);
86 expression_
->Output(out
, CYPA
, CYNoFlags
);
88 for (CYComprehension
*comprehension(comprehensions_
); comprehension
!= NULL
; comprehension
= comprehension
->next_
)
89 comprehension
->End_(out
);
90 out
<< "return $cyv;";
94 void CYAssignment::Output(std::ostream
&out
, CYFlags flags
) const {
95 lhs_
->Output(out
, Precedence() - 1, CYLeft(flags
));
97 rhs_
->Output(out
, Precedence(), CYRight(flags
));
100 void CYBlock::Output(std::ostream
&out
) const {
101 for (CYSource
*statement(statements_
); statement
!= NULL
; statement
= statement
->next_
)
102 statement
->Output(out
);
105 void CYBoolean::Output(std::ostream
&out
, CYFlags flags
) const {
106 if ((flags
& CYNoLeader
) != 0)
108 out
<< (Value() ? "true" : "false");
109 if ((flags
& CYNoTrailer
) != 0)
113 void CYBreak::Output(std::ostream
&out
) const {
116 out
<< ' ' << *label_
;
120 void CYCall::Output(std::ostream
&out
, CYFlags flags
) const {
121 function_
->Output(out
, Precedence(), CYLeft(flags
));
123 if (arguments_
!= NULL
)
124 arguments_
->Output(out
);
128 void CYCatch::Output(std::ostream
&out
) const {
129 out
<< "catch(" << *name_
<< ')';
130 code_
->Output(out
, true);
133 void CYCategory::Output(std::ostream
&out
) const {
134 out
<< "(function($cys,$cyp,$cyc,$cyn,$cyt){";
135 out
<< "$cyp=object_getClass($cys);";
137 if (messages_
!= NULL
)
138 messages_
->Output(out
, true);
140 name_
->ClassName(out
, true);
144 void CYClass::Output(std::ostream
&out
) const {
149 void CYClass::Output(std::ostream
&out
, CYFlags flags
) const {
150 // XXX: I don't necc. need the ()s
151 out
<< "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){";
152 out
<< "$cyp=object_getClass($cys);";
153 out
<< "$cyc=objc_allocateClassPair($cys,";
155 name_
->ClassName(out
, false);
157 out
<< "$cyq(\"CY$\")";
159 out
<< "$cym=object_getClass($cyc);";
161 fields_
->Output(out
);
162 if (messages_
!= NULL
)
163 messages_
->Output(out
, false);
164 out
<< "objc_registerClassPair($cyc);";
165 out
<< "return $cyc;";
168 super_
->Output(out
, CYPA
, CYNoFlags
);
174 void CYCompound::Output(std::ostream
&out
, CYFlags flags
) const {
175 if (CYExpression
*expression
= expressions_
)
176 if (CYExpression
*next
= expression
->next_
) {
177 expression
->Output(out
, CYLeft(flags
));
178 CYFlags
center(CYCenter(flags
));
179 while (next
!= NULL
) {
182 next
= expression
->next_
;
183 CYFlags
right(next
!= NULL
? center
: CYRight(flags
));
184 expression
->Output(out
, right
);
187 expression
->Output(out
, flags
);
190 void CYComprehension::Output(std::ostream
&out
) const {
196 void CYCondition::Output(std::ostream
&out
, CYFlags flags
) const {
197 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
200 true_
->Output(out
, CYPA
, CYNoFlags
);
202 false_
->Output(out
, CYPA
, CYRight(flags
));
205 void CYContinue::Output(std::ostream
&out
) const {
208 out
<< ' ' << *label_
;
212 void CYClause::Output(std::ostream
&out
) const {
215 case_
->Output(out
, CYNoLeader
);
220 code_
->Output(out
, false);
225 const char *CYDeclaration::ForEachIn() const {
226 return identifier_
->Value();
229 void CYDeclaration::ForIn(std::ostream
&out
, CYFlags flags
) const {
230 if ((flags
& CYNoLeader
) != 0)
233 Output(out
, CYRight(flags
));
236 void CYDeclaration::ForEachIn(std::ostream
&out
) const {
240 void CYDeclaration::Output(std::ostream
&out
, CYFlags flags
) const {
242 if (initialiser_
!= NULL
) {
244 initialiser_
->Output(out
, CYPA
, CYRight(flags
));
245 } else if ((flags
& CYNoTrailer
) != 0)
249 void CYDeclarations::For(std::ostream
&out
) const {
254 void CYDeclarations::Output(std::ostream
&out
, CYFlags flags
) const {
255 const CYDeclarations
*declaration(this);
257 CYDeclarations
*next(declaration
->next_
);
258 CYFlags
right(next
== NULL
? CYRight(flags
) : CYCenter(flags
));
259 declaration
->declaration_
->Output(out
, right
);
268 void CYDirectMember::Output(std::ostream
&out
, CYFlags flags
) const {
269 object_
->Output(out
, Precedence(), CYLeft(flags
));
270 if (const char *word
= property_
->Word())
274 property_
->Output(out
, CYNoFlags
);
279 void CYDoWhile::Output(std::ostream
&out
) const {
280 // XXX: extra space character!
282 code_
->Output(out
, false);
284 test_
->Output(out
, CYNoFlags
);
288 void CYElement::Output(std::ostream
&out
) const {
290 value_
->Output(out
, CYPA
, CYNoFlags
);
291 if (next_
!= NULL
|| value_
== NULL
)
297 void CYEmpty::Output(std::ostream
&out
) const {
301 void CYEmpty::Output(std::ostream
&out
, bool block
) const {
303 CYSource::Output(out
, block
);
308 void CYExpress::Output(std::ostream
&out
) const {
309 expression_
->Output(out
, CYNoBF
);
313 void CYExpression::ClassName(std::ostream
&out
, bool object
) const {
314 Output(out
, CYPA
, CYNoFlags
);
317 const char *CYExpression::ForEachIn() const {
321 void CYExpression::For(std::ostream
&out
) const {
325 void CYExpression::ForEachIn(std::ostream
&out
) const {
326 // XXX: this should handle LeftHandSideExpression
327 Output(out
, CYPA
, CYNoFlags
);
330 void CYExpression::ForIn(std::ostream
&out
, CYFlags flags
) const {
331 // XXX: this should handle LeftHandSideExpression
335 void CYExpression::Output(std::ostream
&out
, unsigned precedence
, CYFlags flags
) const {
336 if (precedence
< Precedence()) {
338 Output(out
, CYNoFlags
);
344 void CYField::Output(std::ostream
&out
) const {
348 void CYFor::Output(std::ostream
&out
) const {
350 if (initialiser_
!= NULL
)
351 initialiser_
->For(out
);
354 test_
->Output(out
, CYNoFlags
);
356 if (increment_
!= NULL
)
357 increment_
->Output(out
, CYNoFlags
);
359 code_
->Output(out
, false);
362 void CYForEachIn::Output(std::ostream
&out
) const {
363 const char *name(initialiser_
->ForEachIn());
367 out
<< "var " << name
<< ';';
370 out
<< "(function($cys,$cyt){";
372 set_
->Output(out
, CYPA
, CYNoFlags
);
375 out
<< "for($cyt in $cys){";
377 initialiser_
->ForEachIn(out
);
378 out
<< "=$cys[$cyt];";
388 void CYForEachInComprehension::Begin_(std::ostream
&out
) const {
389 out
<< "(function($cys){";
391 set_
->Output(out
, CYPA
, CYNoFlags
);
394 out
<< "for(" << *name_
<< " in $cys){";
395 out
<< *name_
<< "=$cys[" << *name_
<< "];";
398 void CYForEachInComprehension::End_(std::ostream
&out
) const {
402 void CYForIn::Output(std::ostream
&out
) const {
404 initialiser_
->ForIn(out
, CYNoIn
| CYNoTrailer
);
406 set_
->Output(out
, CYNoLeader
);
408 code_
->Output(out
, false);
411 void CYForInComprehension::Begin_(std::ostream
&out
) const {
412 out
<< "for(" << *name_
<< " in";
413 set_
->Output(out
, CYNoLeader
);
417 void CYFunction::Output(std::ostream
&out
) const {
418 CYLambda::Output(out
, CYNoFlags
);
421 void CYFunctionParameter::Output(std::ostream
&out
) const {
429 void CYIf::Output(std::ostream
&out
) const {
431 test_
->Output(out
, CYNoFlags
);
433 true_
->Output(out
, true);
434 if (false_
!= NULL
) {
436 false_
->Output(out
, false);
440 void CYIfComprehension::Begin_(std::ostream
&out
) const {
442 test_
->Output(out
, CYNoFlags
);
446 void CYIndirect::Output(std::ostream
&out
, CYFlags flags
) const {
447 rhs_
->Output(out
, 1, CYLeft(flags
));
451 void CYIndirectMember::Output(std::ostream
&out
, CYFlags flags
) const {
452 object_
->Output(out
, Precedence(), CYLeft(flags
));
454 if (const char *word
= property_
->Word())
458 property_
->Output(out
, CYNoFlags
);
463 void CYInfix::Output(std::ostream
&out
, CYFlags flags
) const {
464 const char *name(Operator());
465 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in"));
468 bool alphabetic(Alphabetic());
469 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
472 lhs_
->Output(out
, Precedence(), left
);
474 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
477 if (strcmp(name
, "-") == 0)
479 rhs_
->Output(out
, Precedence() - 1, right
);
484 void CYLambda::Output(std::ostream
&out
, CYFlags flags
) const {
485 bool protect((flags
& CYNoFunction
) != 0);
488 else if ((flags
& CYNoLeader
) != 0)
492 out
<< ' ' << *name_
;
494 if (parameters_
!= NULL
)
504 void CYLet::Output(std::ostream
&out
) const {
506 declarations_
->Output(out
, CYNoFlags
);
508 if (statements_
!= NULL
)
509 statements_
->Show(out
);
513 void CYMessage::Output(std::ostream
&out
, bool replace
) const {
515 next_
->Output(out
, replace
);
516 out
<< "$cyn=new Selector(\"";
517 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
518 if (parameter
->tag_
!= NULL
) {
519 out
<< *parameter
->tag_
;
520 if (parameter
->name_
!= NULL
)
524 out
<< "$cyt=$cyn.type($cy" << (instance_
? 's' : 'p') << ");";
525 out
<< "class_" << (replace
? "replace" : "add") << "Method($cy" << (instance_
? 'c' : 'm') << ",$cyn,";
526 out
<< "new Functor(function(self,_cmd";
527 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
528 if (parameter
->name_
!= NULL
)
529 out
<< ',' << *parameter
->name_
;
530 out
<< "){return function(){";
533 out
<< "}.call(self);},$cyt),$cyt);";
536 void CYNew::Output(std::ostream
&out
, CYFlags flags
) const {
537 if ((flags
& CYNoLeader
) != 0)
540 constructor_
->Output(out
, Precedence(), CYCenter(flags
) | CYNoLeader
);
542 if (arguments_
!= NULL
)
543 arguments_
->Output(out
);
547 void CYNull::Output(std::ostream
&out
, CYFlags flags
) const {
548 if ((flags
& CYNoLeader
) != 0)
551 if ((flags
& CYNoTrailer
) != 0)
555 void CYNumber::Output(std::ostream
&out
, CYFlags flags
) const {
556 double value(Value());
557 if ((flags
& CYNoLeader
) != 0 || value
< 0 && (flags
& CYNoHyphen
) != 0)
559 // XXX: decide on correct precision
560 out
<< std::setprecision(9) << value
;
561 if ((flags
& CYNoTrailer
) != 0)
565 void CYNumber::PropertyName(std::ostream
&out
) const {
569 void CYObject::Output(std::ostream
&out
, CYFlags flags
) const {
570 bool protect((flags
& CYNoBrace
) != 0);
574 if (property_
!= NULL
)
575 property_
->Output(out
);
581 void CYPostfix::Output(std::ostream
&out
, CYFlags flags
) const {
582 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
586 void CYPrefix::Output(std::ostream
&out
, CYFlags flags
) const {
587 const char *name(Operator());
588 bool alphabetic(Alphabetic());
589 if (alphabetic
&& (flags
& CYNoLeader
) != 0 || name
[0] == '-' && (flags
& CYNoHyphen
) != 0)
592 CYFlags
right(CYRight(flags
));
595 rhs_
->Output(out
, Precedence(), right
);
598 void CYProperty::Output(std::ostream
&out
) const {
599 name_
->PropertyName(out
);
601 value_
->Output(out
, CYPA
, CYNoFlags
);
608 void CYReturn::Output(std::ostream
&out
) const {
611 value_
->Output(out
, CYNoLeader
);
615 void CYSelector::Output(std::ostream
&out
, CYFlags flags
) const {
616 if ((flags
& CYNoLeader
) != 0)
618 out
<< "new Selector(\"";
624 void CYSelectorPart::Output(std::ostream
&out
) const {
633 void CYSend::Output(std::ostream
&out
, CYFlags flags
) const {
634 if ((flags
& CYNoLeader
) != 0)
636 out
<< "objc_msgSend(";
637 self_
->Output(out
, CYPA
, CYNoFlags
);
639 std::ostringstream name
;
640 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
641 if (argument
->name_
!= NULL
) {
642 name
<< *argument
->name_
;
643 if (argument
->value_
!= NULL
)
646 out
<< reinterpret_cast<void *>(sel_registerName(name
.str().c_str()));
647 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
648 if (argument
->value_
!= NULL
) {
650 argument
->value_
->Output(out
, CYPA
, CYNoFlags
);
655 void CYSource::Show(std::ostream
&out
) const {
656 for (const CYSource
*next(this); next
!= NULL
; next
= next
->next_
)
660 void CYSource::Output(std::ostream
&out
, bool block
) const {
661 if (!block
&& !IsBlock())
670 void CYSource::Output_(std::ostream
&out
) const {
674 void CYStatement::Output_(std::ostream
&out
) const {
675 for (CYLabel
*label(labels_
); label
!= NULL
; label
= label
->next_
)
676 out
<< *label
->name_
<< ':';
680 void CYString::Output(std::ostream
&out
, CYFlags flags
) const {
681 unsigned quot(0), apos(0);
682 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
685 else if (*value
== '\'')
688 bool single(quot
> apos
);
690 out
<< (single
? '\'' : '"');
691 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
693 case '\\': out
<< "\\\\"; break;
694 case '\b': out
<< "\\b"; break;
695 case '\f': out
<< "\\f"; break;
696 case '\n': out
<< "\\n"; break;
697 case '\r': out
<< "\\r"; break;
698 case '\t': out
<< "\\t"; break;
699 case '\v': out
<< "\\v"; break;
714 if (*value
< 0x20 || *value
>= 0x7f)
715 out
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
);
719 out
<< (single
? '\'' : '"');
722 void CYString::PropertyName(std::ostream
&out
) const {
723 if (const char *word
= Word())
729 void CYSwitch::Output(std::ostream
&out
) const {
731 value_
->Output(out
, CYNoFlags
);
733 if (clauses_
!= NULL
)
738 void CYThis::Output(std::ostream
&out
, CYFlags flags
) const {
739 if ((flags
& CYNoLeader
) != 0)
742 if ((flags
& CYNoTrailer
) != 0)
746 void CYThrow::Output(std::ostream
&out
) const {
749 value_
->Output(out
, CYNoLeader
);
753 void CYTry::Output(std::ostream
&out
) const {
755 try_
->Output(out
, true);
758 if (finally_
!= NULL
) {
760 finally_
->Output(out
, true);
764 void CYVar::Output(std::ostream
&out
) const {
766 declarations_
->Output(out
, CYNoFlags
);
770 void CYVariable::Output(std::ostream
&out
, CYFlags flags
) const {
771 if ((flags
& CYNoLeader
) != 0)
774 if ((flags
& CYNoTrailer
) != 0)
778 void CYWhile::Output(std::ostream
&out
) const {
780 test_
->Output(out
, CYNoFlags
);
782 code_
->Output(out
, false);
785 void CYWith::Output(std::ostream
&out
) const {
787 scope_
->Output(out
, CYNoFlags
);
789 code_
->Output(out
, false);
792 void CYWord::ClassName(std::ostream
&out
, bool object
) const {
794 out
<< "objc_getClass(";
795 out
<< '"' << Value() << '"';
800 void CYWord::Output(std::ostream
&out
) const {
804 void CYWord::PropertyName(std::ostream
&out
) const {