]>
git.saurik.com Git - cycript.git/blob - Output.cpp
a73b9c95866b4389f97760e39ff79027c0c1313f
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 CYBlock::Output(std::ostream
&out
) const {
83 for (CYSource
*statement(statements_
); statement
!= NULL
; statement
= statement
->next_
)
84 statement
->Output(out
);
87 void CYBoolean::Output(std::ostream
&out
, CYFlags flags
) const {
88 if ((flags
& CYNoLeader
) != 0)
90 out
<< (Value() ? "true" : "false");
91 if ((flags
& CYNoTrailer
) != 0)
95 void CYBreak::Output(std::ostream
&out
) const {
98 out
<< ' ' << *label_
;
102 void CYCall::Output(std::ostream
&out
, CYFlags flags
) const {
103 function_
->Output(out
, Precedence(), CYLeft(flags
));
105 if (arguments_
!= NULL
)
106 arguments_
->Output(out
);
110 void CYCatch::Output(std::ostream
&out
) const {
111 out
<< "catch(" << *name_
<< ')';
112 code_
->Output(out
, true);
115 void CYCategory::Output(std::ostream
&out
) const {
116 out
<< "(function($cys,$cyp,$cyc,$cyn,$cyt){";
117 out
<< "$cyp=object_getClass($cys);";
119 if (messages_
!= NULL
)
120 messages_
->Output(out
, true);
122 name_
->ClassName(out
, true);
126 void CYClass::Output(std::ostream
&out
) const {
131 void CYClass::Output(std::ostream
&out
, CYFlags flags
) const {
132 // XXX: I don't necc. need the ()s
133 out
<< "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){";
134 out
<< "$cyp=object_getClass($cys);";
135 out
<< "$cyc=objc_allocateClassPair($cys,";
137 name_
->ClassName(out
, false);
139 out
<< "$cyq(\"CY$\")";
141 out
<< "$cym=object_getClass($cyc);";
143 fields_
->Output(out
);
144 if (messages_
!= NULL
)
145 messages_
->Output(out
, false);
146 out
<< "objc_registerClassPair($cyc);";
147 out
<< "return $cyc;";
150 super_
->Output(out
, CYPA
, CYNoFlags
);
156 void CYCompound::Output(std::ostream
&out
, CYFlags flags
) const {
157 if (CYExpression
*expression
= expressions_
)
158 if (CYExpression
*next
= expression
->next_
) {
159 expression
->Output(out
, CYLeft(flags
));
160 CYFlags
center(CYCenter(flags
));
161 while (next
!= NULL
) {
164 next
= expression
->next_
;
165 CYFlags
right(next
!= NULL
? center
: CYRight(flags
));
166 expression
->Output(out
, right
);
169 expression
->Output(out
, flags
);
172 void CYCondition::Output(std::ostream
&out
, CYFlags flags
) const {
173 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
176 true_
->Output(out
, CYPA
, CYNoFlags
);
178 false_
->Output(out
, CYPA
, CYRight(flags
));
181 void CYContinue::Output(std::ostream
&out
) const {
184 out
<< ' ' << *label_
;
188 void CYClause::Output(std::ostream
&out
) const {
191 case_
->Output(out
, CYNoFlags
);
196 code_
->Output(out
, false);
200 // XXX: deal with NoIn
201 void CYDeclaration::Part(std::ostream
&out
) const {
206 void CYDeclaration::Output(std::ostream
&out
) const {
208 if (initialiser_
!= NULL
) {
210 initialiser_
->Output(out
, CYPA
, CYNoFlags
);
214 // XXX: deal with NoIn
215 void CYDeclarations::Part(std::ostream
&out
) const {
218 const CYDeclarations
*declaration(this);
220 out
<< *declaration
->declaration_
;
221 declaration
= declaration
->next_
;
223 if (declaration
!= NULL
) {
229 void CYDeclarations::Output(std::ostream
&out
) const {
234 void CYDirectMember::Output(std::ostream
&out
, CYFlags flags
) const {
235 object_
->Output(out
, Precedence(), CYLeft(flags
));
236 if (const char *word
= property_
->Word())
240 property_
->Output(out
, CYNoFlags
);
245 void CYDoWhile::Output(std::ostream
&out
) const {
246 // XXX: extra space character!
248 code_
->Output(out
, false);
250 test_
->Output(out
, CYNoFlags
);
254 void CYElement::Output(std::ostream
&out
) const {
256 value_
->Output(out
, CYPA
, CYNoFlags
);
257 if (next_
!= NULL
|| value_
== NULL
)
263 void CYEmpty::Output(std::ostream
&out
) const {
267 void CYEmpty::Output(std::ostream
&out
, bool block
) const {
269 CYSource::Output(out
, block
);
274 void CYExpress::Output(std::ostream
&out
) const {
275 expression_
->Output(out
, CYNoBF
);
279 void CYExpression::ClassName(std::ostream
&out
, bool object
) const {
280 Output(out
, CYPA
, CYNoFlags
);
283 void CYExpression::Part(std::ostream
&out
) const {
284 // XXX: this should handle LeftHandSideExpression
288 void CYExpression::Output(std::ostream
&out
, unsigned precedence
, CYFlags flags
) const {
289 if (precedence
< Precedence()) {
291 Output(out
, CYNoFlags
);
297 void CYField::Output(std::ostream
&out
) const {
301 void CYFor::Output(std::ostream
&out
) const {
303 if (initialiser_
!= NULL
)
304 initialiser_
->Part(out
);
307 test_
->Output(out
, CYNoFlags
);
309 if (increment_
!= NULL
)
310 increment_
->Output(out
, CYNoFlags
);
312 code_
->Output(out
, false);
315 void CYForIn::Output(std::ostream
&out
) const {
317 initialiser_
->Part(out
);
318 // XXX: deal with this space character!
321 set_
->Output(out
, CYNoLeader
);
323 code_
->Output(out
, false);
326 void CYFunction::Output(std::ostream
&out
) const {
327 CYLambda::Output(out
, CYNoFlags
);
330 void CYFunctionParameter::Output(std::ostream
&out
) const {
338 void CYIf::Output(std::ostream
&out
) const {
340 test_
->Output(out
, CYNoFlags
);
342 true_
->Output(out
, true);
343 if (false_
!= NULL
) {
345 false_
->Output(out
, false);
349 void CYIndirect::Output(std::ostream
&out
, CYFlags flags
) const {
350 rhs_
->Output(out
, 1, CYLeft(flags
));
354 void CYIndirectMember::Output(std::ostream
&out
, CYFlags flags
) const {
355 object_
->Output(out
, Precedence(), CYLeft(flags
));
357 if (const char *word
= property_
->Word())
361 property_
->Output(out
, CYNoFlags
);
366 void CYInfix::Output(std::ostream
&out
, CYFlags flags
) const {
367 const char *name(Operator());
368 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in"));
371 bool alphabetic(Alphabetic());
372 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
375 lhs_
->Output(out
, Precedence(), left
);
377 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
380 if (strcmp(name
, "-") == 0)
382 rhs_
->Output(out
, Precedence() - 1, right
);
387 void CYLambda::Output(std::ostream
&out
, CYFlags flags
) const {
388 bool protect((flags
& CYNoFunction
) != 0);
391 else if ((flags
& CYNoLeader
) != 0)
395 out
<< ' ' << *name_
;
397 if (parameters_
!= NULL
)
407 void CYMessage::Output(std::ostream
&out
, bool replace
) const {
409 next_
->Output(out
, replace
);
410 out
<< "$cyn=new Selector(\"";
411 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
412 if (parameter
->tag_
!= NULL
) {
413 out
<< *parameter
->tag_
;
414 if (parameter
->name_
!= NULL
)
418 out
<< "$cyt=$cyn.type($cy" << (instance_
? 's' : 'p') << ");";
419 out
<< "class_" << (replace
? "replace" : "add") << "Method($cy" << (instance_
? 'c' : 'm') << ",$cyn,";
420 out
<< "new Functor(function(self,_cmd";
421 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
422 if (parameter
->name_
!= NULL
)
423 out
<< ',' << *parameter
->name_
;
424 out
<< "){return function(){";
427 out
<< "}.call(self);},$cyt),$cyt);";
430 void CYNew::Output(std::ostream
&out
, CYFlags flags
) const {
431 if ((flags
& CYNoLeader
) != 0)
434 constructor_
->Output(out
, Precedence(), CYCenter(flags
) | CYNoLeader
);
436 if (arguments_
!= NULL
)
437 arguments_
->Output(out
);
441 void CYNull::Output(std::ostream
&out
, CYFlags flags
) const {
442 if ((flags
& CYNoLeader
) != 0)
445 if ((flags
& CYNoTrailer
) != 0)
449 void CYNumber::Output(std::ostream
&out
, CYFlags flags
) const {
450 double value(Value());
451 if ((flags
& CYNoLeader
) != 0 || value
< 0 && (flags
& CYNoHyphen
) != 0)
453 // XXX: decide on correct precision
454 out
<< std::setprecision(9) << value
;
455 if ((flags
& CYNoTrailer
) != 0)
459 void CYNumber::PropertyName(std::ostream
&out
) const {
463 void CYObject::Output(std::ostream
&out
, CYFlags flags
) const {
464 bool protect((flags
& CYNoBrace
) != 0);
468 if (property_
!= NULL
)
469 property_
->Output(out
);
475 void CYPostfix::Output(std::ostream
&out
, CYFlags flags
) const {
476 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
480 void CYPrefix::Output(std::ostream
&out
, CYFlags flags
) const {
481 const char *name(Operator());
482 bool alphabetic(Alphabetic());
483 if (alphabetic
&& (flags
& CYNoLeader
) != 0 || name
[0] == '-' && (flags
& CYNoHyphen
) != 0)
486 CYFlags
right(CYRight(flags
));
489 rhs_
->Output(out
, Precedence(), right
);
492 void CYProperty::Output(std::ostream
&out
) const {
493 name_
->PropertyName(out
);
495 value_
->Output(out
, CYPA
, CYNoFlags
);
502 void CYReturn::Output(std::ostream
&out
) const {
505 value_
->Output(out
, CYNoLeader
);
509 void CYSelector::Output(std::ostream
&out
, CYFlags flags
) const {
510 if ((flags
& CYNoLeader
) != 0)
512 out
<< "new Selector(\"";
518 void CYSelectorPart::Output(std::ostream
&out
) const {
527 void CYSend::Output(std::ostream
&out
, CYFlags flags
) const {
528 if ((flags
& CYNoLeader
) != 0)
530 out
<< "objc_msgSend(";
531 self_
->Output(out
, CYPA
, CYNoFlags
);
533 std::ostringstream name
;
534 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
535 if (argument
->name_
!= NULL
) {
536 name
<< *argument
->name_
;
537 if (argument
->value_
!= NULL
)
540 out
<< reinterpret_cast<void *>(sel_registerName(name
.str().c_str()));
541 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
542 if (argument
->value_
!= NULL
) {
544 argument
->value_
->Output(out
, CYPA
, CYNoFlags
);
549 void CYSource::Show(std::ostream
&out
) const {
550 for (const CYSource
*next(this); next
!= NULL
; next
= next
->next_
)
554 void CYSource::Output(std::ostream
&out
, bool block
) const {
555 if (!block
&& !IsBlock())
564 void CYSource::Output_(std::ostream
&out
) const {
568 void CYStatement::Output_(std::ostream
&out
) const {
569 for (CYLabel
*label(labels_
); label
!= NULL
; label
= label
->next_
)
570 out
<< *label
->name_
<< ':';
574 void CYString::Output(std::ostream
&out
, CYFlags flags
) const {
575 unsigned quot(0), apos(0);
576 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
579 else if (*value
== '\'')
582 bool single(quot
> apos
);
584 out
<< (single
? '\'' : '"');
585 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
587 case '\\': out
<< "\\\\"; break;
588 case '\b': out
<< "\\b"; break;
589 case '\f': out
<< "\\f"; break;
590 case '\n': out
<< "\\n"; break;
591 case '\r': out
<< "\\r"; break;
592 case '\t': out
<< "\\t"; break;
593 case '\v': out
<< "\\v"; break;
608 if (*value
< 0x20 || *value
>= 0x7f)
609 out
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
);
613 out
<< (single
? '\'' : '"');
616 void CYString::PropertyName(std::ostream
&out
) const {
617 if (const char *word
= Word())
623 void CYSwitch::Output(std::ostream
&out
) const {
625 value_
->Output(out
, CYNoFlags
);
627 if (clauses_
!= NULL
)
632 void CYThis::Output(std::ostream
&out
, CYFlags flags
) const {
633 if ((flags
& CYNoLeader
) != 0)
636 if ((flags
& CYNoTrailer
) != 0)
640 void CYThrow::Output(std::ostream
&out
) const {
643 value_
->Output(out
, CYNoLeader
);
647 void CYTry::Output(std::ostream
&out
) const {
649 try_
->Output(out
, true);
652 if (finally_
!= NULL
) {
654 finally_
->Output(out
, true);
658 void CYVariable::Output(std::ostream
&out
, CYFlags flags
) const {
659 if ((flags
& CYNoLeader
) != 0)
662 if ((flags
& CYNoTrailer
) != 0)
666 void CYWhile::Output(std::ostream
&out
) const {
668 test_
->Output(out
, CYNoFlags
);
670 code_
->Output(out
, false);
673 void CYWith::Output(std::ostream
&out
) const {
675 scope_
->Output(out
, CYNoFlags
);
677 code_
->Output(out
, false);
680 void CYWord::ClassName(std::ostream
&out
, bool object
) const {
682 out
<< "objc_getClass(";
683 out
<< '"' << Value() << '"';
688 void CYWord::Output(std::ostream
&out
) const {
692 void CYWord::PropertyName(std::ostream
&out
) const {