1 /* Cycript - Inlining/Optimizing JavaScript Compiler
 
   2  * Copyright (C) 2009  Jay Freeman (saurik)
 
   5 /* Modified BSD License {{{ */
 
   7  *        Redistribution and use in source and binary
 
   8  * forms, with or without modification, are permitted
 
   9  * provided that the following conditions are met:
 
  11  * 1. Redistributions of source code must retain the
 
  12  *    above copyright notice, this list of conditions
 
  13  *    and the following disclaimer.
 
  14  * 2. Redistributions in binary form must reproduce the
 
  15  *    above copyright notice, this list of conditions
 
  16  *    and the following disclaimer in the documentation
 
  17  *    and/or other materials provided with the
 
  19  * 3. The name of the author may not be used to endorse
 
  20  *    or promote products derived from this software
 
  21  *    without specific prior written permission.
 
  23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
 
  24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 
  25  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
  26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
  27  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
 
  28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
  29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
  30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
  31  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
  32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
  33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 
  34  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
  35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
  36  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  43 // XXX: wtf is this here?!
 
  55 #include "location.hh"
 
  56 #include "Pooling.hpp"
 
  57 #include "Options.hpp"
 
  61 template <typename Type_>
 
  75     void SetNext(Type_ *next) {
 
  84     virtual void Output(struct CYOutput &out) const = 0;
 
 102     CYOutput(std::ostream &out, CYOptions &options) :
 
 112     void Check(char value);
 
 115     CYOutput &operator <<(char rhs);
 
 116     CYOutput &operator <<(const char *rhs);
 
 118     _finline CYOutput &operator <<(const CYThing *rhs) {
 
 124     _finline CYOutput &operator <<(const CYThing &rhs) {
 
 130 struct CYPropertyName {
 
 131     virtual void PropertyName(CYOutput &out) const = 0;
 
 133     virtual ~CYPropertyName() {
 
 147     CYNoBrace =      (1 << 0),
 
 148     CYNoFunction =   (1 << 1),
 
 151     CYNoRightHand =  (1 << 4),
 
 152     CYNoDangle =     (1 << 5),
 
 153     CYNoInteger =    (1 << 6),
 
 154     CYNoBF =         (CYNoBrace | CYNoFunction),
 
 160     virtual ~CYStatement() {
 
 163     void Single(CYOutput &out, CYFlags flags) const;
 
 164     void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
 
 166     CYStatement *ReplaceAll(CYContext &context);
 
 167     virtual CYStatement *Collapse(CYContext &context);
 
 169     virtual CYStatement *Replace(CYContext &context) = 0;
 
 172     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 175 struct CYStatements {
 
 185     operator CYStatement *() const {
 
 189     CYStatements &operator ->*(CYStatement *next) {
 
 191             if (first_ == NULL) {
 
 194             } else for (;; last_ = last_->next_)
 
 195                 if (last_->next_ == NULL) {
 
 205     virtual ~CYClassName() {
 
 208     virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
 
 209     virtual void ClassName(CYOutput &out, bool object) const = 0;
 
 219     CYWord(const char *word) :
 
 224     void Set(const char *value) {
 
 228     virtual const char *Word() const;
 
 229     virtual void Output(CYOutput &out) const;
 
 231     virtual CYExpression *ClassName(CYContext &context, bool object);
 
 232     virtual void ClassName(CYOutput &out, bool object) const;
 
 233     virtual void PropertyName(CYOutput &out) const;
 
 236 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
 
 238     return lhs << rhs.Word();
 
 241 struct CYIdentifier :
 
 242     CYNext<CYIdentifier>,
 
 245     CYIdentifier *replace_;
 
 248     CYIdentifier(const char *word) :
 
 255     virtual const char *Word() const;
 
 256     CYIdentifier *Replace(CYContext &context);
 
 264     CYComment(const char *value) :
 
 269     virtual CYStatement *Replace(CYContext &context);
 
 270     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 277     CYStatement *statement_;
 
 279     CYLabel(CYIdentifier *name, CYStatement *statement) :
 
 281         statement_(statement)
 
 285     virtual CYStatement *Replace(CYContext &context);
 
 286     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 289 struct CYCStringLess :
 
 290     std::binary_function<const char *, const char *, bool>
 
 292     _finline bool operator ()(const char *lhs, const char *rhs) const {
 
 293         return strcmp(lhs, rhs) < 0;
 
 297 struct CYIdentifierValueLess :
 
 298     std::binary_function<CYIdentifier *, CYIdentifier *, bool>
 
 300     _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
 
 301         return CYCStringLess()(lhs->Word(), rhs->Word());
 
 305 enum CYIdentifierFlags {
 
 306     CYIdentifierArgument,
 
 307     CYIdentifierVariable,
 
 312 typedef std::set<const char *, CYCStringLess> CYCStringSet;
 
 313 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
 
 314 typedef std::set<CYIdentifier *> CYIdentifierAddressSet;
 
 315 typedef std::vector<CYIdentifier *> CYIdentifierAddressVector;
 
 316 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
 
 320     CYIdentifierAddressFlagsMap internal_;
 
 322     CYIdentifierValueSet identifiers_;
 
 329     void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
 
 330     virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
 
 331     void Merge(CYContext &context, CYIdentifier *identifier);
 
 332     void Scope(CYContext &context, CYStatement *&statements);
 
 339     CYStatement *statements_;
 
 340     CYIdentifierAddressVector rename_;
 
 342     CYProgram(CYStatement *statements) :
 
 343         statements_(statements)
 
 347     virtual void Replace(CYContext &context);
 
 348     virtual void Output(CYOutput &out) const;
 
 359     CYContext(apr_pool_t *pool, CYOptions &options) :
 
 367     template <typename Type_>
 
 368     void Replace(Type_ *&value) {
 
 369         for (;;) if (value == NULL)
 
 372             Type_ *replace(value->Replace(*this));
 
 373             if (replace != value)
 
 384     CYStatement *statements_;
 
 387     CYBlock(CYStatement *statements, CYScope *scope = NULL) :
 
 388         statements_(statements),
 
 393     operator CYStatement *() const {
 
 397     void AddPrev(CYStatement *statement) {
 
 398         CYStatement *last(statement);
 
 399         while (last->next_ != NULL)
 
 401         last->SetNext(statements_);
 
 402         statements_ = statement;
 
 405     virtual CYStatement *Replace(CYContext &context);
 
 407     virtual void Output(CYOutput &out) const;
 
 408     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 436     std::string filename_;
 
 440         cy::location location_;
 
 441         std::string message_;
 
 444     typedef std::vector<Error> Errors;
 
 451     void ScannerDestroy();
 
 454     CYDriver(const std::string &filename);
 
 457     Condition GetCondition();
 
 458     void SetCondition(Condition condition);
 
 460     void PushCondition(Condition condition);
 
 463     void Warning(const cy::location &location, const char *message);
 
 466 struct CYForInitialiser {
 
 467     virtual ~CYForInitialiser() {
 
 470     virtual void For(CYOutput &out) const = 0;
 
 471     virtual CYExpression *Replace(CYContext &context) = 0;
 
 474 struct CYForInInitialiser {
 
 475     virtual ~CYForInInitialiser() {
 
 478     virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
 
 479     virtual const char *ForEachIn() const = 0;
 
 480     virtual CYExpression *ForEachIn(CYContext &out) = 0;
 
 481     virtual CYExpression *Replace(CYContext &context) = 0;
 
 487 struct CYExpression :
 
 488     CYNext<CYExpression>,
 
 494     virtual unsigned Precedence() const = 0;
 
 496     virtual bool RightHand() const {
 
 500     virtual void For(CYOutput &out) const;
 
 501     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
 503     virtual const char *ForEachIn() const;
 
 504     virtual CYExpression *ForEachIn(CYContext &out);
 
 506     virtual void Output(CYOutput &out) const;
 
 507     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 508     void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
 
 510     virtual CYExpression *ClassName(CYContext &context, bool object);
 
 511     virtual void ClassName(CYOutput &out, bool object) const;
 
 513     CYExpression *ReplaceAll(CYContext &context);
 
 515     virtual CYExpression *Replace(CYContext &context) = 0;
 
 517     virtual CYExpression *Primitive(CYContext &context) {
 
 521     virtual CYNumber *Number(CYContext &context) {
 
 525     virtual CYString *String(CYContext &context) {
 
 529     virtual const char *Word() const {
 
 534 #define CYAlphabetic(value) \
 
 535     virtual bool Alphabetic() const { \
 
 539 #define CYPrecedence(value) \
 
 540     virtual unsigned Precedence() const { \
 
 544 #define CYRightHand(value) \
 
 545     virtual bool RightHand() const { \
 
 552     CYExpression *expressions_;
 
 554     CYCompound(CYExpression *expressions = NULL) :
 
 555         expressions_(expressions)
 
 559     void AddPrev(CYExpression *expression) {
 
 560         CYExpression *last(expression);
 
 561         while (last->next_ != NULL)
 
 563         last->SetNext(expressions_);
 
 564         expressions_ = expression;
 
 569     virtual CYExpression *Replace(CYContext &context);
 
 570     void Output(CYOutput &out, CYFlags flags) const;
 
 573 struct CYFunctionParameter :
 
 574     CYNext<CYFunctionParameter>,
 
 579     CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
 
 580         CYNext<CYFunctionParameter>(next),
 
 585     void Replace(CYContext &context);
 
 586     virtual void Output(CYOutput &out) const;
 
 589 struct CYComprehension :
 
 590     CYNext<CYComprehension>,
 
 593     virtual const char *Name() const = 0;
 
 595     virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
 
 596     CYFunctionParameter *Parameters(CYContext &context) const;
 
 597     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 598     virtual void Output(CYOutput &out) const = 0;
 
 601 struct CYForInComprehension :
 
 607     CYForInComprehension(CYIdentifier *name, CYExpression *set) :
 
 613     virtual const char *Name() const {
 
 614         return name_->Word();
 
 617     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 618     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 619     virtual void Output(CYOutput &out) const;
 
 622 struct CYForEachInComprehension :
 
 628     CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
 
 634     virtual const char *Name() const {
 
 635         return name_->Word();
 
 638     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 639     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 640     virtual void Output(CYOutput &out) const;
 
 643 struct CYIfComprehension :
 
 648     CYIfComprehension(CYExpression *test) :
 
 653     virtual const char *Name() const {
 
 657     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 658     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 659     virtual void Output(CYOutput &out) const;
 
 662 struct CYArrayComprehension :
 
 665     CYExpression *expression_;
 
 666     CYComprehension *comprehensions_;
 
 668     CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
 
 669         expression_(expression),
 
 670         comprehensions_(comprehensions)
 
 676     virtual CYExpression *Replace(CYContext &context);
 
 677     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 690     virtual CYExpression *Replace(CYContext &context);
 
 704     CYRange(uint64_t lo, uint64_t hi) :
 
 709     bool operator [](uint8_t value) const {
 
 710         return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
 
 713     void operator()(uint8_t value) {
 
 716         (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
 
 720 extern CYRange DigitRange_;
 
 721 extern CYRange WordStartRange_;
 
 722 extern CYRange WordEndRange_;
 
 737     CYString(const char *value) :
 
 743     CYString(const char *value, size_t size) :
 
 749     CYString(const CYWord *word) :
 
 750         value_(word->Word()),
 
 751         size_(strlen(value_))
 
 755     const char *Value() const {
 
 759     virtual const char *Word() const;
 
 761     virtual CYNumber *Number(CYContext &context);
 
 762     virtual CYString *String(CYContext &context);
 
 764     CYString *Concat(CYContext &out, CYString *rhs) const;
 
 765     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 766     virtual void PropertyName(CYOutput &out) const;
 
 775     CYNumber(double value) :
 
 780     double Value() const {
 
 784     virtual CYNumber *Number(CYContext &context);
 
 785     virtual CYString *String(CYContext &context);
 
 787     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 788     virtual void PropertyName(CYOutput &out) const;
 
 796     CYRegEx(const char *value) :
 
 801     const char *Value() const {
 
 805     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 817     virtual CYNumber *Number(CYContext &context);
 
 818     virtual CYString *String(CYContext &context);
 
 820     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 832     virtual CYExpression *Replace(CYContext &context);
 
 833     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 839     virtual bool Value() const = 0;
 
 840     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 852     virtual bool Value() const {
 
 856     virtual CYNumber *Number(CYContext &context);
 
 857     virtual CYString *String(CYContext &context);
 
 869     virtual bool Value() const {
 
 873     virtual CYNumber *Number(CYContext &context);
 
 874     virtual CYString *String(CYContext &context);
 
 882     CYVariable(CYIdentifier *name) :
 
 890     virtual CYExpression *Replace(CYContext &context);
 
 891     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 899     CYPrefix(CYExpression *rhs) :
 
 904     virtual bool Alphabetic() const = 0;
 
 905     virtual const char *Operator() const = 0;
 
 909     virtual CYExpression *Replace(CYContext &context);
 
 910     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 919     CYInfix(CYExpression *lhs, CYExpression *rhs) :
 
 925     void SetLeft(CYExpression *lhs) {
 
 929     virtual bool Alphabetic() const = 0;
 
 930     virtual const char *Operator() const = 0;
 
 932     virtual CYExpression *Replace(CYContext &context);
 
 933     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 941     CYPostfix(CYExpression *lhs) :
 
 946     virtual const char *Operator() const = 0;
 
 950     virtual CYExpression *Replace(CYContext &context);
 
 951     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 954 struct CYAssignment :
 
 960     CYAssignment(CYExpression *lhs, CYExpression *rhs) :
 
 966     void SetLeft(CYExpression *lhs) {
 
 970     virtual const char *Operator() const = 0;
 
 974     virtual CYExpression *Replace(CYContext &context);
 
 975     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 983     CYExpression *value_;
 
 985     CYArgument(CYExpression *value, CYArgument *next = NULL) :
 
 986         CYNext<CYArgument>(next),
 
 992     CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
 
 993         CYNext<CYArgument>(next),
 
 999     void Replace(CYContext &context);
 
1000     void Output(CYOutput &out) const;
 
1016     CYExpression *case_;
 
1017     CYStatement *statements_;
 
1019     CYClause(CYExpression *_case, CYStatement *statements) :
 
1021         statements_(statements)
 
1025     void Replace(CYContext &context);
 
1026     virtual void Output(CYOutput &out) const;
 
1033     CYExpression *value_;
 
1035     CYElement(CYExpression *value, CYElement *next) :
 
1036         CYNext<CYElement>(next),
 
1041     void Replace(CYContext &context);
 
1042     void Output(CYOutput &out) const;
 
1048     CYElement *elements_;
 
1050     CYArray(CYElement *elements = NULL) :
 
1055     virtual CYExpression *Replace(CYContext &context);
 
1056     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1063     CYPropertyName *name_;
 
1064     CYExpression *value_;
 
1066     CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
 
1067         CYNext<CYProperty>(next),
 
1073     void Replace(CYContext &context);
 
1074     virtual void Output(CYOutput &out) const;
 
1077 struct CYDeclaration :
 
1080     CYIdentifier *identifier_;
 
1081     CYExpression *initialiser_;
 
1083     CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
 
1084         identifier_(identifier),
 
1085         initialiser_(initialiser)
 
1089     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
1091     virtual const char *ForEachIn() const;
 
1092     virtual CYExpression *ForEachIn(CYContext &out);
 
1094     virtual CYExpression *Replace(CYContext &context);
 
1095     virtual CYAssignment *Assignment(CYContext &context);
 
1097     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1100 struct CYDeclarations :
 
1101     CYNext<CYDeclarations>,
 
1105     CYDeclaration *declaration_;
 
1107     CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
 
1108         CYNext<CYDeclarations>(next),
 
1109         declaration_(declaration)
 
1113     virtual void For(CYOutput &out) const;
 
1115     virtual CYCompound *Replace(CYContext &context);
 
1116     CYProperty *Property(CYContext &context);
 
1118     virtual void Output(CYOutput &out) const;
 
1119     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1125     CYDeclarations *declarations_;
 
1127     CYVar(CYDeclarations *declarations) :
 
1128         declarations_(declarations)
 
1132     virtual CYStatement *Replace(CYContext &context);
 
1133     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1139     CYDeclarations *declarations_;
 
1142     CYLet(CYDeclarations *declarations, CYStatement *statements) :
 
1143         declarations_(declarations),
 
1148     virtual CYStatement *Replace(CYContext &context);
 
1149     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1155     CYForInitialiser *initialiser_;
 
1156     CYExpression *test_;
 
1157     CYExpression *increment_;
 
1160     CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
 
1161         initialiser_(initialiser),
 
1163         increment_(increment),
 
1168     virtual CYStatement *Replace(CYContext &context);
 
1169     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1175     CYForInInitialiser *initialiser_;
 
1179     CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1180         initialiser_(initialiser),
 
1186     virtual CYStatement *Replace(CYContext &context);
 
1187     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1190 struct CYForEachIn :
 
1193     CYForInInitialiser *initialiser_;
 
1197     CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1198         initialiser_(initialiser),
 
1204     virtual CYStatement *Replace(CYContext &context);
 
1205     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1211     CYProperty *properties_;
 
1213     CYObject(CYProperty *properties) :
 
1214         properties_(properties)
 
1218     virtual CYExpression *Replace(CYContext &context);
 
1219     void Output(CYOutput &out, CYFlags flags) const;
 
1225     CYExpression *object_;
 
1226     CYExpression *property_;
 
1228     CYMember(CYExpression *object, CYExpression *property) :
 
1234     void SetLeft(CYExpression *object) {
 
1238     void Replace_(CYContext &context);
 
1241 struct CYDirectMember :
 
1244     CYDirectMember(CYExpression *object, CYExpression *property) :
 
1245         CYMember(object, property)
 
1252     virtual CYExpression *Replace(CYContext &context);
 
1253     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1256 struct CYIndirectMember :
 
1259     CYIndirectMember(CYExpression *object, CYExpression *property) :
 
1260         CYMember(object, property)
 
1267     virtual CYExpression *Replace(CYContext &context);
 
1268     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1274     CYExpression *constructor_;
 
1275     CYArgument *arguments_;
 
1277     CYNew(CYExpression *constructor, CYArgument *arguments) :
 
1278         constructor_(constructor),
 
1279         arguments_(arguments)
 
1283     virtual unsigned Precedence() const {
 
1284         return arguments_ == NULL ? 2 : 1;
 
1289     virtual CYExpression *Replace(CYContext &context);
 
1290     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1296     CYExpression *function_;
 
1297     CYArgument *arguments_;
 
1299     CYCall(CYExpression *function, CYArgument *arguments = NULL) :
 
1300         function_(function),
 
1301         arguments_(arguments)
 
1308     virtual CYExpression *Replace(CYContext &context);
 
1309     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1315     CYExpression *test_;
 
1317     CYStatement *false_;
 
1319     CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
 
1326     virtual CYStatement *Replace(CYContext &context);
 
1327     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1333     CYExpression *test_;
 
1336     CYDoWhile(CYExpression *test, CYStatement *code) :
 
1342     virtual CYStatement *Replace(CYContext &context);
 
1343     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1349     CYExpression *test_;
 
1352     CYWhile(CYExpression *test, CYStatement *code) :
 
1358     virtual CYStatement *Replace(CYContext &context);
 
1359     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1365     CYIdentifier *name_;
 
1366     CYFunctionParameter *parameters_;
 
1369     CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1371         parameters_(parameters),
 
1372         code_(statements, this)
 
1376     virtual ~CYFunction() {
 
1379     void Inject(CYContext &context);
 
1380     virtual void Replace_(CYContext &context, bool outer);
 
1381     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1384 struct CYFunctionExpression :
 
1388     CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1389         CYFunction(name, parameters, statements)
 
1396     virtual CYExpression *Replace(CYContext &context);
 
1397     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1400 struct CYFunctionStatement :
 
1404     CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1405         CYFunction(name, parameters, statements)
 
1409     virtual CYStatement *Replace(CYContext &context);
 
1410     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1416     CYExpression *expression_;
 
1418     CYExpress(CYExpression *expression) :
 
1419         expression_(expression)
 
1421         if (expression == NULL)
 
1425     virtual CYStatement *Collapse(CYContext &context);
 
1426     virtual CYStatement *Replace(CYContext &context);
 
1427     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1433     CYIdentifier *label_;
 
1435     CYContinue(CYIdentifier *label) :
 
1440     virtual CYStatement *Replace(CYContext &context);
 
1441     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1447     CYIdentifier *label_;
 
1449     CYBreak(CYIdentifier *label) :
 
1454     virtual CYStatement *Replace(CYContext &context);
 
1455     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1461     CYExpression *value_;
 
1463     CYReturn(CYExpression *value) :
 
1468     virtual CYStatement *Replace(CYContext &context);
 
1469     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1475     virtual CYStatement *Collapse(CYContext &context);
 
1476     virtual CYStatement *Replace(CYContext &context);
 
1477     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1485     CYFinally(CYStatement *statements) :
 
1490     void Replace(CYContext &context);
 
1491     virtual void Output(CYOutput &out) const;
 
1500     CYIdentifier *name_;
 
1503     Catch(CYIdentifier *name, CYStatement *statements) :
 
1509     void Replace(CYContext &context);
 
1510     virtual void Output(CYOutput &out) const;
 
1518     CYFinally *finally_;
 
1520     Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
 
1527     virtual CYStatement *Replace(CYContext &context);
 
1528     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1534     CYExpression *value_;
 
1536     Throw(CYExpression *value) :
 
1541     virtual CYStatement *Replace(CYContext &context);
 
1542     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1550     CYExpression *scope_;
 
1553     CYWith(CYExpression *scope, CYStatement *code) :
 
1559     virtual CYStatement *Replace(CYContext &context);
 
1560     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1566     CYExpression *value_;
 
1569     CYSwitch(CYExpression *value, CYClause *clauses) :
 
1575     virtual CYStatement *Replace(CYContext &context);
 
1576     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1579 struct CYCondition :
 
1582     CYExpression *test_;
 
1583     CYExpression *true_;
 
1584     CYExpression *false_;
 
1586     CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
 
1595     virtual CYExpression *Replace(CYContext &context);
 
1596     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1599 struct CYAddressOf :
 
1602     CYAddressOf(CYExpression *rhs) :
 
1607     virtual const char *Operator() const {
 
1613     virtual CYExpression *Replace(CYContext &context);
 
1619     CYIndirect(CYExpression *rhs) :
 
1624     virtual const char *Operator() const {
 
1630     virtual CYExpression *Replace(CYContext &context);
 
1634     virtual CYExpression *Replace(CYContext &context);
 
1636 #define CYPostfix_(op, name, args...) \
 
1637     struct CY ## name : \
 
1640         CY ## name(CYExpression *lhs) : \
 
1645         virtual const char *Operator() const { \
 
1650 #define CYPrefix_(alphabetic, op, name, args...) \
 
1651     struct CY ## name : \
 
1654         CY ## name(CYExpression *rhs) : \
 
1659         CYAlphabetic(alphabetic) \
 
1661         virtual const char *Operator() const { \
 
1666 #define CYInfix_(alphabetic, precedence, op, name, args...) \
 
1667     struct CY ## name : \
 
1670         CY ## name(CYExpression *lhs, CYExpression *rhs) : \
 
1675         CYAlphabetic(alphabetic) \
 
1676         CYPrecedence(precedence) \
 
1678         virtual const char *Operator() const { \
 
1683 #define CYAssignment_(op, name, args...) \
 
1684     struct CY ## name ## Assign : \
 
1687         CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
 
1688             CYAssignment(lhs, rhs) \
 
1692         virtual const char *Operator() const { \
 
1697 CYPostfix_("++", PostIncrement)
 
1698 CYPostfix_("--", PostDecrement)
 
1700 CYPrefix_(true, "delete", Delete)
 
1701 CYPrefix_(true, "void", Void)
 
1702 CYPrefix_(true, "typeof", TypeOf)
 
1703 CYPrefix_(false, "++", PreIncrement)
 
1704 CYPrefix_(false, "--", PreDecrement)
 
1705 CYPrefix_(false, "+", Affirm)
 
1706 CYPrefix_(false, "-", Negate)
 
1707 CYPrefix_(false, "~", BitwiseNot)
 
1708 CYPrefix_(false, "!", LogicalNot)
 
1710 CYInfix_(false, 5, "*", Multiply)
 
1711 CYInfix_(false, 5, "/", Divide)
 
1712 CYInfix_(false, 5, "%", Modulus)
 
1713 CYInfix_(false, 6, "+", Add, CYReplace)
 
1714 CYInfix_(false, 6, "-", Subtract)
 
1715 CYInfix_(false, 7, "<<", ShiftLeft)
 
1716 CYInfix_(false, 7, ">>", ShiftRightSigned)
 
1717 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
 
1718 CYInfix_(false, 8, "<", Less)
 
1719 CYInfix_(false, 8, ">", Greater)
 
1720 CYInfix_(false, 8, "<=", LessOrEqual)
 
1721 CYInfix_(false, 8, ">=", GreaterOrEqual)
 
1722 CYInfix_(true, 8, "instanceof", InstanceOf)
 
1723 CYInfix_(true, 8, "in", In)
 
1724 CYInfix_(false, 9, "==", Equal)
 
1725 CYInfix_(false, 9, "!=", NotEqual)
 
1726 CYInfix_(false, 9, "===", Identical)
 
1727 CYInfix_(false, 9, "!==", NotIdentical)
 
1728 CYInfix_(false, 10, "&", BitwiseAnd)
 
1729 CYInfix_(false, 11, "^", BitwiseXOr)
 
1730 CYInfix_(false, 12, "|", BitwiseOr)
 
1731 CYInfix_(false, 13, "&&", LogicalAnd)
 
1732 CYInfix_(false, 14, "||", LogicalOr)
 
1734 CYAssignment_("=", )
 
1735 CYAssignment_("*=", Multiply)
 
1736 CYAssignment_("/=", Divide)
 
1737 CYAssignment_("%=", Modulus)
 
1738 CYAssignment_("+=", Add)
 
1739 CYAssignment_("-=", Subtract)
 
1740 CYAssignment_("<<=", ShiftLeft)
 
1741 CYAssignment_(">>=", ShiftRightSigned)
 
1742 CYAssignment_(">>>=", ShiftRightUnsigned)
 
1743 CYAssignment_("&=", BitwiseAnd)
 
1744 CYAssignment_("^=", BitwiseXOr)
 
1745 CYAssignment_("|=", BitwiseOr)
 
1747 #endif/*CYPARSER_HPP*/