1 /* Cycript - Optimizing JavaScript Compiler/Runtime
 
   2  * Copyright (C) 2009-2012  Jay Freeman (saurik)
 
   5 /* GNU Lesser General Public License, Version 3 {{{ */
 
   7  * Cycript is free software: you can redistribute it and/or modify it under
 
   8  * the terms of the GNU Lesser General Public License as published by the
 
   9  * Free Software Foundation, either version 3 of the License, or (at your
 
  10  * option) any later version.
 
  12  * Cycript is distributed in the hope that it will be useful, but WITHOUT
 
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 
  15  * License for more details.
 
  17  * You should have received a copy of the GNU Lesser 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;
 
 358     CYIdentifierUsageVector rename_;
 
 360     CYNonLocal *nonlocal_;
 
 361     CYNonLocal *nextlocal_;
 
 364     CYContext(CYOptions &options) :
 
 373     virtual ~CYContext() {
 
 376     template <typename Type_>
 
 377     void ReplaceAll(Type_ *&values) {
 
 378         Type_ **last(&values);
 
 379         CYForEach (next, values) {
 
 380             Replace(*last = next);
 
 382                 last = &(*last)->next_;
 
 386     template <typename Type_>
 
 387     void Replace(Type_ *&value) {
 
 388         for (;;) if (value == NULL)
 
 391             Type_ *replace(value->Replace(*this));
 
 392             if (replace != value)
 
 398     void NonLocal(CYStatement *&statements);
 
 399     CYIdentifier *Unique();
 
 403     CYIdentifier *identifier_;
 
 410     CYIdentifier *Target(CYContext &context) {
 
 411         if (identifier_ == NULL)
 
 412             identifier_ = context.Unique();
 
 421     CYStatement *statements_;
 
 423     CYBlock(CYStatement *statements) :
 
 424         statements_(statements)
 
 428     operator CYStatement *() const {
 
 432     void AddPrev(CYStatement *statement) {
 
 433         CYSetLast(statement, statements_);
 
 434         statements_ = statement;
 
 437     virtual CYStatement *Replace(CYContext &context);
 
 439     virtual void Output(CYOutput &out) const;
 
 440     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 455     std::stack<bool> in_;
 
 469     std::string filename_;
 
 473         cy::location location_;
 
 474         std::string message_;
 
 477     typedef std::vector<Error> Errors;
 
 485         CYExpression *context_;
 
 487         Context(CYExpression *context) :
 
 492         typedef std::vector<CYWord *> Words;
 
 496     typedef std::vector<Context> Contexts;
 
 499     CYExpression *context_;
 
 511     void ScannerDestroy();
 
 514     CYDriver(const std::string &filename = "");
 
 517     Condition GetCondition();
 
 518     void SetCondition(Condition condition);
 
 520     void PushCondition(Condition condition);
 
 523     void Warning(const cy::location &location, const char *message);
 
 526 struct CYForInitialiser {
 
 527     virtual ~CYForInitialiser() {
 
 530     virtual CYExpression *Replace(CYContext &context) = 0;
 
 531     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 534 struct CYForInInitialiser {
 
 535     virtual ~CYForInInitialiser() {
 
 538     virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
 
 539     virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value) = 0;
 
 541     virtual CYExpression *Replace(CYContext &context) = 0;
 
 542     virtual CYAssignment *Assignment(CYContext &context) = 0;
 
 544     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 550 struct CYExpression :
 
 551     CYNext<CYExpression>,
 
 557     virtual unsigned Precedence() const = 0;
 
 559     virtual bool RightHand() const {
 
 563     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
 564     virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
 
 566     virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
 
 568     virtual void Output(CYOutput &out) const;
 
 569     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 
 570     void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
 
 572     virtual CYExpression *ClassName(CYContext &context, bool object);
 
 573     virtual void ClassName(CYOutput &out, bool object) const;
 
 575     virtual CYExpression *Replace(CYContext &context) = 0;
 
 576     virtual CYAssignment *Assignment(CYContext &context);
 
 578     virtual CYExpression *Primitive(CYContext &context) {
 
 582     virtual CYNumber *Number(CYContext &context) {
 
 586     virtual CYString *String(CYContext &context) {
 
 590     virtual const char *Word() const {
 
 595 #define CYAlphabetic(value) \
 
 596     virtual bool Alphabetic() const { \
 
 600 #define CYPrecedence(value) \
 
 601     static const unsigned Precedence_ = value; \
 
 602     virtual unsigned Precedence() const { \
 
 603         return Precedence_; \
 
 606 #define CYRightHand(value) \
 
 607     virtual bool RightHand() const { \
 
 614     CYExpression *expressions_;
 
 616     CYCompound(CYExpression *expressions = NULL) :
 
 617         expressions_(expressions)
 
 621     void AddPrev(CYExpression *expression) {
 
 622         CYSetLast(expression, expressions_);
 
 623         expressions_ = expression;
 
 628     virtual CYExpression *Replace(CYContext &context);
 
 629     void Output(CYOutput &out, CYFlags flags) const;
 
 631     virtual CYExpression *Primitive(CYContext &context);
 
 634 struct CYDeclaration;
 
 636 struct CYFunctionParameter :
 
 637     CYNext<CYFunctionParameter>,
 
 640     CYForInInitialiser *initialiser_;
 
 642     CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
 
 643         CYNext<CYFunctionParameter>(next),
 
 644         initialiser_(initialiser)
 
 648     void Replace(CYContext &context, CYBlock &code);
 
 649     void Output(CYOutput &out) const;
 
 652 struct CYComprehension :
 
 653     CYNext<CYComprehension>,
 
 656     CYComprehension(CYComprehension *next = NULL) :
 
 657         CYNext<CYComprehension>(next)
 
 661     virtual const char *Name() const = 0;
 
 663     virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
 
 664     CYFunctionParameter *Parameters(CYContext &context) const;
 
 665     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 666     virtual void Output(CYOutput &out) const = 0;
 
 669 struct CYForInComprehension :
 
 675     CYForInComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
 
 676         CYComprehension(next),
 
 682     virtual const char *Name() const {
 
 683         return name_->Word();
 
 686     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 687     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 688     virtual void Output(CYOutput &out) const;
 
 691 struct CYForOfComprehension :
 
 697     CYForOfComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
 
 698         CYComprehension(next),
 
 704     virtual const char *Name() const {
 
 705         return name_->Word();
 
 708     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 709     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 710     virtual void Output(CYOutput &out) const;
 
 713 struct CYIfComprehension :
 
 718     CYIfComprehension(CYExpression *test) :
 
 723     virtual const char *Name() const {
 
 727     virtual CYFunctionParameter *Parameter(CYContext &context) const;
 
 728     virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
 
 729     virtual void Output(CYOutput &out) const;
 
 732 struct CYArrayComprehension :
 
 735     CYExpression *expression_;
 
 736     CYComprehension *comprehensions_;
 
 738     CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
 
 739         expression_(expression),
 
 740         comprehensions_(comprehensions)
 
 746     virtual CYExpression *Replace(CYContext &context);
 
 747     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 760     virtual CYExpression *Replace(CYContext &context);
 
 774     CYRange(uint64_t lo, uint64_t hi) :
 
 779     bool operator [](uint8_t value) const {
 
 780         return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
 
 783     void operator()(uint8_t value) {
 
 786         (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
 
 790 extern CYRange DigitRange_;
 
 791 extern CYRange WordStartRange_;
 
 792 extern CYRange WordEndRange_;
 
 807     CYString(const char *value) :
 
 813     CYString(const char *value, size_t size) :
 
 819     CYString(const CYWord *word) :
 
 820         value_(word->Word()),
 
 821         size_(strlen(value_))
 
 825     const char *Value() const {
 
 829     virtual const char *Word() const;
 
 831     virtual CYNumber *Number(CYContext &context);
 
 832     virtual CYString *String(CYContext &context);
 
 834     CYString *Concat(CYContext &out, CYString *rhs) const;
 
 835     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 836     virtual void PropertyName(CYOutput &out) const;
 
 845     CYNumber(double value) :
 
 850     double Value() const {
 
 854     virtual CYNumber *Number(CYContext &context);
 
 855     virtual CYString *String(CYContext &context);
 
 857     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 858     virtual void PropertyName(CYOutput &out) const;
 
 866     CYRegEx(const char *value) :
 
 871     const char *Value() const {
 
 875     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 887     virtual CYNumber *Number(CYContext &context);
 
 888     virtual CYString *String(CYContext &context);
 
 890     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 902     virtual CYExpression *Replace(CYContext &context);
 
 903     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 909     virtual bool Value() const = 0;
 
 910     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 922     virtual bool Value() const {
 
 926     virtual CYNumber *Number(CYContext &context);
 
 927     virtual CYString *String(CYContext &context);
 
 939     virtual bool Value() const {
 
 943     virtual CYNumber *Number(CYContext &context);
 
 944     virtual CYString *String(CYContext &context);
 
 952     CYVariable(CYIdentifier *name) :
 
 957     CYVariable(const char *name) :
 
 958         name_(new($pool) CYIdentifier(name))
 
 965     virtual CYExpression *Replace(CYContext &context);
 
 966     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 974     CYPrefix(CYExpression *rhs) :
 
 979     virtual bool Alphabetic() const = 0;
 
 980     virtual const char *Operator() const = 0;
 
 984     virtual CYExpression *Replace(CYContext &context);
 
 985     virtual void Output(CYOutput &out, CYFlags flags) const;
 
 994     CYInfix(CYExpression *lhs, CYExpression *rhs) :
 
1000     void SetLeft(CYExpression *lhs) {
 
1004     virtual bool Alphabetic() const = 0;
 
1005     virtual const char *Operator() const = 0;
 
1007     virtual CYExpression *Replace(CYContext &context);
 
1008     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1016     CYPostfix(CYExpression *lhs) :
 
1021     virtual const char *Operator() const = 0;
 
1025     virtual CYExpression *Replace(CYContext &context);
 
1026     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1029 struct CYAssignment :
 
1035     CYAssignment(CYExpression *lhs, CYExpression *rhs) :
 
1041     void SetLeft(CYExpression *lhs) {
 
1045     virtual const char *Operator() const = 0;
 
1049     virtual CYExpression *Replace(CYContext &context);
 
1050     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1058     CYExpression *value_;
 
1060     CYArgument(CYExpression *value, CYArgument *next = NULL) :
 
1061         CYNext<CYArgument>(next),
 
1067     CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
 
1068         CYNext<CYArgument>(next),
 
1074     CYArgument *Replace(CYContext &context);
 
1075     void Output(CYOutput &out) const;
 
1091     CYExpression *case_;
 
1092     CYStatement *statements_;
 
1094     CYClause(CYExpression *_case, CYStatement *statements) :
 
1096         statements_(statements)
 
1100     void Replace(CYContext &context);
 
1101     virtual void Output(CYOutput &out) const;
 
1108     CYExpression *value_;
 
1110     CYElement(CYExpression *value, CYElement *next) :
 
1111         CYNext<CYElement>(next),
 
1116     void Replace(CYContext &context);
 
1117     void Output(CYOutput &out) const;
 
1123     CYElement *elements_;
 
1125     CYArray(CYElement *elements = NULL) :
 
1130     virtual CYExpression *Replace(CYContext &context);
 
1131     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1138     CYPropertyName *name_;
 
1139     CYExpression *value_;
 
1141     CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
 
1142         CYNext<CYProperty>(next),
 
1148     void Replace(CYContext &context);
 
1149     virtual void Output(CYOutput &out) const;
 
1152 struct CYDeclaration :
 
1155     CYIdentifier *identifier_;
 
1156     CYExpression *initialiser_;
 
1158     CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
 
1159         identifier_(identifier),
 
1160         initialiser_(initialiser)
 
1164     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
1165     virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
 
1167     virtual CYExpression *Replace(CYContext &context);
 
1169     virtual CYAssignment *Assignment(CYContext &context);
 
1170     CYVariable *Variable(CYContext &context);
 
1172     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1175 struct CYDeclarations :
 
1176     CYNext<CYDeclarations>,
 
1179     CYDeclaration *declaration_;
 
1181     CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
 
1182         CYNext<CYDeclarations>(next),
 
1183         declaration_(declaration)
 
1187     void Replace(CYContext &context);
 
1189     CYCompound *Compound(CYContext &context);
 
1190     CYProperty *Property(CYContext &context);
 
1191     CYArgument *Argument(CYContext &context);
 
1192     CYFunctionParameter *Parameter(CYContext &context);
 
1194     virtual void Output(CYOutput &out) const;
 
1195     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1198 struct CYForDeclarations :
 
1201     CYDeclarations *declarations_;
 
1203     CYForDeclarations(CYDeclarations *declarations) :
 
1204         declarations_(declarations)
 
1208     virtual CYCompound *Replace(CYContext &context);
 
1209     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1215     CYDeclarations *declarations_;
 
1217     CYVar(CYDeclarations *declarations) :
 
1218         declarations_(declarations)
 
1222     virtual CYStatement *Replace(CYContext &context);
 
1223     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1226 struct CYLetStatement :
 
1229     CYDeclarations *declarations_;
 
1232     CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
 
1233         declarations_(declarations),
 
1238     virtual CYStatement *Replace(CYContext &context);
 
1239     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1245     CYForInitialiser *initialiser_;
 
1246     CYExpression *test_;
 
1247     CYExpression *increment_;
 
1250     CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
 
1251         initialiser_(initialiser),
 
1253         increment_(increment),
 
1258     virtual CYStatement *Replace(CYContext &context);
 
1259     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1265     CYForInInitialiser *initialiser_;
 
1269     CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1270         initialiser_(initialiser),
 
1276     virtual CYStatement *Replace(CYContext &context);
 
1277     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1283     CYForInInitialiser *initialiser_;
 
1287     CYForOf(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
 
1288         initialiser_(initialiser),
 
1294     virtual CYStatement *Replace(CYContext &context);
 
1295     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1301     CYProperty *properties_;
 
1303     CYObject(CYProperty *properties = NULL) :
 
1304         properties_(properties)
 
1308     virtual CYExpression *Replace(CYContext &context);
 
1309     void Output(CYOutput &out, CYFlags flags) const;
 
1315     CYExpression *object_;
 
1316     CYExpression *property_;
 
1318     CYMember(CYExpression *object, CYExpression *property) :
 
1324     void SetLeft(CYExpression *object) {
 
1329 struct CYDirectMember :
 
1332     CYDirectMember(CYExpression *object, CYExpression *property) :
 
1333         CYMember(object, property)
 
1340     virtual CYExpression *Replace(CYContext &context);
 
1341     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1344 struct CYIndirectMember :
 
1347     CYIndirectMember(CYExpression *object, CYExpression *property) :
 
1348         CYMember(object, property)
 
1355     virtual CYExpression *Replace(CYContext &context);
 
1356     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1365     CYExpression *constructor_;
 
1366     CYArgument *arguments_;
 
1368     New(CYExpression *constructor, CYArgument *arguments) :
 
1369         constructor_(constructor),
 
1370         arguments_(arguments)
 
1374     virtual unsigned Precedence() const {
 
1375         return arguments_ == NULL ? 2 : 1;
 
1380     virtual CYExpression *Replace(CYContext &context);
 
1381     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1383     virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
 
1391     CYExpression *function_;
 
1392     CYArgument *arguments_;
 
1394     CYCall(CYExpression *function, CYArgument *arguments = NULL) :
 
1395         function_(function),
 
1396         arguments_(arguments)
 
1403     virtual CYExpression *Replace(CYContext &context);
 
1404     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1406     virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
 
1411 struct CYRubyBlock :
 
1414     CYExpression *call_;
 
1417     CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
 
1426     virtual CYExpression *Replace(CYContext &context);
 
1427     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1433     CYExpression *test_;
 
1435     CYStatement *false_;
 
1437     CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
 
1444     virtual CYStatement *Replace(CYContext &context);
 
1445     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1451     CYExpression *test_;
 
1454     CYDoWhile(CYExpression *test, CYStatement *code) :
 
1460     virtual CYStatement *Replace(CYContext &context);
 
1461     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1467     CYExpression *test_;
 
1470     CYWhile(CYExpression *test, CYStatement *code) :
 
1476     virtual CYStatement *Replace(CYContext &context);
 
1477     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1480 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
 
1482     CYIdentifier *name_;
 
1483     CYFunctionParameter *parameters_;
 
1485     CYNonLocal *nonlocal_;
 
1487     CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1489         parameters_(parameters),
 
1495     virtual ~CYFunction() {
 
1498     void Inject(CYContext &context);
 
1499     virtual void Replace_(CYContext &context, bool outer);
 
1500     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1503 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
 
1504 struct CYFunctionExpression :
 
1508     CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1509         CYFunction(name, parameters, statements)
 
1516     virtual CYExpression *Replace(CYContext &context);
 
1517     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1520 // XXX: this should derive from CYAnonymousFunctionExpression
 
1522     CYFunctionExpression
 
1524     CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
 
1525         CYFunctionExpression(NULL, parameters, statements)
 
1529     virtual CYExpression *Replace(CYContext &context);
 
1530     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1533 // XXX: this should derive from CYNamedFunction
 
1534 struct CYFunctionStatement :
 
1538     CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
 
1539         CYFunction(name, parameters, statements)
 
1543     virtual CYStatement *Replace(CYContext &context);
 
1544     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1550     CYExpression *expression_;
 
1552     CYExpress(CYExpression *expression) :
 
1553         expression_(expression)
 
1555         if (expression == NULL)
 
1559     virtual CYStatement *Replace(CYContext &context);
 
1560     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1566     CYIdentifier *label_;
 
1568     CYContinue(CYIdentifier *label) :
 
1573     virtual CYStatement *Replace(CYContext &context);
 
1574     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1580     CYIdentifier *label_;
 
1582     CYBreak(CYIdentifier *label) :
 
1587     virtual CYStatement *Replace(CYContext &context);
 
1588     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1594     CYExpression *value_;
 
1596     CYReturn(CYExpression *value) :
 
1601     virtual CYStatement *Replace(CYContext &context);
 
1602     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1608     virtual CYStatement *Replace(CYContext &context);
 
1609     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1617     CYFinally(CYStatement *statements) :
 
1622     void Replace(CYContext &context);
 
1623     virtual void Output(CYOutput &out) const;
 
1632     CYIdentifier *name_;
 
1635     Catch(CYIdentifier *name, CYStatement *statements) :
 
1641     void Replace(CYContext &context);
 
1642     virtual void Output(CYOutput &out) const;
 
1650     CYFinally *finally_;
 
1652     Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
 
1659     virtual CYStatement *Replace(CYContext &context);
 
1660     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1666     CYExpression *value_;
 
1668     Throw(CYExpression *value = NULL) :
 
1673     virtual CYStatement *Replace(CYContext &context);
 
1674     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1682     CYExpression *scope_;
 
1685     CYWith(CYExpression *scope, CYStatement *code) :
 
1691     virtual CYStatement *Replace(CYContext &context);
 
1692     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1698     CYExpression *value_;
 
1701     CYSwitch(CYExpression *value, CYClause *clauses) :
 
1707     virtual CYStatement *Replace(CYContext &context);
 
1708     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1718     virtual CYStatement *Replace(CYContext &context);
 
1719     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1722 struct CYCondition :
 
1725     CYExpression *test_;
 
1726     CYExpression *true_;
 
1727     CYExpression *false_;
 
1729     CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
 
1738     virtual CYExpression *Replace(CYContext &context);
 
1739     virtual void Output(CYOutput &out, CYFlags flags) const;
 
1742 struct CYAddressOf :
 
1745     CYAddressOf(CYExpression *rhs) :
 
1750     virtual const char *Operator() const {
 
1756     virtual CYExpression *Replace(CYContext &context);
 
1762     CYIndirect(CYExpression *rhs) :
 
1767     virtual const char *Operator() const {
 
1773     virtual CYExpression *Replace(CYContext &context);
 
1777     virtual CYExpression *Replace(CYContext &context);
 
1779 #define CYPostfix_(op, name, args...) \
 
1780     struct CY ## name : \
 
1783         CY ## name(CYExpression *lhs) : \
 
1788         virtual const char *Operator() const { \
 
1793 #define CYPrefix_(alphabetic, op, name, args...) \
 
1794     struct CY ## name : \
 
1797         CY ## name(CYExpression *rhs) : \
 
1802         CYAlphabetic(alphabetic) \
 
1804         virtual const char *Operator() const { \
 
1809 #define CYInfix_(alphabetic, precedence, op, name, args...) \
 
1810     struct CY ## name : \
 
1813         CY ## name(CYExpression *lhs, CYExpression *rhs) : \
 
1818         CYAlphabetic(alphabetic) \
 
1819         CYPrecedence(precedence) \
 
1821         virtual const char *Operator() const { \
 
1826 #define CYAssignment_(op, name, args...) \
 
1827     struct CY ## name ## Assign : \
 
1830         CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
 
1831             CYAssignment(lhs, rhs) \
 
1835         virtual const char *Operator() const { \
 
1840 CYPostfix_("++", PostIncrement)
 
1841 CYPostfix_("--", PostDecrement)
 
1843 CYPrefix_(true, "delete", Delete)
 
1844 CYPrefix_(true, "void", Void)
 
1845 CYPrefix_(true, "typeof", TypeOf)
 
1846 CYPrefix_(false, "++", PreIncrement)
 
1847 CYPrefix_(false, "--", PreDecrement)
 
1848 CYPrefix_(false, "+", Affirm)
 
1849 CYPrefix_(false, "-", Negate)
 
1850 CYPrefix_(false, "~", BitwiseNot)
 
1851 CYPrefix_(false, "!", LogicalNot)
 
1853 CYInfix_(false, 5, "*", Multiply)
 
1854 CYInfix_(false, 5, "/", Divide)
 
1855 CYInfix_(false, 5, "%", Modulus)
 
1856 CYInfix_(false, 6, "+", Add, CYReplace)
 
1857 CYInfix_(false, 6, "-", Subtract)
 
1858 CYInfix_(false, 7, "<<", ShiftLeft)
 
1859 CYInfix_(false, 7, ">>", ShiftRightSigned)
 
1860 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
 
1861 CYInfix_(false, 8, "<", Less)
 
1862 CYInfix_(false, 8, ">", Greater)
 
1863 CYInfix_(false, 8, "<=", LessOrEqual)
 
1864 CYInfix_(false, 8, ">=", GreaterOrEqual)
 
1865 CYInfix_(true, 8, "instanceof", InstanceOf)
 
1866 CYInfix_(true, 8, "in", In)
 
1867 CYInfix_(false, 9, "==", Equal)
 
1868 CYInfix_(false, 9, "!=", NotEqual)
 
1869 CYInfix_(false, 9, "===", Identical)
 
1870 CYInfix_(false, 9, "!==", NotIdentical)
 
1871 CYInfix_(false, 10, "&", BitwiseAnd)
 
1872 CYInfix_(false, 11, "^", BitwiseXOr)
 
1873 CYInfix_(false, 12, "|", BitwiseOr)
 
1874 CYInfix_(false, 13, "&&", LogicalAnd)
 
1875 CYInfix_(false, 14, "||", LogicalOr)
 
1877 CYAssignment_("=", )
 
1878 CYAssignment_("*=", Multiply)
 
1879 CYAssignment_("/=", Divide)
 
1880 CYAssignment_("%=", Modulus)
 
1881 CYAssignment_("+=", Add)
 
1882 CYAssignment_("-=", Subtract)
 
1883 CYAssignment_("<<=", ShiftLeft)
 
1884 CYAssignment_(">>=", ShiftRightSigned)
 
1885 CYAssignment_(">>>=", ShiftRightUnsigned)
 
1886 CYAssignment_("&=", BitwiseAnd)
 
1887 CYAssignment_("^=", BitwiseXOr)
 
1888 CYAssignment_("|=", BitwiseOr)
 
1890 #endif/*CYCRIPT_PARSER_HPP*/