1 /* Cycript - Optimizing JavaScript Compiler/Runtime
 
   2  * Copyright (C) 2009-2013  Jay Freeman (saurik)
 
   5 /* GNU General Public License, Version 3 {{{ */
 
   7  * Cycript is free software: you can redistribute it and/or modify
 
   8  * it under the terms of the GNU General Public License as published
 
   9  * by the Free Software Foundation, either version 3 of the License,
 
  10  * or (at your option) any later version.
 
  12  * Cycript is distributed in the hope that it will be useful, but
 
  13  * WITHOUT ANY WARRANTY; without even the implied warranty of
 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  15  * GNU General Public License for more details.
 
  17  * You should have received a copy of the GNU General Public License
 
  18  * along with Cycript.  If not, see <http://www.gnu.org/licenses/>.
 
  22 #ifndef CYCRIPT_PARSER_HPP
 
  23 #define CYCRIPT_PARSER_HPP
 
  36 #include "location.hh"
 
  39 #include "Pooling.hpp"
 
  40 #include "Options.hpp"
 
  48     virtual void Output(struct CYOutput &out) const = 0;
 
  66     CYOutput(std::ostream &out, CYOptions &options) :
 
  76     void Check(char value);
 
  79     CYOutput &operator <<(char rhs);
 
  80     CYOutput &operator <<(const char *rhs);
 
  82     _finline CYOutput &operator <<(const CYThing *rhs) {
 
  88     _finline CYOutput &operator <<(const CYThing &rhs) {
 
  94 struct CYPropertyName {
 
  95     virtual void PropertyName(CYOutput &out) const = 0;
 
  97     virtual ~CYPropertyName() {
 
 112     CYNoBrace =      (1 << 0),
 
 113     CYNoFunction =   (1 << 1),
 
 116     CYNoRightHand =  (1 << 4),
 
 117     CYNoDangle =     (1 << 5),
 
 118     CYNoInteger =    (1 << 6),
 
 119     CYNoBF =         (CYNoBrace | CYNoFunction),
 
 122 _finline CYFlags operator ~(CYFlags rhs) {
 
 123     return static_cast<CYFlags>(~static_cast<unsigned>(rhs));
 
 126 _finline CYFlags operator &(CYFlags lhs, CYFlags rhs) {
 
 127     return static_cast<CYFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
 
 130 _finline CYFlags operator |(CYFlags lhs, CYFlags rhs) {
 
 131     return static_cast<CYFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
 
 134 _finline CYFlags &operator |=(CYFlags &lhs, CYFlags rhs) {
 
 135     return lhs = lhs | rhs;
 
 138 _finline CYFlags CYLeft(CYFlags flags) {
 
 139     return flags & ~(CYNoDangle | CYNoInteger);
 
 142 _finline CYFlags CYRight(CYFlags flags) {
 
 143     return flags & ~CYNoBF;
 
 146 _finline CYFlags CYCenter(CYFlags flags) {
 
 147     return CYLeft(CYRight(flags));
 
 153     virtual ~CYStatement() {
 
 156     void Single(CYOutput &out, CYFlags flags) const;
 
 157     void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
 
 159     virtual CYStatement *Replace(CYContext &context) = 0;
 
 162     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 165 struct CYStatements {
 
 175     operator CYStatement *() const {
 
 179     CYStatements &operator ->*(CYStatement *next) {
 
 181             if (first_ == NULL) {
 
 184             } else for (;; last_ = last_->next_)
 
 185                 if (last_->next_ == NULL) {
 
 195     virtual ~CYClassName() {
 
 198     virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
 
 199     virtual void ClassName(CYOutput &out, bool object) const = 0;
 
 209     CYWord(const char *word) :
 
 214     void Set(const char *value) {
 
 218     virtual const char *Word() const;
 
 219     virtual void Output(CYOutput &out) const;
 
 221     virtual CYExpression *ClassName(CYContext &context, bool object);
 
 222     virtual void ClassName(CYOutput &out, bool object) const;
 
 223     virtual void PropertyName(CYOutput &out) const;
 
 226 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
 
 228     return lhs << rhs.Word();
 
 231 struct CYIdentifier :
 
 232     CYNext<CYIdentifier>,
 
 235     CYIdentifier *replace_;
 
 239     CYIdentifier(const char *word) :
 
 247     virtual const char *Word() const;
 
 248     CYIdentifier *Replace(CYContext &context);
 
 256     CYComment(const char *value) :
 
 261     virtual CYStatement *Replace(CYContext &context);
 
 262     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 269     CYStatement *statement_;
 
 271     CYLabel(CYIdentifier *name, CYStatement *statement) :
 
 273         statement_(statement)
 
 277     virtual CYStatement *Replace(CYContext &context);
 
 278     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 281 struct CYCStringLess :
 
 282     std::binary_function<const char *, const char *, bool>
 
 284     _finline bool operator ()(const char *lhs, const char *rhs) const {
 
 285         return strcmp(lhs, rhs) < 0;
 
 289 struct CYIdentifierValueLess :
 
 290     std::binary_function<CYIdentifier *, CYIdentifier *, bool>
 
 292     _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
 
 293         return CYCStringLess()(lhs->Word(), rhs->Word());
 
 297 enum CYIdentifierFlags {
 
 298     CYIdentifierArgument,
 
 299     CYIdentifierVariable,
 
 305 typedef std::set<const char *, CYCStringLess> CYCStringSet;
 
 306 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
 
 307 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
 
 309 struct CYIdentifierUsage {
 
 310     CYIdentifier *identifier_;
 
 314 typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
 
 320     CYStatement *&statements_;
 
 324     CYIdentifierAddressFlagsMap internal_;
 
 325     CYIdentifierValueSet identifiers_;
 
 327     CYScope(bool transparent, CYContext &context, CYStatement *&statements);
 
 332     void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
 
 333     virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
 
 334     void Merge(CYContext &context, CYIdentifier *identifier);
 
 335     void Scope(CYContext &context, CYStatement *&statements);
 
 341     CYStatement *statements_;
 
 343     CYProgram(CYStatement *statements) :
 
 344         statements_(statements)
 
 348     virtual void Replace(CYContext &context);
 
 349     virtual void Output(CYOutput &out) const;
 
 361     CYIdentifierUsageVector rename_;
 
 363     CYNonLocal *nonlocal_;
 
 364     CYNonLocal *nextlocal_;
 
 367     CYContext(CYOptions &options) :
 
 377     virtual ~CYContext() {
 
 380     template <typename Type_>
 
 381     void ReplaceAll(Type_ *&values) {
 
 382         Type_ **last(&values);
 
 383         CYForEach (next, values) {
 
 384             Replace(*last = next);
 
 386                 last = &(*last)->next_;
 
 390     template <typename Type_>
 
 391     void Replace(Type_ *&value) {
 
 392         for (;;) if (value == NULL)
 
 395             Type_ *replace(value->Replace(*this));
 
 396             if (replace != value)
 
 402     void NonLocal(CYStatement *&statements);
 
 403     CYIdentifier *Unique();
 
 407     CYIdentifier *identifier_;
 
 414     CYIdentifier *Target(CYContext &context) {
 
 415         if (identifier_ == NULL)
 
 416             identifier_ = context.Unique();
 
 424     CYIdentifier *identifier_;
 
 431     CYIdentifier *Identifier(CYContext &context) {
 
 433             return next_->Identifier(context);
 
 434         if (identifier_ == NULL)
 
 435             identifier_ = context.Unique();
 
 444     CYStatement *statements_;
 
 446     CYBlock(CYStatement *statements) :
 
 447         statements_(statements)
 
 451     operator CYStatement *() const {
 
 455     void AddPrev(CYStatement *statement) {
 
 456         CYSetLast(statement) = statements_;
 
 457         statements_ = statement;
 
 460     virtual CYStatement *Replace(CYContext &context);
 
 462     virtual void Output(CYOutput &out) const;
 
 463     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 477         public std::streambuf
 
 480         CYBuffer(const char *start, const char *end) {
 
 481             setg(const_cast<char *>(start), const_cast<char *>(start), const_cast<char *>(end));
 
 486     CYStream(const char *start, const char *end) :
 
 487         std::istream(&buffer_),
 
 498     std::stack<bool> in_;
 
 501         bool AtImplementation;
 
 517     std::string filename_;
 
 521         cy::location location_;
 
 522         std::string message_;
 
 525     typedef std::vector<Error> Errors;
 
 533         CYExpression *context_;
 
 535         Context(CYExpression *context) :
 
 540         typedef std::vector<CYWord *> Words;
 
 544     typedef std::vector<Context> Contexts;
 
 547     CYExpression *context_;
 
 559     void ScannerDestroy();
 
 562     CYDriver(std::istream &data, const std::string &filename = "");
 
 565     Condition GetCondition();
 
 566     void SetCondition(Condition condition);
 
 568     void PushCondition(Condition condition);
 
 571     void Warning(const cy::location &location, const char *message);
 
 574 struct CYForInitialiser {
 
 575     virtual ~CYForInitialiser() {
 
 578     virtual CYExpression *Replace(CYContext &context) = 0;
 
 579     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 582 struct CYForInInitialiser {
 
 583     virtual ~CYForInInitialiser() {
 
 586     virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
 
 587     virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value) = 0;
 
 589     virtual CYExpression *Replace(CYContext &context) = 0;
 
 590     virtual CYAssignment *Assignment(CYContext &context) = 0;
 
 592     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 598 struct CYExpression :
 
 599     CYNext<CYExpression>,
 
 605     virtual unsigned Precedence() const = 0;
 
 607     virtual bool RightHand() const {
 
 611     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
 612     virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
 
 614     virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
 
 616     virtual void Output(CYOutput &out) const;
 
 617     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 618     void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
 
 620     virtual CYExpression *ClassName(CYContext &context, bool object);
 
 621     virtual void ClassName(CYOutput &out, bool object) const;
 
 623     virtual CYExpression *Replace(CYContext &context) = 0;
 
 624     virtual CYAssignment *Assignment(CYContext &context);
 
 626     virtual CYExpression *Primitive(CYContext &context) {
 
 630     virtual CYNumber *Number(CYContext &context) {
 
 634     virtual CYString *String(CYContext &context) {
 
 638     virtual const char *Word() const {
 
 643 #define CYAlphabetic(value) \
 
 644     virtual bool Alphabetic() const { \
 
 648 #define CYPrecedence(value) \
 
 649     static const unsigned Precedence_ = value; \
 
 650     virtual unsigned Precedence() const { \
 
 651         return Precedence_; \
 
 654 #define CYRightHand(value) \
 
 655     virtual bool RightHand() const { \
 
 662     CYExpression *expressions_;
 
 664     CYCompound(CYExpression *expressions = NULL) :
 
 665         expressions_(expressions)
 
 669     void AddPrev(CYExpression *expression) {
 
 670         CYSetLast(expression) = expressions_;
 
 671         expressions_ = expression;
 
 676     virtual CYExpression *Replace(CYContext &context);
 
 677     void Output(CYOutput &out, CYFlags flags) const;
 
 679     virtual CYExpression *Primitive(CYContext &context);
 
 682 struct CYDeclaration;
 
 684 struct CYFunctionParameter :
 
 685     CYNext<CYFunctionParameter>,
 
 688     CYForInInitialiser *initialiser_;
 
 690     CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
 
 691         CYNext<CYFunctionParameter>(next),
 
 692         initialiser_(initialiser)
 
 696     void Replace(CYContext &context, CYBlock &code);
 
 697     void Output(CYOutput &out) const;
 
 700 struct CYComprehension :
 
 701     CYNext<CYComprehension>,
 
 704     CYComprehension(CYComprehension *next = NULL) :
 
 705         CYNext<CYComprehension>(next)
 
 709     virtual const char *Name() const = 0;
 
 711     virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
 
 712     CYFunctionParameter *Parameters(CYContext &context) const;
 
 713     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 714     virtual void Output(CYOutput &out) const = 0;
 
 717 struct CYForInComprehension :
 
 723     CYForInComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
 
 724         CYComprehension(next),
 
 730     virtual const char *Name() const {
 
 731         return name_->Word();
 
 734     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 735     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 736     virtual void Output(CYOutput &out) const;
 
 739 struct CYForOfComprehension :
 
 745     CYForOfComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
 
 746         CYComprehension(next),
 
 752     virtual const char *Name() const {
 
 753         return name_->Word();
 
 756     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 757     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 758     virtual void Output(CYOutput &out) const;
 
 761 struct CYIfComprehension :
 
 766     CYIfComprehension(CYExpression *test) :
 
 771     virtual const char *Name() const {
 
 775     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 776     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 777     virtual void Output(CYOutput &out) const;
 
 780 struct CYArrayComprehension :
 
 783     CYExpression *expression_;
 
 784     CYComprehension *comprehensions_;
 
 786     CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
 
 787         expression_(expression),
 
 788         comprehensions_(comprehensions)
 
 794     virtual CYExpression *Replace(CYContext &context);
 
 795     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 808     virtual CYExpression *Replace(CYContext &context);
 
 822     CYRange(uint64_t lo, uint64_t hi) :
 
 827     bool operator [](uint8_t value) const {
 
 828         return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
 
 831     void operator()(uint8_t value) {
 
 834         (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
 
 838 extern CYRange DigitRange_;
 
 839 extern CYRange WordStartRange_;
 
 840 extern CYRange WordEndRange_;
 
 855     CYString(const char *value) :
 
 861     CYString(const char *value, size_t size) :
 
 867     CYString(const CYWord *word) :
 
 868         value_(word->Word()),
 
 869         size_(strlen(value_))
 
 873     const char *Value() const {
 
 877     virtual const char *Word() const;
 
 879     virtual CYNumber *Number(CYContext &context);
 
 880     virtual CYString *String(CYContext &context);
 
 882     CYString *Concat(CYContext &out, CYString *rhs) const;
 
 883     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 884     virtual void PropertyName(CYOutput &out) const;
 
 893     CYNumber(double value) :
 
 898     double Value() const {
 
 902     virtual CYNumber *Number(CYContext &context);
 
 903     virtual CYString *String(CYContext &context);
 
 905     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 906     virtual void PropertyName(CYOutput &out) const;
 
 914     CYRegEx(const char *value) :
 
 919     const char *Value() const {
 
 923     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 935     virtual CYNumber *Number(CYContext &context);
 
 936     virtual CYString *String(CYContext &context);
 
 938     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 950     virtual CYExpression *Replace(CYContext &context);
 
 951     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 957     virtual bool Value() const = 0;
 
 958     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 970     virtual bool Value() const {
 
 974     virtual CYNumber *Number(CYContext &context);
 
 975     virtual CYString *String(CYContext &context);
 
 987     virtual bool Value() const {
 
 991     virtual CYNumber *Number(CYContext &context);
 
 992     virtual CYString *String(CYContext &context);
 
1000     CYVariable(CYIdentifier *name) :
 
1005     CYVariable(const char *name) :
 
1006         name_(new($pool) CYIdentifier(name))
 
1013     virtual CYExpression *Replace(CYContext &context);
 
1014     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1022     CYPrefix(CYExpression *rhs) :
 
1027     virtual bool Alphabetic() const = 0;
 
1028     virtual const char *Operator() const = 0;
 
1032     virtual CYExpression *Replace(CYContext &context);
 
1033     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1042     CYInfix(CYExpression *lhs, CYExpression *rhs) :
 
1048     void SetLeft(CYExpression *lhs) {
 
1052     virtual bool Alphabetic() const = 0;
 
1053     virtual const char *Operator() const = 0;
 
1055     virtual CYExpression *Replace(CYContext &context);
 
1056     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1064     CYPostfix(CYExpression *lhs) :
 
1069     virtual const char *Operator() const = 0;
 
1073     virtual CYExpression *Replace(CYContext &context);
 
1074     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1077 struct CYAssignment :
 
1083     CYAssignment(CYExpression *lhs, CYExpression *rhs) :
 
1089     void SetLeft(CYExpression *lhs) {
 
1093     virtual const char *Operator() const = 0;
 
1097     virtual CYExpression *Replace(CYContext &context);
 
1098     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1106     CYExpression *value_;
 
1108     CYArgument(CYExpression *value, CYArgument *next = NULL) :
 
1109         CYNext<CYArgument>(next),
 
1115     CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
 
1116         CYNext<CYArgument>(next),
 
1122     CYArgument *Replace(CYContext &context);
 
1123     void Output(CYOutput &out) const;
 
1139     CYExpression *case_;
 
1140     CYStatement *statements_;
 
1142     CYClause(CYExpression *_case, CYStatement *statements) :
 
1144         statements_(statements)
 
1148     void Replace(CYContext &context);
 
1149     virtual void Output(CYOutput &out) const;
 
1156     CYExpression *value_;
 
1158     CYElement(CYExpression *value, CYElement *next) :
 
1159         CYNext<CYElement>(next),
 
1164     void Replace(CYContext &context);
 
1165     void Output(CYOutput &out) const;
 
1171     CYElement *elements_;
 
1173     CYArray(CYElement *elements = NULL) :
 
1178     virtual CYExpression *Replace(CYContext &context);
 
1179     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1186     CYPropertyName *name_;
 
1187     CYExpression *value_;
 
1189     CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
 
1190         CYNext<CYProperty>(next),
 
1196     void Replace(CYContext &context);
 
1197     virtual void Output(CYOutput &out) const;
 
1200 struct CYDeclaration :
 
1203     CYIdentifier *identifier_;
 
1204     CYExpression *initialiser_;
 
1206     CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
 
1207         identifier_(identifier),
 
1208         initialiser_(initialiser)
 
1212     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
1213     virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
 
1215     virtual CYExpression *Replace(CYContext &context);
 
1217     virtual CYAssignment *Assignment(CYContext &context);
 
1218     CYVariable *Variable(CYContext &context);
 
1220     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1223 struct CYDeclarations :
 
1224     CYNext<CYDeclarations>,
 
1227     CYDeclaration *declaration_;
 
1229     CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
 
1230         CYNext<CYDeclarations>(next),
 
1231         declaration_(declaration)
 
1235     void Replace(CYContext &context);
 
1237     CYCompound *Compound(CYContext &context);
 
1238     CYProperty *Property(CYContext &context);
 
1239     CYArgument *Argument(CYContext &context);
 
1240     CYFunctionParameter *Parameter(CYContext &context);
 
1242     virtual void Output(CYOutput &out) const;
 
1243     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1246 struct CYForDeclarations :
 
1249     CYDeclarations *declarations_;
 
1251     CYForDeclarations(CYDeclarations *declarations) :
 
1252         declarations_(declarations)
 
1256     virtual CYCompound *Replace(CYContext &context);
 
1257     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1263     CYDeclarations *declarations_;
 
1265     CYVar(CYDeclarations *declarations) :
 
1266         declarations_(declarations)
 
1270     virtual CYStatement *Replace(CYContext &context);
 
1271     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1274 struct CYLetStatement :
 
1277     CYDeclarations *declarations_;
 
1280     CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
 
1281         declarations_(declarations),
 
1286     virtual CYStatement *Replace(CYContext &context);
 
1287     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1293     CYForInitialiser *initialiser_;
 
1294     CYExpression *test_;
 
1295     CYExpression *increment_;
 
1298     CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
 
1299         initialiser_(initialiser),
 
1301         increment_(increment),
 
1306     virtual CYStatement *Replace(CYContext &context);
 
1307     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1313     CYForInInitialiser *initialiser_;
 
1317     CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1318         initialiser_(initialiser),
 
1324     virtual CYStatement *Replace(CYContext &context);
 
1325     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1331     CYForInInitialiser *initialiser_;
 
1335     CYForOf(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1336         initialiser_(initialiser),
 
1342     virtual CYStatement *Replace(CYContext &context);
 
1343     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1349     CYProperty *properties_;
 
1351     CYObject(CYProperty *properties = NULL) :
 
1352         properties_(properties)
 
1356     virtual CYExpression *Replace(CYContext &context);
 
1357     void Output(CYOutput &out, CYFlags flags) const;
 
1363     CYExpression *object_;
 
1364     CYExpression *property_;
 
1366     CYMember(CYExpression *object, CYExpression *property) :
 
1372     void SetLeft(CYExpression *object) {
 
1377 struct CYDirectMember :
 
1380     CYDirectMember(CYExpression *object, CYExpression *property) :
 
1381         CYMember(object, property)
 
1388     virtual CYExpression *Replace(CYContext &context);
 
1389     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1392 struct CYIndirectMember :
 
1395     CYIndirectMember(CYExpression *object, CYExpression *property) :
 
1396         CYMember(object, property)
 
1403     virtual CYExpression *Replace(CYContext &context);
 
1404     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1413     CYExpression *constructor_;
 
1414     CYArgument *arguments_;
 
1416     New(CYExpression *constructor, CYArgument *arguments) :
 
1417         constructor_(constructor),
 
1418         arguments_(arguments)
 
1422     virtual unsigned Precedence() const {
 
1423         return arguments_ == NULL ? 2 : 1;
 
1428     virtual CYExpression *Replace(CYContext &context);
 
1429     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1431     virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
 
1439     CYExpression *function_;
 
1440     CYArgument *arguments_;
 
1442     CYCall(CYExpression *function, CYArgument *arguments = NULL) :
 
1443         function_(function),
 
1444         arguments_(arguments)
 
1451     virtual CYExpression *Replace(CYContext &context);
 
1452     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1454     virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
 
1459 struct CYRubyBlock :
 
1462     CYExpression *call_;
 
1465     CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
 
1474     virtual CYExpression *Replace(CYContext &context);
 
1475     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1481     CYExpression *test_;
 
1483     CYStatement *false_;
 
1485     CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
 
1492     virtual CYStatement *Replace(CYContext &context);
 
1493     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1499     CYExpression *test_;
 
1502     CYDoWhile(CYExpression *test, CYStatement *code) :
 
1508     virtual CYStatement *Replace(CYContext &context);
 
1509     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1515     CYExpression *test_;
 
1518     CYWhile(CYExpression *test, CYStatement *code) :
 
1524     virtual CYStatement *Replace(CYContext &context);
 
1525     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1528 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
 
1530     CYIdentifier *name_;
 
1531     CYFunctionParameter *parameters_;
 
1534     CYNonLocal *nonlocal_;
 
1537     CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1539         parameters_(parameters),
 
1545     virtual ~CYFunction() {
 
1548     void Inject(CYContext &context);
 
1549     virtual void Replace_(CYContext &context, bool outer);
 
1550     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1553 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
 
1554 struct CYFunctionExpression :
 
1558     CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1559         CYFunction(name, parameters, statements)
 
1566     virtual CYExpression *Replace(CYContext &context);
 
1567     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1570 // XXX: this should derive from CYAnonymousFunction
 
1575     CYFatArrow(CYFunctionParameter *parameters, CYStatement *statements) :
 
1576         CYFunction(NULL, parameters, statements)
 
1583     virtual CYExpression *Replace(CYContext &context);
 
1584     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1587 // XXX: this should derive from CYAnonymousFunctionExpression
 
1589     CYFunctionExpression
 
1591     CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
 
1592         CYFunctionExpression(NULL, parameters, statements)
 
1596     virtual CYExpression *Replace(CYContext &context);
 
1597     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1600 // XXX: this should derive from CYNamedFunction
 
1601 struct CYFunctionStatement :
 
1605     CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1606         CYFunction(name, parameters, statements)
 
1610     virtual CYStatement *Replace(CYContext &context);
 
1611     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1617     CYExpression *expression_;
 
1619     CYExpress(CYExpression *expression) :
 
1620         expression_(expression)
 
1622         if (expression == NULL)
 
1626     virtual CYStatement *Replace(CYContext &context);
 
1627     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1633     CYIdentifier *label_;
 
1635     CYContinue(CYIdentifier *label) :
 
1640     virtual CYStatement *Replace(CYContext &context);
 
1641     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1647     CYIdentifier *label_;
 
1649     CYBreak(CYIdentifier *label) :
 
1654     virtual CYStatement *Replace(CYContext &context);
 
1655     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1661     CYExpression *value_;
 
1663     CYReturn(CYExpression *value) :
 
1668     virtual CYStatement *Replace(CYContext &context);
 
1669     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1675     virtual CYStatement *Replace(CYContext &context);
 
1676     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1684     CYFinally(CYStatement *statements) :
 
1689     void Replace(CYContext &context);
 
1690     virtual void Output(CYOutput &out) const;
 
1699     CYIdentifier *name_;
 
1702     Catch(CYIdentifier *name, CYStatement *statements) :
 
1708     void Replace(CYContext &context);
 
1709     virtual void Output(CYOutput &out) const;
 
1717     CYFinally *finally_;
 
1719     Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
 
1726     virtual CYStatement *Replace(CYContext &context);
 
1727     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1733     CYExpression *value_;
 
1735     Throw(CYExpression *value = NULL) :
 
1740     virtual CYStatement *Replace(CYContext &context);
 
1741     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1749     CYExpression *scope_;
 
1752     CYWith(CYExpression *scope, CYStatement *code) :
 
1758     virtual CYStatement *Replace(CYContext &context);
 
1759     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1765     CYExpression *value_;
 
1768     CYSwitch(CYExpression *value, CYClause *clauses) :
 
1774     virtual CYStatement *Replace(CYContext &context);
 
1775     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1785     virtual CYStatement *Replace(CYContext &context);
 
1786     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1789 struct CYCondition :
 
1792     CYExpression *test_;
 
1793     CYExpression *true_;
 
1794     CYExpression *false_;
 
1796     CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
 
1805     virtual CYExpression *Replace(CYContext &context);
 
1806     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1809 struct CYAddressOf :
 
1812     CYAddressOf(CYExpression *rhs) :
 
1817     virtual const char *Operator() const {
 
1823     virtual CYExpression *Replace(CYContext &context);
 
1829     CYIndirect(CYExpression *rhs) :
 
1834     virtual const char *Operator() const {
 
1840     virtual CYExpression *Replace(CYContext &context);
 
1844     virtual CYExpression *Replace(CYContext &context);
 
1846 #define CYPostfix_(op, name, args...) \
 
1847     struct CY ## name : \
 
1850         CY ## name(CYExpression *lhs) : \
 
1855         virtual const char *Operator() const { \
 
1860 #define CYPrefix_(alphabetic, op, name, args...) \
 
1861     struct CY ## name : \
 
1864         CY ## name(CYExpression *rhs) : \
 
1869         CYAlphabetic(alphabetic) \
 
1871         virtual const char *Operator() const { \
 
1876 #define CYInfix_(alphabetic, precedence, op, name, args...) \
 
1877     struct CY ## name : \
 
1880         CY ## name(CYExpression *lhs, CYExpression *rhs) : \
 
1885         CYAlphabetic(alphabetic) \
 
1886         CYPrecedence(precedence) \
 
1888         virtual const char *Operator() const { \
 
1893 #define CYAssignment_(op, name, args...) \
 
1894     struct CY ## name ## Assign : \
 
1897         CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
 
1898             CYAssignment(lhs, rhs) \
 
1902         virtual const char *Operator() const { \
 
1907 CYPostfix_("++", PostIncrement)
 
1908 CYPostfix_("--", PostDecrement)
 
1910 CYPrefix_(true, "delete", Delete)
 
1911 CYPrefix_(true, "void", Void)
 
1912 CYPrefix_(true, "typeof", TypeOf)
 
1913 CYPrefix_(false, "++", PreIncrement)
 
1914 CYPrefix_(false, "--", PreDecrement)
 
1915 CYPrefix_(false, "+", Affirm)
 
1916 CYPrefix_(false, "-", Negate)
 
1917 CYPrefix_(false, "~", BitwiseNot)
 
1918 CYPrefix_(false, "!", LogicalNot)
 
1920 CYInfix_(false, 5, "*", Multiply)
 
1921 CYInfix_(false, 5, "/", Divide)
 
1922 CYInfix_(false, 5, "%", Modulus)
 
1923 CYInfix_(false, 6, "+", Add, CYReplace)
 
1924 CYInfix_(false, 6, "-", Subtract)
 
1925 CYInfix_(false, 7, "<<", ShiftLeft)
 
1926 CYInfix_(false, 7, ">>", ShiftRightSigned)
 
1927 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
 
1928 CYInfix_(false, 8, "<", Less)
 
1929 CYInfix_(false, 8, ">", Greater)
 
1930 CYInfix_(false, 8, "<=", LessOrEqual)
 
1931 CYInfix_(false, 8, ">=", GreaterOrEqual)
 
1932 CYInfix_(true, 8, "instanceof", InstanceOf)
 
1933 CYInfix_(true, 8, "in", In)
 
1934 CYInfix_(false, 9, "==", Equal)
 
1935 CYInfix_(false, 9, "!=", NotEqual)
 
1936 CYInfix_(false, 9, "===", Identical)
 
1937 CYInfix_(false, 9, "!==", NotIdentical)
 
1938 CYInfix_(false, 10, "&", BitwiseAnd)
 
1939 CYInfix_(false, 11, "^", BitwiseXOr)
 
1940 CYInfix_(false, 12, "|", BitwiseOr)
 
1941 CYInfix_(false, 13, "&&", LogicalAnd)
 
1942 CYInfix_(false, 14, "||", LogicalOr)
 
1944 CYAssignment_("=", )
 
1945 CYAssignment_("*=", Multiply)
 
1946 CYAssignment_("/=", Divide)
 
1947 CYAssignment_("%=", Modulus)
 
1948 CYAssignment_("+=", Add)
 
1949 CYAssignment_("-=", Subtract)
 
1950 CYAssignment_("<<=", ShiftLeft)
 
1951 CYAssignment_(">>=", ShiftRightSigned)
 
1952 CYAssignment_(">>>=", ShiftRightUnsigned)
 
1953 CYAssignment_("&=", BitwiseAnd)
 
1954 CYAssignment_("^=", BitwiseXOr)
 
1955 CYAssignment_("|=", BitwiseOr)
 
1957 #endif/*CYCRIPT_PARSER_HPP*/