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 CYIdentifierValueSet identifiers_;
319 CYIdentifierAddressFlagsMap internal_;
328 void Add(CYContext &context, CYIdentifierAddressVector &external);
329 void Scope(CYContext &context, CYStatement *&statements);
336 CYStatement *statements_;
337 CYIdentifierAddressVector rename_;
338 CYCStringSet external_;
340 CYProgram(CYStatement *statements) :
341 statements_(statements)
345 virtual void Replace(CYContext &context);
346 virtual void Output(CYOutput &out) const;
353 CYStatement *statements_;
356 CYBlock(CYStatement *statements, CYScope *scope = NULL) :
357 statements_(statements),
362 operator CYStatement *() const {
366 void AddPrev(CYStatement *statement) {
367 CYStatement *last(statement);
368 while (last->next_ != NULL)
370 last->SetNext(statements_);
371 statements_ = statement;
374 virtual CYStatement *Replace(CYContext &context);
376 virtual void Output(CYOutput &out) const;
377 virtual void Output(CYOutput &out, CYFlags flags) const;
405 std::string filename_;
409 cy::location location_;
410 std::string message_;
413 typedef std::vector<Error> Errors;
420 void ScannerDestroy();
423 CYDriver(const std::string &filename);
426 Condition GetCondition();
427 void SetCondition(Condition condition);
429 void PushCondition(Condition condition);
432 void Warning(const cy::location &location, const char *message);
435 struct CYForInitialiser {
436 virtual ~CYForInitialiser() {
439 virtual void For(CYOutput &out) const = 0;
440 virtual CYExpression *Replace(CYContext &context) = 0;
443 struct CYForInInitialiser {
444 virtual ~CYForInInitialiser() {
447 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
448 virtual const char *ForEachIn() const = 0;
449 virtual CYExpression *ForEachIn(CYContext &out) = 0;
450 virtual CYExpression *Replace(CYContext &context) = 0;
456 struct CYExpression :
457 CYNext<CYExpression>,
463 virtual unsigned Precedence() const = 0;
465 virtual bool RightHand() const {
469 virtual void For(CYOutput &out) const;
470 virtual void ForIn(CYOutput &out, CYFlags flags) const;
472 virtual const char *ForEachIn() const;
473 virtual CYExpression *ForEachIn(CYContext &out);
475 virtual void Output(CYOutput &out) const;
476 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
477 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
479 virtual CYExpression *ClassName(CYContext &context, bool object);
480 virtual void ClassName(CYOutput &out, bool object) const;
482 CYExpression *ReplaceAll(CYContext &context);
484 virtual CYExpression *Replace(CYContext &context) = 0;
486 virtual CYExpression *Primitive(CYContext &context) {
490 virtual CYNumber *Number(CYContext &context) {
494 virtual CYString *String(CYContext &context) {
498 virtual const char *Word() const {
503 #define CYAlphabetic(value) \
504 virtual bool Alphabetic() const { \
508 #define CYPrecedence(value) \
509 virtual unsigned Precedence() const { \
513 #define CYRightHand(value) \
514 virtual bool RightHand() const { \
521 CYExpression *expressions_;
523 CYCompound(CYExpression *expressions = NULL) :
524 expressions_(expressions)
528 void AddPrev(CYExpression *expression) {
529 CYExpression *last(expression);
530 while (last->next_ != NULL)
532 last->SetNext(expressions_);
533 expressions_ = expression;
538 virtual CYExpression *Replace(CYContext &context);
539 void Output(CYOutput &out, CYFlags flags) const;
542 struct CYFunctionParameter :
543 CYNext<CYFunctionParameter>,
548 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
549 CYNext<CYFunctionParameter>(next),
554 void Replace(CYContext &context);
555 virtual void Output(CYOutput &out) const;
558 struct CYComprehension :
559 CYNext<CYComprehension>,
562 virtual const char *Name() const = 0;
564 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
565 CYFunctionParameter *Parameters(CYContext &context) const;
566 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
567 virtual void Output(CYOutput &out) const = 0;
570 struct CYForInComprehension :
576 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
582 virtual const char *Name() const {
583 return name_->Word();
586 virtual CYFunctionParameter *Parameter(CYContext &context) const;
587 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
588 virtual void Output(CYOutput &out) const;
591 struct CYForEachInComprehension :
597 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
603 virtual const char *Name() const {
604 return name_->Word();
607 virtual CYFunctionParameter *Parameter(CYContext &context) const;
608 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
609 virtual void Output(CYOutput &out) const;
612 struct CYIfComprehension :
617 CYIfComprehension(CYExpression *test) :
622 virtual const char *Name() const {
626 virtual CYFunctionParameter *Parameter(CYContext &context) const;
627 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
628 virtual void Output(CYOutput &out) const;
631 struct CYArrayComprehension :
634 CYExpression *expression_;
635 CYComprehension *comprehensions_;
637 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
638 expression_(expression),
639 comprehensions_(comprehensions)
645 virtual CYExpression *Replace(CYContext &context);
646 virtual void Output(CYOutput &out, CYFlags flags) const;
659 virtual CYExpression *Replace(CYContext &context);
673 CYRange(uint64_t lo, uint64_t hi) :
678 bool operator [](uint8_t value) const {
679 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
682 void operator()(uint8_t value) {
685 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
689 extern CYRange DigitRange_;
690 extern CYRange WordStartRange_;
691 extern CYRange WordEndRange_;
706 CYString(const char *value) :
712 CYString(const char *value, size_t size) :
718 CYString(const CYWord *word) :
719 value_(word->Word()),
720 size_(strlen(value_))
724 const char *Value() const {
728 virtual const char *Word() const;
730 virtual CYNumber *Number(CYContext &context);
731 virtual CYString *String(CYContext &context);
733 CYString *Concat(CYContext &out, CYString *rhs) const;
734 virtual void Output(CYOutput &out, CYFlags flags) const;
735 virtual void PropertyName(CYOutput &out) const;
744 CYNumber(double value) :
749 double Value() const {
753 virtual CYNumber *Number(CYContext &context);
754 virtual CYString *String(CYContext &context);
756 virtual void Output(CYOutput &out, CYFlags flags) const;
757 virtual void PropertyName(CYOutput &out) const;
765 CYRegEx(const char *value) :
770 const char *Value() const {
774 virtual void Output(CYOutput &out, CYFlags flags) const;
786 virtual CYNumber *Number(CYContext &context);
787 virtual CYString *String(CYContext &context);
789 virtual void Output(CYOutput &out, CYFlags flags) const;
801 virtual CYExpression *Replace(CYContext &context);
802 virtual void Output(CYOutput &out, CYFlags flags) const;
808 virtual bool Value() const = 0;
809 virtual void Output(CYOutput &out, CYFlags flags) const;
821 virtual bool Value() const {
825 virtual CYNumber *Number(CYContext &context);
826 virtual CYString *String(CYContext &context);
838 virtual bool Value() const {
842 virtual CYNumber *Number(CYContext &context);
843 virtual CYString *String(CYContext &context);
851 CYVariable(CYIdentifier *name) :
859 virtual CYExpression *Replace(CYContext &context);
860 virtual void Output(CYOutput &out, CYFlags flags) const;
868 CYPrefix(CYExpression *rhs) :
873 virtual bool Alphabetic() const = 0;
874 virtual const char *Operator() const = 0;
878 virtual CYExpression *Replace(CYContext &context);
879 virtual void Output(CYOutput &out, CYFlags flags) const;
888 CYInfix(CYExpression *lhs, CYExpression *rhs) :
894 void SetLeft(CYExpression *lhs) {
898 virtual bool Alphabetic() const = 0;
899 virtual const char *Operator() const = 0;
901 virtual CYExpression *Replace(CYContext &context);
902 virtual void Output(CYOutput &out, CYFlags flags) const;
910 CYPostfix(CYExpression *lhs) :
915 virtual const char *Operator() const = 0;
919 virtual CYExpression *Replace(CYContext &context);
920 virtual void Output(CYOutput &out, CYFlags flags) const;
923 struct CYAssignment :
929 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
935 void SetLeft(CYExpression *lhs) {
939 virtual const char *Operator() const = 0;
943 virtual CYExpression *Replace(CYContext &context);
944 virtual void Output(CYOutput &out, CYFlags flags) const;
952 CYExpression *value_;
954 CYArgument(CYExpression *value, CYArgument *next = NULL) :
955 CYNext<CYArgument>(next),
961 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
962 CYNext<CYArgument>(next),
968 void Replace(CYContext &context);
969 void Output(CYOutput &out) const;
986 CYStatement *statements_;
988 CYClause(CYExpression *_case, CYStatement *statements) :
990 statements_(statements)
994 void Replace(CYContext &context);
995 virtual void Output(CYOutput &out) const;
1002 CYExpression *value_;
1004 CYElement(CYExpression *value, CYElement *next) :
1005 CYNext<CYElement>(next),
1010 void Replace(CYContext &context);
1011 void Output(CYOutput &out) const;
1017 CYElement *elements_;
1019 CYArray(CYElement *elements = NULL) :
1024 virtual CYExpression *Replace(CYContext &context);
1025 virtual void Output(CYOutput &out, CYFlags flags) const;
1032 CYPropertyName *name_;
1033 CYExpression *value_;
1035 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1036 CYNext<CYProperty>(next),
1042 void Replace(CYContext &context);
1043 virtual void Output(CYOutput &out) const;
1046 struct CYDeclaration :
1049 CYIdentifier *identifier_;
1050 CYExpression *initialiser_;
1052 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1053 identifier_(identifier),
1054 initialiser_(initialiser)
1058 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1060 virtual const char *ForEachIn() const;
1061 virtual CYExpression *ForEachIn(CYContext &out);
1063 virtual CYExpression *Replace(CYContext &context);
1064 virtual CYAssignment *Assignment(CYContext &context);
1066 virtual void Output(CYOutput &out, CYFlags flags) const;
1069 struct CYDeclarations :
1070 CYNext<CYDeclarations>,
1074 CYDeclaration *declaration_;
1076 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1077 CYNext<CYDeclarations>(next),
1078 declaration_(declaration)
1082 virtual void For(CYOutput &out) const;
1084 virtual CYCompound *Replace(CYContext &context);
1085 CYProperty *Property(CYContext &context);
1087 virtual void Output(CYOutput &out) const;
1088 virtual void Output(CYOutput &out, CYFlags flags) const;
1094 CYDeclarations *declarations_;
1096 CYVar(CYDeclarations *declarations) :
1097 declarations_(declarations)
1101 virtual CYStatement *Replace(CYContext &context);
1102 virtual void Output(CYOutput &out, CYFlags flags) const;
1108 CYDeclarations *declarations_;
1111 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1112 declarations_(declarations),
1117 virtual CYStatement *Replace(CYContext &context);
1118 virtual void Output(CYOutput &out, CYFlags flags) const;
1124 CYForInitialiser *initialiser_;
1125 CYExpression *test_;
1126 CYExpression *increment_;
1129 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1130 initialiser_(initialiser),
1132 increment_(increment),
1137 virtual CYStatement *Replace(CYContext &context);
1138 virtual void Output(CYOutput &out, CYFlags flags) const;
1144 CYForInInitialiser *initialiser_;
1148 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1149 initialiser_(initialiser),
1155 virtual CYStatement *Replace(CYContext &context);
1156 virtual void Output(CYOutput &out, CYFlags flags) const;
1159 struct CYForEachIn :
1162 CYForInInitialiser *initialiser_;
1166 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1167 initialiser_(initialiser),
1173 virtual CYStatement *Replace(CYContext &context);
1174 virtual void Output(CYOutput &out, CYFlags flags) const;
1180 CYProperty *properties_;
1182 CYObject(CYProperty *properties) :
1183 properties_(properties)
1187 virtual CYExpression *Replace(CYContext &context);
1188 void Output(CYOutput &out, CYFlags flags) const;
1194 CYExpression *object_;
1195 CYExpression *property_;
1197 CYMember(CYExpression *object, CYExpression *property) :
1203 void SetLeft(CYExpression *object) {
1207 void Replace_(CYContext &context);
1210 struct CYDirectMember :
1213 CYDirectMember(CYExpression *object, CYExpression *property) :
1214 CYMember(object, property)
1221 virtual CYExpression *Replace(CYContext &context);
1222 virtual void Output(CYOutput &out, CYFlags flags) const;
1225 struct CYIndirectMember :
1228 CYIndirectMember(CYExpression *object, CYExpression *property) :
1229 CYMember(object, property)
1236 virtual CYExpression *Replace(CYContext &context);
1237 virtual void Output(CYOutput &out, CYFlags flags) const;
1243 CYExpression *constructor_;
1244 CYArgument *arguments_;
1246 CYNew(CYExpression *constructor, CYArgument *arguments) :
1247 constructor_(constructor),
1248 arguments_(arguments)
1252 virtual unsigned Precedence() const {
1253 return arguments_ == NULL ? 2 : 1;
1258 virtual CYExpression *Replace(CYContext &context);
1259 virtual void Output(CYOutput &out, CYFlags flags) const;
1265 CYExpression *function_;
1266 CYArgument *arguments_;
1268 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1269 function_(function),
1270 arguments_(arguments)
1277 virtual CYExpression *Replace(CYContext &context);
1278 virtual void Output(CYOutput &out, CYFlags flags) const;
1284 CYExpression *test_;
1286 CYStatement *false_;
1288 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1295 virtual CYStatement *Replace(CYContext &context);
1296 virtual void Output(CYOutput &out, CYFlags flags) const;
1302 CYExpression *test_;
1305 CYDoWhile(CYExpression *test, CYStatement *code) :
1311 virtual CYStatement *Replace(CYContext &context);
1312 virtual void Output(CYOutput &out, CYFlags flags) const;
1318 CYExpression *test_;
1321 CYWhile(CYExpression *test, CYStatement *code) :
1327 virtual CYStatement *Replace(CYContext &context);
1328 virtual void Output(CYOutput &out, CYFlags flags) const;
1334 CYIdentifier *name_;
1335 CYFunctionParameter *parameters_;
1338 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1340 parameters_(parameters),
1341 code_(statements, this)
1345 virtual ~CYFunction() {
1348 void Inject(CYContext &context);
1349 virtual void Replace_(CYContext &context, bool outer);
1350 virtual void Output(CYOutput &out, CYFlags flags) const;
1353 struct CYFunctionExpression :
1357 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1358 CYFunction(name, parameters, statements)
1365 virtual CYExpression *Replace(CYContext &context);
1366 virtual void Output(CYOutput &out, CYFlags flags) const;
1369 struct CYFunctionStatement :
1373 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1374 CYFunction(name, parameters, statements)
1378 virtual CYStatement *Replace(CYContext &context);
1379 virtual void Output(CYOutput &out, CYFlags flags) const;
1385 CYExpression *expression_;
1387 CYExpress(CYExpression *expression) :
1388 expression_(expression)
1390 if (expression == NULL)
1394 virtual CYStatement *Collapse(CYContext &context);
1395 virtual CYStatement *Replace(CYContext &context);
1396 virtual void Output(CYOutput &out, CYFlags flags) const;
1402 CYIdentifier *label_;
1404 CYContinue(CYIdentifier *label) :
1409 virtual CYStatement *Replace(CYContext &context);
1410 virtual void Output(CYOutput &out, CYFlags flags) const;
1416 CYIdentifier *label_;
1418 CYBreak(CYIdentifier *label) :
1423 virtual CYStatement *Replace(CYContext &context);
1424 virtual void Output(CYOutput &out, CYFlags flags) const;
1430 CYExpression *value_;
1432 CYReturn(CYExpression *value) :
1437 virtual CYStatement *Replace(CYContext &context);
1438 virtual void Output(CYOutput &out, CYFlags flags) const;
1444 virtual CYStatement *Collapse(CYContext &context);
1445 virtual CYStatement *Replace(CYContext &context);
1446 virtual void Output(CYOutput &out, CYFlags flags) const;
1454 CYFinally(CYStatement *statements) :
1459 void Replace(CYContext &context);
1460 virtual void Output(CYOutput &out) const;
1469 CYIdentifier *name_;
1472 Catch(CYIdentifier *name, CYStatement *statements) :
1478 void Replace(CYContext &context);
1479 virtual void Output(CYOutput &out) const;
1487 CYFinally *finally_;
1489 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1496 virtual CYStatement *Replace(CYContext &context);
1497 virtual void Output(CYOutput &out, CYFlags flags) const;
1503 CYExpression *value_;
1505 Throw(CYExpression *value) :
1510 virtual CYStatement *Replace(CYContext &context);
1511 virtual void Output(CYOutput &out, CYFlags flags) const;
1519 CYExpression *scope_;
1522 CYWith(CYExpression *scope, CYStatement *code) :
1528 virtual CYStatement *Replace(CYContext &context);
1529 virtual void Output(CYOutput &out, CYFlags flags) const;
1535 CYExpression *value_;
1538 CYSwitch(CYExpression *value, CYClause *clauses) :
1544 virtual CYStatement *Replace(CYContext &context);
1545 virtual void Output(CYOutput &out, CYFlags flags) const;
1548 struct CYCondition :
1551 CYExpression *test_;
1552 CYExpression *true_;
1553 CYExpression *false_;
1555 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1564 virtual CYExpression *Replace(CYContext &context);
1565 virtual void Output(CYOutput &out, CYFlags flags) const;
1568 struct CYAddressOf :
1571 CYAddressOf(CYExpression *rhs) :
1576 virtual const char *Operator() const {
1582 virtual CYExpression *Replace(CYContext &context);
1588 CYIndirect(CYExpression *rhs) :
1593 virtual const char *Operator() const {
1599 virtual CYExpression *Replace(CYContext &context);
1603 virtual CYExpression *Replace(CYContext &context);
1605 #define CYPostfix_(op, name, args...) \
1606 struct CY ## name : \
1609 CY ## name(CYExpression *lhs) : \
1614 virtual const char *Operator() const { \
1619 #define CYPrefix_(alphabetic, op, name, args...) \
1620 struct CY ## name : \
1623 CY ## name(CYExpression *rhs) : \
1628 CYAlphabetic(alphabetic) \
1630 virtual const char *Operator() const { \
1635 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1636 struct CY ## name : \
1639 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1644 CYAlphabetic(alphabetic) \
1645 CYPrecedence(precedence) \
1647 virtual const char *Operator() const { \
1652 #define CYAssignment_(op, name, args...) \
1653 struct CY ## name ## Assign : \
1656 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1657 CYAssignment(lhs, rhs) \
1661 virtual const char *Operator() const { \
1666 CYPostfix_("++", PostIncrement)
1667 CYPostfix_("--", PostDecrement)
1669 CYPrefix_(true, "delete", Delete)
1670 CYPrefix_(true, "void", Void)
1671 CYPrefix_(true, "typeof", TypeOf)
1672 CYPrefix_(false, "++", PreIncrement)
1673 CYPrefix_(false, "--", PreDecrement)
1674 CYPrefix_(false, "+", Affirm)
1675 CYPrefix_(false, "-", Negate)
1676 CYPrefix_(false, "~", BitwiseNot)
1677 CYPrefix_(false, "!", LogicalNot)
1679 CYInfix_(false, 5, "*", Multiply)
1680 CYInfix_(false, 5, "/", Divide)
1681 CYInfix_(false, 5, "%", Modulus)
1682 CYInfix_(false, 6, "+", Add, CYReplace)
1683 CYInfix_(false, 6, "-", Subtract)
1684 CYInfix_(false, 7, "<<", ShiftLeft)
1685 CYInfix_(false, 7, ">>", ShiftRightSigned)
1686 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1687 CYInfix_(false, 8, "<", Less)
1688 CYInfix_(false, 8, ">", Greater)
1689 CYInfix_(false, 8, "<=", LessOrEqual)
1690 CYInfix_(false, 8, ">=", GreaterOrEqual)
1691 CYInfix_(true, 8, "instanceof", InstanceOf)
1692 CYInfix_(true, 8, "in", In)
1693 CYInfix_(false, 9, "==", Equal)
1694 CYInfix_(false, 9, "!=", NotEqual)
1695 CYInfix_(false, 9, "===", Identical)
1696 CYInfix_(false, 9, "!==", NotIdentical)
1697 CYInfix_(false, 10, "&", BitwiseAnd)
1698 CYInfix_(false, 11, "^", BitwiseXOr)
1699 CYInfix_(false, 12, "|", BitwiseOr)
1700 CYInfix_(false, 13, "&&", LogicalAnd)
1701 CYInfix_(false, 14, "||", LogicalOr)
1703 CYAssignment_("=", )
1704 CYAssignment_("*=", Multiply)
1705 CYAssignment_("/=", Divide)
1706 CYAssignment_("%=", Modulus)
1707 CYAssignment_("+=", Add)
1708 CYAssignment_("-=", Subtract)
1709 CYAssignment_("<<=", ShiftLeft)
1710 CYAssignment_(">>=", ShiftRightSigned)
1711 CYAssignment_(">>>=", ShiftRightUnsigned)
1712 CYAssignment_("&=", BitwiseAnd)
1713 CYAssignment_("^=", BitwiseXOr)
1714 CYAssignment_("|=", BitwiseOr)
1716 #endif/*CYPARSER_HPP*/