]>
git.saurik.com Git - cycript.git/blob - Output.cpp
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 CYAssignment::Output(std::ostream
&out
, CYFlags flags
) const {
77 lhs_
->Output(out
, Precedence() - 1, CYLeft(flags
));
79 rhs_
->Output(out
, Precedence(), CYRight(flags
));
82 void CYBoolean::Output(std::ostream
&out
, CYFlags flags
) const {
83 if ((flags
& CYNoLeader
) != 0)
85 out
<< (Value() ? "true" : "false");
86 if ((flags
& CYNoTrailer
) != 0)
90 void CYBreak::Output(std::ostream
&out
) const {
93 out
<< ' ' << *label_
;
97 void CYCall::Output(std::ostream
&out
, CYFlags flags
) const {
98 function_
->Output(out
, Precedence(), CYLeft(flags
));
100 if (arguments_
!= NULL
)
101 arguments_
->Output(out
);
105 void CYCatch::Output(std::ostream
&out
) const {
106 out
<< "catch(" << *name_
<< ')';
107 code_
->Output(out
, true);
110 void CYCategory::Output(std::ostream
&out
) const {
111 out
<< "(function($cys,$cyp,$cyc,$cyn,$cyt){";
112 out
<< "$cyp=object_getClass($cys);";
114 if (messages_
!= NULL
)
115 messages_
->Output(out
, true);
117 name_
->ClassName(out
);
121 void CYClass::Output(std::ostream
&out
) const {
122 out
<< "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){";
123 out
<< "$cyp=object_getClass($cys);";
124 out
<< "$cyc=objc_allocateClassPair($cys,\"" << *name_
<< "\",0);";
125 out
<< "$cym=object_getClass($cyc);";
127 fields_
->Output(out
);
128 if (messages_
!= NULL
)
129 messages_
->Output(out
, false);
130 out
<< "objc_registerClassPair($cyc);";
133 super_
->Output(out
, CYPA
, CYNoFlags
);
139 void CYCompound::Output(std::ostream
&out
, CYFlags flags
) const {
140 if (CYExpression
*expression
= expressions_
)
141 if (CYExpression
*next
= expression
->next_
) {
142 expression
->Output(out
, CYLeft(flags
));
143 CYFlags
center(CYCenter(flags
));
144 while (next
!= NULL
) {
147 next
= expression
->next_
;
148 CYFlags
right(next
!= NULL
? center
: CYRight(flags
));
149 expression
->Output(out
, right
);
152 expression
->Output(out
, flags
);
155 void CYCondition::Output(std::ostream
&out
, CYFlags flags
) const {
156 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
159 true_
->Output(out
, CYPA
, CYNoFlags
);
161 false_
->Output(out
, CYPA
, CYRight(flags
));
164 void CYContinue::Output(std::ostream
&out
) const {
167 out
<< ' ' << *label_
;
171 void CYClause::Output(std::ostream
&out
) const {
174 case_
->Output(out
, CYNoFlags
);
179 code_
->Output(out
, false);
183 // XXX: deal with NoIn
184 void CYDeclaration::Part(std::ostream
&out
) const {
189 void CYDeclaration::Output(std::ostream
&out
) const {
191 if (initialiser_
!= NULL
) {
193 initialiser_
->Output(out
, CYPA
, CYNoFlags
);
197 // XXX: deal with NoIn
198 void CYDeclarations::Part(std::ostream
&out
) const {
201 const CYDeclarations
*declaration(this);
203 out
<< *declaration
->declaration_
;
204 declaration
= declaration
->next_
;
206 if (declaration
!= NULL
) {
212 void CYDeclarations::Output(std::ostream
&out
) const {
217 void CYDirectMember::Output(std::ostream
&out
, CYFlags flags
) const {
218 object_
->Output(out
, Precedence(), CYLeft(flags
));
219 if (const char *word
= property_
->Word())
223 property_
->Output(out
, CYNoFlags
);
228 void CYDoWhile::Output(std::ostream
&out
) const {
229 // XXX: extra space character!
231 code_
->Output(out
, false);
233 test_
->Output(out
, CYNoFlags
);
237 void CYElement::Output(std::ostream
&out
) const {
239 value_
->Output(out
, CYPA
, CYNoFlags
);
240 if (next_
!= NULL
|| value_
== NULL
)
246 void CYEmpty::Output(std::ostream
&out
) const {
250 void CYEmpty::Output(std::ostream
&out
, bool block
) const {
252 CYSource::Output(out
, block
);
257 void CYExpress::Output(std::ostream
&out
) const {
258 expression_
->Output(out
, CYNoFunction
| CYNoBrace
);
262 void CYExpression::ClassName(std::ostream
&out
) const {
263 Output(out
, CYPA
, CYNoFlags
);
266 void CYExpression::Part(std::ostream
&out
) const {
267 // XXX: this should handle LeftHandSideExpression
271 void CYExpression::Output(std::ostream
&out
, unsigned precedence
, CYFlags flags
) const {
272 if (precedence
< Precedence()) {
274 Output(out
, CYNoFlags
);
280 void CYField::Output(std::ostream
&out
) const {
284 void CYFor::Output(std::ostream
&out
) const {
286 if (initialiser_
!= NULL
)
287 initialiser_
->Part(out
);
290 test_
->Output(out
, CYNoFlags
);
292 if (increment_
!= NULL
)
293 increment_
->Output(out
, CYNoFlags
);
295 code_
->Output(out
, false);
298 void CYForIn::Output(std::ostream
&out
) const {
300 initialiser_
->Part(out
);
301 // XXX: deal with this space character!
304 set_
->Output(out
, CYNoLeader
);
306 code_
->Output(out
, false);
309 void CYFunction::Output(std::ostream
&out
) const {
310 CYLambda::Output(out
, CYNoFlags
);
313 void CYFunctionParameter::Output(std::ostream
&out
) const {
321 void CYIf::Output(std::ostream
&out
) const {
323 test_
->Output(out
, CYNoFlags
);
325 true_
->Output(out
, true);
326 if (false_
!= NULL
) {
328 false_
->Output(out
, false);
332 void CYIndirect::Output(std::ostream
&out
, CYFlags flags
) const {
333 rhs_
->Output(out
, 1, CYLeft(flags
));
337 void CYIndirectMember::Output(std::ostream
&out
, CYFlags flags
) const {
338 object_
->Output(out
, Precedence(), CYLeft(flags
));
340 if (const char *word
= property_
->Word())
344 property_
->Output(out
, CYNoFlags
);
349 void CYInfix::Output(std::ostream
&out
, CYFlags flags
) const {
350 const char *name(Operator());
351 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in"));
354 bool alphabetic(Alphabetic());
355 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
358 lhs_
->Output(out
, Precedence(), left
);
360 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
363 rhs_
->Output(out
, Precedence() - 1, right
);
368 void CYLambda::Output(std::ostream
&out
, CYFlags flags
) const {
369 bool protect((flags
& CYNoFunction
) != 0);
374 out
<< ' ' << *name_
;
376 if (parameters_
!= NULL
)
386 void CYMessage::Output(std::ostream
&out
, bool replace
) const {
388 next_
->Output(out
, replace
);
389 out
<< "$cyn=new Selector(\"";
390 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
391 if (parameter
->tag_
!= NULL
) {
392 out
<< *parameter
->tag_
;
393 if (parameter
->name_
!= NULL
)
397 out
<< "$cyt=$cyn.type($cy" << (instance_
? 's' : 'p') << ");";
398 out
<< "class_" << (replace
? "replace" : "add") << "Method($cy" << (instance_
? 'c' : 'm') << ",$cyn,";
399 out
<< "new Functor(function(self,_cmd";
400 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
401 if (parameter
->name_
!= NULL
)
402 out
<< ',' << *parameter
->name_
;
403 out
<< "){return function(){";
406 out
<< "}.call(self);},$cyt),$cyt);";
409 void CYNew::Output(std::ostream
&out
, CYFlags flags
) const {
410 if ((flags
& CYNoLeader
) != 0)
413 constructor_
->Output(out
, Precedence(), CYCenter(flags
) | CYNoLeader
);
415 if (arguments_
!= NULL
)
416 arguments_
->Output(out
);
420 void CYNull::Output(std::ostream
&out
, CYFlags flags
) const {
421 if ((flags
& CYNoLeader
) != 0)
424 if ((flags
& CYNoTrailer
) != 0)
428 void CYNumber::Output(std::ostream
&out
, CYFlags flags
) const {
429 if ((flags
& CYNoLeader
) != 0)
431 // XXX: decide on correct precision
432 out
<< std::setprecision(9) << Value();
433 if ((flags
& CYNoTrailer
) != 0)
437 void CYNumber::PropertyName(std::ostream
&out
) const {
441 void CYObject::Output(std::ostream
&out
, CYFlags flags
) const {
442 bool protect((flags
& CYNoBrace
) != 0);
446 if (property_
!= NULL
)
447 property_
->Output(out
);
453 void CYPostfix::Output(std::ostream
&out
, CYFlags flags
) const {
454 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
458 void CYPrefix::Output(std::ostream
&out
, CYFlags flags
) const {
459 bool alphabetic(Alphabetic());
461 CYFlags
right(CYRight(flags
));
464 rhs_
->Output(out
, Precedence(), right
);
467 void CYProperty::Output(std::ostream
&out
) const {
468 name_
->PropertyName(out
);
470 value_
->Output(out
, CYPA
, CYNoFlags
);
477 void CYReturn::Output(std::ostream
&out
) const {
480 value_
->Output(out
, CYNoLeader
);
484 void CYSelector::Output(std::ostream
&out
, CYFlags flags
) const {
485 if ((flags
& CYNoLeader
) != 0)
487 out
<< "new Selector(\"";
493 void CYSelectorPart::Output(std::ostream
&out
) const {
502 void CYSend::Output(std::ostream
&out
, CYFlags flags
) const {
503 if ((flags
& CYNoLeader
) != 0)
505 out
<< "objc_msgSend(";
506 self_
->Output(out
, CYPA
, CYNoFlags
);
508 std::ostringstream name
;
509 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
510 if (argument
->name_
!= NULL
) {
511 name
<< *argument
->name_
;
512 if (argument
->value_
!= NULL
)
515 out
<< reinterpret_cast<void *>(sel_registerName(name
.str().c_str()));
516 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
517 if (argument
->value_
!= NULL
) {
519 argument
->value_
->Output(out
, CYPA
, CYNoFlags
);
524 void CYSource::Show(std::ostream
&out
) const {
525 for (const CYSource
*next(this); next
!= NULL
; next
= next
->next_
)
529 void CYSource::Output(std::ostream
&out
, bool block
) const {
530 if (!block
&& next_
== NULL
)
539 void CYString::Output(std::ostream
&out
, CYFlags flags
) const {
540 unsigned quot(0), apos(0);
541 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
544 else if (*value
== '\'')
547 bool single(quot
> apos
);
549 out
<< (single
? '\'' : '"');
550 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
552 case '\\': out
<< "\\\\"; break;
553 case '\b': out
<< "\\b"; break;
554 case '\f': out
<< "\\f"; break;
555 case '\n': out
<< "\\n"; break;
556 case '\r': out
<< "\\r"; break;
557 case '\t': out
<< "\\t"; break;
558 case '\v': out
<< "\\v"; break;
573 if (*value
< 0x20 || *value
>= 0x7f)
574 out
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
);
578 out
<< (single
? '\'' : '"');
581 void CYString::PropertyName(std::ostream
&out
) const {
582 if (const char *word
= Word())
588 void CYSwitch::Output(std::ostream
&out
) const {
590 value_
->Output(out
, CYNoFlags
);
592 if (clauses_
!= NULL
)
597 void CYThis::Output(std::ostream
&out
, CYFlags flags
) const {
598 if ((flags
& CYNoLeader
) != 0)
601 if ((flags
& CYNoTrailer
) != 0)
605 void CYThrow::Output(std::ostream
&out
) const {
608 value_
->Output(out
, CYNoLeader
);
612 void CYTry::Output(std::ostream
&out
) const {
614 try_
->Output(out
, true);
617 if (finally_
!= NULL
) {
619 finally_
->Output(out
, true);
623 void CYVariable::Output(std::ostream
&out
, CYFlags flags
) const {
624 if ((flags
& CYNoLeader
) != 0)
627 if ((flags
& CYNoTrailer
) != 0)
631 void CYWhile::Output(std::ostream
&out
) const {
633 test_
->Output(out
, CYNoFlags
);
635 code_
->Output(out
, false);
638 void CYWith::Output(std::ostream
&out
) const {
640 scope_
->Output(out
, CYNoFlags
);
642 code_
->Output(out
, false);
645 void CYWord::ClassName(std::ostream
&out
) const {
646 out
<< "objc_getClass(\"" << Value() << "\")";
649 void CYWord::Output(std::ostream
&out
) const {
653 void CYWord::PropertyName(std::ostream
&out
) const {