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?!
 
  56 #include "location.hh"
 
  57 #include "Pooling.hpp"
 
  58 #include "Options.hpp"
 
  62 template <typename Type_>
 
  76     void SetNext(Type_ *next) {
 
  85     virtual void Output(struct CYOutput &out) const = 0;
 
 103     CYOutput(std::ostream &out, CYOptions &options) :
 
 113     void Check(char value);
 
 116     CYOutput &operator <<(char rhs);
 
 117     CYOutput &operator <<(const char *rhs);
 
 119     _finline CYOutput &operator <<(const CYThing *rhs) {
 
 125     _finline CYOutput &operator <<(const CYThing &rhs) {
 
 131 struct CYPropertyName {
 
 132     virtual void PropertyName(CYOutput &out) const = 0;
 
 134     virtual ~CYPropertyName() {
 
 148     CYNoBrace =      (1 << 0),
 
 149     CYNoFunction =   (1 << 1),
 
 152     CYNoRightHand =  (1 << 4),
 
 153     CYNoDangle =     (1 << 5),
 
 154     CYNoInteger =    (1 << 6),
 
 155     CYNoBF =         (CYNoBrace | CYNoFunction),
 
 161     virtual ~CYStatement() {
 
 164     void Single(CYOutput &out, CYFlags flags) const;
 
 165     void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
 
 167     CYStatement *ReplaceAll(CYContext &context);
 
 168     virtual CYStatement *Collapse(CYContext &context);
 
 170     virtual CYStatement *Replace(CYContext &context) = 0;
 
 173     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 176 struct CYStatements {
 
 186     operator CYStatement *() const {
 
 190     CYStatements &operator ->*(CYStatement *next) {
 
 192             if (first_ == NULL) {
 
 195             } else for (;; last_ = last_->next_)
 
 196                 if (last_->next_ == NULL) {
 
 206     virtual ~CYClassName() {
 
 209     virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
 
 210     virtual void ClassName(CYOutput &out, bool object) const = 0;
 
 220     CYWord(const char *word) :
 
 225     void Set(const char *value) {
 
 229     virtual const char *Word() const;
 
 230     virtual void Output(CYOutput &out) const;
 
 232     virtual CYExpression *ClassName(CYContext &context, bool object);
 
 233     virtual void ClassName(CYOutput &out, bool object) const;
 
 234     virtual void PropertyName(CYOutput &out) const;
 
 237 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
 
 239     return lhs << rhs.Word();
 
 242 struct CYIdentifier :
 
 243     CYNext<CYIdentifier>,
 
 246     CYIdentifier *replace_;
 
 250     CYIdentifier(const char *word) :
 
 258     virtual const char *Word() const;
 
 259     CYIdentifier *Replace(CYContext &context);
 
 267     CYComment(const char *value) :
 
 272     virtual CYStatement *Replace(CYContext &context);
 
 273     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 280     CYStatement *statement_;
 
 282     CYLabel(CYIdentifier *name, CYStatement *statement) :
 
 284         statement_(statement)
 
 288     virtual CYStatement *Replace(CYContext &context);
 
 289     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 292 struct CYCStringLess :
 
 293     std::binary_function<const char *, const char *, bool>
 
 295     _finline bool operator ()(const char *lhs, const char *rhs) const {
 
 296         return strcmp(lhs, rhs) < 0;
 
 300 struct CYIdentifierValueLess :
 
 301     std::binary_function<CYIdentifier *, CYIdentifier *, bool>
 
 303     _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
 
 304         return CYCStringLess()(lhs->Word(), rhs->Word());
 
 308 enum CYIdentifierFlags {
 
 309     CYIdentifierArgument,
 
 310     CYIdentifierVariable,
 
 315 typedef std::set<const char *, CYCStringLess> CYCStringSet;
 
 316 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
 
 317 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
 
 319 struct CYIdentifierUsage {
 
 320     CYIdentifier *identifier_;
 
 324 typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
 
 329     CYIdentifierAddressFlagsMap internal_;
 
 330     CYIdentifierValueSet identifiers_;
 
 340     void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
 
 341     virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
 
 342     void Merge(CYContext &context, CYIdentifier *identifier);
 
 343     void Scope(CYContext &context, CYStatement *&statements);
 
 349     CYStatement *statements_;
 
 351     CYProgram(CYStatement *statements) :
 
 352         statements_(statements)
 
 356     virtual void Replace(CYContext &context);
 
 357     virtual void Output(CYOutput &out) const;
 
 364     CYIdentifierUsageVector rename_;
 
 366     CYContext(apr_pool_t *pool, CYOptions &options) :
 
 373     virtual ~CYContext() {
 
 376     template <typename Type_>
 
 377     void Replace(Type_ *&value) {
 
 378         for (;;) if (value == NULL)
 
 381             Type_ *replace(value->Replace(*this));
 
 382             if (replace != value)
 
 393     CYStatement *statements_;
 
 395     CYBlock(CYStatement *statements) :
 
 396         statements_(statements)
 
 400     operator CYStatement *() const {
 
 404     void AddPrev(CYStatement *statement) {
 
 405         CYStatement *last(statement);
 
 406         while (last->next_ != NULL)
 
 408         last->SetNext(statements_);
 
 409         statements_ = statement;
 
 412     virtual CYStatement *Replace(CYContext &context);
 
 414     virtual void Output(CYOutput &out) const;
 
 415     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 443     std::string filename_;
 
 447         cy::location location_;
 
 448         std::string message_;
 
 451     typedef std::vector<Error> Errors;
 
 459         CYExpression *context_;
 
 461         Context(CYExpression *context) :
 
 466         typedef std::vector<CYWord *> Words;
 
 470     typedef std::vector<Context> Contexts;
 
 473     CYExpression *context_;
 
 485     void ScannerDestroy();
 
 488     CYDriver(apr_pool_t *pool = NULL, const std::string &filename = "");
 
 491     Condition GetCondition();
 
 492     void SetCondition(Condition condition);
 
 494     void PushCondition(Condition condition);
 
 497     void Warning(const cy::location &location, const char *message);
 
 500 struct CYForInitialiser {
 
 501     virtual ~CYForInitialiser() {
 
 504     virtual void For(CYOutput &out) const = 0;
 
 505     virtual CYExpression *Replace(CYContext &context) = 0;
 
 508 struct CYForInInitialiser {
 
 509     virtual ~CYForInInitialiser() {
 
 512     virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
 
 513     virtual const char *ForEachIn() const = 0;
 
 514     virtual CYExpression *ForEachIn(CYContext &out) = 0;
 
 515     virtual CYExpression *Replace(CYContext &context) = 0;
 
 521 struct CYExpression :
 
 522     CYNext<CYExpression>,
 
 528     virtual unsigned Precedence() const = 0;
 
 530     virtual bool RightHand() const {
 
 534     virtual void For(CYOutput &out) const;
 
 535     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
 537     virtual const char *ForEachIn() const;
 
 538     virtual CYExpression *ForEachIn(CYContext &out);
 
 540     virtual void Output(CYOutput &out) const;
 
 541     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 542     void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
 
 544     virtual CYExpression *ClassName(CYContext &context, bool object);
 
 545     virtual void ClassName(CYOutput &out, bool object) const;
 
 547     CYExpression *ReplaceAll(CYContext &context);
 
 549     virtual CYExpression *Replace(CYContext &context) = 0;
 
 551     virtual CYExpression *Primitive(CYContext &context) {
 
 555     virtual CYNumber *Number(CYContext &context) {
 
 559     virtual CYString *String(CYContext &context) {
 
 563     virtual const char *Word() const {
 
 568 #define CYAlphabetic(value) \
 
 569     virtual bool Alphabetic() const { \
 
 573 #define CYPrecedence(value) \
 
 574     virtual unsigned Precedence() const { \
 
 578 #define CYRightHand(value) \
 
 579     virtual bool RightHand() const { \
 
 586     CYExpression *expressions_;
 
 588     CYCompound(CYExpression *expressions = NULL) :
 
 589         expressions_(expressions)
 
 593     void AddPrev(CYExpression *expression) {
 
 594         CYExpression *last(expression);
 
 595         while (last->next_ != NULL)
 
 597         last->SetNext(expressions_);
 
 598         expressions_ = expression;
 
 603     virtual CYExpression *Replace(CYContext &context);
 
 604     void Output(CYOutput &out, CYFlags flags) const;
 
 607 struct CYFunctionParameter :
 
 608     CYNext<CYFunctionParameter>,
 
 613     CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
 
 614         CYNext<CYFunctionParameter>(next),
 
 619     virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
 
 620     virtual void Output(CYOutput &out) const;
 
 623 struct CYOptionalFunctionParameter :
 
 626     CYExpression *initializer_;
 
 628     CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
 
 629         CYFunctionParameter(name, next),
 
 630         initializer_(initializer)
 
 634     virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
 
 635     virtual void Output(CYOutput &out) const;
 
 638 struct CYComprehension :
 
 639     CYNext<CYComprehension>,
 
 642     virtual const char *Name() const = 0;
 
 644     virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
 
 645     CYFunctionParameter *Parameters(CYContext &context) const;
 
 646     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 647     virtual void Output(CYOutput &out) const = 0;
 
 650 struct CYForInComprehension :
 
 656     CYForInComprehension(CYIdentifier *name, CYExpression *set) :
 
 662     virtual const char *Name() const {
 
 663         return name_->Word();
 
 666     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 667     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 668     virtual void Output(CYOutput &out) const;
 
 671 struct CYForEachInComprehension :
 
 677     CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
 
 683     virtual const char *Name() const {
 
 684         return name_->Word();
 
 687     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 688     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 689     virtual void Output(CYOutput &out) const;
 
 692 struct CYIfComprehension :
 
 697     CYIfComprehension(CYExpression *test) :
 
 702     virtual const char *Name() const {
 
 706     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 707     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 708     virtual void Output(CYOutput &out) const;
 
 711 struct CYArrayComprehension :
 
 714     CYExpression *expression_;
 
 715     CYComprehension *comprehensions_;
 
 717     CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
 
 718         expression_(expression),
 
 719         comprehensions_(comprehensions)
 
 725     virtual CYExpression *Replace(CYContext &context);
 
 726     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 739     virtual CYExpression *Replace(CYContext &context);
 
 753     CYRange(uint64_t lo, uint64_t hi) :
 
 758     bool operator [](uint8_t value) const {
 
 759         return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
 
 762     void operator()(uint8_t value) {
 
 765         (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
 
 769 extern CYRange DigitRange_;
 
 770 extern CYRange WordStartRange_;
 
 771 extern CYRange WordEndRange_;
 
 786     CYString(const char *value) :
 
 792     CYString(const char *value, size_t size) :
 
 798     CYString(const CYWord *word) :
 
 799         value_(word->Word()),
 
 800         size_(strlen(value_))
 
 804     const char *Value() const {
 
 808     virtual const char *Word() const;
 
 810     virtual CYNumber *Number(CYContext &context);
 
 811     virtual CYString *String(CYContext &context);
 
 813     CYString *Concat(CYContext &out, CYString *rhs) const;
 
 814     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 815     virtual void PropertyName(CYOutput &out) const;
 
 824     CYNumber(double value) :
 
 829     double Value() const {
 
 833     virtual CYNumber *Number(CYContext &context);
 
 834     virtual CYString *String(CYContext &context);
 
 836     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 837     virtual void PropertyName(CYOutput &out) const;
 
 845     CYRegEx(const char *value) :
 
 850     const char *Value() const {
 
 854     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 866     virtual CYNumber *Number(CYContext &context);
 
 867     virtual CYString *String(CYContext &context);
 
 869     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 881     virtual CYExpression *Replace(CYContext &context);
 
 882     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 888     virtual bool Value() const = 0;
 
 889     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 901     virtual bool Value() const {
 
 905     virtual CYNumber *Number(CYContext &context);
 
 906     virtual CYString *String(CYContext &context);
 
 918     virtual bool Value() const {
 
 922     virtual CYNumber *Number(CYContext &context);
 
 923     virtual CYString *String(CYContext &context);
 
 931     CYVariable(CYIdentifier *name) :
 
 939     virtual CYExpression *Replace(CYContext &context);
 
 940     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 948     CYPrefix(CYExpression *rhs) :
 
 953     virtual bool Alphabetic() const = 0;
 
 954     virtual const char *Operator() const = 0;
 
 958     virtual CYExpression *Replace(CYContext &context);
 
 959     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 968     CYInfix(CYExpression *lhs, CYExpression *rhs) :
 
 974     void SetLeft(CYExpression *lhs) {
 
 978     virtual bool Alphabetic() const = 0;
 
 979     virtual const char *Operator() const = 0;
 
 981     virtual CYExpression *Replace(CYContext &context);
 
 982     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 990     CYPostfix(CYExpression *lhs) :
 
 995     virtual const char *Operator() const = 0;
 
 999     virtual CYExpression *Replace(CYContext &context);
 
1000     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1003 struct CYAssignment :
 
1009     CYAssignment(CYExpression *lhs, CYExpression *rhs) :
 
1015     void SetLeft(CYExpression *lhs) {
 
1019     virtual const char *Operator() const = 0;
 
1023     virtual CYExpression *Replace(CYContext &context);
 
1024     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1032     CYExpression *value_;
 
1034     CYArgument(CYExpression *value, CYArgument *next = NULL) :
 
1035         CYNext<CYArgument>(next),
 
1041     CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
 
1042         CYNext<CYArgument>(next),
 
1048     void Replace(CYContext &context);
 
1049     void Output(CYOutput &out) const;
 
1065     CYExpression *case_;
 
1066     CYStatement *statements_;
 
1068     CYClause(CYExpression *_case, CYStatement *statements) :
 
1070         statements_(statements)
 
1074     void Replace(CYContext &context);
 
1075     virtual void Output(CYOutput &out) const;
 
1082     CYExpression *value_;
 
1084     CYElement(CYExpression *value, CYElement *next) :
 
1085         CYNext<CYElement>(next),
 
1090     void Replace(CYContext &context);
 
1091     void Output(CYOutput &out) const;
 
1097     CYElement *elements_;
 
1099     CYArray(CYElement *elements = NULL) :
 
1104     virtual CYExpression *Replace(CYContext &context);
 
1105     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1112     CYPropertyName *name_;
 
1113     CYExpression *value_;
 
1115     CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
 
1116         CYNext<CYProperty>(next),
 
1122     void Replace(CYContext &context);
 
1123     virtual void Output(CYOutput &out) const;
 
1126 struct CYDeclaration :
 
1129     CYIdentifier *identifier_;
 
1130     CYExpression *initialiser_;
 
1132     CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
 
1133         identifier_(identifier),
 
1134         initialiser_(initialiser)
 
1138     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
1140     virtual const char *ForEachIn() const;
 
1141     virtual CYExpression *ForEachIn(CYContext &out);
 
1143     virtual CYExpression *Replace(CYContext &context);
 
1144     virtual CYAssignment *Assignment(CYContext &context);
 
1146     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1149 struct CYDeclarations :
 
1150     CYNext<CYDeclarations>,
 
1154     CYDeclaration *declaration_;
 
1156     CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
 
1157         CYNext<CYDeclarations>(next),
 
1158         declaration_(declaration)
 
1162     virtual void For(CYOutput &out) const;
 
1164     virtual CYCompound *Replace(CYContext &context);
 
1165     CYProperty *Property(CYContext &context);
 
1167     virtual void Output(CYOutput &out) const;
 
1168     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1174     CYDeclarations *declarations_;
 
1176     CYVar(CYDeclarations *declarations) :
 
1177         declarations_(declarations)
 
1181     virtual CYStatement *Replace(CYContext &context);
 
1182     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1188     CYDeclarations *declarations_;
 
1191     CYLet(CYDeclarations *declarations, CYStatement *statements) :
 
1192         declarations_(declarations),
 
1197     virtual CYStatement *Replace(CYContext &context);
 
1198     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1204     CYForInitialiser *initialiser_;
 
1205     CYExpression *test_;
 
1206     CYExpression *increment_;
 
1209     CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
 
1210         initialiser_(initialiser),
 
1212         increment_(increment),
 
1217     virtual CYStatement *Replace(CYContext &context);
 
1218     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1224     CYForInInitialiser *initialiser_;
 
1228     CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1229         initialiser_(initialiser),
 
1235     virtual CYStatement *Replace(CYContext &context);
 
1236     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1239 struct CYForEachIn :
 
1242     CYForInInitialiser *initialiser_;
 
1246     CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1247         initialiser_(initialiser),
 
1253     virtual CYStatement *Replace(CYContext &context);
 
1254     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1260     CYProperty *properties_;
 
1262     CYObject(CYProperty *properties) :
 
1263         properties_(properties)
 
1267     virtual CYExpression *Replace(CYContext &context);
 
1268     void Output(CYOutput &out, CYFlags flags) const;
 
1274     CYExpression *object_;
 
1275     CYExpression *property_;
 
1277     CYMember(CYExpression *object, CYExpression *property) :
 
1283     void SetLeft(CYExpression *object) {
 
1287     void Replace_(CYContext &context);
 
1290 struct CYDirectMember :
 
1293     CYDirectMember(CYExpression *object, CYExpression *property) :
 
1294         CYMember(object, property)
 
1301     virtual CYExpression *Replace(CYContext &context);
 
1302     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1305 struct CYIndirectMember :
 
1308     CYIndirectMember(CYExpression *object, CYExpression *property) :
 
1309         CYMember(object, property)
 
1316     virtual CYExpression *Replace(CYContext &context);
 
1317     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1323     CYExpression *constructor_;
 
1324     CYArgument *arguments_;
 
1326     CYNew(CYExpression *constructor, CYArgument *arguments) :
 
1327         constructor_(constructor),
 
1328         arguments_(arguments)
 
1332     virtual unsigned Precedence() const {
 
1333         return arguments_ == NULL ? 2 : 1;
 
1338     virtual CYExpression *Replace(CYContext &context);
 
1339     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1345     CYExpression *function_;
 
1346     CYArgument *arguments_;
 
1348     CYCall(CYExpression *function, CYArgument *arguments = NULL) :
 
1349         function_(function),
 
1350         arguments_(arguments)
 
1357     virtual CYExpression *Replace(CYContext &context);
 
1358     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1364     CYExpression *test_;
 
1366     CYStatement *false_;
 
1368     CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
 
1375     virtual CYStatement *Replace(CYContext &context);
 
1376     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1382     CYExpression *test_;
 
1385     CYDoWhile(CYExpression *test, CYStatement *code) :
 
1391     virtual CYStatement *Replace(CYContext &context);
 
1392     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1398     CYExpression *test_;
 
1401     CYWhile(CYExpression *test, CYStatement *code) :
 
1407     virtual CYStatement *Replace(CYContext &context);
 
1408     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1412     CYIdentifier *name_;
 
1413     CYFunctionParameter *parameters_;
 
1416     CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1418         parameters_(parameters),
 
1423     virtual ~CYFunction() {
 
1426     void Inject(CYContext &context);
 
1427     virtual void Replace_(CYContext &context, bool outer);
 
1428     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1431 struct CYFunctionExpression :
 
1435     CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1436         CYFunction(name, parameters, statements)
 
1443     virtual CYExpression *Replace(CYContext &context);
 
1444     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1447 struct CYFunctionStatement :
 
1451     CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1452         CYFunction(name, parameters, statements)
 
1456     virtual CYStatement *Replace(CYContext &context);
 
1457     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1463     CYExpression *expression_;
 
1465     CYExpress(CYExpression *expression) :
 
1466         expression_(expression)
 
1468         if (expression == NULL)
 
1472     virtual CYStatement *Collapse(CYContext &context);
 
1473     virtual CYStatement *Replace(CYContext &context);
 
1474     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1480     CYIdentifier *label_;
 
1482     CYContinue(CYIdentifier *label) :
 
1487     virtual CYStatement *Replace(CYContext &context);
 
1488     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1494     CYIdentifier *label_;
 
1496     CYBreak(CYIdentifier *label) :
 
1501     virtual CYStatement *Replace(CYContext &context);
 
1502     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1508     CYExpression *value_;
 
1510     CYReturn(CYExpression *value) :
 
1515     virtual CYStatement *Replace(CYContext &context);
 
1516     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1522     virtual CYStatement *Collapse(CYContext &context);
 
1523     virtual CYStatement *Replace(CYContext &context);
 
1524     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1532     CYFinally(CYStatement *statements) :
 
1537     void Replace(CYContext &context);
 
1538     virtual void Output(CYOutput &out) const;
 
1547     CYIdentifier *name_;
 
1550     Catch(CYIdentifier *name, CYStatement *statements) :
 
1556     void Replace(CYContext &context);
 
1557     virtual void Output(CYOutput &out) const;
 
1565     CYFinally *finally_;
 
1567     Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
 
1574     virtual CYStatement *Replace(CYContext &context);
 
1575     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1581     CYExpression *value_;
 
1583     Throw(CYExpression *value) :
 
1588     virtual CYStatement *Replace(CYContext &context);
 
1589     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1597     CYExpression *scope_;
 
1600     CYWith(CYExpression *scope, CYStatement *code) :
 
1606     virtual CYStatement *Replace(CYContext &context);
 
1607     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1613     CYExpression *value_;
 
1616     CYSwitch(CYExpression *value, CYClause *clauses) :
 
1622     virtual CYStatement *Replace(CYContext &context);
 
1623     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1626 struct CYCondition :
 
1629     CYExpression *test_;
 
1630     CYExpression *true_;
 
1631     CYExpression *false_;
 
1633     CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
 
1642     virtual CYExpression *Replace(CYContext &context);
 
1643     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1646 struct CYAddressOf :
 
1649     CYAddressOf(CYExpression *rhs) :
 
1654     virtual const char *Operator() const {
 
1660     virtual CYExpression *Replace(CYContext &context);
 
1666     CYIndirect(CYExpression *rhs) :
 
1671     virtual const char *Operator() const {
 
1677     virtual CYExpression *Replace(CYContext &context);
 
1681     virtual CYExpression *Replace(CYContext &context);
 
1683 #define CYPostfix_(op, name, args...) \
 
1684     struct CY ## name : \
 
1687         CY ## name(CYExpression *lhs) : \
 
1692         virtual const char *Operator() const { \
 
1697 #define CYPrefix_(alphabetic, op, name, args...) \
 
1698     struct CY ## name : \
 
1701         CY ## name(CYExpression *rhs) : \
 
1706         CYAlphabetic(alphabetic) \
 
1708         virtual const char *Operator() const { \
 
1713 #define CYInfix_(alphabetic, precedence, op, name, args...) \
 
1714     struct CY ## name : \
 
1717         CY ## name(CYExpression *lhs, CYExpression *rhs) : \
 
1722         CYAlphabetic(alphabetic) \
 
1723         CYPrecedence(precedence) \
 
1725         virtual const char *Operator() const { \
 
1730 #define CYAssignment_(op, name, args...) \
 
1731     struct CY ## name ## Assign : \
 
1734         CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
 
1735             CYAssignment(lhs, rhs) \
 
1739         virtual const char *Operator() const { \
 
1744 CYPostfix_("++", PostIncrement)
 
1745 CYPostfix_("--", PostDecrement)
 
1747 CYPrefix_(true, "delete", Delete)
 
1748 CYPrefix_(true, "void", Void)
 
1749 CYPrefix_(true, "typeof", TypeOf)
 
1750 CYPrefix_(false, "++", PreIncrement)
 
1751 CYPrefix_(false, "--", PreDecrement)
 
1752 CYPrefix_(false, "+", Affirm)
 
1753 CYPrefix_(false, "-", Negate)
 
1754 CYPrefix_(false, "~", BitwiseNot)
 
1755 CYPrefix_(false, "!", LogicalNot)
 
1757 CYInfix_(false, 5, "*", Multiply)
 
1758 CYInfix_(false, 5, "/", Divide)
 
1759 CYInfix_(false, 5, "%", Modulus)
 
1760 CYInfix_(false, 6, "+", Add, CYReplace)
 
1761 CYInfix_(false, 6, "-", Subtract)
 
1762 CYInfix_(false, 7, "<<", ShiftLeft)
 
1763 CYInfix_(false, 7, ">>", ShiftRightSigned)
 
1764 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
 
1765 CYInfix_(false, 8, "<", Less)
 
1766 CYInfix_(false, 8, ">", Greater)
 
1767 CYInfix_(false, 8, "<=", LessOrEqual)
 
1768 CYInfix_(false, 8, ">=", GreaterOrEqual)
 
1769 CYInfix_(true, 8, "instanceof", InstanceOf)
 
1770 CYInfix_(true, 8, "in", In)
 
1771 CYInfix_(false, 9, "==", Equal)
 
1772 CYInfix_(false, 9, "!=", NotEqual)
 
1773 CYInfix_(false, 9, "===", Identical)
 
1774 CYInfix_(false, 9, "!==", NotIdentical)
 
1775 CYInfix_(false, 10, "&", BitwiseAnd)
 
1776 CYInfix_(false, 11, "^", BitwiseXOr)
 
1777 CYInfix_(false, 12, "|", BitwiseOr)
 
1778 CYInfix_(false, 13, "&&", LogicalAnd)
 
1779 CYInfix_(false, 14, "||", LogicalOr)
 
1781 CYAssignment_("=", )
 
1782 CYAssignment_("*=", Multiply)
 
1783 CYAssignment_("/=", Divide)
 
1784 CYAssignment_("%=", Modulus)
 
1785 CYAssignment_("+=", Add)
 
1786 CYAssignment_("-=", Subtract)
 
1787 CYAssignment_("<<=", ShiftLeft)
 
1788 CYAssignment_(">>=", ShiftRightSigned)
 
1789 CYAssignment_(">>>=", ShiftRightUnsigned)
 
1790 CYAssignment_("&=", BitwiseAnd)
 
1791 CYAssignment_("^=", BitwiseXOr)
 
1792 CYAssignment_("|=", BitwiseOr)
 
1794 #endif/*CYPARSER_HPP*/