1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2010 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/>.
35 #include "location.hh"
36 #include "Pooling.hpp"
37 #include "Options.hpp"
41 template <typename Type_>
55 void SetNext(Type_ *next) {
60 #define CYForEach(value, list) \
61 for (__typeof__(*list) *value(list); value != NULL; value = value->next_)
67 virtual void Output(struct CYOutput &out) const = 0;
85 CYOutput(std::ostream &out, CYOptions &options) :
95 void Check(char value);
98 CYOutput &operator <<(char rhs);
99 CYOutput &operator <<(const char *rhs);
101 _finline CYOutput &operator <<(const CYThing *rhs) {
107 _finline CYOutput &operator <<(const CYThing &rhs) {
113 struct CYPropertyName {
114 virtual void PropertyName(CYOutput &out) const = 0;
116 virtual ~CYPropertyName() {
130 CYNoBrace = (1 << 0),
131 CYNoFunction = (1 << 1),
134 CYNoRightHand = (1 << 4),
135 CYNoDangle = (1 << 5),
136 CYNoInteger = (1 << 6),
137 CYNoBF = (CYNoBrace | CYNoFunction),
143 virtual ~CYStatement() {
146 void Single(CYOutput &out, CYFlags flags) const;
147 void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
149 virtual CYStatement *Collapse(CYContext &context);
150 virtual CYStatement *Replace(CYContext &context) = 0;
153 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
156 struct CYStatements {
166 operator CYStatement *() const {
170 CYStatements &operator ->*(CYStatement *next) {
172 if (first_ == NULL) {
175 } else for (;; last_ = last_->next_)
176 if (last_->next_ == NULL) {
186 virtual ~CYClassName() {
189 virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
190 virtual void ClassName(CYOutput &out, bool object) const = 0;
200 CYWord(const char *word) :
205 void Set(const char *value) {
209 virtual const char *Word() const;
210 virtual void Output(CYOutput &out) const;
212 virtual CYExpression *ClassName(CYContext &context, bool object);
213 virtual void ClassName(CYOutput &out, bool object) const;
214 virtual void PropertyName(CYOutput &out) const;
217 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
219 return lhs << rhs.Word();
222 struct CYIdentifier :
223 CYNext<CYIdentifier>,
226 CYIdentifier *replace_;
230 CYIdentifier(const char *word) :
238 virtual const char *Word() const;
239 CYIdentifier *Replace(CYContext &context);
247 CYComment(const char *value) :
252 virtual CYStatement *Replace(CYContext &context);
253 virtual void Output(CYOutput &out, CYFlags flags) const;
260 CYStatement *statement_;
262 CYLabel(CYIdentifier *name, CYStatement *statement) :
264 statement_(statement)
268 virtual CYStatement *Replace(CYContext &context);
269 virtual void Output(CYOutput &out, CYFlags flags) const;
272 struct CYCStringLess :
273 std::binary_function<const char *, const char *, bool>
275 _finline bool operator ()(const char *lhs, const char *rhs) const {
276 return strcmp(lhs, rhs) < 0;
280 struct CYIdentifierValueLess :
281 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
283 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
284 return CYCStringLess()(lhs->Word(), rhs->Word());
288 enum CYIdentifierFlags {
289 CYIdentifierArgument,
290 CYIdentifierVariable,
296 typedef std::set<const char *, CYCStringLess> CYCStringSet;
297 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
298 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
300 struct CYIdentifierUsage {
301 CYIdentifier *identifier_;
305 typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
307 // XXX: strategy pattern, maybe subclass
318 CYStatement *&statements_;
322 CYIdentifierAddressFlagsMap internal_;
323 CYIdentifierValueSet identifiers_;
325 CYScope(CYScopeType type, CYContext &context, CYStatement *&statements);
329 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
330 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
331 void Merge(CYContext &context, CYIdentifier *identifier);
332 void Scope(CYContext &context, CYStatement *&statements);
338 CYStatement *statements_;
340 CYProgram(CYStatement *statements) :
341 statements_(statements)
345 virtual void Replace(CYContext &context);
346 virtual void Output(CYOutput &out) const;
355 CYIdentifierUsageVector rename_;
357 CYNonLocal *nonlocal_;
358 CYNonLocal *nextlocal_;
361 CYContext(CYOptions &options) :
370 virtual ~CYContext() {
373 template <typename Type_>
374 void ReplaceAll(Type_ *&values) {
375 Type_ **last(&values);
376 CYForEach (next, values) {
378 last = &(*last)->next_;
382 template <typename Type_>
383 void Replace(Type_ *&value) {
384 for (;;) if (value == NULL)
387 Type_ *replace(value->Replace(*this));
388 if (replace != value)
394 void NonLocal(CYStatement *&statements);
395 CYIdentifier *Unique();
399 CYIdentifier *identifier_;
406 CYIdentifier *Target(CYContext &context) {
407 if (identifier_ == NULL)
408 identifier_ = context.Unique();
417 CYStatement *statements_;
419 CYBlock(CYStatement *statements) :
420 statements_(statements)
424 operator CYStatement *() const {
428 void AddPrev(CYStatement *statement) {
429 CYStatement *last(statement);
430 while (last->next_ != NULL)
432 last->SetNext(statements_);
433 statements_ = statement;
436 virtual CYStatement *Replace(CYContext &context);
438 virtual void Output(CYOutput &out) const;
439 virtual void Output(CYOutput &out, CYFlags flags) const;
465 std::string filename_;
469 cy::location location_;
470 std::string message_;
473 typedef std::vector<Error> Errors;
481 CYExpression *context_;
483 Context(CYExpression *context) :
488 typedef std::vector<CYWord *> Words;
492 typedef std::vector<Context> Contexts;
495 CYExpression *context_;
507 void ScannerDestroy();
510 CYDriver(const std::string &filename = "");
513 Condition GetCondition();
514 void SetCondition(Condition condition);
516 void PushCondition(Condition condition);
519 void Warning(const cy::location &location, const char *message);
522 struct CYForInitialiser {
523 virtual ~CYForInitialiser() {
526 virtual void For(CYOutput &out) const = 0;
527 virtual CYExpression *Replace(CYContext &context) = 0;
530 struct CYForInInitialiser {
531 virtual ~CYForInInitialiser() {
534 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
535 virtual const char *ForEachIn() const = 0;
536 virtual CYExpression *ForEachIn(CYContext &out) = 0;
537 virtual CYExpression *Replace(CYContext &context) = 0;
543 struct CYExpression :
544 CYNext<CYExpression>,
550 virtual unsigned Precedence() const = 0;
552 virtual bool RightHand() const {
556 virtual void For(CYOutput &out) const;
557 virtual void ForIn(CYOutput &out, CYFlags flags) const;
559 virtual const char *ForEachIn() const;
560 virtual CYExpression *ForEachIn(CYContext &out);
562 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
564 virtual void Output(CYOutput &out) const;
565 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
566 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
568 virtual CYExpression *ClassName(CYContext &context, bool object);
569 virtual void ClassName(CYOutput &out, bool object) const;
571 virtual CYExpression *Replace(CYContext &context) = 0;
573 virtual CYExpression *Primitive(CYContext &context) {
577 virtual CYNumber *Number(CYContext &context) {
581 virtual CYString *String(CYContext &context) {
585 virtual const char *Word() const {
590 #define CYAlphabetic(value) \
591 virtual bool Alphabetic() const { \
595 #define CYPrecedence(value) \
596 static const unsigned Precedence_ = value; \
597 virtual unsigned Precedence() const { \
598 return Precedence_; \
601 #define CYRightHand(value) \
602 virtual bool RightHand() const { \
609 CYExpression *expressions_;
611 CYCompound(CYExpression *expressions = NULL) :
612 expressions_(expressions)
616 void AddPrev(CYExpression *expression) {
617 CYExpression *last(expression);
618 while (last->next_ != NULL)
620 last->SetNext(expressions_);
621 expressions_ = expression;
626 virtual CYExpression *Replace(CYContext &context);
627 void Output(CYOutput &out, CYFlags flags) const;
630 struct CYFunctionParameter :
631 CYNext<CYFunctionParameter>,
636 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
637 CYNext<CYFunctionParameter>(next),
642 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
643 virtual void Output(CYOutput &out) const;
646 struct CYOptionalFunctionParameter :
649 CYExpression *initializer_;
651 CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
652 CYFunctionParameter(name, next),
653 initializer_(initializer)
657 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
658 virtual void Output(CYOutput &out) const;
661 struct CYComprehension :
662 CYNext<CYComprehension>,
665 virtual const char *Name() const = 0;
667 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
668 CYFunctionParameter *Parameters(CYContext &context) const;
669 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
670 virtual void Output(CYOutput &out) const = 0;
673 struct CYForInComprehension :
679 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
685 virtual const char *Name() const {
686 return name_->Word();
689 virtual CYFunctionParameter *Parameter(CYContext &context) const;
690 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
691 virtual void Output(CYOutput &out) const;
694 struct CYForEachInComprehension :
700 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
706 virtual const char *Name() const {
707 return name_->Word();
710 virtual CYFunctionParameter *Parameter(CYContext &context) const;
711 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
712 virtual void Output(CYOutput &out) const;
715 struct CYIfComprehension :
720 CYIfComprehension(CYExpression *test) :
725 virtual const char *Name() const {
729 virtual CYFunctionParameter *Parameter(CYContext &context) const;
730 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
731 virtual void Output(CYOutput &out) const;
734 struct CYArrayComprehension :
737 CYExpression *expression_;
738 CYComprehension *comprehensions_;
740 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
741 expression_(expression),
742 comprehensions_(comprehensions)
748 virtual CYExpression *Replace(CYContext &context);
749 virtual void Output(CYOutput &out, CYFlags flags) const;
762 virtual CYExpression *Replace(CYContext &context);
776 CYRange(uint64_t lo, uint64_t hi) :
781 bool operator [](uint8_t value) const {
782 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
785 void operator()(uint8_t value) {
788 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
792 extern CYRange DigitRange_;
793 extern CYRange WordStartRange_;
794 extern CYRange WordEndRange_;
809 CYString(const char *value) :
815 CYString(const char *value, size_t size) :
821 CYString(const CYWord *word) :
822 value_(word->Word()),
823 size_(strlen(value_))
827 const char *Value() const {
831 virtual const char *Word() const;
833 virtual CYNumber *Number(CYContext &context);
834 virtual CYString *String(CYContext &context);
836 CYString *Concat(CYContext &out, CYString *rhs) const;
837 virtual void Output(CYOutput &out, CYFlags flags) const;
838 virtual void PropertyName(CYOutput &out) const;
847 CYNumber(double value) :
852 double Value() const {
856 virtual CYNumber *Number(CYContext &context);
857 virtual CYString *String(CYContext &context);
859 virtual void Output(CYOutput &out, CYFlags flags) const;
860 virtual void PropertyName(CYOutput &out) const;
868 CYRegEx(const char *value) :
873 const char *Value() const {
877 virtual void Output(CYOutput &out, CYFlags flags) const;
889 virtual CYNumber *Number(CYContext &context);
890 virtual CYString *String(CYContext &context);
892 virtual void Output(CYOutput &out, CYFlags flags) const;
904 virtual CYExpression *Replace(CYContext &context);
905 virtual void Output(CYOutput &out, CYFlags flags) const;
911 virtual bool Value() const = 0;
912 virtual void Output(CYOutput &out, CYFlags flags) const;
924 virtual bool Value() const {
928 virtual CYNumber *Number(CYContext &context);
929 virtual CYString *String(CYContext &context);
941 virtual bool Value() const {
945 virtual CYNumber *Number(CYContext &context);
946 virtual CYString *String(CYContext &context);
954 CYVariable(CYIdentifier *name) :
959 CYVariable(const char *name) :
960 name_(new($pool) CYIdentifier(name))
967 virtual CYExpression *Replace(CYContext &context);
968 virtual void Output(CYOutput &out, CYFlags flags) const;
976 CYPrefix(CYExpression *rhs) :
981 virtual bool Alphabetic() const = 0;
982 virtual const char *Operator() const = 0;
986 virtual CYExpression *Replace(CYContext &context);
987 virtual void Output(CYOutput &out, CYFlags flags) const;
996 CYInfix(CYExpression *lhs, CYExpression *rhs) :
1002 void SetLeft(CYExpression *lhs) {
1006 virtual bool Alphabetic() const = 0;
1007 virtual const char *Operator() const = 0;
1009 virtual CYExpression *Replace(CYContext &context);
1010 virtual void Output(CYOutput &out, CYFlags flags) const;
1018 CYPostfix(CYExpression *lhs) :
1023 virtual const char *Operator() const = 0;
1027 virtual CYExpression *Replace(CYContext &context);
1028 virtual void Output(CYOutput &out, CYFlags flags) const;
1031 struct CYAssignment :
1037 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1043 void SetLeft(CYExpression *lhs) {
1047 virtual const char *Operator() const = 0;
1051 virtual CYExpression *Replace(CYContext &context);
1052 virtual void Output(CYOutput &out, CYFlags flags) const;
1060 CYExpression *value_;
1062 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1063 CYNext<CYArgument>(next),
1069 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1070 CYNext<CYArgument>(next),
1076 void Replace(CYContext &context);
1077 void Output(CYOutput &out) const;
1093 CYExpression *case_;
1094 CYStatement *statements_;
1096 CYClause(CYExpression *_case, CYStatement *statements) :
1098 statements_(statements)
1102 void Replace(CYContext &context);
1103 virtual void Output(CYOutput &out) const;
1110 CYExpression *value_;
1112 CYElement(CYExpression *value, CYElement *next) :
1113 CYNext<CYElement>(next),
1118 void Replace(CYContext &context);
1119 void Output(CYOutput &out) const;
1125 CYElement *elements_;
1127 CYArray(CYElement *elements = NULL) :
1132 virtual CYExpression *Replace(CYContext &context);
1133 virtual void Output(CYOutput &out, CYFlags flags) const;
1140 CYPropertyName *name_;
1141 CYExpression *value_;
1143 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1144 CYNext<CYProperty>(next),
1150 void Replace(CYContext &context);
1151 virtual void Output(CYOutput &out) const;
1154 struct CYDeclaration :
1157 CYIdentifier *identifier_;
1158 CYExpression *initialiser_;
1160 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1161 identifier_(identifier),
1162 initialiser_(initialiser)
1166 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1168 virtual const char *ForEachIn() const;
1169 virtual CYExpression *ForEachIn(CYContext &out);
1171 virtual CYExpression *Replace(CYContext &context);
1172 virtual CYAssignment *Assignment(CYContext &context);
1174 virtual void Output(CYOutput &out, CYFlags flags) const;
1177 struct CYDeclarations :
1178 CYNext<CYDeclarations>,
1182 CYDeclaration *declaration_;
1184 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1185 CYNext<CYDeclarations>(next),
1186 declaration_(declaration)
1190 virtual void For(CYOutput &out) const;
1192 virtual CYCompound *Replace(CYContext &context);
1193 CYProperty *Property(CYContext &context);
1195 virtual void Output(CYOutput &out) const;
1196 virtual void Output(CYOutput &out, CYFlags flags) const;
1202 CYDeclarations *declarations_;
1204 CYVar(CYDeclarations *declarations) :
1205 declarations_(declarations)
1209 virtual CYStatement *Replace(CYContext &context);
1210 virtual void Output(CYOutput &out, CYFlags flags) const;
1216 CYDeclarations *declarations_;
1219 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1220 declarations_(declarations),
1225 virtual CYStatement *Replace(CYContext &context);
1226 virtual void Output(CYOutput &out, CYFlags flags) const;
1232 CYForInitialiser *initialiser_;
1233 CYExpression *test_;
1234 CYExpression *increment_;
1237 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1238 initialiser_(initialiser),
1240 increment_(increment),
1245 virtual CYStatement *Replace(CYContext &context);
1246 virtual void Output(CYOutput &out, CYFlags flags) const;
1252 CYForInInitialiser *initialiser_;
1256 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1257 initialiser_(initialiser),
1263 virtual CYStatement *Replace(CYContext &context);
1264 virtual void Output(CYOutput &out, CYFlags flags) const;
1267 struct CYForEachIn :
1270 CYForInInitialiser *initialiser_;
1274 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1275 initialiser_(initialiser),
1281 virtual CYStatement *Replace(CYContext &context);
1282 virtual void Output(CYOutput &out, CYFlags flags) const;
1288 CYProperty *properties_;
1290 CYObject(CYProperty *properties = NULL) :
1291 properties_(properties)
1295 virtual CYExpression *Replace(CYContext &context);
1296 void Output(CYOutput &out, CYFlags flags) const;
1302 CYExpression *object_;
1303 CYExpression *property_;
1305 CYMember(CYExpression *object, CYExpression *property) :
1311 void SetLeft(CYExpression *object) {
1315 void Replace_(CYContext &context);
1318 struct CYDirectMember :
1321 CYDirectMember(CYExpression *object, CYExpression *property) :
1322 CYMember(object, property)
1329 virtual CYExpression *Replace(CYContext &context);
1330 virtual void Output(CYOutput &out, CYFlags flags) const;
1333 struct CYIndirectMember :
1336 CYIndirectMember(CYExpression *object, CYExpression *property) :
1337 CYMember(object, property)
1344 virtual CYExpression *Replace(CYContext &context);
1345 virtual void Output(CYOutput &out, CYFlags flags) const;
1354 CYExpression *constructor_;
1355 CYArgument *arguments_;
1357 New(CYExpression *constructor, CYArgument *arguments) :
1358 constructor_(constructor),
1359 arguments_(arguments)
1363 virtual unsigned Precedence() const {
1364 return arguments_ == NULL ? 2 : 1;
1369 virtual CYExpression *Replace(CYContext &context);
1370 virtual void Output(CYOutput &out, CYFlags flags) const;
1372 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1380 CYExpression *function_;
1381 CYArgument *arguments_;
1383 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1384 function_(function),
1385 arguments_(arguments)
1392 virtual CYExpression *Replace(CYContext &context);
1393 virtual void Output(CYOutput &out, CYFlags flags) const;
1395 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1400 struct CYRubyBlock :
1403 CYExpression *call_;
1406 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1415 virtual CYExpression *Replace(CYContext &context);
1416 virtual void Output(CYOutput &out, CYFlags flags) const;
1422 CYExpression *test_;
1424 CYStatement *false_;
1426 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1433 virtual CYStatement *Replace(CYContext &context);
1434 virtual void Output(CYOutput &out, CYFlags flags) const;
1440 CYExpression *test_;
1443 CYDoWhile(CYExpression *test, CYStatement *code) :
1449 virtual CYStatement *Replace(CYContext &context);
1450 virtual void Output(CYOutput &out, CYFlags flags) const;
1456 CYExpression *test_;
1459 CYWhile(CYExpression *test, CYStatement *code) :
1465 virtual CYStatement *Replace(CYContext &context);
1466 virtual void Output(CYOutput &out, CYFlags flags) const;
1469 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
1471 CYIdentifier *name_;
1472 CYFunctionParameter *parameters_;
1474 CYNonLocal *nonlocal_;
1476 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1478 parameters_(parameters),
1484 virtual ~CYFunction() {
1487 void Inject(CYContext &context);
1488 virtual void Replace_(CYContext &context, bool outer);
1489 virtual void Output(CYOutput &out, CYFlags flags) const;
1492 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
1493 struct CYFunctionExpression :
1497 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1498 CYFunction(name, parameters, statements)
1505 virtual CYExpression *Replace(CYContext &context);
1506 virtual void Output(CYOutput &out, CYFlags flags) const;
1509 // XXX: this should derive from CYAnonymousFunctionExpression
1511 CYFunctionExpression
1513 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1514 CYFunctionExpression(NULL, parameters, statements)
1518 virtual CYExpression *Replace(CYContext &context);
1519 virtual void Output(CYOutput &out, CYFlags flags) const;
1522 // XXX: this should derive from CYNamedFunction
1523 struct CYFunctionStatement :
1527 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1528 CYFunction(name, parameters, statements)
1532 virtual CYStatement *Replace(CYContext &context);
1533 virtual void Output(CYOutput &out, CYFlags flags) const;
1539 CYExpression *expression_;
1541 CYExpress(CYExpression *expression) :
1542 expression_(expression)
1544 if (expression == NULL)
1548 virtual CYStatement *Collapse(CYContext &context);
1549 virtual CYStatement *Replace(CYContext &context);
1550 virtual void Output(CYOutput &out, CYFlags flags) const;
1556 CYIdentifier *label_;
1558 CYContinue(CYIdentifier *label) :
1563 virtual CYStatement *Replace(CYContext &context);
1564 virtual void Output(CYOutput &out, CYFlags flags) const;
1570 CYIdentifier *label_;
1572 CYBreak(CYIdentifier *label) :
1577 virtual CYStatement *Replace(CYContext &context);
1578 virtual void Output(CYOutput &out, CYFlags flags) const;
1584 CYExpression *value_;
1586 CYReturn(CYExpression *value) :
1591 virtual CYStatement *Replace(CYContext &context);
1592 virtual void Output(CYOutput &out, CYFlags flags) const;
1598 virtual CYStatement *Collapse(CYContext &context);
1599 virtual CYStatement *Replace(CYContext &context);
1600 virtual void Output(CYOutput &out, CYFlags flags) const;
1608 CYFinally(CYStatement *statements) :
1613 void Replace(CYContext &context);
1614 virtual void Output(CYOutput &out) const;
1623 CYIdentifier *name_;
1626 Catch(CYIdentifier *name, CYStatement *statements) :
1632 void Replace(CYContext &context);
1633 virtual void Output(CYOutput &out) const;
1641 CYFinally *finally_;
1643 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1650 virtual CYStatement *Replace(CYContext &context);
1651 virtual void Output(CYOutput &out, CYFlags flags) const;
1657 CYExpression *value_;
1659 Throw(CYExpression *value = NULL) :
1664 virtual CYStatement *Replace(CYContext &context);
1665 virtual void Output(CYOutput &out, CYFlags flags) const;
1673 CYExpression *scope_;
1676 CYWith(CYExpression *scope, CYStatement *code) :
1682 virtual CYStatement *Replace(CYContext &context);
1683 virtual void Output(CYOutput &out, CYFlags flags) const;
1689 CYExpression *value_;
1692 CYSwitch(CYExpression *value, CYClause *clauses) :
1698 virtual CYStatement *Replace(CYContext &context);
1699 virtual void Output(CYOutput &out, CYFlags flags) const;
1702 struct CYCondition :
1705 CYExpression *test_;
1706 CYExpression *true_;
1707 CYExpression *false_;
1709 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1718 virtual CYExpression *Replace(CYContext &context);
1719 virtual void Output(CYOutput &out, CYFlags flags) const;
1722 struct CYAddressOf :
1725 CYAddressOf(CYExpression *rhs) :
1730 virtual const char *Operator() const {
1736 virtual CYExpression *Replace(CYContext &context);
1742 CYIndirect(CYExpression *rhs) :
1747 virtual const char *Operator() const {
1753 virtual CYExpression *Replace(CYContext &context);
1757 virtual CYExpression *Replace(CYContext &context);
1759 #define CYPostfix_(op, name, args...) \
1760 struct CY ## name : \
1763 CY ## name(CYExpression *lhs) : \
1768 virtual const char *Operator() const { \
1773 #define CYPrefix_(alphabetic, op, name, args...) \
1774 struct CY ## name : \
1777 CY ## name(CYExpression *rhs) : \
1782 CYAlphabetic(alphabetic) \
1784 virtual const char *Operator() const { \
1789 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1790 struct CY ## name : \
1793 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1798 CYAlphabetic(alphabetic) \
1799 CYPrecedence(precedence) \
1801 virtual const char *Operator() const { \
1806 #define CYAssignment_(op, name, args...) \
1807 struct CY ## name ## Assign : \
1810 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1811 CYAssignment(lhs, rhs) \
1815 virtual const char *Operator() const { \
1820 CYPostfix_("++", PostIncrement)
1821 CYPostfix_("--", PostDecrement)
1823 CYPrefix_(true, "delete", Delete)
1824 CYPrefix_(true, "void", Void)
1825 CYPrefix_(true, "typeof", TypeOf)
1826 CYPrefix_(false, "++", PreIncrement)
1827 CYPrefix_(false, "--", PreDecrement)
1828 CYPrefix_(false, "+", Affirm)
1829 CYPrefix_(false, "-", Negate)
1830 CYPrefix_(false, "~", BitwiseNot)
1831 CYPrefix_(false, "!", LogicalNot)
1833 CYInfix_(false, 5, "*", Multiply)
1834 CYInfix_(false, 5, "/", Divide)
1835 CYInfix_(false, 5, "%", Modulus)
1836 CYInfix_(false, 6, "+", Add, CYReplace)
1837 CYInfix_(false, 6, "-", Subtract)
1838 CYInfix_(false, 7, "<<", ShiftLeft)
1839 CYInfix_(false, 7, ">>", ShiftRightSigned)
1840 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1841 CYInfix_(false, 8, "<", Less)
1842 CYInfix_(false, 8, ">", Greater)
1843 CYInfix_(false, 8, "<=", LessOrEqual)
1844 CYInfix_(false, 8, ">=", GreaterOrEqual)
1845 CYInfix_(true, 8, "instanceof", InstanceOf)
1846 CYInfix_(true, 8, "in", In)
1847 CYInfix_(false, 9, "==", Equal)
1848 CYInfix_(false, 9, "!=", NotEqual)
1849 CYInfix_(false, 9, "===", Identical)
1850 CYInfix_(false, 9, "!==", NotIdentical)
1851 CYInfix_(false, 10, "&", BitwiseAnd)
1852 CYInfix_(false, 11, "^", BitwiseXOr)
1853 CYInfix_(false, 12, "|", BitwiseOr)
1854 CYInfix_(false, 13, "&&", LogicalAnd)
1855 CYInfix_(false, 14, "||", LogicalOr)
1857 CYAssignment_("=", )
1858 CYAssignment_("*=", Multiply)
1859 CYAssignment_("/=", Divide)
1860 CYAssignment_("%=", Modulus)
1861 CYAssignment_("+=", Add)
1862 CYAssignment_("-=", Subtract)
1863 CYAssignment_("<<=", ShiftLeft)
1864 CYAssignment_(">>=", ShiftRightSigned)
1865 CYAssignment_(">>>=", ShiftRightUnsigned)
1866 CYAssignment_("&=", BitwiseAnd)
1867 CYAssignment_("^=", BitwiseXOr)
1868 CYAssignment_("|=", BitwiseOr)
1870 #endif/*CYPARSER_HPP*/