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;
367 CYIdentifierUsageVector rename_;
369 CYNonLocal *nonlocal_;
370 CYNonLocal *nextlocal_;
373 CYContext(apr_pool_t *pool, CYOptions &options) :
383 virtual ~CYContext() {
386 template <typename Type_>
387 void Replace(Type_ *&value) {
388 for (;;) if (value == NULL)
391 Type_ *replace(value->Replace(*this));
392 if (replace != value)
398 void NonLocal(CYStatement *&statements);
399 CYIdentifier *Unique();
403 CYIdentifier *identifier_;
410 CYIdentifier *Target(CYContext &context) {
411 if (identifier_ == NULL)
412 identifier_ = context.Unique();
421 CYStatement *statements_;
423 CYBlock(CYStatement *statements) :
424 statements_(statements)
428 operator CYStatement *() const {
432 void AddPrev(CYStatement *statement) {
433 CYStatement *last(statement);
434 while (last->next_ != NULL)
436 last->SetNext(statements_);
437 statements_ = statement;
440 virtual CYStatement *Replace(CYContext &context);
442 virtual void Output(CYOutput &out) const;
443 virtual void Output(CYOutput &out, CYFlags flags) const;
471 std::string filename_;
475 cy::location location_;
476 std::string message_;
479 typedef std::vector<Error> Errors;
487 CYExpression *context_;
489 Context(CYExpression *context) :
494 typedef std::vector<CYWord *> Words;
498 typedef std::vector<Context> Contexts;
501 CYExpression *context_;
513 void ScannerDestroy();
516 CYDriver(apr_pool_t *pool = NULL, const std::string &filename = "");
519 Condition GetCondition();
520 void SetCondition(Condition condition);
522 void PushCondition(Condition condition);
525 void Warning(const cy::location &location, const char *message);
528 struct CYForInitialiser {
529 virtual ~CYForInitialiser() {
532 virtual void For(CYOutput &out) const = 0;
533 virtual CYExpression *Replace(CYContext &context) = 0;
536 struct CYForInInitialiser {
537 virtual ~CYForInInitialiser() {
540 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
541 virtual const char *ForEachIn() const = 0;
542 virtual CYExpression *ForEachIn(CYContext &out) = 0;
543 virtual CYExpression *Replace(CYContext &context) = 0;
549 struct CYExpression :
550 CYNext<CYExpression>,
556 virtual unsigned Precedence() const = 0;
558 virtual bool RightHand() const {
562 virtual void For(CYOutput &out) const;
563 virtual void ForIn(CYOutput &out, CYFlags flags) const;
565 virtual const char *ForEachIn() const;
566 virtual CYExpression *ForEachIn(CYContext &out);
568 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
570 virtual void Output(CYOutput &out) const;
571 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
572 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
574 virtual CYExpression *ClassName(CYContext &context, bool object);
575 virtual void ClassName(CYOutput &out, bool object) const;
577 CYExpression *ReplaceAll(CYContext &context);
579 virtual CYExpression *Replace(CYContext &context) = 0;
581 virtual CYExpression *Primitive(CYContext &context) {
585 virtual CYNumber *Number(CYContext &context) {
589 virtual CYString *String(CYContext &context) {
593 virtual const char *Word() const {
598 #define CYAlphabetic(value) \
599 virtual bool Alphabetic() const { \
603 #define CYPrecedence(value) \
604 virtual unsigned Precedence() const { \
608 #define CYRightHand(value) \
609 virtual bool RightHand() const { \
616 CYExpression *expressions_;
618 CYCompound(CYExpression *expressions = NULL) :
619 expressions_(expressions)
623 void AddPrev(CYExpression *expression) {
624 CYExpression *last(expression);
625 while (last->next_ != NULL)
627 last->SetNext(expressions_);
628 expressions_ = expression;
633 virtual CYExpression *Replace(CYContext &context);
634 void Output(CYOutput &out, CYFlags flags) const;
637 struct CYFunctionParameter :
638 CYNext<CYFunctionParameter>,
643 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
644 CYNext<CYFunctionParameter>(next),
649 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
650 virtual void Output(CYOutput &out) const;
653 struct CYOptionalFunctionParameter :
656 CYExpression *initializer_;
658 CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
659 CYFunctionParameter(name, next),
660 initializer_(initializer)
664 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
665 virtual void Output(CYOutput &out) const;
668 struct CYComprehension :
669 CYNext<CYComprehension>,
672 virtual const char *Name() const = 0;
674 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
675 CYFunctionParameter *Parameters(CYContext &context) const;
676 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
677 virtual void Output(CYOutput &out) const = 0;
680 struct CYForInComprehension :
686 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
692 virtual const char *Name() const {
693 return name_->Word();
696 virtual CYFunctionParameter *Parameter(CYContext &context) const;
697 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
698 virtual void Output(CYOutput &out) const;
701 struct CYForEachInComprehension :
707 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
713 virtual const char *Name() const {
714 return name_->Word();
717 virtual CYFunctionParameter *Parameter(CYContext &context) const;
718 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
719 virtual void Output(CYOutput &out) const;
722 struct CYIfComprehension :
727 CYIfComprehension(CYExpression *test) :
732 virtual const char *Name() const {
736 virtual CYFunctionParameter *Parameter(CYContext &context) const;
737 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
738 virtual void Output(CYOutput &out) const;
741 struct CYArrayComprehension :
744 CYExpression *expression_;
745 CYComprehension *comprehensions_;
747 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
748 expression_(expression),
749 comprehensions_(comprehensions)
755 virtual CYExpression *Replace(CYContext &context);
756 virtual void Output(CYOutput &out, CYFlags flags) const;
769 virtual CYExpression *Replace(CYContext &context);
783 CYRange(uint64_t lo, uint64_t hi) :
788 bool operator [](uint8_t value) const {
789 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
792 void operator()(uint8_t value) {
795 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
799 extern CYRange DigitRange_;
800 extern CYRange WordStartRange_;
801 extern CYRange WordEndRange_;
816 CYString(const char *value) :
822 CYString(const char *value, size_t size) :
828 CYString(const CYWord *word) :
829 value_(word->Word()),
830 size_(strlen(value_))
834 const char *Value() const {
838 virtual const char *Word() const;
840 virtual CYNumber *Number(CYContext &context);
841 virtual CYString *String(CYContext &context);
843 CYString *Concat(CYContext &out, CYString *rhs) const;
844 virtual void Output(CYOutput &out, CYFlags flags) const;
845 virtual void PropertyName(CYOutput &out) const;
854 CYNumber(double value) :
859 double Value() const {
863 virtual CYNumber *Number(CYContext &context);
864 virtual CYString *String(CYContext &context);
866 virtual void Output(CYOutput &out, CYFlags flags) const;
867 virtual void PropertyName(CYOutput &out) const;
875 CYRegEx(const char *value) :
880 const char *Value() const {
884 virtual void Output(CYOutput &out, CYFlags flags) const;
896 virtual CYNumber *Number(CYContext &context);
897 virtual CYString *String(CYContext &context);
899 virtual void Output(CYOutput &out, CYFlags flags) const;
911 virtual CYExpression *Replace(CYContext &context);
912 virtual void Output(CYOutput &out, CYFlags flags) const;
918 virtual bool Value() const = 0;
919 virtual void Output(CYOutput &out, CYFlags flags) const;
931 virtual bool Value() const {
935 virtual CYNumber *Number(CYContext &context);
936 virtual CYString *String(CYContext &context);
948 virtual bool Value() const {
952 virtual CYNumber *Number(CYContext &context);
953 virtual CYString *String(CYContext &context);
961 CYVariable(CYIdentifier *name) :
969 virtual CYExpression *Replace(CYContext &context);
970 virtual void Output(CYOutput &out, CYFlags flags) const;
978 CYPrefix(CYExpression *rhs) :
983 virtual bool Alphabetic() const = 0;
984 virtual const char *Operator() const = 0;
988 virtual CYExpression *Replace(CYContext &context);
989 virtual void Output(CYOutput &out, CYFlags flags) const;
998 CYInfix(CYExpression *lhs, CYExpression *rhs) :
1004 void SetLeft(CYExpression *lhs) {
1008 virtual bool Alphabetic() const = 0;
1009 virtual const char *Operator() const = 0;
1011 virtual CYExpression *Replace(CYContext &context);
1012 virtual void Output(CYOutput &out, CYFlags flags) const;
1020 CYPostfix(CYExpression *lhs) :
1025 virtual const char *Operator() const = 0;
1029 virtual CYExpression *Replace(CYContext &context);
1030 virtual void Output(CYOutput &out, CYFlags flags) const;
1033 struct CYAssignment :
1039 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1045 void SetLeft(CYExpression *lhs) {
1049 virtual const char *Operator() const = 0;
1053 virtual CYExpression *Replace(CYContext &context);
1054 virtual void Output(CYOutput &out, CYFlags flags) const;
1062 CYExpression *value_;
1064 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1065 CYNext<CYArgument>(next),
1071 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1072 CYNext<CYArgument>(next),
1078 void Replace(CYContext &context);
1079 void Output(CYOutput &out) const;
1095 CYExpression *case_;
1096 CYStatement *statements_;
1098 CYClause(CYExpression *_case, CYStatement *statements) :
1100 statements_(statements)
1104 void Replace(CYContext &context);
1105 virtual void Output(CYOutput &out) const;
1112 CYExpression *value_;
1114 CYElement(CYExpression *value, CYElement *next) :
1115 CYNext<CYElement>(next),
1120 void Replace(CYContext &context);
1121 void Output(CYOutput &out) const;
1127 CYElement *elements_;
1129 CYArray(CYElement *elements = NULL) :
1134 virtual CYExpression *Replace(CYContext &context);
1135 virtual void Output(CYOutput &out, CYFlags flags) const;
1142 CYPropertyName *name_;
1143 CYExpression *value_;
1145 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1146 CYNext<CYProperty>(next),
1152 void Replace(CYContext &context);
1153 virtual void Output(CYOutput &out) const;
1156 struct CYDeclaration :
1159 CYIdentifier *identifier_;
1160 CYExpression *initialiser_;
1162 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1163 identifier_(identifier),
1164 initialiser_(initialiser)
1168 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1170 virtual const char *ForEachIn() const;
1171 virtual CYExpression *ForEachIn(CYContext &out);
1173 virtual CYExpression *Replace(CYContext &context);
1174 virtual CYAssignment *Assignment(CYContext &context);
1176 virtual void Output(CYOutput &out, CYFlags flags) const;
1179 struct CYDeclarations :
1180 CYNext<CYDeclarations>,
1184 CYDeclaration *declaration_;
1186 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1187 CYNext<CYDeclarations>(next),
1188 declaration_(declaration)
1192 virtual void For(CYOutput &out) const;
1194 virtual CYCompound *Replace(CYContext &context);
1195 CYProperty *Property(CYContext &context);
1197 virtual void Output(CYOutput &out) const;
1198 virtual void Output(CYOutput &out, CYFlags flags) const;
1204 CYDeclarations *declarations_;
1206 CYVar(CYDeclarations *declarations) :
1207 declarations_(declarations)
1211 virtual CYStatement *Replace(CYContext &context);
1212 virtual void Output(CYOutput &out, CYFlags flags) const;
1218 CYDeclarations *declarations_;
1221 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1222 declarations_(declarations),
1227 virtual CYStatement *Replace(CYContext &context);
1228 virtual void Output(CYOutput &out, CYFlags flags) const;
1234 CYForInitialiser *initialiser_;
1235 CYExpression *test_;
1236 CYExpression *increment_;
1239 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1240 initialiser_(initialiser),
1242 increment_(increment),
1247 virtual CYStatement *Replace(CYContext &context);
1248 virtual void Output(CYOutput &out, CYFlags flags) const;
1254 CYForInInitialiser *initialiser_;
1258 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1259 initialiser_(initialiser),
1265 virtual CYStatement *Replace(CYContext &context);
1266 virtual void Output(CYOutput &out, CYFlags flags) const;
1269 struct CYForEachIn :
1272 CYForInInitialiser *initialiser_;
1276 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1277 initialiser_(initialiser),
1283 virtual CYStatement *Replace(CYContext &context);
1284 virtual void Output(CYOutput &out, CYFlags flags) const;
1290 CYProperty *properties_;
1292 CYObject(CYProperty *properties = NULL) :
1293 properties_(properties)
1297 virtual CYExpression *Replace(CYContext &context);
1298 void Output(CYOutput &out, CYFlags flags) const;
1304 CYExpression *object_;
1305 CYExpression *property_;
1307 CYMember(CYExpression *object, CYExpression *property) :
1313 void SetLeft(CYExpression *object) {
1317 void Replace_(CYContext &context);
1320 struct CYDirectMember :
1323 CYDirectMember(CYExpression *object, CYExpression *property) :
1324 CYMember(object, property)
1331 virtual CYExpression *Replace(CYContext &context);
1332 virtual void Output(CYOutput &out, CYFlags flags) const;
1335 struct CYIndirectMember :
1338 CYIndirectMember(CYExpression *object, CYExpression *property) :
1339 CYMember(object, property)
1346 virtual CYExpression *Replace(CYContext &context);
1347 virtual void Output(CYOutput &out, CYFlags flags) const;
1353 CYExpression *constructor_;
1354 CYArgument *arguments_;
1356 CYNew(CYExpression *constructor, CYArgument *arguments) :
1357 constructor_(constructor),
1358 arguments_(arguments)
1362 virtual unsigned Precedence() const {
1363 return arguments_ == NULL ? 2 : 1;
1368 virtual CYExpression *Replace(CYContext &context);
1369 virtual void Output(CYOutput &out, CYFlags flags) const;
1371 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1377 CYExpression *function_;
1378 CYArgument *arguments_;
1380 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1381 function_(function),
1382 arguments_(arguments)
1389 virtual CYExpression *Replace(CYContext &context);
1390 virtual void Output(CYOutput &out, CYFlags flags) const;
1392 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1397 struct CYRubyBlock :
1400 CYExpression *call_;
1403 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1412 virtual CYExpression *Replace(CYContext &context);
1413 virtual void Output(CYOutput &out, CYFlags flags) const;
1419 CYExpression *test_;
1421 CYStatement *false_;
1423 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1430 virtual CYStatement *Replace(CYContext &context);
1431 virtual void Output(CYOutput &out, CYFlags flags) const;
1437 CYExpression *test_;
1440 CYDoWhile(CYExpression *test, CYStatement *code) :
1446 virtual CYStatement *Replace(CYContext &context);
1447 virtual void Output(CYOutput &out, CYFlags flags) const;
1453 CYExpression *test_;
1456 CYWhile(CYExpression *test, CYStatement *code) :
1462 virtual CYStatement *Replace(CYContext &context);
1463 virtual void Output(CYOutput &out, CYFlags flags) const;
1466 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
1468 CYIdentifier *name_;
1469 CYFunctionParameter *parameters_;
1471 CYNonLocal *nonlocal_;
1473 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1475 parameters_(parameters),
1481 virtual ~CYFunction() {
1484 void Inject(CYContext &context);
1485 virtual void Replace_(CYContext &context, bool outer);
1486 virtual void Output(CYOutput &out, CYFlags flags) const;
1489 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
1490 struct CYFunctionExpression :
1494 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1495 CYFunction(name, parameters, statements)
1502 virtual CYExpression *Replace(CYContext &context);
1503 virtual void Output(CYOutput &out, CYFlags flags) const;
1506 // XXX: this should derive from CYAnonymousFunctionExpression
1508 CYFunctionExpression
1510 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1511 CYFunctionExpression(NULL, parameters, statements)
1515 virtual CYExpression *Replace(CYContext &context);
1516 virtual void Output(CYOutput &out, CYFlags flags) const;
1519 // XXX: this should derive from CYNamedFunction
1520 struct CYFunctionStatement :
1524 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1525 CYFunction(name, parameters, statements)
1529 virtual CYStatement *Replace(CYContext &context);
1530 virtual void Output(CYOutput &out, CYFlags flags) const;
1536 CYExpression *expression_;
1538 CYExpress(CYExpression *expression) :
1539 expression_(expression)
1541 if (expression == NULL)
1545 virtual CYStatement *Collapse(CYContext &context);
1546 virtual CYStatement *Replace(CYContext &context);
1547 virtual void Output(CYOutput &out, CYFlags flags) const;
1553 CYIdentifier *label_;
1555 CYContinue(CYIdentifier *label) :
1560 virtual CYStatement *Replace(CYContext &context);
1561 virtual void Output(CYOutput &out, CYFlags flags) const;
1567 CYIdentifier *label_;
1569 CYBreak(CYIdentifier *label) :
1574 virtual CYStatement *Replace(CYContext &context);
1575 virtual void Output(CYOutput &out, CYFlags flags) const;
1581 CYExpression *value_;
1583 CYReturn(CYExpression *value) :
1588 virtual CYStatement *Replace(CYContext &context);
1589 virtual void Output(CYOutput &out, CYFlags flags) const;
1595 virtual CYStatement *Collapse(CYContext &context);
1596 virtual CYStatement *Replace(CYContext &context);
1597 virtual void Output(CYOutput &out, CYFlags flags) const;
1605 CYFinally(CYStatement *statements) :
1610 void Replace(CYContext &context);
1611 virtual void Output(CYOutput &out) const;
1620 CYIdentifier *name_;
1623 Catch(CYIdentifier *name, CYStatement *statements) :
1629 void Replace(CYContext &context);
1630 virtual void Output(CYOutput &out) const;
1638 CYFinally *finally_;
1640 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1647 virtual CYStatement *Replace(CYContext &context);
1648 virtual void Output(CYOutput &out, CYFlags flags) const;
1654 CYExpression *value_;
1656 Throw(CYExpression *value = NULL) :
1661 virtual CYStatement *Replace(CYContext &context);
1662 virtual void Output(CYOutput &out, CYFlags flags) const;
1670 CYExpression *scope_;
1673 CYWith(CYExpression *scope, CYStatement *code) :
1679 virtual CYStatement *Replace(CYContext &context);
1680 virtual void Output(CYOutput &out, CYFlags flags) const;
1686 CYExpression *value_;
1689 CYSwitch(CYExpression *value, CYClause *clauses) :
1695 virtual CYStatement *Replace(CYContext &context);
1696 virtual void Output(CYOutput &out, CYFlags flags) const;
1699 struct CYCondition :
1702 CYExpression *test_;
1703 CYExpression *true_;
1704 CYExpression *false_;
1706 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1715 virtual CYExpression *Replace(CYContext &context);
1716 virtual void Output(CYOutput &out, CYFlags flags) const;
1719 struct CYAddressOf :
1722 CYAddressOf(CYExpression *rhs) :
1727 virtual const char *Operator() const {
1733 virtual CYExpression *Replace(CYContext &context);
1739 CYIndirect(CYExpression *rhs) :
1744 virtual const char *Operator() const {
1750 virtual CYExpression *Replace(CYContext &context);
1754 virtual CYExpression *Replace(CYContext &context);
1756 #define CYPostfix_(op, name, args...) \
1757 struct CY ## name : \
1760 CY ## name(CYExpression *lhs) : \
1765 virtual const char *Operator() const { \
1770 #define CYPrefix_(alphabetic, op, name, args...) \
1771 struct CY ## name : \
1774 CY ## name(CYExpression *rhs) : \
1779 CYAlphabetic(alphabetic) \
1781 virtual const char *Operator() const { \
1786 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1787 struct CY ## name : \
1790 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1795 CYAlphabetic(alphabetic) \
1796 CYPrecedence(precedence) \
1798 virtual const char *Operator() const { \
1803 #define CYAssignment_(op, name, args...) \
1804 struct CY ## name ## Assign : \
1807 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1808 CYAssignment(lhs, rhs) \
1812 virtual const char *Operator() const { \
1817 CYPostfix_("++", PostIncrement)
1818 CYPostfix_("--", PostDecrement)
1820 CYPrefix_(true, "delete", Delete)
1821 CYPrefix_(true, "void", Void)
1822 CYPrefix_(true, "typeof", TypeOf)
1823 CYPrefix_(false, "++", PreIncrement)
1824 CYPrefix_(false, "--", PreDecrement)
1825 CYPrefix_(false, "+", Affirm)
1826 CYPrefix_(false, "-", Negate)
1827 CYPrefix_(false, "~", BitwiseNot)
1828 CYPrefix_(false, "!", LogicalNot)
1830 CYInfix_(false, 5, "*", Multiply)
1831 CYInfix_(false, 5, "/", Divide)
1832 CYInfix_(false, 5, "%", Modulus)
1833 CYInfix_(false, 6, "+", Add, CYReplace)
1834 CYInfix_(false, 6, "-", Subtract)
1835 CYInfix_(false, 7, "<<", ShiftLeft)
1836 CYInfix_(false, 7, ">>", ShiftRightSigned)
1837 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1838 CYInfix_(false, 8, "<", Less)
1839 CYInfix_(false, 8, ">", Greater)
1840 CYInfix_(false, 8, "<=", LessOrEqual)
1841 CYInfix_(false, 8, ">=", GreaterOrEqual)
1842 CYInfix_(true, 8, "instanceof", InstanceOf)
1843 CYInfix_(true, 8, "in", In)
1844 CYInfix_(false, 9, "==", Equal)
1845 CYInfix_(false, 9, "!=", NotEqual)
1846 CYInfix_(false, 9, "===", Identical)
1847 CYInfix_(false, 9, "!==", NotIdentical)
1848 CYInfix_(false, 10, "&", BitwiseAnd)
1849 CYInfix_(false, 11, "^", BitwiseXOr)
1850 CYInfix_(false, 12, "|", BitwiseOr)
1851 CYInfix_(false, 13, "&&", LogicalAnd)
1852 CYInfix_(false, 14, "||", LogicalOr)
1854 CYAssignment_("=", )
1855 CYAssignment_("*=", Multiply)
1856 CYAssignment_("/=", Divide)
1857 CYAssignment_("%=", Modulus)
1858 CYAssignment_("+=", Add)
1859 CYAssignment_("-=", Subtract)
1860 CYAssignment_("<<=", ShiftLeft)
1861 CYAssignment_(">>=", ShiftRightSigned)
1862 CYAssignment_(">>>=", ShiftRightUnsigned)
1863 CYAssignment_("&=", BitwiseAnd)
1864 CYAssignment_("^=", BitwiseXOr)
1865 CYAssignment_("|=", BitwiseOr)
1867 #endif/*CYPARSER_HPP*/