]>
git.saurik.com Git - cycript.git/blob - Output.cpp
f15b90d6324c9a399c5a093c84f2fb864bb0e0c0
   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
); 
 126 void CYClass::Output(std::ostream 
&out
) const { 
 127     out 
<< "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){"; 
 128     out 
<< "$cyp=object_getClass($cys);"; 
 129     out 
<< "$cyc=objc_allocateClassPair($cys,\"" << *name_ 
<< "\",0);"; 
 130     out 
<< "$cym=object_getClass($cyc);"; 
 132         fields_
->Output(out
); 
 133     if (messages_ 
!= NULL
) 
 134         messages_
->Output(out
, false); 
 135     out 
<< "objc_registerClassPair($cyc);"; 
 138         super_
->Output(out
, CYPA
, CYNoFlags
); 
 144 void CYCompound::Output(std::ostream 
&out
, CYFlags flags
) const { 
 145     if (CYExpression 
*expression 
= expressions_
) 
 146         if (CYExpression 
*next 
= expression
->next_
) { 
 147             expression
->Output(out
, CYLeft(flags
)); 
 148             CYFlags 
center(CYCenter(flags
)); 
 149             while (next 
!= NULL
) { 
 152                 next 
= expression
->next_
; 
 153                 CYFlags 
right(next 
!= NULL 
? center 
: CYRight(flags
)); 
 154                 expression
->Output(out
, right
); 
 157             expression
->Output(out
, flags
); 
 160 void CYCondition::Output(std::ostream 
&out
, CYFlags flags
) const { 
 161     test_
->Output(out
, Precedence() - 1, CYLeft(flags
)); 
 164         true_
->Output(out
, CYPA
, CYNoFlags
); 
 166     false_
->Output(out
, CYPA
, CYRight(flags
)); 
 169 void CYContinue::Output(std::ostream 
&out
) const { 
 172         out 
<< ' ' << *label_
; 
 176 void CYClause::Output(std::ostream 
&out
) const { 
 179         case_
->Output(out
, CYNoFlags
); 
 184         code_
->Output(out
, false); 
 188 // XXX: deal with NoIn 
 189 void CYDeclaration::Part(std::ostream 
&out
) const { 
 194 void CYDeclaration::Output(std::ostream 
&out
) const { 
 196     if (initialiser_ 
!= NULL
) { 
 198         initialiser_
->Output(out
, CYPA
, CYNoFlags
); 
 202 // XXX: deal with NoIn 
 203 void CYDeclarations::Part(std::ostream 
&out
) const { 
 206     const CYDeclarations 
*declaration(this); 
 208     out 
<< *declaration
->declaration_
; 
 209     declaration 
= declaration
->next_
; 
 211     if (declaration 
!= NULL
) { 
 217 void CYDeclarations::Output(std::ostream 
&out
) const { 
 222 void CYDirectMember::Output(std::ostream 
&out
, CYFlags flags
) const { 
 223     object_
->Output(out
, Precedence(), CYLeft(flags
)); 
 224     if (const char *word 
= property_
->Word()) 
 228         property_
->Output(out
, CYNoFlags
); 
 233 void CYDoWhile::Output(std::ostream 
&out
) const { 
 234     // XXX: extra space character! 
 236     code_
->Output(out
, false); 
 238     test_
->Output(out
, CYNoFlags
); 
 242 void CYElement::Output(std::ostream 
&out
) const { 
 244         value_
->Output(out
, CYPA
, CYNoFlags
); 
 245     if (next_ 
!= NULL 
|| value_ 
== NULL
) 
 251 void CYEmpty::Output(std::ostream 
&out
) const { 
 255 void CYEmpty::Output(std::ostream 
&out
, bool block
) const { 
 257         CYSource::Output(out
, block
); 
 262 void CYExpress::Output(std::ostream 
&out
) const { 
 263     expression_
->Output(out
, CYNoFunction 
| CYNoBrace
); 
 267 void CYExpression::ClassName(std::ostream 
&out
) const { 
 268     Output(out
, CYPA
, CYNoFlags
); 
 271 void CYExpression::Part(std::ostream 
&out
) const { 
 272     // XXX: this should handle LeftHandSideExpression 
 276 void CYExpression::Output(std::ostream 
&out
, unsigned precedence
, CYFlags flags
) const { 
 277     if (precedence 
< Precedence()) { 
 279         Output(out
, CYNoFlags
); 
 285 void CYField::Output(std::ostream 
&out
) const { 
 289 void CYFor::Output(std::ostream 
&out
) const { 
 291     if (initialiser_ 
!= NULL
) 
 292         initialiser_
->Part(out
); 
 295         test_
->Output(out
, CYNoFlags
); 
 297     if (increment_ 
!= NULL
) 
 298         increment_
->Output(out
, CYNoFlags
); 
 300     code_
->Output(out
, false); 
 303 void CYForIn::Output(std::ostream 
&out
) const { 
 305     initialiser_
->Part(out
); 
 306     // XXX: deal with this space character! 
 309     set_
->Output(out
, CYNoLeader
); 
 311     code_
->Output(out
, false); 
 314 void CYFunction::Output(std::ostream 
&out
) const { 
 315     CYLambda::Output(out
, CYNoFlags
); 
 318 void CYFunctionParameter::Output(std::ostream 
&out
) const { 
 326 void CYIf::Output(std::ostream 
&out
) const { 
 328     test_
->Output(out
, CYNoFlags
); 
 330     true_
->Output(out
, true); 
 331     if (false_ 
!= NULL
) { 
 333         false_
->Output(out
, false); 
 337 void CYIndirect::Output(std::ostream 
&out
, CYFlags flags
) const { 
 338     rhs_
->Output(out
, 1, CYLeft(flags
)); 
 342 void CYIndirectMember::Output(std::ostream 
&out
, CYFlags flags
) const { 
 343     object_
->Output(out
, Precedence(), CYLeft(flags
)); 
 345     if (const char *word 
= property_
->Word()) 
 349         property_
->Output(out
, CYNoFlags
); 
 354 void CYInfix::Output(std::ostream 
&out
, CYFlags flags
) const { 
 355     const char *name(Operator()); 
 356     bool protect((flags 
& CYNoIn
) != 0 && strcmp(name
, "in")); 
 359     bool alphabetic(Alphabetic()); 
 360     CYFlags 
left(protect 
? CYNoFlags 
: CYLeft(flags
)); 
 363     lhs_
->Output(out
, Precedence(), left
); 
 365     CYFlags 
right(protect 
? CYNoFlags 
: CYRight(flags
)); 
 368     if (strcmp(name
, "-") == 0) 
 370     rhs_
->Output(out
, Precedence() - 1, right
); 
 375 void CYLambda::Output(std::ostream 
&out
, CYFlags flags
) const { 
 376     bool protect((flags 
& CYNoFunction
) != 0); 
 381         out 
<< ' ' << *name_
; 
 383     if (parameters_ 
!= NULL
) 
 393 void CYMessage::Output(std::ostream 
&out
, bool replace
) const { 
 395         next_
->Output(out
, replace
); 
 396     out 
<< "$cyn=new Selector(\""; 
 397     for (CYMessageParameter 
*parameter(parameter_
); parameter 
!= NULL
; parameter 
= parameter
->next_
) 
 398         if (parameter
->tag_ 
!= NULL
) { 
 399             out 
<< *parameter
->tag_
; 
 400             if (parameter
->name_ 
!= NULL
) 
 404     out 
<< "$cyt=$cyn.type($cy" << (instance_ 
? 's' : 'p') << ");"; 
 405     out 
<< "class_" << (replace 
? "replace" : "add") << "Method($cy" << (instance_ 
? 'c' : 'm') << ",$cyn,"; 
 406     out 
<< "new Functor(function(self,_cmd"; 
 407     for (CYMessageParameter 
*parameter(parameter_
); parameter 
!= NULL
; parameter 
= parameter
->next_
) 
 408         if (parameter
->name_ 
!= NULL
) 
 409             out 
<< ',' << *parameter
->name_
; 
 410     out 
<< "){return function(){"; 
 413     out 
<< "}.call(self);},$cyt),$cyt);"; 
 416 void CYNew::Output(std::ostream 
&out
, CYFlags flags
) const { 
 417     if ((flags 
& CYNoLeader
) != 0) 
 420     constructor_
->Output(out
, Precedence(), CYCenter(flags
) | CYNoLeader
); 
 422     if (arguments_ 
!= NULL
) 
 423         arguments_
->Output(out
); 
 427 void CYNull::Output(std::ostream 
&out
, CYFlags flags
) const { 
 428     if ((flags 
& CYNoLeader
) != 0) 
 431     if ((flags 
& CYNoTrailer
) != 0) 
 435 void CYNumber::Output(std::ostream 
&out
, CYFlags flags
) const { 
 436     double value(Value()); 
 437     if ((flags 
& CYNoLeader
) != 0 || value 
< 0 && (flags 
& CYNoHyphen
) != 0) 
 439     // XXX: decide on correct precision 
 440     out 
<< std::setprecision(9) << value
; 
 441     if ((flags 
& CYNoTrailer
) != 0) 
 445 void CYNumber::PropertyName(std::ostream 
&out
) const { 
 449 void CYObject::Output(std::ostream 
&out
, CYFlags flags
) const { 
 450     bool protect((flags 
& CYNoBrace
) != 0); 
 454     if (property_ 
!= NULL
) 
 455         property_
->Output(out
); 
 461 void CYPostfix::Output(std::ostream 
&out
, CYFlags flags
) const { 
 462     lhs_
->Output(out
, Precedence(), CYLeft(flags
)); 
 466 void CYPrefix::Output(std::ostream 
&out
, CYFlags flags
) const { 
 467     const char *name(Operator()); 
 468     bool alphabetic(Alphabetic()); 
 469     if (alphabetic 
&& (flags 
& CYNoLeader
) != 0 || name
[0] == '-' && (flags 
& CYNoHyphen
) != 0) 
 472     CYFlags 
right(CYRight(flags
)); 
 475     rhs_
->Output(out
, Precedence(), right
); 
 478 void CYProperty::Output(std::ostream 
&out
) const { 
 479     name_
->PropertyName(out
); 
 481     value_
->Output(out
, CYPA
, CYNoFlags
); 
 488 void CYReturn::Output(std::ostream 
&out
) const { 
 491         value_
->Output(out
, CYNoLeader
); 
 495 void CYSelector::Output(std::ostream 
&out
, CYFlags flags
) const { 
 496     if ((flags 
& CYNoLeader
) != 0) 
 498     out 
<< "new Selector(\""; 
 504 void CYSelectorPart::Output(std::ostream 
&out
) const { 
 513 void CYSend::Output(std::ostream 
&out
, CYFlags flags
) const { 
 514     if ((flags 
& CYNoLeader
) != 0) 
 516     out 
<< "objc_msgSend("; 
 517     self_
->Output(out
, CYPA
, CYNoFlags
); 
 519     std::ostringstream name
; 
 520     for (CYArgument 
*argument(arguments_
); argument 
!= NULL
; argument 
= argument
->next_
) 
 521         if (argument
->name_ 
!= NULL
) { 
 522             name 
<< *argument
->name_
; 
 523             if (argument
->value_ 
!= NULL
) 
 526     out 
<< reinterpret_cast<void *>(sel_registerName(name
.str().c_str())); 
 527     for (CYArgument 
*argument(arguments_
); argument 
!= NULL
; argument 
= argument
->next_
) 
 528         if (argument
->value_ 
!= NULL
) { 
 530             argument
->value_
->Output(out
, CYPA
, CYNoFlags
); 
 535 void CYSource::Show(std::ostream 
&out
) const { 
 536     for (const CYSource 
*next(this); next 
!= NULL
; next 
= next
->next_
) 
 540 void CYSource::Output(std::ostream 
&out
, bool block
) const { 
 541     if (!block 
&& !IsBlock()) 
 550 void CYSource::Output_(std::ostream 
&out
) const { 
 554 void CYStatement::Output_(std::ostream 
&out
) const { 
 555     for (CYLabel 
*label(labels_
); label 
!= NULL
; label 
= label
->next_
) 
 556         out 
<< *label
->name_ 
<< ':'; 
 560 void CYString::Output(std::ostream 
&out
, CYFlags flags
) const { 
 561     unsigned quot(0), apos(0); 
 562     for (const char *value(value_
), *end(value_ 
+ size_
); value 
!= end
; ++value
) 
 565         else if (*value 
== '\'') 
 568     bool single(quot 
> apos
); 
 570     out 
<< (single 
? '\'' : '"'); 
 571     for (const char *value(value_
), *end(value_ 
+ size_
); value 
!= end
; ++value
) 
 573             case '\\': out 
<< "\\\\"; break; 
 574             case '\b': out 
<< "\\b"; break; 
 575             case '\f': out 
<< "\\f"; break; 
 576             case '\n': out 
<< "\\n"; break; 
 577             case '\r': out 
<< "\\r"; break; 
 578             case '\t': out 
<< "\\t"; break; 
 579             case '\v': out 
<< "\\v"; break; 
 594                 if (*value 
< 0x20 || *value 
>= 0x7f) 
 595                     out 
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
); 
 599     out 
<< (single 
? '\'' : '"'); 
 602 void CYString::PropertyName(std::ostream 
&out
) const { 
 603     if (const char *word 
= Word()) 
 609 void CYSwitch::Output(std::ostream 
&out
) const { 
 611     value_
->Output(out
, CYNoFlags
); 
 613     if (clauses_ 
!= NULL
) 
 618 void CYThis::Output(std::ostream 
&out
, CYFlags flags
) const { 
 619     if ((flags 
& CYNoLeader
) != 0) 
 622     if ((flags 
& CYNoTrailer
) != 0) 
 626 void CYThrow::Output(std::ostream 
&out
) const { 
 629         value_
->Output(out
, CYNoLeader
); 
 633 void CYTry::Output(std::ostream 
&out
) const { 
 635     try_
->Output(out
, true); 
 638     if (finally_ 
!= NULL
) { 
 640         finally_
->Output(out
, true); 
 644 void CYVariable::Output(std::ostream 
&out
, CYFlags flags
) const { 
 645     if ((flags 
& CYNoLeader
) != 0) 
 648     if ((flags 
& CYNoTrailer
) != 0) 
 652 void CYWhile::Output(std::ostream 
&out
) const { 
 654     test_
->Output(out
, CYNoFlags
); 
 656     code_
->Output(out
, false); 
 659 void CYWith::Output(std::ostream 
&out
) const { 
 661     scope_
->Output(out
, CYNoFlags
); 
 663     code_
->Output(out
, false); 
 666 void CYWord::ClassName(std::ostream 
&out
) const { 
 667     out 
<< "objc_getClass(\"" << Value() << "\")"; 
 670 void CYWord::Output(std::ostream 
&out
) const { 
 674 void CYWord::PropertyName(std::ostream 
&out
) const {