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?!
56 #include "location.hh"
57 #include "Pooling.hpp"
58 #include "Options.hpp"
62 template <typename Type_>
76 void SetNext(Type_ *next) {
85 virtual void Output(struct CYOutput &out) const = 0;
103 CYOutput(std::ostream &out, CYOptions &options) :
113 void Check(char value);
116 CYOutput &operator <<(char rhs);
117 CYOutput &operator <<(const char *rhs);
119 _finline CYOutput &operator <<(const CYThing *rhs) {
125 _finline CYOutput &operator <<(const CYThing &rhs) {
131 struct CYPropertyName {
132 virtual void PropertyName(CYOutput &out) const = 0;
134 virtual ~CYPropertyName() {
148 CYNoBrace = (1 << 0),
149 CYNoFunction = (1 << 1),
152 CYNoRightHand = (1 << 4),
153 CYNoDangle = (1 << 5),
154 CYNoInteger = (1 << 6),
155 CYNoBF = (CYNoBrace | CYNoFunction),
161 virtual ~CYStatement() {
164 void Single(CYOutput &out, CYFlags flags) const;
165 void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
167 CYStatement *ReplaceAll(CYContext &context);
168 virtual CYStatement *Collapse(CYContext &context);
170 virtual CYStatement *Replace(CYContext &context) = 0;
173 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
176 struct CYStatements {
186 operator CYStatement *() const {
190 CYStatements &operator ->*(CYStatement *next) {
192 if (first_ == NULL) {
195 } else for (;; last_ = last_->next_)
196 if (last_->next_ == NULL) {
206 virtual ~CYClassName() {
209 virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
210 virtual void ClassName(CYOutput &out, bool object) const = 0;
220 CYWord(const char *word) :
225 void Set(const char *value) {
229 virtual const char *Word() const;
230 virtual void Output(CYOutput &out) const;
232 virtual CYExpression *ClassName(CYContext &context, bool object);
233 virtual void ClassName(CYOutput &out, bool object) const;
234 virtual void PropertyName(CYOutput &out) const;
237 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
239 return lhs << rhs.Word();
242 struct CYIdentifier :
243 CYNext<CYIdentifier>,
246 CYIdentifier *replace_;
250 CYIdentifier(const char *word) :
258 virtual const char *Word() const;
259 CYIdentifier *Replace(CYContext &context);
267 CYComment(const char *value) :
272 virtual CYStatement *Replace(CYContext &context);
273 virtual void Output(CYOutput &out, CYFlags flags) const;
280 CYStatement *statement_;
282 CYLabel(CYIdentifier *name, CYStatement *statement) :
284 statement_(statement)
288 virtual CYStatement *Replace(CYContext &context);
289 virtual void Output(CYOutput &out, CYFlags flags) const;
292 struct CYCStringLess :
293 std::binary_function<const char *, const char *, bool>
295 _finline bool operator ()(const char *lhs, const char *rhs) const {
296 return strcmp(lhs, rhs) < 0;
300 struct CYIdentifierValueLess :
301 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
303 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
304 return CYCStringLess()(lhs->Word(), rhs->Word());
308 enum CYIdentifierFlags {
309 CYIdentifierArgument,
310 CYIdentifierVariable,
315 typedef std::set<const char *, CYCStringLess> CYCStringSet;
316 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
317 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
319 struct CYIdentifierUsage {
320 CYIdentifier *identifier_;
324 typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
329 CYIdentifierAddressFlagsMap internal_;
330 CYIdentifierValueSet identifiers_;
340 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
341 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
342 void Merge(CYContext &context, CYIdentifier *identifier);
343 void Scope(CYContext &context, CYStatement *&statements);
349 CYStatement *statements_;
351 CYProgram(CYStatement *statements) :
352 statements_(statements)
356 virtual void Replace(CYContext &context);
357 virtual void Output(CYOutput &out) const;
364 CYIdentifierUsageVector rename_;
366 CYContext(apr_pool_t *pool, CYOptions &options) :
373 virtual ~CYContext() {
376 template <typename Type_>
377 void Replace(Type_ *&value) {
378 for (;;) if (value == NULL)
381 Type_ *replace(value->Replace(*this));
382 if (replace != value)
393 CYStatement *statements_;
395 CYBlock(CYStatement *statements) :
396 statements_(statements)
400 operator CYStatement *() const {
404 void AddPrev(CYStatement *statement) {
405 CYStatement *last(statement);
406 while (last->next_ != NULL)
408 last->SetNext(statements_);
409 statements_ = statement;
412 virtual CYStatement *Replace(CYContext &context);
414 virtual void Output(CYOutput &out) const;
415 virtual void Output(CYOutput &out, CYFlags flags) const;
443 std::string filename_;
447 cy::location location_;
448 std::string message_;
451 typedef std::vector<Error> Errors;
459 CYExpression *context_;
461 Context(CYExpression *context) :
466 typedef std::vector<CYWord *> Words;
470 typedef std::vector<Context> Contexts;
473 CYExpression *context_;
485 void ScannerDestroy();
488 CYDriver(apr_pool_t *pool = NULL, const std::string &filename = "");
491 Condition GetCondition();
492 void SetCondition(Condition condition);
494 void PushCondition(Condition condition);
497 void Warning(const cy::location &location, const char *message);
500 struct CYForInitialiser {
501 virtual ~CYForInitialiser() {
504 virtual void For(CYOutput &out) const = 0;
505 virtual CYExpression *Replace(CYContext &context) = 0;
508 struct CYForInInitialiser {
509 virtual ~CYForInInitialiser() {
512 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
513 virtual const char *ForEachIn() const = 0;
514 virtual CYExpression *ForEachIn(CYContext &out) = 0;
515 virtual CYExpression *Replace(CYContext &context) = 0;
521 struct CYExpression :
522 CYNext<CYExpression>,
528 virtual unsigned Precedence() const = 0;
530 virtual bool RightHand() const {
534 virtual void For(CYOutput &out) const;
535 virtual void ForIn(CYOutput &out, CYFlags flags) const;
537 virtual const char *ForEachIn() const;
538 virtual CYExpression *ForEachIn(CYContext &out);
540 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
542 virtual void Output(CYOutput &out) const;
543 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
544 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
546 virtual CYExpression *ClassName(CYContext &context, bool object);
547 virtual void ClassName(CYOutput &out, bool object) const;
549 CYExpression *ReplaceAll(CYContext &context);
551 virtual CYExpression *Replace(CYContext &context) = 0;
553 virtual CYExpression *Primitive(CYContext &context) {
557 virtual CYNumber *Number(CYContext &context) {
561 virtual CYString *String(CYContext &context) {
565 virtual const char *Word() const {
570 #define CYAlphabetic(value) \
571 virtual bool Alphabetic() const { \
575 #define CYPrecedence(value) \
576 virtual unsigned Precedence() const { \
580 #define CYRightHand(value) \
581 virtual bool RightHand() const { \
588 CYExpression *expressions_;
590 CYCompound(CYExpression *expressions = NULL) :
591 expressions_(expressions)
595 void AddPrev(CYExpression *expression) {
596 CYExpression *last(expression);
597 while (last->next_ != NULL)
599 last->SetNext(expressions_);
600 expressions_ = expression;
605 virtual CYExpression *Replace(CYContext &context);
606 void Output(CYOutput &out, CYFlags flags) const;
609 struct CYFunctionParameter :
610 CYNext<CYFunctionParameter>,
615 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
616 CYNext<CYFunctionParameter>(next),
621 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
622 virtual void Output(CYOutput &out) const;
625 struct CYOptionalFunctionParameter :
628 CYExpression *initializer_;
630 CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
631 CYFunctionParameter(name, next),
632 initializer_(initializer)
636 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
637 virtual void Output(CYOutput &out) const;
640 struct CYComprehension :
641 CYNext<CYComprehension>,
644 virtual const char *Name() const = 0;
646 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
647 CYFunctionParameter *Parameters(CYContext &context) const;
648 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
649 virtual void Output(CYOutput &out) const = 0;
652 struct CYForInComprehension :
658 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
664 virtual const char *Name() const {
665 return name_->Word();
668 virtual CYFunctionParameter *Parameter(CYContext &context) const;
669 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
670 virtual void Output(CYOutput &out) const;
673 struct CYForEachInComprehension :
679 CYForEachInComprehension(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 CYIfComprehension :
699 CYIfComprehension(CYExpression *test) :
704 virtual const char *Name() const {
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 CYArrayComprehension :
716 CYExpression *expression_;
717 CYComprehension *comprehensions_;
719 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
720 expression_(expression),
721 comprehensions_(comprehensions)
727 virtual CYExpression *Replace(CYContext &context);
728 virtual void Output(CYOutput &out, CYFlags flags) const;
741 virtual CYExpression *Replace(CYContext &context);
755 CYRange(uint64_t lo, uint64_t hi) :
760 bool operator [](uint8_t value) const {
761 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
764 void operator()(uint8_t value) {
767 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
771 extern CYRange DigitRange_;
772 extern CYRange WordStartRange_;
773 extern CYRange WordEndRange_;
788 CYString(const char *value) :
794 CYString(const char *value, size_t size) :
800 CYString(const CYWord *word) :
801 value_(word->Word()),
802 size_(strlen(value_))
806 const char *Value() const {
810 virtual const char *Word() const;
812 virtual CYNumber *Number(CYContext &context);
813 virtual CYString *String(CYContext &context);
815 CYString *Concat(CYContext &out, CYString *rhs) const;
816 virtual void Output(CYOutput &out, CYFlags flags) const;
817 virtual void PropertyName(CYOutput &out) const;
826 CYNumber(double value) :
831 double Value() const {
835 virtual CYNumber *Number(CYContext &context);
836 virtual CYString *String(CYContext &context);
838 virtual void Output(CYOutput &out, CYFlags flags) const;
839 virtual void PropertyName(CYOutput &out) const;
847 CYRegEx(const char *value) :
852 const char *Value() const {
856 virtual void Output(CYOutput &out, CYFlags flags) const;
868 virtual CYNumber *Number(CYContext &context);
869 virtual CYString *String(CYContext &context);
871 virtual void Output(CYOutput &out, CYFlags flags) const;
883 virtual CYExpression *Replace(CYContext &context);
884 virtual void Output(CYOutput &out, CYFlags flags) const;
890 virtual bool Value() const = 0;
891 virtual void Output(CYOutput &out, CYFlags flags) const;
903 virtual bool Value() const {
907 virtual CYNumber *Number(CYContext &context);
908 virtual CYString *String(CYContext &context);
920 virtual bool Value() const {
924 virtual CYNumber *Number(CYContext &context);
925 virtual CYString *String(CYContext &context);
933 CYVariable(CYIdentifier *name) :
941 virtual CYExpression *Replace(CYContext &context);
942 virtual void Output(CYOutput &out, CYFlags flags) const;
950 CYPrefix(CYExpression *rhs) :
955 virtual bool Alphabetic() const = 0;
956 virtual const char *Operator() const = 0;
960 virtual CYExpression *Replace(CYContext &context);
961 virtual void Output(CYOutput &out, CYFlags flags) const;
970 CYInfix(CYExpression *lhs, CYExpression *rhs) :
976 void SetLeft(CYExpression *lhs) {
980 virtual bool Alphabetic() const = 0;
981 virtual const char *Operator() const = 0;
983 virtual CYExpression *Replace(CYContext &context);
984 virtual void Output(CYOutput &out, CYFlags flags) const;
992 CYPostfix(CYExpression *lhs) :
997 virtual const char *Operator() const = 0;
1001 virtual CYExpression *Replace(CYContext &context);
1002 virtual void Output(CYOutput &out, CYFlags flags) const;
1005 struct CYAssignment :
1011 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1017 void SetLeft(CYExpression *lhs) {
1021 virtual const char *Operator() const = 0;
1025 virtual CYExpression *Replace(CYContext &context);
1026 virtual void Output(CYOutput &out, CYFlags flags) const;
1034 CYExpression *value_;
1036 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1037 CYNext<CYArgument>(next),
1043 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1044 CYNext<CYArgument>(next),
1050 void Replace(CYContext &context);
1051 void Output(CYOutput &out) const;
1067 CYExpression *case_;
1068 CYStatement *statements_;
1070 CYClause(CYExpression *_case, CYStatement *statements) :
1072 statements_(statements)
1076 void Replace(CYContext &context);
1077 virtual void Output(CYOutput &out) const;
1084 CYExpression *value_;
1086 CYElement(CYExpression *value, CYElement *next) :
1087 CYNext<CYElement>(next),
1092 void Replace(CYContext &context);
1093 void Output(CYOutput &out) const;
1099 CYElement *elements_;
1101 CYArray(CYElement *elements = NULL) :
1106 virtual CYExpression *Replace(CYContext &context);
1107 virtual void Output(CYOutput &out, CYFlags flags) const;
1114 CYPropertyName *name_;
1115 CYExpression *value_;
1117 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1118 CYNext<CYProperty>(next),
1124 void Replace(CYContext &context);
1125 virtual void Output(CYOutput &out) const;
1128 struct CYDeclaration :
1131 CYIdentifier *identifier_;
1132 CYExpression *initialiser_;
1134 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1135 identifier_(identifier),
1136 initialiser_(initialiser)
1140 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1142 virtual const char *ForEachIn() const;
1143 virtual CYExpression *ForEachIn(CYContext &out);
1145 virtual CYExpression *Replace(CYContext &context);
1146 virtual CYAssignment *Assignment(CYContext &context);
1148 virtual void Output(CYOutput &out, CYFlags flags) const;
1151 struct CYDeclarations :
1152 CYNext<CYDeclarations>,
1156 CYDeclaration *declaration_;
1158 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1159 CYNext<CYDeclarations>(next),
1160 declaration_(declaration)
1164 virtual void For(CYOutput &out) const;
1166 virtual CYCompound *Replace(CYContext &context);
1167 CYProperty *Property(CYContext &context);
1169 virtual void Output(CYOutput &out) const;
1170 virtual void Output(CYOutput &out, CYFlags flags) const;
1176 CYDeclarations *declarations_;
1178 CYVar(CYDeclarations *declarations) :
1179 declarations_(declarations)
1183 virtual CYStatement *Replace(CYContext &context);
1184 virtual void Output(CYOutput &out, CYFlags flags) const;
1190 CYDeclarations *declarations_;
1193 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1194 declarations_(declarations),
1199 virtual CYStatement *Replace(CYContext &context);
1200 virtual void Output(CYOutput &out, CYFlags flags) const;
1206 CYForInitialiser *initialiser_;
1207 CYExpression *test_;
1208 CYExpression *increment_;
1211 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1212 initialiser_(initialiser),
1214 increment_(increment),
1219 virtual CYStatement *Replace(CYContext &context);
1220 virtual void Output(CYOutput &out, CYFlags flags) const;
1226 CYForInInitialiser *initialiser_;
1230 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1231 initialiser_(initialiser),
1237 virtual CYStatement *Replace(CYContext &context);
1238 virtual void Output(CYOutput &out, CYFlags flags) const;
1241 struct CYForEachIn :
1244 CYForInInitialiser *initialiser_;
1248 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1249 initialiser_(initialiser),
1255 virtual CYStatement *Replace(CYContext &context);
1256 virtual void Output(CYOutput &out, CYFlags flags) const;
1262 CYProperty *properties_;
1264 CYObject(CYProperty *properties) :
1265 properties_(properties)
1269 virtual CYExpression *Replace(CYContext &context);
1270 void Output(CYOutput &out, CYFlags flags) const;
1276 CYExpression *object_;
1277 CYExpression *property_;
1279 CYMember(CYExpression *object, CYExpression *property) :
1285 void SetLeft(CYExpression *object) {
1289 void Replace_(CYContext &context);
1292 struct CYDirectMember :
1295 CYDirectMember(CYExpression *object, CYExpression *property) :
1296 CYMember(object, property)
1303 virtual CYExpression *Replace(CYContext &context);
1304 virtual void Output(CYOutput &out, CYFlags flags) const;
1307 struct CYIndirectMember :
1310 CYIndirectMember(CYExpression *object, CYExpression *property) :
1311 CYMember(object, property)
1318 virtual CYExpression *Replace(CYContext &context);
1319 virtual void Output(CYOutput &out, CYFlags flags) const;
1325 CYExpression *constructor_;
1326 CYArgument *arguments_;
1328 CYNew(CYExpression *constructor, CYArgument *arguments) :
1329 constructor_(constructor),
1330 arguments_(arguments)
1334 virtual unsigned Precedence() const {
1335 return arguments_ == NULL ? 2 : 1;
1340 virtual CYExpression *Replace(CYContext &context);
1341 virtual void Output(CYOutput &out, CYFlags flags) const;
1343 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1349 CYExpression *function_;
1350 CYArgument *arguments_;
1352 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1353 function_(function),
1354 arguments_(arguments)
1361 virtual CYExpression *Replace(CYContext &context);
1362 virtual void Output(CYOutput &out, CYFlags flags) const;
1364 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1369 struct CYRubyBlock :
1372 CYExpression *call_;
1375 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1384 virtual CYExpression *Replace(CYContext &context);
1385 virtual void Output(CYOutput &out, CYFlags flags) const;
1391 CYExpression *test_;
1393 CYStatement *false_;
1395 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1402 virtual CYStatement *Replace(CYContext &context);
1403 virtual void Output(CYOutput &out, CYFlags flags) const;
1409 CYExpression *test_;
1412 CYDoWhile(CYExpression *test, CYStatement *code) :
1418 virtual CYStatement *Replace(CYContext &context);
1419 virtual void Output(CYOutput &out, CYFlags flags) const;
1425 CYExpression *test_;
1428 CYWhile(CYExpression *test, CYStatement *code) :
1434 virtual CYStatement *Replace(CYContext &context);
1435 virtual void Output(CYOutput &out, CYFlags flags) const;
1438 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
1440 CYIdentifier *name_;
1441 CYFunctionParameter *parameters_;
1444 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1446 parameters_(parameters),
1451 virtual ~CYFunction() {
1454 void Inject(CYContext &context);
1455 virtual void Replace_(CYContext &context, bool outer);
1456 virtual void Output(CYOutput &out, CYFlags flags) const;
1459 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
1460 struct CYFunctionExpression :
1464 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1465 CYFunction(name, parameters, statements)
1472 virtual CYExpression *Replace(CYContext &context);
1473 virtual void Output(CYOutput &out, CYFlags flags) const;
1476 // XXX: this should derive from CYAnonymousFunctionExpression
1478 CYFunctionExpression
1480 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1481 CYFunctionExpression(NULL, parameters, statements)
1485 virtual CYExpression *Replace(CYContext &context);
1486 virtual void Output(CYOutput &out, CYFlags flags) const;
1489 // XXX: this should derive from CYNamedFunction
1490 struct CYFunctionStatement :
1494 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1495 CYFunction(name, parameters, statements)
1499 virtual CYStatement *Replace(CYContext &context);
1500 virtual void Output(CYOutput &out, CYFlags flags) const;
1506 CYExpression *expression_;
1508 CYExpress(CYExpression *expression) :
1509 expression_(expression)
1511 if (expression == NULL)
1515 virtual CYStatement *Collapse(CYContext &context);
1516 virtual CYStatement *Replace(CYContext &context);
1517 virtual void Output(CYOutput &out, CYFlags flags) const;
1523 CYIdentifier *label_;
1525 CYContinue(CYIdentifier *label) :
1530 virtual CYStatement *Replace(CYContext &context);
1531 virtual void Output(CYOutput &out, CYFlags flags) const;
1537 CYIdentifier *label_;
1539 CYBreak(CYIdentifier *label) :
1544 virtual CYStatement *Replace(CYContext &context);
1545 virtual void Output(CYOutput &out, CYFlags flags) const;
1551 CYExpression *value_;
1553 CYReturn(CYExpression *value) :
1558 virtual CYStatement *Replace(CYContext &context);
1559 virtual void Output(CYOutput &out, CYFlags flags) const;
1565 virtual CYStatement *Collapse(CYContext &context);
1566 virtual CYStatement *Replace(CYContext &context);
1567 virtual void Output(CYOutput &out, CYFlags flags) const;
1575 CYFinally(CYStatement *statements) :
1580 void Replace(CYContext &context);
1581 virtual void Output(CYOutput &out) const;
1590 CYIdentifier *name_;
1593 Catch(CYIdentifier *name, CYStatement *statements) :
1599 void Replace(CYContext &context);
1600 virtual void Output(CYOutput &out) const;
1608 CYFinally *finally_;
1610 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1617 virtual CYStatement *Replace(CYContext &context);
1618 virtual void Output(CYOutput &out, CYFlags flags) const;
1624 CYExpression *value_;
1626 Throw(CYExpression *value) :
1631 virtual CYStatement *Replace(CYContext &context);
1632 virtual void Output(CYOutput &out, CYFlags flags) const;
1640 CYExpression *scope_;
1643 CYWith(CYExpression *scope, CYStatement *code) :
1649 virtual CYStatement *Replace(CYContext &context);
1650 virtual void Output(CYOutput &out, CYFlags flags) const;
1656 CYExpression *value_;
1659 CYSwitch(CYExpression *value, CYClause *clauses) :
1665 virtual CYStatement *Replace(CYContext &context);
1666 virtual void Output(CYOutput &out, CYFlags flags) const;
1669 struct CYCondition :
1672 CYExpression *test_;
1673 CYExpression *true_;
1674 CYExpression *false_;
1676 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1685 virtual CYExpression *Replace(CYContext &context);
1686 virtual void Output(CYOutput &out, CYFlags flags) const;
1689 struct CYAddressOf :
1692 CYAddressOf(CYExpression *rhs) :
1697 virtual const char *Operator() const {
1703 virtual CYExpression *Replace(CYContext &context);
1709 CYIndirect(CYExpression *rhs) :
1714 virtual const char *Operator() const {
1720 virtual CYExpression *Replace(CYContext &context);
1724 virtual CYExpression *Replace(CYContext &context);
1726 #define CYPostfix_(op, name, args...) \
1727 struct CY ## name : \
1730 CY ## name(CYExpression *lhs) : \
1735 virtual const char *Operator() const { \
1740 #define CYPrefix_(alphabetic, op, name, args...) \
1741 struct CY ## name : \
1744 CY ## name(CYExpression *rhs) : \
1749 CYAlphabetic(alphabetic) \
1751 virtual const char *Operator() const { \
1756 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1757 struct CY ## name : \
1760 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1765 CYAlphabetic(alphabetic) \
1766 CYPrecedence(precedence) \
1768 virtual const char *Operator() const { \
1773 #define CYAssignment_(op, name, args...) \
1774 struct CY ## name ## Assign : \
1777 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1778 CYAssignment(lhs, rhs) \
1782 virtual const char *Operator() const { \
1787 CYPostfix_("++", PostIncrement)
1788 CYPostfix_("--", PostDecrement)
1790 CYPrefix_(true, "delete", Delete)
1791 CYPrefix_(true, "void", Void)
1792 CYPrefix_(true, "typeof", TypeOf)
1793 CYPrefix_(false, "++", PreIncrement)
1794 CYPrefix_(false, "--", PreDecrement)
1795 CYPrefix_(false, "+", Affirm)
1796 CYPrefix_(false, "-", Negate)
1797 CYPrefix_(false, "~", BitwiseNot)
1798 CYPrefix_(false, "!", LogicalNot)
1800 CYInfix_(false, 5, "*", Multiply)
1801 CYInfix_(false, 5, "/", Divide)
1802 CYInfix_(false, 5, "%", Modulus)
1803 CYInfix_(false, 6, "+", Add, CYReplace)
1804 CYInfix_(false, 6, "-", Subtract)
1805 CYInfix_(false, 7, "<<", ShiftLeft)
1806 CYInfix_(false, 7, ">>", ShiftRightSigned)
1807 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1808 CYInfix_(false, 8, "<", Less)
1809 CYInfix_(false, 8, ">", Greater)
1810 CYInfix_(false, 8, "<=", LessOrEqual)
1811 CYInfix_(false, 8, ">=", GreaterOrEqual)
1812 CYInfix_(true, 8, "instanceof", InstanceOf)
1813 CYInfix_(true, 8, "in", In)
1814 CYInfix_(false, 9, "==", Equal)
1815 CYInfix_(false, 9, "!=", NotEqual)
1816 CYInfix_(false, 9, "===", Identical)
1817 CYInfix_(false, 9, "!==", NotIdentical)
1818 CYInfix_(false, 10, "&", BitwiseAnd)
1819 CYInfix_(false, 11, "^", BitwiseXOr)
1820 CYInfix_(false, 12, "|", BitwiseOr)
1821 CYInfix_(false, 13, "&&", LogicalAnd)
1822 CYInfix_(false, 14, "||", LogicalOr)
1824 CYAssignment_("=", )
1825 CYAssignment_("*=", Multiply)
1826 CYAssignment_("/=", Divide)
1827 CYAssignment_("%=", Modulus)
1828 CYAssignment_("+=", Add)
1829 CYAssignment_("-=", Subtract)
1830 CYAssignment_("<<=", ShiftLeft)
1831 CYAssignment_(">>=", ShiftRightSigned)
1832 CYAssignment_(">>>=", ShiftRightUnsigned)
1833 CYAssignment_("&=", BitwiseAnd)
1834 CYAssignment_("^=", BitwiseXOr)
1835 CYAssignment_("|=", BitwiseOr)
1837 #endif/*CYPARSER_HPP*/