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,
316 typedef std::set<const char *, CYCStringLess> CYCStringSet;
317 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
318 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
320 struct CYIdentifierUsage {
321 CYIdentifier *identifier_;
325 typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
327 // XXX: strategy pattern, maybe subclass
338 CYStatement *&statements_;
342 CYIdentifierAddressFlagsMap internal_;
343 CYIdentifierValueSet identifiers_;
345 CYScope(CYScopeType type, CYContext &context, CYStatement *&statements);
349 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
350 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
351 void Merge(CYContext &context, CYIdentifier *identifier);
352 void Scope(CYContext &context, CYStatement *&statements);
358 CYStatement *statements_;
360 CYProgram(CYStatement *statements) :
361 statements_(statements)
365 virtual void Replace(CYContext &context);
366 virtual void Output(CYOutput &out) const;
376 CYIdentifierUsageVector rename_;
378 CYNonLocal *nonlocal_;
379 CYNonLocal *nextlocal_;
382 CYContext(apr_pool_t *pool, CYOptions &options) :
392 virtual ~CYContext() {
395 template <typename Type_>
396 void Replace(Type_ *&value) {
397 for (;;) if (value == NULL)
400 Type_ *replace(value->Replace(*this));
401 if (replace != value)
407 void NonLocal(CYStatement *&statements);
408 CYIdentifier *Unique();
412 CYIdentifier *identifier_;
419 CYIdentifier *Target(CYContext &context) {
420 if (identifier_ == NULL)
421 identifier_ = context.Unique();
430 CYStatement *statements_;
432 CYBlock(CYStatement *statements) :
433 statements_(statements)
437 operator CYStatement *() const {
441 void AddPrev(CYStatement *statement) {
442 CYStatement *last(statement);
443 while (last->next_ != NULL)
445 last->SetNext(statements_);
446 statements_ = statement;
449 virtual CYStatement *Replace(CYContext &context);
451 virtual void Output(CYOutput &out) const;
452 virtual void Output(CYOutput &out, CYFlags flags) const;
480 std::string filename_;
484 cy::location location_;
485 std::string message_;
488 typedef std::vector<Error> Errors;
496 CYExpression *context_;
498 Context(CYExpression *context) :
503 typedef std::vector<CYWord *> Words;
507 typedef std::vector<Context> Contexts;
510 CYExpression *context_;
522 void ScannerDestroy();
525 CYDriver(apr_pool_t *pool = NULL, const std::string &filename = "");
528 Condition GetCondition();
529 void SetCondition(Condition condition);
531 void PushCondition(Condition condition);
534 void Warning(const cy::location &location, const char *message);
537 struct CYForInitialiser {
538 virtual ~CYForInitialiser() {
541 virtual void For(CYOutput &out) const = 0;
542 virtual CYExpression *Replace(CYContext &context) = 0;
545 struct CYForInInitialiser {
546 virtual ~CYForInInitialiser() {
549 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
550 virtual const char *ForEachIn() const = 0;
551 virtual CYExpression *ForEachIn(CYContext &out) = 0;
552 virtual CYExpression *Replace(CYContext &context) = 0;
558 struct CYExpression :
559 CYNext<CYExpression>,
565 virtual unsigned Precedence() const = 0;
567 virtual bool RightHand() const {
571 virtual void For(CYOutput &out) const;
572 virtual void ForIn(CYOutput &out, CYFlags flags) const;
574 virtual const char *ForEachIn() const;
575 virtual CYExpression *ForEachIn(CYContext &out);
577 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
579 virtual void Output(CYOutput &out) const;
580 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
581 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
583 virtual CYExpression *ClassName(CYContext &context, bool object);
584 virtual void ClassName(CYOutput &out, bool object) const;
586 CYExpression *ReplaceAll(CYContext &context);
588 virtual CYExpression *Replace(CYContext &context) = 0;
590 virtual CYExpression *Primitive(CYContext &context) {
594 virtual CYNumber *Number(CYContext &context) {
598 virtual CYString *String(CYContext &context) {
602 virtual const char *Word() const {
607 #define CYAlphabetic(value) \
608 virtual bool Alphabetic() const { \
612 #define CYPrecedence(value) \
613 virtual unsigned Precedence() const { \
617 #define CYRightHand(value) \
618 virtual bool RightHand() const { \
625 CYExpression *expressions_;
627 CYCompound(CYExpression *expressions = NULL) :
628 expressions_(expressions)
632 void AddPrev(CYExpression *expression) {
633 CYExpression *last(expression);
634 while (last->next_ != NULL)
636 last->SetNext(expressions_);
637 expressions_ = expression;
642 virtual CYExpression *Replace(CYContext &context);
643 void Output(CYOutput &out, CYFlags flags) const;
646 struct CYFunctionParameter :
647 CYNext<CYFunctionParameter>,
652 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
653 CYNext<CYFunctionParameter>(next),
658 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
659 virtual void Output(CYOutput &out) const;
662 struct CYOptionalFunctionParameter :
665 CYExpression *initializer_;
667 CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
668 CYFunctionParameter(name, next),
669 initializer_(initializer)
673 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
674 virtual void Output(CYOutput &out) const;
677 struct CYComprehension :
678 CYNext<CYComprehension>,
681 virtual const char *Name() const = 0;
683 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
684 CYFunctionParameter *Parameters(CYContext &context) const;
685 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
686 virtual void Output(CYOutput &out) const = 0;
689 struct CYForInComprehension :
695 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
701 virtual const char *Name() const {
702 return name_->Word();
705 virtual CYFunctionParameter *Parameter(CYContext &context) const;
706 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
707 virtual void Output(CYOutput &out) const;
710 struct CYForEachInComprehension :
716 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
722 virtual const char *Name() const {
723 return name_->Word();
726 virtual CYFunctionParameter *Parameter(CYContext &context) const;
727 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
728 virtual void Output(CYOutput &out) const;
731 struct CYIfComprehension :
736 CYIfComprehension(CYExpression *test) :
741 virtual const char *Name() const {
745 virtual CYFunctionParameter *Parameter(CYContext &context) const;
746 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
747 virtual void Output(CYOutput &out) const;
750 struct CYArrayComprehension :
753 CYExpression *expression_;
754 CYComprehension *comprehensions_;
756 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
757 expression_(expression),
758 comprehensions_(comprehensions)
764 virtual CYExpression *Replace(CYContext &context);
765 virtual void Output(CYOutput &out, CYFlags flags) const;
778 virtual CYExpression *Replace(CYContext &context);
792 CYRange(uint64_t lo, uint64_t hi) :
797 bool operator [](uint8_t value) const {
798 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
801 void operator()(uint8_t value) {
804 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
808 extern CYRange DigitRange_;
809 extern CYRange WordStartRange_;
810 extern CYRange WordEndRange_;
825 CYString(const char *value) :
831 CYString(const char *value, size_t size) :
837 CYString(const CYWord *word) :
838 value_(word->Word()),
839 size_(strlen(value_))
843 const char *Value() const {
847 virtual const char *Word() const;
849 virtual CYNumber *Number(CYContext &context);
850 virtual CYString *String(CYContext &context);
852 CYString *Concat(CYContext &out, CYString *rhs) const;
853 virtual void Output(CYOutput &out, CYFlags flags) const;
854 virtual void PropertyName(CYOutput &out) const;
863 CYNumber(double value) :
868 double Value() const {
872 virtual CYNumber *Number(CYContext &context);
873 virtual CYString *String(CYContext &context);
875 virtual void Output(CYOutput &out, CYFlags flags) const;
876 virtual void PropertyName(CYOutput &out) const;
884 CYRegEx(const char *value) :
889 const char *Value() const {
893 virtual void Output(CYOutput &out, CYFlags flags) const;
905 virtual CYNumber *Number(CYContext &context);
906 virtual CYString *String(CYContext &context);
908 virtual void Output(CYOutput &out, CYFlags flags) const;
920 virtual CYExpression *Replace(CYContext &context);
921 virtual void Output(CYOutput &out, CYFlags flags) const;
927 virtual bool Value() const = 0;
928 virtual void Output(CYOutput &out, CYFlags flags) const;
940 virtual bool Value() const {
944 virtual CYNumber *Number(CYContext &context);
945 virtual CYString *String(CYContext &context);
957 virtual bool Value() const {
961 virtual CYNumber *Number(CYContext &context);
962 virtual CYString *String(CYContext &context);
970 CYVariable(CYIdentifier *name) :
978 virtual CYExpression *Replace(CYContext &context);
979 virtual void Output(CYOutput &out, CYFlags flags) const;
987 CYPrefix(CYExpression *rhs) :
992 virtual bool Alphabetic() const = 0;
993 virtual const char *Operator() const = 0;
997 virtual CYExpression *Replace(CYContext &context);
998 virtual void Output(CYOutput &out, CYFlags flags) const;
1007 CYInfix(CYExpression *lhs, CYExpression *rhs) :
1013 void SetLeft(CYExpression *lhs) {
1017 virtual bool Alphabetic() const = 0;
1018 virtual const char *Operator() const = 0;
1020 virtual CYExpression *Replace(CYContext &context);
1021 virtual void Output(CYOutput &out, CYFlags flags) const;
1029 CYPostfix(CYExpression *lhs) :
1034 virtual const char *Operator() const = 0;
1038 virtual CYExpression *Replace(CYContext &context);
1039 virtual void Output(CYOutput &out, CYFlags flags) const;
1042 struct CYAssignment :
1048 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1054 void SetLeft(CYExpression *lhs) {
1058 virtual const char *Operator() const = 0;
1062 virtual CYExpression *Replace(CYContext &context);
1063 virtual void Output(CYOutput &out, CYFlags flags) const;
1071 CYExpression *value_;
1073 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1074 CYNext<CYArgument>(next),
1080 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1081 CYNext<CYArgument>(next),
1087 void Replace(CYContext &context);
1088 void Output(CYOutput &out) const;
1104 CYExpression *case_;
1105 CYStatement *statements_;
1107 CYClause(CYExpression *_case, CYStatement *statements) :
1109 statements_(statements)
1113 void Replace(CYContext &context);
1114 virtual void Output(CYOutput &out) const;
1121 CYExpression *value_;
1123 CYElement(CYExpression *value, CYElement *next) :
1124 CYNext<CYElement>(next),
1129 void Replace(CYContext &context);
1130 void Output(CYOutput &out) const;
1136 CYElement *elements_;
1138 CYArray(CYElement *elements = NULL) :
1143 virtual CYExpression *Replace(CYContext &context);
1144 virtual void Output(CYOutput &out, CYFlags flags) const;
1151 CYPropertyName *name_;
1152 CYExpression *value_;
1154 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1155 CYNext<CYProperty>(next),
1161 void Replace(CYContext &context);
1162 virtual void Output(CYOutput &out) const;
1165 struct CYDeclaration :
1168 CYIdentifier *identifier_;
1169 CYExpression *initialiser_;
1171 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1172 identifier_(identifier),
1173 initialiser_(initialiser)
1177 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1179 virtual const char *ForEachIn() const;
1180 virtual CYExpression *ForEachIn(CYContext &out);
1182 virtual CYExpression *Replace(CYContext &context);
1183 virtual CYAssignment *Assignment(CYContext &context);
1185 virtual void Output(CYOutput &out, CYFlags flags) const;
1188 struct CYDeclarations :
1189 CYNext<CYDeclarations>,
1193 CYDeclaration *declaration_;
1195 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1196 CYNext<CYDeclarations>(next),
1197 declaration_(declaration)
1201 virtual void For(CYOutput &out) const;
1203 virtual CYCompound *Replace(CYContext &context);
1204 CYProperty *Property(CYContext &context);
1206 virtual void Output(CYOutput &out) const;
1207 virtual void Output(CYOutput &out, CYFlags flags) const;
1213 CYDeclarations *declarations_;
1215 CYVar(CYDeclarations *declarations) :
1216 declarations_(declarations)
1220 virtual CYStatement *Replace(CYContext &context);
1221 virtual void Output(CYOutput &out, CYFlags flags) const;
1227 CYDeclarations *declarations_;
1230 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1231 declarations_(declarations),
1236 virtual CYStatement *Replace(CYContext &context);
1237 virtual void Output(CYOutput &out, CYFlags flags) const;
1243 CYForInitialiser *initialiser_;
1244 CYExpression *test_;
1245 CYExpression *increment_;
1248 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1249 initialiser_(initialiser),
1251 increment_(increment),
1256 virtual CYStatement *Replace(CYContext &context);
1257 virtual void Output(CYOutput &out, CYFlags flags) const;
1263 CYForInInitialiser *initialiser_;
1267 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1268 initialiser_(initialiser),
1274 virtual CYStatement *Replace(CYContext &context);
1275 virtual void Output(CYOutput &out, CYFlags flags) const;
1278 struct CYForEachIn :
1281 CYForInInitialiser *initialiser_;
1285 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1286 initialiser_(initialiser),
1292 virtual CYStatement *Replace(CYContext &context);
1293 virtual void Output(CYOutput &out, CYFlags flags) const;
1299 CYProperty *properties_;
1301 CYObject(CYProperty *properties = NULL) :
1302 properties_(properties)
1306 virtual CYExpression *Replace(CYContext &context);
1307 void Output(CYOutput &out, CYFlags flags) const;
1313 CYExpression *object_;
1314 CYExpression *property_;
1316 CYMember(CYExpression *object, CYExpression *property) :
1322 void SetLeft(CYExpression *object) {
1326 void Replace_(CYContext &context);
1329 struct CYDirectMember :
1332 CYDirectMember(CYExpression *object, CYExpression *property) :
1333 CYMember(object, property)
1340 virtual CYExpression *Replace(CYContext &context);
1341 virtual void Output(CYOutput &out, CYFlags flags) const;
1344 struct CYIndirectMember :
1347 CYIndirectMember(CYExpression *object, CYExpression *property) :
1348 CYMember(object, property)
1355 virtual CYExpression *Replace(CYContext &context);
1356 virtual void Output(CYOutput &out, CYFlags flags) const;
1362 CYExpression *constructor_;
1363 CYArgument *arguments_;
1365 CYNew(CYExpression *constructor, CYArgument *arguments) :
1366 constructor_(constructor),
1367 arguments_(arguments)
1371 virtual unsigned Precedence() const {
1372 return arguments_ == NULL ? 2 : 1;
1377 virtual CYExpression *Replace(CYContext &context);
1378 virtual void Output(CYOutput &out, CYFlags flags) const;
1380 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1386 CYExpression *function_;
1387 CYArgument *arguments_;
1389 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1390 function_(function),
1391 arguments_(arguments)
1398 virtual CYExpression *Replace(CYContext &context);
1399 virtual void Output(CYOutput &out, CYFlags flags) const;
1401 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1406 struct CYRubyBlock :
1409 CYExpression *call_;
1412 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1421 virtual CYExpression *Replace(CYContext &context);
1422 virtual void Output(CYOutput &out, CYFlags flags) const;
1428 CYExpression *test_;
1430 CYStatement *false_;
1432 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1439 virtual CYStatement *Replace(CYContext &context);
1440 virtual void Output(CYOutput &out, CYFlags flags) const;
1446 CYExpression *test_;
1449 CYDoWhile(CYExpression *test, CYStatement *code) :
1455 virtual CYStatement *Replace(CYContext &context);
1456 virtual void Output(CYOutput &out, CYFlags flags) const;
1462 CYExpression *test_;
1465 CYWhile(CYExpression *test, CYStatement *code) :
1471 virtual CYStatement *Replace(CYContext &context);
1472 virtual void Output(CYOutput &out, CYFlags flags) const;
1475 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
1477 CYIdentifier *name_;
1478 CYFunctionParameter *parameters_;
1480 CYNonLocal *nonlocal_;
1482 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1484 parameters_(parameters),
1490 virtual ~CYFunction() {
1493 void Inject(CYContext &context);
1494 virtual void Replace_(CYContext &context, bool outer);
1495 virtual void Output(CYOutput &out, CYFlags flags) const;
1498 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
1499 struct CYFunctionExpression :
1503 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1504 CYFunction(name, parameters, statements)
1511 virtual CYExpression *Replace(CYContext &context);
1512 virtual void Output(CYOutput &out, CYFlags flags) const;
1515 // XXX: this should derive from CYAnonymousFunctionExpression
1517 CYFunctionExpression
1519 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1520 CYFunctionExpression(NULL, parameters, statements)
1524 virtual CYExpression *Replace(CYContext &context);
1525 virtual void Output(CYOutput &out, CYFlags flags) const;
1528 // XXX: this should derive from CYNamedFunction
1529 struct CYFunctionStatement :
1533 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1534 CYFunction(name, parameters, statements)
1538 virtual CYStatement *Replace(CYContext &context);
1539 virtual void Output(CYOutput &out, CYFlags flags) const;
1545 CYExpression *expression_;
1547 CYExpress(CYExpression *expression) :
1548 expression_(expression)
1550 if (expression == NULL)
1554 virtual CYStatement *Collapse(CYContext &context);
1555 virtual CYStatement *Replace(CYContext &context);
1556 virtual void Output(CYOutput &out, CYFlags flags) const;
1562 CYIdentifier *label_;
1564 CYContinue(CYIdentifier *label) :
1569 virtual CYStatement *Replace(CYContext &context);
1570 virtual void Output(CYOutput &out, CYFlags flags) const;
1576 CYIdentifier *label_;
1578 CYBreak(CYIdentifier *label) :
1583 virtual CYStatement *Replace(CYContext &context);
1584 virtual void Output(CYOutput &out, CYFlags flags) const;
1590 CYExpression *value_;
1592 CYReturn(CYExpression *value) :
1597 virtual CYStatement *Replace(CYContext &context);
1598 virtual void Output(CYOutput &out, CYFlags flags) const;
1604 virtual CYStatement *Collapse(CYContext &context);
1605 virtual CYStatement *Replace(CYContext &context);
1606 virtual void Output(CYOutput &out, CYFlags flags) const;
1614 CYFinally(CYStatement *statements) :
1619 void Replace(CYContext &context);
1620 virtual void Output(CYOutput &out) const;
1629 CYIdentifier *name_;
1632 Catch(CYIdentifier *name, CYStatement *statements) :
1638 void Replace(CYContext &context);
1639 virtual void Output(CYOutput &out) const;
1647 CYFinally *finally_;
1649 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1656 virtual CYStatement *Replace(CYContext &context);
1657 virtual void Output(CYOutput &out, CYFlags flags) const;
1663 CYExpression *value_;
1665 Throw(CYExpression *value = NULL) :
1670 virtual CYStatement *Replace(CYContext &context);
1671 virtual void Output(CYOutput &out, CYFlags flags) const;
1679 CYExpression *scope_;
1682 CYWith(CYExpression *scope, CYStatement *code) :
1688 virtual CYStatement *Replace(CYContext &context);
1689 virtual void Output(CYOutput &out, CYFlags flags) const;
1695 CYExpression *value_;
1698 CYSwitch(CYExpression *value, CYClause *clauses) :
1704 virtual CYStatement *Replace(CYContext &context);
1705 virtual void Output(CYOutput &out, CYFlags flags) const;
1708 struct CYCondition :
1711 CYExpression *test_;
1712 CYExpression *true_;
1713 CYExpression *false_;
1715 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1724 virtual CYExpression *Replace(CYContext &context);
1725 virtual void Output(CYOutput &out, CYFlags flags) const;
1728 struct CYAddressOf :
1731 CYAddressOf(CYExpression *rhs) :
1736 virtual const char *Operator() const {
1742 virtual CYExpression *Replace(CYContext &context);
1748 CYIndirect(CYExpression *rhs) :
1753 virtual const char *Operator() const {
1759 virtual CYExpression *Replace(CYContext &context);
1763 virtual CYExpression *Replace(CYContext &context);
1765 #define CYPostfix_(op, name, args...) \
1766 struct CY ## name : \
1769 CY ## name(CYExpression *lhs) : \
1774 virtual const char *Operator() const { \
1779 #define CYPrefix_(alphabetic, op, name, args...) \
1780 struct CY ## name : \
1783 CY ## name(CYExpression *rhs) : \
1788 CYAlphabetic(alphabetic) \
1790 virtual const char *Operator() const { \
1795 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1796 struct CY ## name : \
1799 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1804 CYAlphabetic(alphabetic) \
1805 CYPrecedence(precedence) \
1807 virtual const char *Operator() const { \
1812 #define CYAssignment_(op, name, args...) \
1813 struct CY ## name ## Assign : \
1816 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1817 CYAssignment(lhs, rhs) \
1821 virtual const char *Operator() const { \
1826 CYPostfix_("++", PostIncrement)
1827 CYPostfix_("--", PostDecrement)
1829 CYPrefix_(true, "delete", Delete)
1830 CYPrefix_(true, "void", Void)
1831 CYPrefix_(true, "typeof", TypeOf)
1832 CYPrefix_(false, "++", PreIncrement)
1833 CYPrefix_(false, "--", PreDecrement)
1834 CYPrefix_(false, "+", Affirm)
1835 CYPrefix_(false, "-", Negate)
1836 CYPrefix_(false, "~", BitwiseNot)
1837 CYPrefix_(false, "!", LogicalNot)
1839 CYInfix_(false, 5, "*", Multiply)
1840 CYInfix_(false, 5, "/", Divide)
1841 CYInfix_(false, 5, "%", Modulus)
1842 CYInfix_(false, 6, "+", Add, CYReplace)
1843 CYInfix_(false, 6, "-", Subtract)
1844 CYInfix_(false, 7, "<<", ShiftLeft)
1845 CYInfix_(false, 7, ">>", ShiftRightSigned)
1846 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1847 CYInfix_(false, 8, "<", Less)
1848 CYInfix_(false, 8, ">", Greater)
1849 CYInfix_(false, 8, "<=", LessOrEqual)
1850 CYInfix_(false, 8, ">=", GreaterOrEqual)
1851 CYInfix_(true, 8, "instanceof", InstanceOf)
1852 CYInfix_(true, 8, "in", In)
1853 CYInfix_(false, 9, "==", Equal)
1854 CYInfix_(false, 9, "!=", NotEqual)
1855 CYInfix_(false, 9, "===", Identical)
1856 CYInfix_(false, 9, "!==", NotIdentical)
1857 CYInfix_(false, 10, "&", BitwiseAnd)
1858 CYInfix_(false, 11, "^", BitwiseXOr)
1859 CYInfix_(false, 12, "|", BitwiseOr)
1860 CYInfix_(false, 13, "&&", LogicalAnd)
1861 CYInfix_(false, 14, "||", LogicalOr)
1863 CYAssignment_("=", )
1864 CYAssignment_("*=", Multiply)
1865 CYAssignment_("/=", Divide)
1866 CYAssignment_("%=", Modulus)
1867 CYAssignment_("+=", Add)
1868 CYAssignment_("-=", Subtract)
1869 CYAssignment_("<<=", ShiftLeft)
1870 CYAssignment_(">>=", ShiftRightSigned)
1871 CYAssignment_(">>>=", ShiftRightUnsigned)
1872 CYAssignment_("&=", BitwiseAnd)
1873 CYAssignment_("^=", BitwiseXOr)
1874 CYAssignment_("|=", BitwiseOr)
1876 #endif/*CYPARSER_HPP*/