1 /* Cycript - Inlining/Optimizing JavaScript Compiler
2 * Copyright (C) 2009 Jay Freeman (saurik)
5 /* Modified BSD License {{{ */
7 * Redistribution and use in source and binary
8 * forms, with or without modification, are permitted
9 * provided that the following conditions are met:
11 * 1. Redistributions of source code must retain the
12 * above copyright notice, this list of conditions
13 * and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the
15 * above copyright notice, this list of conditions
16 * and the following disclaimer in the documentation
17 * and/or other materials provided with the
19 * 3. The name of the author may not be used to endorse
20 * or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
25 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 // XXX: wtf is this here?!
55 #include "location.hh"
56 #include "Pooling.hpp"
57 #include "Options.hpp"
61 template <typename Type_>
75 void SetNext(Type_ *next) {
84 virtual void Output(struct CYOutput &out) const = 0;
102 CYOutput(std::ostream &out, CYOptions &options) :
112 void Check(char value);
115 CYOutput &operator <<(char rhs);
116 CYOutput &operator <<(const char *rhs);
118 _finline CYOutput &operator <<(const CYThing *rhs) {
124 _finline CYOutput &operator <<(const CYThing &rhs) {
130 struct CYPropertyName {
131 virtual void PropertyName(CYOutput &out) const = 0;
133 virtual ~CYPropertyName() {
147 CYNoBrace = (1 << 0),
148 CYNoFunction = (1 << 1),
151 CYNoRightHand = (1 << 4),
152 CYNoDangle = (1 << 5),
153 CYNoInteger = (1 << 6),
154 CYNoBF = (CYNoBrace | CYNoFunction),
160 virtual ~CYStatement() {
163 void Single(CYOutput &out, CYFlags flags) const;
164 void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
166 CYStatement *ReplaceAll(CYContext &context);
167 virtual CYStatement *Collapse(CYContext &context);
169 virtual CYStatement *Replace(CYContext &context) = 0;
172 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
175 struct CYStatements {
185 operator CYStatement *() const {
189 CYStatements &operator ->*(CYStatement *next) {
191 if (first_ == NULL) {
194 } else for (;; last_ = last_->next_)
195 if (last_->next_ == NULL) {
205 virtual ~CYClassName() {
208 virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
209 virtual void ClassName(CYOutput &out, bool object) const = 0;
219 CYWord(const char *word) :
224 void Set(const char *value) {
228 virtual const char *Word() const;
229 virtual void Output(CYOutput &out) const;
231 virtual CYExpression *ClassName(CYContext &context, bool object);
232 virtual void ClassName(CYOutput &out, bool object) const;
233 virtual void PropertyName(CYOutput &out) const;
236 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
238 return lhs << rhs.Word();
241 struct CYIdentifier :
242 CYNext<CYIdentifier>,
245 CYIdentifier *replace_;
247 CYIdentifier(const char *word) :
253 virtual const char *Word() const;
254 CYIdentifier *Replace(CYContext &context);
262 CYComment(const char *value) :
267 virtual CYStatement *Replace(CYContext &context);
268 virtual void Output(CYOutput &out, CYFlags flags) const;
275 CYStatement *statement_;
277 CYLabel(CYIdentifier *name, CYStatement *statement) :
279 statement_(statement)
283 virtual CYStatement *Replace(CYContext &context);
284 virtual void Output(CYOutput &out, CYFlags flags) const;
287 struct CYCStringLess :
288 std::binary_function<const char *, const char *, bool>
290 _finline bool operator ()(const char *lhs, const char *rhs) const {
291 return strcmp(lhs, rhs) < 0;
295 struct CYIdentifierValueLess :
296 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
298 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
299 return CYCStringLess()(lhs->Word(), rhs->Word());
303 enum CYIdentifierFlags {
304 CYIdentifierArgument,
305 CYIdentifierVariable,
310 typedef std::set<const char *, CYCStringLess> CYCStringSet;
311 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
312 typedef std::set<CYIdentifier *> CYIdentifierAddressSet;
313 typedef std::vector<CYIdentifier *> CYIdentifierAddressVector;
314 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
318 CYIdentifierAddressFlagsMap internal_;
320 CYIdentifierValueSet identifiers_;
329 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
330 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
331 void Merge(CYContext &context, CYIdentifierAddressVector &external);
332 void Scope(CYContext &context, CYStatement *&statements);
339 CYStatement *statements_;
340 CYIdentifierAddressVector rename_;
341 CYCStringSet external_;
343 CYProgram(CYStatement *statements) :
344 statements_(statements)
348 virtual void Replace(CYContext &context);
349 virtual void Output(CYOutput &out) const;
356 CYStatement *statements_;
359 CYBlock(CYStatement *statements, CYScope *scope = NULL) :
360 statements_(statements),
365 operator CYStatement *() const {
369 void AddPrev(CYStatement *statement) {
370 CYStatement *last(statement);
371 while (last->next_ != NULL)
373 last->SetNext(statements_);
374 statements_ = statement;
377 virtual CYStatement *Replace(CYContext &context);
379 virtual void Output(CYOutput &out) const;
380 virtual void Output(CYOutput &out, CYFlags flags) const;
408 std::string filename_;
412 cy::location location_;
413 std::string message_;
416 typedef std::vector<Error> Errors;
423 void ScannerDestroy();
426 CYDriver(const std::string &filename);
429 Condition GetCondition();
430 void SetCondition(Condition condition);
432 void PushCondition(Condition condition);
435 void Warning(const cy::location &location, const char *message);
438 struct CYForInitialiser {
439 virtual ~CYForInitialiser() {
442 virtual void For(CYOutput &out) const = 0;
443 virtual CYExpression *Replace(CYContext &context) = 0;
446 struct CYForInInitialiser {
447 virtual ~CYForInInitialiser() {
450 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
451 virtual const char *ForEachIn() const = 0;
452 virtual CYExpression *ForEachIn(CYContext &out) = 0;
453 virtual CYExpression *Replace(CYContext &context) = 0;
459 struct CYExpression :
460 CYNext<CYExpression>,
466 virtual unsigned Precedence() const = 0;
468 virtual bool RightHand() const {
472 virtual void For(CYOutput &out) const;
473 virtual void ForIn(CYOutput &out, CYFlags flags) const;
475 virtual const char *ForEachIn() const;
476 virtual CYExpression *ForEachIn(CYContext &out);
478 virtual void Output(CYOutput &out) const;
479 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
480 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
482 virtual CYExpression *ClassName(CYContext &context, bool object);
483 virtual void ClassName(CYOutput &out, bool object) const;
485 CYExpression *ReplaceAll(CYContext &context);
487 virtual CYExpression *Replace(CYContext &context) = 0;
489 virtual CYExpression *Primitive(CYContext &context) {
493 virtual CYNumber *Number(CYContext &context) {
497 virtual CYString *String(CYContext &context) {
501 virtual const char *Word() const {
506 #define CYAlphabetic(value) \
507 virtual bool Alphabetic() const { \
511 #define CYPrecedence(value) \
512 virtual unsigned Precedence() const { \
516 #define CYRightHand(value) \
517 virtual bool RightHand() const { \
524 CYExpression *expressions_;
526 CYCompound(CYExpression *expressions = NULL) :
527 expressions_(expressions)
531 void AddPrev(CYExpression *expression) {
532 CYExpression *last(expression);
533 while (last->next_ != NULL)
535 last->SetNext(expressions_);
536 expressions_ = expression;
541 virtual CYExpression *Replace(CYContext &context);
542 void Output(CYOutput &out, CYFlags flags) const;
545 struct CYFunctionParameter :
546 CYNext<CYFunctionParameter>,
551 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
552 CYNext<CYFunctionParameter>(next),
557 void Replace(CYContext &context);
558 virtual void Output(CYOutput &out) const;
561 struct CYComprehension :
562 CYNext<CYComprehension>,
565 virtual const char *Name() const = 0;
567 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
568 CYFunctionParameter *Parameters(CYContext &context) const;
569 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
570 virtual void Output(CYOutput &out) const = 0;
573 struct CYForInComprehension :
579 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
585 virtual const char *Name() const {
586 return name_->Word();
589 virtual CYFunctionParameter *Parameter(CYContext &context) const;
590 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
591 virtual void Output(CYOutput &out) const;
594 struct CYForEachInComprehension :
600 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
606 virtual const char *Name() const {
607 return name_->Word();
610 virtual CYFunctionParameter *Parameter(CYContext &context) const;
611 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
612 virtual void Output(CYOutput &out) const;
615 struct CYIfComprehension :
620 CYIfComprehension(CYExpression *test) :
625 virtual const char *Name() const {
629 virtual CYFunctionParameter *Parameter(CYContext &context) const;
630 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
631 virtual void Output(CYOutput &out) const;
634 struct CYArrayComprehension :
637 CYExpression *expression_;
638 CYComprehension *comprehensions_;
640 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
641 expression_(expression),
642 comprehensions_(comprehensions)
648 virtual CYExpression *Replace(CYContext &context);
649 virtual void Output(CYOutput &out, CYFlags flags) const;
662 virtual CYExpression *Replace(CYContext &context);
676 CYRange(uint64_t lo, uint64_t hi) :
681 bool operator [](uint8_t value) const {
682 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
685 void operator()(uint8_t value) {
688 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
692 extern CYRange DigitRange_;
693 extern CYRange WordStartRange_;
694 extern CYRange WordEndRange_;
709 CYString(const char *value) :
715 CYString(const char *value, size_t size) :
721 CYString(const CYWord *word) :
722 value_(word->Word()),
723 size_(strlen(value_))
727 const char *Value() const {
731 virtual const char *Word() const;
733 virtual CYNumber *Number(CYContext &context);
734 virtual CYString *String(CYContext &context);
736 CYString *Concat(CYContext &out, CYString *rhs) const;
737 virtual void Output(CYOutput &out, CYFlags flags) const;
738 virtual void PropertyName(CYOutput &out) const;
747 CYNumber(double value) :
752 double Value() const {
756 virtual CYNumber *Number(CYContext &context);
757 virtual CYString *String(CYContext &context);
759 virtual void Output(CYOutput &out, CYFlags flags) const;
760 virtual void PropertyName(CYOutput &out) const;
768 CYRegEx(const char *value) :
773 const char *Value() const {
777 virtual void Output(CYOutput &out, CYFlags flags) const;
789 virtual CYNumber *Number(CYContext &context);
790 virtual CYString *String(CYContext &context);
792 virtual void Output(CYOutput &out, CYFlags flags) const;
804 virtual CYExpression *Replace(CYContext &context);
805 virtual void Output(CYOutput &out, CYFlags flags) const;
811 virtual bool Value() const = 0;
812 virtual void Output(CYOutput &out, CYFlags flags) const;
824 virtual bool Value() const {
828 virtual CYNumber *Number(CYContext &context);
829 virtual CYString *String(CYContext &context);
841 virtual bool Value() const {
845 virtual CYNumber *Number(CYContext &context);
846 virtual CYString *String(CYContext &context);
854 CYVariable(CYIdentifier *name) :
862 virtual CYExpression *Replace(CYContext &context);
863 virtual void Output(CYOutput &out, CYFlags flags) const;
871 CYPrefix(CYExpression *rhs) :
876 virtual bool Alphabetic() const = 0;
877 virtual const char *Operator() const = 0;
881 virtual CYExpression *Replace(CYContext &context);
882 virtual void Output(CYOutput &out, CYFlags flags) const;
891 CYInfix(CYExpression *lhs, CYExpression *rhs) :
897 void SetLeft(CYExpression *lhs) {
901 virtual bool Alphabetic() const = 0;
902 virtual const char *Operator() const = 0;
904 virtual CYExpression *Replace(CYContext &context);
905 virtual void Output(CYOutput &out, CYFlags flags) const;
913 CYPostfix(CYExpression *lhs) :
918 virtual const char *Operator() const = 0;
922 virtual CYExpression *Replace(CYContext &context);
923 virtual void Output(CYOutput &out, CYFlags flags) const;
926 struct CYAssignment :
932 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
938 void SetLeft(CYExpression *lhs) {
942 virtual const char *Operator() const = 0;
946 virtual CYExpression *Replace(CYContext &context);
947 virtual void Output(CYOutput &out, CYFlags flags) const;
955 CYExpression *value_;
957 CYArgument(CYExpression *value, CYArgument *next = NULL) :
958 CYNext<CYArgument>(next),
964 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
965 CYNext<CYArgument>(next),
971 void Replace(CYContext &context);
972 void Output(CYOutput &out) const;
989 CYStatement *statements_;
991 CYClause(CYExpression *_case, CYStatement *statements) :
993 statements_(statements)
997 void Replace(CYContext &context);
998 virtual void Output(CYOutput &out) const;
1005 CYExpression *value_;
1007 CYElement(CYExpression *value, CYElement *next) :
1008 CYNext<CYElement>(next),
1013 void Replace(CYContext &context);
1014 void Output(CYOutput &out) const;
1020 CYElement *elements_;
1022 CYArray(CYElement *elements = NULL) :
1027 virtual CYExpression *Replace(CYContext &context);
1028 virtual void Output(CYOutput &out, CYFlags flags) const;
1035 CYPropertyName *name_;
1036 CYExpression *value_;
1038 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1039 CYNext<CYProperty>(next),
1045 void Replace(CYContext &context);
1046 virtual void Output(CYOutput &out) const;
1049 struct CYDeclaration :
1052 CYIdentifier *identifier_;
1053 CYExpression *initialiser_;
1055 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1056 identifier_(identifier),
1057 initialiser_(initialiser)
1061 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1063 virtual const char *ForEachIn() const;
1064 virtual CYExpression *ForEachIn(CYContext &out);
1066 virtual CYExpression *Replace(CYContext &context);
1067 virtual CYAssignment *Assignment(CYContext &context);
1069 virtual void Output(CYOutput &out, CYFlags flags) const;
1072 struct CYDeclarations :
1073 CYNext<CYDeclarations>,
1077 CYDeclaration *declaration_;
1079 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1080 CYNext<CYDeclarations>(next),
1081 declaration_(declaration)
1085 virtual void For(CYOutput &out) const;
1087 virtual CYCompound *Replace(CYContext &context);
1088 CYProperty *Property(CYContext &context);
1090 virtual void Output(CYOutput &out) const;
1091 virtual void Output(CYOutput &out, CYFlags flags) const;
1097 CYDeclarations *declarations_;
1099 CYVar(CYDeclarations *declarations) :
1100 declarations_(declarations)
1104 virtual CYStatement *Replace(CYContext &context);
1105 virtual void Output(CYOutput &out, CYFlags flags) const;
1111 CYDeclarations *declarations_;
1114 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1115 declarations_(declarations),
1120 virtual CYStatement *Replace(CYContext &context);
1121 virtual void Output(CYOutput &out, CYFlags flags) const;
1127 CYForInitialiser *initialiser_;
1128 CYExpression *test_;
1129 CYExpression *increment_;
1132 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1133 initialiser_(initialiser),
1135 increment_(increment),
1140 virtual CYStatement *Replace(CYContext &context);
1141 virtual void Output(CYOutput &out, CYFlags flags) const;
1147 CYForInInitialiser *initialiser_;
1151 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1152 initialiser_(initialiser),
1158 virtual CYStatement *Replace(CYContext &context);
1159 virtual void Output(CYOutput &out, CYFlags flags) const;
1162 struct CYForEachIn :
1165 CYForInInitialiser *initialiser_;
1169 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1170 initialiser_(initialiser),
1176 virtual CYStatement *Replace(CYContext &context);
1177 virtual void Output(CYOutput &out, CYFlags flags) const;
1183 CYProperty *properties_;
1185 CYObject(CYProperty *properties) :
1186 properties_(properties)
1190 virtual CYExpression *Replace(CYContext &context);
1191 void Output(CYOutput &out, CYFlags flags) const;
1197 CYExpression *object_;
1198 CYExpression *property_;
1200 CYMember(CYExpression *object, CYExpression *property) :
1206 void SetLeft(CYExpression *object) {
1210 void Replace_(CYContext &context);
1213 struct CYDirectMember :
1216 CYDirectMember(CYExpression *object, CYExpression *property) :
1217 CYMember(object, property)
1224 virtual CYExpression *Replace(CYContext &context);
1225 virtual void Output(CYOutput &out, CYFlags flags) const;
1228 struct CYIndirectMember :
1231 CYIndirectMember(CYExpression *object, CYExpression *property) :
1232 CYMember(object, property)
1239 virtual CYExpression *Replace(CYContext &context);
1240 virtual void Output(CYOutput &out, CYFlags flags) const;
1246 CYExpression *constructor_;
1247 CYArgument *arguments_;
1249 CYNew(CYExpression *constructor, CYArgument *arguments) :
1250 constructor_(constructor),
1251 arguments_(arguments)
1255 virtual unsigned Precedence() const {
1256 return arguments_ == NULL ? 2 : 1;
1261 virtual CYExpression *Replace(CYContext &context);
1262 virtual void Output(CYOutput &out, CYFlags flags) const;
1268 CYExpression *function_;
1269 CYArgument *arguments_;
1271 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1272 function_(function),
1273 arguments_(arguments)
1280 virtual CYExpression *Replace(CYContext &context);
1281 virtual void Output(CYOutput &out, CYFlags flags) const;
1287 CYExpression *test_;
1289 CYStatement *false_;
1291 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1298 virtual CYStatement *Replace(CYContext &context);
1299 virtual void Output(CYOutput &out, CYFlags flags) const;
1305 CYExpression *test_;
1308 CYDoWhile(CYExpression *test, CYStatement *code) :
1314 virtual CYStatement *Replace(CYContext &context);
1315 virtual void Output(CYOutput &out, CYFlags flags) const;
1321 CYExpression *test_;
1324 CYWhile(CYExpression *test, CYStatement *code) :
1330 virtual CYStatement *Replace(CYContext &context);
1331 virtual void Output(CYOutput &out, CYFlags flags) const;
1337 CYIdentifier *name_;
1338 CYFunctionParameter *parameters_;
1341 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1343 parameters_(parameters),
1344 code_(statements, this)
1348 virtual ~CYFunction() {
1351 void Inject(CYContext &context);
1352 virtual void Replace_(CYContext &context, bool outer);
1353 virtual void Output(CYOutput &out, CYFlags flags) const;
1356 struct CYFunctionExpression :
1360 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1361 CYFunction(name, parameters, statements)
1368 virtual CYExpression *Replace(CYContext &context);
1369 virtual void Output(CYOutput &out, CYFlags flags) const;
1372 struct CYFunctionStatement :
1376 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1377 CYFunction(name, parameters, statements)
1381 virtual CYStatement *Replace(CYContext &context);
1382 virtual void Output(CYOutput &out, CYFlags flags) const;
1388 CYExpression *expression_;
1390 CYExpress(CYExpression *expression) :
1391 expression_(expression)
1393 if (expression == NULL)
1397 virtual CYStatement *Collapse(CYContext &context);
1398 virtual CYStatement *Replace(CYContext &context);
1399 virtual void Output(CYOutput &out, CYFlags flags) const;
1405 CYIdentifier *label_;
1407 CYContinue(CYIdentifier *label) :
1412 virtual CYStatement *Replace(CYContext &context);
1413 virtual void Output(CYOutput &out, CYFlags flags) const;
1419 CYIdentifier *label_;
1421 CYBreak(CYIdentifier *label) :
1426 virtual CYStatement *Replace(CYContext &context);
1427 virtual void Output(CYOutput &out, CYFlags flags) const;
1433 CYExpression *value_;
1435 CYReturn(CYExpression *value) :
1440 virtual CYStatement *Replace(CYContext &context);
1441 virtual void Output(CYOutput &out, CYFlags flags) const;
1447 virtual CYStatement *Collapse(CYContext &context);
1448 virtual CYStatement *Replace(CYContext &context);
1449 virtual void Output(CYOutput &out, CYFlags flags) const;
1457 CYFinally(CYStatement *statements) :
1462 void Replace(CYContext &context);
1463 virtual void Output(CYOutput &out) const;
1472 CYIdentifier *name_;
1475 Catch(CYIdentifier *name, CYStatement *statements) :
1481 void Replace(CYContext &context);
1482 virtual void Output(CYOutput &out) const;
1490 CYFinally *finally_;
1492 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1499 virtual CYStatement *Replace(CYContext &context);
1500 virtual void Output(CYOutput &out, CYFlags flags) const;
1506 CYExpression *value_;
1508 Throw(CYExpression *value) :
1513 virtual CYStatement *Replace(CYContext &context);
1514 virtual void Output(CYOutput &out, CYFlags flags) const;
1522 CYExpression *scope_;
1525 CYWith(CYExpression *scope, CYStatement *code) :
1531 virtual CYStatement *Replace(CYContext &context);
1532 virtual void Output(CYOutput &out, CYFlags flags) const;
1538 CYExpression *value_;
1541 CYSwitch(CYExpression *value, CYClause *clauses) :
1547 virtual CYStatement *Replace(CYContext &context);
1548 virtual void Output(CYOutput &out, CYFlags flags) const;
1551 struct CYCondition :
1554 CYExpression *test_;
1555 CYExpression *true_;
1556 CYExpression *false_;
1558 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1567 virtual CYExpression *Replace(CYContext &context);
1568 virtual void Output(CYOutput &out, CYFlags flags) const;
1571 struct CYAddressOf :
1574 CYAddressOf(CYExpression *rhs) :
1579 virtual const char *Operator() const {
1585 virtual CYExpression *Replace(CYContext &context);
1591 CYIndirect(CYExpression *rhs) :
1596 virtual const char *Operator() const {
1602 virtual CYExpression *Replace(CYContext &context);
1606 virtual CYExpression *Replace(CYContext &context);
1608 #define CYPostfix_(op, name, args...) \
1609 struct CY ## name : \
1612 CY ## name(CYExpression *lhs) : \
1617 virtual const char *Operator() const { \
1622 #define CYPrefix_(alphabetic, op, name, args...) \
1623 struct CY ## name : \
1626 CY ## name(CYExpression *rhs) : \
1631 CYAlphabetic(alphabetic) \
1633 virtual const char *Operator() const { \
1638 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1639 struct CY ## name : \
1642 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1647 CYAlphabetic(alphabetic) \
1648 CYPrecedence(precedence) \
1650 virtual const char *Operator() const { \
1655 #define CYAssignment_(op, name, args...) \
1656 struct CY ## name ## Assign : \
1659 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1660 CYAssignment(lhs, rhs) \
1664 virtual const char *Operator() const { \
1669 CYPostfix_("++", PostIncrement)
1670 CYPostfix_("--", PostDecrement)
1672 CYPrefix_(true, "delete", Delete)
1673 CYPrefix_(true, "void", Void)
1674 CYPrefix_(true, "typeof", TypeOf)
1675 CYPrefix_(false, "++", PreIncrement)
1676 CYPrefix_(false, "--", PreDecrement)
1677 CYPrefix_(false, "+", Affirm)
1678 CYPrefix_(false, "-", Negate)
1679 CYPrefix_(false, "~", BitwiseNot)
1680 CYPrefix_(false, "!", LogicalNot)
1682 CYInfix_(false, 5, "*", Multiply)
1683 CYInfix_(false, 5, "/", Divide)
1684 CYInfix_(false, 5, "%", Modulus)
1685 CYInfix_(false, 6, "+", Add, CYReplace)
1686 CYInfix_(false, 6, "-", Subtract)
1687 CYInfix_(false, 7, "<<", ShiftLeft)
1688 CYInfix_(false, 7, ">>", ShiftRightSigned)
1689 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1690 CYInfix_(false, 8, "<", Less)
1691 CYInfix_(false, 8, ">", Greater)
1692 CYInfix_(false, 8, "<=", LessOrEqual)
1693 CYInfix_(false, 8, ">=", GreaterOrEqual)
1694 CYInfix_(true, 8, "instanceof", InstanceOf)
1695 CYInfix_(true, 8, "in", In)
1696 CYInfix_(false, 9, "==", Equal)
1697 CYInfix_(false, 9, "!=", NotEqual)
1698 CYInfix_(false, 9, "===", Identical)
1699 CYInfix_(false, 9, "!==", NotIdentical)
1700 CYInfix_(false, 10, "&", BitwiseAnd)
1701 CYInfix_(false, 11, "^", BitwiseXOr)
1702 CYInfix_(false, 12, "|", BitwiseOr)
1703 CYInfix_(false, 13, "&&", LogicalAnd)
1704 CYInfix_(false, 14, "||", LogicalOr)
1706 CYAssignment_("=", )
1707 CYAssignment_("*=", Multiply)
1708 CYAssignment_("/=", Divide)
1709 CYAssignment_("%=", Modulus)
1710 CYAssignment_("+=", Add)
1711 CYAssignment_("-=", Subtract)
1712 CYAssignment_("<<=", ShiftLeft)
1713 CYAssignment_(">>=", ShiftRightSigned)
1714 CYAssignment_(">>>=", ShiftRightUnsigned)
1715 CYAssignment_("&=", BitwiseAnd)
1716 CYAssignment_("^=", BitwiseXOr)
1717 CYAssignment_("|=", BitwiseOr)
1719 #endif/*CYPARSER_HPP*/