]>
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
));
49 out
<< ".addressOf()";
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 CYClass::Output(std::ostream
&out
) const {
111 out
<< "(function($cys,$cyc,$cym,$cyn,$cyt){";
112 out
<< "$cyc=objc_allocateClassPair($cys,\"" << *name_
<< "\",0);";
113 out
<< "$cym=object_getClass($cyc);";
115 fields_
->Output(out
);
116 if (messages_
!= NULL
)
117 messages_
->Output(out
);
118 out
<< "objc_registerClassPair($cyc);";
121 super_
->Output(out
, CYPA
, CYNoFlags
);
127 void CYCondition::Output(std::ostream
&out
, CYFlags flags
) const {
128 test_
->Output(out
, Precedence() - 1, CYLeft(flags
));
131 true_
->Output(out
, CYPA
, CYNoFlags
);
133 false_
->Output(out
, CYPA
, CYRight(flags
));
136 void CYContinue::Output(std::ostream
&out
) const {
139 out
<< ' ' << *label_
;
143 void CYClause::Output(std::ostream
&out
) const {
146 case_
->Output(out
, CYNoFlags
);
151 code_
->Output(out
, false);
155 // XXX: deal with NoIn
156 void CYDeclaration::Part(std::ostream
&out
) const {
161 void CYDeclaration::Output(std::ostream
&out
) const {
163 if (initialiser_
!= NULL
) {
165 initialiser_
->Output(out
, CYPA
, CYNoFlags
);
169 // XXX: deal with NoIn
170 void CYDeclarations::Part(std::ostream
&out
) const {
173 const CYDeclarations
*declaration(this);
175 out
<< *declaration
->declaration_
;
176 declaration
= declaration
->next_
;
178 if (declaration
!= NULL
) {
184 void CYDeclarations::Output(std::ostream
&out
) const {
189 void CYDoWhile::Output(std::ostream
&out
) const {
190 // XXX: extra space character!
192 code_
->Output(out
, false);
194 test_
->Output(out
, CYNoFlags
);
198 void CYElement::Output(std::ostream
&out
) const {
200 value_
->Output(out
, CYPA
, CYNoFlags
);
201 if (next_
!= NULL
|| value_
== NULL
)
207 void CYEmpty::Output(std::ostream
&out
) const {
211 void CYEmpty::Output(std::ostream
&out
, bool block
) const {
213 CYSource::Output(out
, block
);
218 void CYExpress::Output(std::ostream
&out
) const {
219 expression_
->Output(out
, CYNoFunction
| CYNoBrace
);
223 void CYExpression::Part(std::ostream
&out
) const {
224 // XXX: this should handle LeftHandSideExpression
228 void CYCompound::Output(std::ostream
&out
, CYFlags flags
) const {
229 if (CYExpression
*expression
= expressions_
)
230 if (CYExpression
*next
= expression
->next_
) {
231 expression
->Output(out
, CYLeft(flags
));
232 CYFlags
center(CYCenter(flags
));
233 while (next
!= NULL
) {
236 next
= expression
->next_
;
237 CYFlags
right(next
!= NULL
? center
: CYRight(flags
));
238 expression
->Output(out
, right
);
241 expression
->Output(out
, flags
);
244 void CYExpression::Output(std::ostream
&out
, unsigned precedence
, CYFlags flags
) const {
245 if (precedence
< Precedence()) {
247 Output(out
, CYNoFlags
);
253 void CYField::Output(std::ostream
&out
) const {
257 void CYFor::Output(std::ostream
&out
) const {
259 if (initialiser_
!= NULL
)
260 initialiser_
->Part(out
);
263 test_
->Output(out
, CYNoFlags
);
265 if (increment_
!= NULL
)
266 increment_
->Output(out
, CYNoFlags
);
268 code_
->Output(out
, false);
271 void CYForIn::Output(std::ostream
&out
) const {
273 initialiser_
->Part(out
);
274 // XXX: deal with this space character!
277 set_
->Output(out
, CYNoLeader
);
279 code_
->Output(out
, false);
282 void CYFunction::Output(std::ostream
&out
) const {
283 CYLambda::Output(out
, CYNoFlags
);
286 void CYFunctionParameter::Output(std::ostream
&out
) const {
294 void CYIf::Output(std::ostream
&out
) const {
296 test_
->Output(out
, CYNoFlags
);
298 true_
->Output(out
, true);
299 if (false_
!= NULL
) {
301 false_
->Output(out
, false);
305 void CYIndirect::Output(std::ostream
&out
, CYFlags flags
) const {
306 rhs_
->Output(out
, 1, CYLeft(flags
));
310 void CYInfix::Output(std::ostream
&out
, CYFlags flags
) const {
311 const char *name(Operator());
312 bool protect((flags
& CYNoIn
) != 0 && strcmp(name
, "in"));
315 bool alphabetic(Alphabetic());
316 CYFlags
left(protect
? CYNoFlags
: CYLeft(flags
));
319 lhs_
->Output(out
, Precedence(), left
);
321 CYFlags
right(protect
? CYNoFlags
: CYRight(flags
));
324 rhs_
->Output(out
, Precedence() - 1, right
);
329 void CYLambda::Output(std::ostream
&out
, CYFlags flags
) const {
330 bool protect((flags
& CYNoFunction
) != 0);
335 out
<< ' ' << *name_
;
337 if (parameters_
!= NULL
)
347 void CYMember::Output(std::ostream
&out
, CYFlags flags
) const {
348 object_
->Output(out
, Precedence(), CYLeft(flags
));
349 if (const char *word
= property_
->Word())
353 property_
->Output(out
, CYNoFlags
);
358 void CYMessage::Output(std::ostream
&out
) const {
361 out
<< "$cyn=new Selector(\"";
362 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
363 if (parameter
->tag_
!= NULL
) {
364 out
<< *parameter
->tag_
;
365 if (parameter
->name_
!= NULL
)
369 out
<< "$cyt=$cyn.type($cys," << (instance_
? "true" : "false") << ");";
370 out
<< "class_addMethod($cy" << (instance_
? 'c' : 'm') << ",$cyn,";
371 out
<< "new Functor(function(self,_cmd";
372 for (CYMessageParameter
*parameter(parameter_
); parameter
!= NULL
; parameter
= parameter
->next_
)
373 if (parameter
->name_
!= NULL
)
374 out
<< ',' << *parameter
->name_
;
375 out
<< "){return function(){";
378 out
<< "}.call(self);},$cyt),$cyt);";
381 void CYNew::Output(std::ostream
&out
, CYFlags flags
) const {
382 if ((flags
& CYNoLeader
) != 0)
385 constructor_
->Output(out
, Precedence(), CYCenter(flags
) | CYNoLeader
);
387 if (arguments_
!= NULL
)
388 arguments_
->Output(out
);
392 void CYNull::Output(std::ostream
&out
, CYFlags flags
) const {
393 if ((flags
& CYNoLeader
) != 0)
396 if ((flags
& CYNoTrailer
) != 0)
400 void CYNumber::Output(std::ostream
&out
, CYFlags flags
) const {
401 if ((flags
& CYNoLeader
) != 0)
403 // XXX: decide on correct precision
404 out
<< std::setprecision(9) << Value();
405 if ((flags
& CYNoTrailer
) != 0)
409 void CYObject::Output(std::ostream
&out
, CYFlags flags
) const {
410 bool protect((flags
& CYNoBrace
) != 0);
414 if (property_
!= NULL
)
415 property_
->Output(out
);
421 void CYPostfix::Output(std::ostream
&out
, CYFlags flags
) const {
422 lhs_
->Output(out
, Precedence(), CYLeft(flags
));
426 void CYPrefix::Output(std::ostream
&out
, CYFlags flags
) const {
427 bool alphabetic(Alphabetic());
429 CYFlags
right(CYRight(flags
));
432 rhs_
->Output(out
, Precedence(), right
);
435 void CYProperty::Output(std::ostream
&out
) const {
438 value_
->Output(out
, CYPA
, CYNoFlags
);
445 void CYReturn::Output(std::ostream
&out
) const {
448 value_
->Output(out
, CYNoLeader
);
452 void CYSelector::Output(std::ostream
&out
, CYFlags flags
) const {
453 if ((flags
& CYNoLeader
) != 0)
455 out
<< "new Selector(\"";
461 void CYSelectorPart::Output(std::ostream
&out
) const {
470 void CYSend::Output(std::ostream
&out
, CYFlags flags
) const {
471 out
<< "objc_msgSend(";
472 self_
->Output(out
, CYPA
, CYNoFlags
);
474 std::ostringstream name
;
475 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
476 if (argument
->name_
!= NULL
) {
477 name
<< *argument
->name_
;
478 if (argument
->value_
!= NULL
)
481 out
<< reinterpret_cast<void *>(sel_registerName(name
.str().c_str()));
482 for (CYArgument
*argument(arguments_
); argument
!= NULL
; argument
= argument
->next_
)
483 if (argument
->value_
!= NULL
) {
485 argument
->value_
->Output(out
, CYPA
, CYNoFlags
);
490 void CYSource::Show(std::ostream
&out
) const {
491 for (const CYSource
*next(this); next
!= NULL
; next
= next
->next_
)
495 void CYSource::Output(std::ostream
&out
, bool block
) const {
496 if (!block
&& next_
== NULL
)
505 void CYString::Output(std::ostream
&out
, CYFlags flags
) const {
506 unsigned quot(0), apos(0);
507 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
510 else if (*value
== '\'')
513 bool single(quot
> apos
);
515 out
<< (single
? '\'' : '"');
516 for (const char *value(value_
), *end(value_
+ size_
); value
!= end
; ++value
)
518 case '\\': out
<< "\\\\"; break;
519 case '\b': out
<< "\\b"; break;
520 case '\f': out
<< "\\f"; break;
521 case '\n': out
<< "\\n"; break;
522 case '\r': out
<< "\\r"; break;
523 case '\t': out
<< "\\t"; break;
524 case '\v': out
<< "\\v"; break;
539 if (*value
< 0x20 || *value
>= 0x7f)
540 out
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
);
544 out
<< (single
? '\'' : '"');
547 void CYSwitch::Output(std::ostream
&out
) const {
549 value_
->Output(out
, CYNoFlags
);
551 if (clauses_
!= NULL
)
556 void CYThis::Output(std::ostream
&out
, CYFlags flags
) const {
557 if ((flags
& CYNoLeader
) != 0)
560 if ((flags
& CYNoTrailer
) != 0)
564 void CYThrow::Output(std::ostream
&out
) const {
567 value_
->Output(out
, CYNoLeader
);
571 void CYTry::Output(std::ostream
&out
) const {
573 try_
->Output(out
, true);
576 if (finally_
!= NULL
) {
578 finally_
->Output(out
, true);
582 void CYVariable::Output(std::ostream
&out
, CYFlags flags
) const {
583 if ((flags
& CYNoLeader
) != 0)
586 if ((flags
& CYNoTrailer
) != 0)
590 void CYWhile::Output(std::ostream
&out
) const {
592 test_
->Output(out
, CYNoFlags
);
594 code_
->Output(out
, false);
597 void CYWith::Output(std::ostream
&out
) const {
599 scope_
->Output(out
, CYNoFlags
);
601 code_
->Output(out
, false);
604 void CYWord::Output(std::ostream
&out
) const {