]>
git.saurik.com Git - cycript.git/blob - Output.cpp
09ee163a739f138b964081d9a9d0aab5e4afdefd
   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(CYOutput 
&out
, CYFlags flags
) const { 
  48     rhs_
->Output(out
, 1, CYLeft(flags
)); 
  52 void CYArgument::Output(CYOutput 
&out
) const { 
  59         value_
->Output(out
, CYPA
, CYNoFlags
); 
  61         if (next_
->name_ 
== NULL
) 
  69 void CYArray::Output(CYOutput 
&out
, CYFlags flags
) const { 
  71     if (elements_ 
!= NULL
) 
  72         elements_
->Output(out
); 
  76 void CYArrayComprehension::Output(CYOutput 
&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(CYOutput 
&out
, CYFlags flags
) const { 
  95     lhs_
->Output(out
, Precedence() - 1, CYLeft(flags
)); 
  97     rhs_
->Output(out
, Precedence(), CYRight(flags
)); 
 100 void CYBlock::Output(CYOutput 
&out
) const { 
 101     for (CYStatement 
*statement(statements_
); statement 
!= NULL
; statement 
= statement
->next_
) 
 102         statement
->Output(out
); 
 105 void CYBoolean::Output(CYOutput 
&out
, CYFlags flags
) const { 
 106     if ((flags 
& CYNoLeader
) != 0) 
 108     out 
<< (Value() ? "true" : "false"); 
 109     if ((flags 
& CYNoTrailer
) != 0) 
 113 void CYBreak::Output(CYOutput 
&out
) const { 
 116         out 
<< ' ' << *label_
; 
 120 void CYCall::Output(CYOutput 
&out
, CYFlags flags
) const { 
 121     function_
->Output(out
, Precedence(), CYLeft(flags
)); 
 123     if (arguments_ 
!= NULL
) 
 124         arguments_
->Output(out
); 
 128 void CYCatch::Output(CYOutput 
&out
) const { 
 129     out 
<< "catch(" << *name_ 
<< "){"; 
 135 void CYCategory::Output(CYOutput 
&out
) const { 
 136     out 
<< "(function($cys,$cyp,$cyc,$cyn,$cyt){"; 
 137     out 
<< "$cyp=object_getClass($cys);"; 
 139     if (messages_ 
!= NULL
) 
 140         messages_
->Output(out
, true); 
 142     name_
->ClassName(out
, true); 
 146 void CYClass::Output(CYOutput 
&out
) const { 
 151 void CYClass::Output(CYOutput 
&out
, CYFlags flags
) const { 
 152     // XXX: I don't necc. need the ()s 
 153     out 
<< "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){"; 
 154     out 
<< "$cyp=object_getClass($cys);"; 
 155     out 
<< "$cyc=objc_allocateClassPair($cys,"; 
 157         name_
->ClassName(out
, false); 
 159         out 
<< "$cyq(\"CY$\")"; 
 161     out 
<< "$cym=object_getClass($cyc);"; 
 163         fields_
->Output(out
); 
 164     if (messages_ 
!= NULL
) 
 165         messages_
->Output(out
, false); 
 166     out 
<< "objc_registerClassPair($cyc);"; 
 167     out 
<< "return $cyc;"; 
 170         super_
->Output(out
, CYPA
, CYNoFlags
); 
 176 void CYCompound::Output(CYOutput 
&out
, CYFlags flags
) const { 
 177     if (CYExpression 
*expression 
= expressions_
) 
 178         if (CYExpression 
*next 
= expression
->next_
) { 
 179             expression
->Output(out
, CYLeft(flags
)); 
 180             CYFlags 
center(CYCenter(flags
)); 
 181             while (next 
!= NULL
) { 
 184                 next 
= expression
->next_
; 
 185                 CYFlags 
right(next 
!= NULL 
? center 
: CYRight(flags
)); 
 186                 expression
->Output(out
, right
); 
 189             expression
->Output(out
, flags
); 
 192 void CYComprehension::Output(CYOutput 
&out
) const { 
 198 void CYCondition::Output(CYOutput 
&out
, CYFlags flags
) const { 
 199     test_
->Output(out
, Precedence() - 1, CYLeft(flags
)); 
 202         true_
->Output(out
, CYPA
, CYNoFlags
); 
 204     false_
->Output(out
, CYPA
, CYRight(flags
)); 
 207 void CYContinue::Output(CYOutput 
&out
) const { 
 210         out 
<< ' ' << *label_
; 
 214 void CYClause::Output(CYOutput 
&out
) const { 
 217         case_
->Output(out
, CYNoLeader
); 
 222         code_
->Output(out
, false); 
 227 const char *CYDeclaration::ForEachIn() const { 
 228     return identifier_
->Value(); 
 231 void CYDeclaration::ForIn(CYOutput 
&out
, CYFlags flags
) const { 
 232     if ((flags 
& CYNoLeader
) != 0) 
 235     Output(out
, CYRight(flags
)); 
 238 void CYDeclaration::ForEachIn(CYOutput 
&out
) const { 
 242 void CYDeclaration::Output(CYOutput 
&out
, CYFlags flags
) const { 
 244     if (initialiser_ 
!= NULL
) { 
 246         initialiser_
->Output(out
, CYPA
, CYRight(flags
)); 
 247     } else if ((flags 
& CYNoTrailer
) != 0) 
 251 void CYDeclarations::For(CYOutput 
&out
) const { 
 256 void CYDeclarations::Output(CYOutput 
&out
, CYFlags flags
) const { 
 257     const CYDeclarations 
*declaration(this); 
 259     CYDeclarations 
*next(declaration
->next_
); 
 260     CYFlags 
right(next 
== NULL 
? CYRight(flags
) : CYCenter(flags
)); 
 261     declaration
->declaration_
->Output(out
, right
); 
 270 void CYDirectMember::Output(CYOutput 
&out
, CYFlags flags
) const { 
 271     object_
->Output(out
, Precedence(), CYLeft(flags
)); 
 272     if (const char *word 
= property_
->Word()) 
 276         property_
->Output(out
, CYNoFlags
); 
 281 void CYDoWhile::Output(CYOutput 
&out
) const { 
 282     // XXX: extra space character! 
 284     code_
->Output(out
, false); 
 286     test_
->Output(out
, CYNoFlags
); 
 290 void CYElement::Output(CYOutput 
&out
) const { 
 292         value_
->Output(out
, CYPA
, CYNoFlags
); 
 293     if (next_ 
!= NULL 
|| value_ 
== NULL
) 
 299 void CYEmpty::Output(CYOutput 
&out
) const { 
 303 void CYEmpty::Output(CYOutput 
&out
, bool block
) const { 
 305         CYStatement::Output(out
, block
); 
 310 void CYExpress::Output(CYOutput 
&out
) const { 
 311     expression_
->Output(out
, CYNoBF
); 
 315 void CYExpression::ClassName(CYOutput 
&out
, bool object
) const { 
 316     Output(out
, CYPA
, CYNoFlags
); 
 319 const char *CYExpression::ForEachIn() const { 
 323 void CYExpression::For(CYOutput 
&out
) const { 
 327 void CYExpression::ForEachIn(CYOutput 
&out
) const { 
 328     // XXX: this should handle LeftHandSideExpression 
 329     Output(out
, CYPA
, CYNoFlags
); 
 332 void CYExpression::ForIn(CYOutput 
&out
, CYFlags flags
) const { 
 333     // XXX: this should handle LeftHandSideExpression 
 337 void CYExpression::Output(CYOutput 
&out
, unsigned precedence
, CYFlags flags
) const { 
 338     if (precedence 
< Precedence()) { 
 340         Output(out
, CYNoFlags
); 
 346 void CYField::Output(CYOutput 
&out
) const { 
 350 void CYFinally::Output(CYOutput 
&out
) const { 
 357 void CYFor::Output(CYOutput 
&out
) const { 
 359     if (initialiser_ 
!= NULL
) 
 360         initialiser_
->For(out
); 
 363         test_
->Output(out
, CYNoFlags
); 
 365     if (increment_ 
!= NULL
) 
 366         increment_
->Output(out
, CYNoFlags
); 
 368     code_
->Output(out
, false); 
 371 void CYForEachIn::Output(CYOutput 
&out
) const { 
 372     out 
<< "with({$cys:0,$cyt:0}){"; 
 375     set_
->Output(out
, CYPA
, CYNoFlags
); 
 378     out 
<< "for($cyt in $cys){"; 
 380     initialiser_
->ForEachIn(out
); 
 381     out 
<< "=$cys[$cyt];"; 
 390 void CYForEachInComprehension::Begin_(CYOutput 
&out
) const { 
 391     out 
<< "(function($cys){"; 
 393     set_
->Output(out
, CYPA
, CYNoFlags
); 
 396     out 
<< "for(" << *name_ 
<< " in $cys){"; 
 397     out 
<< *name_ 
<< "=$cys[" << *name_ 
<< "];"; 
 400 void CYForEachInComprehension::End_(CYOutput 
&out
) const { 
 404 void CYForIn::Output(CYOutput 
&out
) const { 
 406     initialiser_
->ForIn(out
, CYNoIn 
| CYNoTrailer
); 
 408     set_
->Output(out
, CYNoLeader
); 
 410     code_
->Output(out
, false); 
 413 void CYForInComprehension::Begin_(CYOutput 
&out
) const { 
 414     out 
<< "for(" << *name_ 
<< " in"; 
 415     set_
->Output(out
, CYNoLeader
); 
 419 void CYFunction::Output(CYOutput 
&out
) const { 
 420     CYLambda::Output(out
, CYNoFlags
); 
 423 void CYFunctionParameter::Output(CYOutput 
&out
) const { 
 431 void CYIf::Output(CYOutput 
&out
) const { 
 433     test_
->Output(out
, CYNoFlags
); 
 435     true_
->Output(out
, true); 
 436     if (false_ 
!= NULL
) { 
 438         false_
->Output(out
, false); 
 442 void CYIfComprehension::Begin_(CYOutput 
&out
) const { 
 444     test_
->Output(out
, CYNoFlags
); 
 448 void CYIndirect::Output(CYOutput 
&out
, CYFlags flags
) const { 
 449     rhs_
->Output(out
, 1, CYLeft(flags
)); 
 453 void CYIndirectMember::Output(CYOutput 
&out
, CYFlags flags
) const { 
 454     object_
->Output(out
, Precedence(), CYLeft(flags
)); 
 456     if (const char *word 
= property_
->Word()) 
 460         property_
->Output(out
, CYNoFlags
); 
 465 void CYInfix::Output(CYOutput 
&out
, CYFlags flags
) const { 
 466     const char *name(Operator()); 
 467     bool protect((flags 
& CYNoIn
) != 0 && strcmp(name
, "in")); 
 470     bool alphabetic(Alphabetic()); 
 471     CYFlags 
left(protect 
? CYNoFlags 
: CYLeft(flags
)); 
 474     lhs_
->Output(out
, Precedence(), left
); 
 476     CYFlags 
right(protect 
? CYNoFlags 
: CYRight(flags
)); 
 479     if (strcmp(name
, "-") == 0) 
 481     rhs_
->Output(out
, Precedence() - 1, right
); 
 486 void CYLambda::Output(CYOutput 
&out
, CYFlags flags
) const { 
 487     bool protect((flags 
& CYNoFunction
) != 0); 
 490     else if ((flags 
& CYNoLeader
) != 0) 
 494         out 
<< ' ' << *name_
; 
 496     if (parameters_ 
!= NULL
) 
 506 void CYLet::Output(CYOutput 
&out
) const { 
 508     declarations_
->Output(out
, CYNoFlags
); 
 510     if (statements_ 
!= NULL
) 
 511         statements_
->Show(out
); 
 515 void CYMessage::Output(CYOutput 
&out
, bool replace
) const { 
 517         next_
->Output(out
, replace
); 
 518     out 
<< "$cyn=new Selector(\""; 
 519     for (CYMessageParameter 
*parameter(parameter_
); parameter 
!= NULL
; parameter 
= parameter
->next_
) 
 520         if (parameter
->tag_ 
!= NULL
) { 
 521             out 
<< *parameter
->tag_
; 
 522             if (parameter
->name_ 
!= NULL
) 
 526     out 
<< "$cyt=$cyn.type($cy" << (instance_ 
? 's' : 'p') << ");"; 
 527     out 
<< "class_" << (replace 
? "replace" : "add") << "Method($cy" << (instance_ 
? 'c' : 'm') << ",$cyn,"; 
 528     out 
<< "new Functor(function(self,_cmd"; 
 529     for (CYMessageParameter 
*parameter(parameter_
); parameter 
!= NULL
; parameter 
= parameter
->next_
) 
 530         if (parameter
->name_ 
!= NULL
) 
 531             out 
<< ',' << *parameter
->name_
; 
 532     out 
<< "){return function(){"; 
 535     out 
<< "}.call(self);},$cyt),$cyt);"; 
 538 void CYNew::Output(CYOutput 
&out
, CYFlags flags
) const { 
 539     if ((flags 
& CYNoLeader
) != 0) 
 542     constructor_
->Output(out
, Precedence(), CYCenter(flags
) | CYNoLeader
); 
 544     if (arguments_ 
!= NULL
) 
 545         arguments_
->Output(out
); 
 549 void CYNull::Output(CYOutput 
&out
, CYFlags flags
) const { 
 550     if ((flags 
& CYNoLeader
) != 0) 
 553     if ((flags 
& CYNoTrailer
) != 0) 
 557 void CYNumber::Output(CYOutput 
&out
, CYFlags flags
) const { 
 558     double value(Value()); 
 559     if ((flags 
& CYNoLeader
) != 0 || value 
< 0 && (flags 
& CYNoHyphen
) != 0) 
 561     // XXX: decide on correct precision 
 562     out
.out_ 
<< std::setprecision(9) << value
; 
 563     if ((flags 
& CYNoTrailer
) != 0) 
 567 void CYNumber::PropertyName(CYOutput 
&out
) const { 
 571 void CYObject::Output(CYOutput 
&out
, CYFlags flags
) const { 
 572     bool protect((flags 
& CYNoBrace
) != 0); 
 576     if (property_ 
!= NULL
) 
 577         property_
->Output(out
); 
 583 void CYPostfix::Output(CYOutput 
&out
, CYFlags flags
) const { 
 584     lhs_
->Output(out
, Precedence(), CYLeft(flags
)); 
 588 void CYPrefix::Output(CYOutput 
&out
, CYFlags flags
) const { 
 589     const char *name(Operator()); 
 590     bool alphabetic(Alphabetic()); 
 591     if (alphabetic 
&& (flags 
& CYNoLeader
) != 0 || name
[0] == '-' && (flags 
& CYNoHyphen
) != 0) 
 594     CYFlags 
right(CYRight(flags
)); 
 597     rhs_
->Output(out
, Precedence(), right
); 
 600 void CYProperty::Output(CYOutput 
&out
) const { 
 601     name_
->PropertyName(out
); 
 603     value_
->Output(out
, CYPA
, CYNoFlags
); 
 610 void CYRegEx::Output(CYOutput 
&out
, CYFlags flags
) const { 
 612     if ((flags 
& CYNoTrailer
) != 0) 
 616 void CYReturn::Output(CYOutput 
&out
) const { 
 619         value_
->Output(out
, CYNoLeader
); 
 623 void CYSelector::Output(CYOutput 
&out
, CYFlags flags
) const { 
 624     if ((flags 
& CYNoLeader
) != 0) 
 626     out 
<< "new Selector(\""; 
 632 void CYSelectorPart::Output(CYOutput 
&out
) const { 
 641 void CYSend::Output(CYOutput 
&out
, CYFlags flags
) const { 
 642     if ((flags 
& CYNoLeader
) != 0) 
 644     out 
<< "objc_msgSend("; 
 645     self_
->Output(out
, CYPA
, CYNoFlags
); 
 647     std::ostringstream name
; 
 648     for (CYArgument 
*argument(arguments_
); argument 
!= NULL
; argument 
= argument
->next_
) 
 649         if (argument
->name_ 
!= NULL
) { 
 650             name 
<< *argument
->name_
; 
 651             if (argument
->value_ 
!= NULL
) 
 654     out
.out_ 
<< reinterpret_cast<void *>(sel_registerName(name
.str().c_str())); 
 655     for (CYArgument 
*argument(arguments_
); argument 
!= NULL
; argument 
= argument
->next_
) 
 656         if (argument
->value_ 
!= NULL
) { 
 658             argument
->value_
->Output(out
, CYPA
, CYNoFlags
); 
 663 void CYStatement::Show(CYOutput 
&out
) const { 
 664     for (const CYStatement 
*next(this); next 
!= NULL
; next 
= next
->next_
) 
 668 void CYStatement::Output(CYOutput 
&out
, bool block
) const { 
 669     if (!block 
&& !IsBlock()) 
 678 void CYStatement::Output_(CYOutput 
&out
) const { 
 679     for (CYLabel 
*label(labels_
); label 
!= NULL
; label 
= label
->next_
) 
 680         out 
<< *label
->name_ 
<< ':'; 
 684 void CYString::Output(CYOutput 
&out
, CYFlags flags
) const { 
 685     unsigned quot(0), apos(0); 
 686     for (const char *value(value_
), *end(value_ 
+ size_
); value 
!= end
; ++value
) 
 689         else if (*value 
== '\'') 
 692     bool single(quot 
> apos
); 
 694     out 
<< (single 
? '\'' : '"'); 
 695     for (const char *value(value_
), *end(value_ 
+ size_
); value 
!= end
; ++value
) 
 697             case '\\': out 
<< "\\\\"; break; 
 698             case '\b': out 
<< "\\b"; break; 
 699             case '\f': out 
<< "\\f"; break; 
 700             case '\n': out 
<< "\\n"; break; 
 701             case '\r': out 
<< "\\r"; break; 
 702             case '\t': out 
<< "\\t"; break; 
 703             case '\v': out 
<< "\\v"; break; 
 718                 if (*value 
< 0x20 || *value 
>= 0x7f) 
 719                     out
.out_ 
<< "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value
); 
 723     out 
<< (single 
? '\'' : '"'); 
 726 void CYString::PropertyName(CYOutput 
&out
) const { 
 727     if (const char *word 
= Word()) 
 733 void CYSwitch::Output(CYOutput 
&out
) const { 
 735     value_
->Output(out
, CYNoFlags
); 
 737     if (clauses_ 
!= NULL
) 
 742 void CYThis::Output(CYOutput 
&out
, CYFlags flags
) const { 
 743     if ((flags 
& CYNoLeader
) != 0) 
 746     if ((flags 
& CYNoTrailer
) != 0) 
 750 void CYThrow::Output(CYOutput 
&out
) const { 
 753         value_
->Output(out
, CYNoLeader
); 
 757 void CYTry::Output(CYOutput 
&out
) const { 
 764     if (finally_ 
!= NULL
) 
 765         finally_
->Output(out
); 
 768 void CYVar::Output(CYOutput 
&out
) const { 
 770     declarations_
->Output(out
, CYNoFlags
); 
 774 void CYVariable::Output(CYOutput 
&out
, CYFlags flags
) const { 
 775     if ((flags 
& CYNoLeader
) != 0) 
 778     if ((flags 
& CYNoTrailer
) != 0) 
 782 void CYWhile::Output(CYOutput 
&out
) const { 
 784     test_
->Output(out
, CYNoFlags
); 
 786     code_
->Output(out
, false); 
 789 void CYWith::Output(CYOutput 
&out
) const { 
 791     scope_
->Output(out
, CYNoFlags
); 
 793     code_
->Output(out
, false); 
 796 void CYWord::ClassName(CYOutput 
&out
, bool object
) const { 
 798         out 
<< "objc_getClass("; 
 799     out 
<< '"' << Value() << '"'; 
 804 void CYWord::Output(CYOutput 
&out
) const { 
 808 void CYWord::PropertyName(CYOutput 
&out
) const {