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;
375 CYIdentifierUsageVector rename_;
377 CYNonLocal *nonlocal_;
378 CYNonLocal *nextlocal_;
381 CYContext(CYOptions &options) :
390 virtual ~CYContext() {
393 template <typename Type_>
394 void Replace(Type_ *&value) {
395 for (;;) if (value == NULL)
398 Type_ *replace(value->Replace(*this));
399 if (replace != value)
405 void NonLocal(CYStatement *&statements);
406 CYIdentifier *Unique();
410 CYIdentifier *identifier_;
417 CYIdentifier *Target(CYContext &context) {
418 if (identifier_ == NULL)
419 identifier_ = context.Unique();
428 CYStatement *statements_;
430 CYBlock(CYStatement *statements) :
431 statements_(statements)
435 operator CYStatement *() const {
439 void AddPrev(CYStatement *statement) {
440 CYStatement *last(statement);
441 while (last->next_ != NULL)
443 last->SetNext(statements_);
444 statements_ = statement;
447 virtual CYStatement *Replace(CYContext &context);
449 virtual void Output(CYOutput &out) const;
450 virtual void Output(CYOutput &out, CYFlags flags) const;
476 std::string filename_;
480 cy::location location_;
481 std::string message_;
484 typedef std::vector<Error> Errors;
492 CYExpression *context_;
494 Context(CYExpression *context) :
499 typedef std::vector<CYWord *> Words;
503 typedef std::vector<Context> Contexts;
506 CYExpression *context_;
518 void ScannerDestroy();
521 CYDriver(const std::string &filename = "");
524 Condition GetCondition();
525 void SetCondition(Condition condition);
527 void PushCondition(Condition condition);
530 void Warning(const cy::location &location, const char *message);
533 struct CYForInitialiser {
534 virtual ~CYForInitialiser() {
537 virtual void For(CYOutput &out) const = 0;
538 virtual CYExpression *Replace(CYContext &context) = 0;
541 struct CYForInInitialiser {
542 virtual ~CYForInInitialiser() {
545 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
546 virtual const char *ForEachIn() const = 0;
547 virtual CYExpression *ForEachIn(CYContext &out) = 0;
548 virtual CYExpression *Replace(CYContext &context) = 0;
554 struct CYExpression :
555 CYNext<CYExpression>,
561 virtual unsigned Precedence() const = 0;
563 virtual bool RightHand() const {
567 virtual void For(CYOutput &out) const;
568 virtual void ForIn(CYOutput &out, CYFlags flags) const;
570 virtual const char *ForEachIn() const;
571 virtual CYExpression *ForEachIn(CYContext &out);
573 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
575 virtual void Output(CYOutput &out) const;
576 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
577 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
579 virtual CYExpression *ClassName(CYContext &context, bool object);
580 virtual void ClassName(CYOutput &out, bool object) const;
582 CYExpression *ReplaceAll(CYContext &context);
584 virtual CYExpression *Replace(CYContext &context) = 0;
586 virtual CYExpression *Primitive(CYContext &context) {
590 virtual CYNumber *Number(CYContext &context) {
594 virtual CYString *String(CYContext &context) {
598 virtual const char *Word() const {
603 #define CYAlphabetic(value) \
604 virtual bool Alphabetic() const { \
608 #define CYPrecedence(value) \
609 virtual unsigned Precedence() const { \
613 #define CYRightHand(value) \
614 virtual bool RightHand() const { \
621 CYExpression *expressions_;
623 CYCompound(CYExpression *expressions = NULL) :
624 expressions_(expressions)
628 void AddPrev(CYExpression *expression) {
629 CYExpression *last(expression);
630 while (last->next_ != NULL)
632 last->SetNext(expressions_);
633 expressions_ = expression;
638 virtual CYExpression *Replace(CYContext &context);
639 void Output(CYOutput &out, CYFlags flags) const;
642 struct CYFunctionParameter :
643 CYNext<CYFunctionParameter>,
648 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
649 CYNext<CYFunctionParameter>(next),
654 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
655 virtual void Output(CYOutput &out) const;
658 struct CYOptionalFunctionParameter :
661 CYExpression *initializer_;
663 CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
664 CYFunctionParameter(name, next),
665 initializer_(initializer)
669 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
670 virtual void Output(CYOutput &out) const;
673 struct CYComprehension :
674 CYNext<CYComprehension>,
677 virtual const char *Name() const = 0;
679 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
680 CYFunctionParameter *Parameters(CYContext &context) const;
681 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
682 virtual void Output(CYOutput &out) const = 0;
685 struct CYForInComprehension :
691 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
697 virtual const char *Name() const {
698 return name_->Word();
701 virtual CYFunctionParameter *Parameter(CYContext &context) const;
702 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
703 virtual void Output(CYOutput &out) const;
706 struct CYForEachInComprehension :
712 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
718 virtual const char *Name() const {
719 return name_->Word();
722 virtual CYFunctionParameter *Parameter(CYContext &context) const;
723 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
724 virtual void Output(CYOutput &out) const;
727 struct CYIfComprehension :
732 CYIfComprehension(CYExpression *test) :
737 virtual const char *Name() const {
741 virtual CYFunctionParameter *Parameter(CYContext &context) const;
742 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
743 virtual void Output(CYOutput &out) const;
746 struct CYArrayComprehension :
749 CYExpression *expression_;
750 CYComprehension *comprehensions_;
752 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
753 expression_(expression),
754 comprehensions_(comprehensions)
760 virtual CYExpression *Replace(CYContext &context);
761 virtual void Output(CYOutput &out, CYFlags flags) const;
774 virtual CYExpression *Replace(CYContext &context);
788 CYRange(uint64_t lo, uint64_t hi) :
793 bool operator [](uint8_t value) const {
794 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
797 void operator()(uint8_t value) {
800 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
804 extern CYRange DigitRange_;
805 extern CYRange WordStartRange_;
806 extern CYRange WordEndRange_;
821 CYString(const char *value) :
827 CYString(const char *value, size_t size) :
833 CYString(const CYWord *word) :
834 value_(word->Word()),
835 size_(strlen(value_))
839 const char *Value() const {
843 virtual const char *Word() const;
845 virtual CYNumber *Number(CYContext &context);
846 virtual CYString *String(CYContext &context);
848 CYString *Concat(CYContext &out, CYString *rhs) const;
849 virtual void Output(CYOutput &out, CYFlags flags) const;
850 virtual void PropertyName(CYOutput &out) const;
859 CYNumber(double value) :
864 double Value() const {
868 virtual CYNumber *Number(CYContext &context);
869 virtual CYString *String(CYContext &context);
871 virtual void Output(CYOutput &out, CYFlags flags) const;
872 virtual void PropertyName(CYOutput &out) const;
880 CYRegEx(const char *value) :
885 const char *Value() const {
889 virtual void Output(CYOutput &out, CYFlags flags) const;
901 virtual CYNumber *Number(CYContext &context);
902 virtual CYString *String(CYContext &context);
904 virtual void Output(CYOutput &out, CYFlags flags) const;
916 virtual CYExpression *Replace(CYContext &context);
917 virtual void Output(CYOutput &out, CYFlags flags) const;
923 virtual bool Value() const = 0;
924 virtual void Output(CYOutput &out, CYFlags flags) const;
936 virtual bool Value() const {
940 virtual CYNumber *Number(CYContext &context);
941 virtual CYString *String(CYContext &context);
953 virtual bool Value() const {
957 virtual CYNumber *Number(CYContext &context);
958 virtual CYString *String(CYContext &context);
966 CYVariable(CYIdentifier *name) :
971 CYVariable(const char *name) :
972 name_(new($pool) CYIdentifier(name))
979 virtual CYExpression *Replace(CYContext &context);
980 virtual void Output(CYOutput &out, CYFlags flags) const;
988 CYPrefix(CYExpression *rhs) :
993 virtual bool Alphabetic() const = 0;
994 virtual const char *Operator() const = 0;
998 virtual CYExpression *Replace(CYContext &context);
999 virtual void Output(CYOutput &out, CYFlags flags) const;
1008 CYInfix(CYExpression *lhs, CYExpression *rhs) :
1014 void SetLeft(CYExpression *lhs) {
1018 virtual bool Alphabetic() const = 0;
1019 virtual const char *Operator() const = 0;
1021 virtual CYExpression *Replace(CYContext &context);
1022 virtual void Output(CYOutput &out, CYFlags flags) const;
1030 CYPostfix(CYExpression *lhs) :
1035 virtual const char *Operator() const = 0;
1039 virtual CYExpression *Replace(CYContext &context);
1040 virtual void Output(CYOutput &out, CYFlags flags) const;
1043 struct CYAssignment :
1049 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1055 void SetLeft(CYExpression *lhs) {
1059 virtual const char *Operator() const = 0;
1063 virtual CYExpression *Replace(CYContext &context);
1064 virtual void Output(CYOutput &out, CYFlags flags) const;
1072 CYExpression *value_;
1074 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1075 CYNext<CYArgument>(next),
1081 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1082 CYNext<CYArgument>(next),
1088 void Replace(CYContext &context);
1089 void Output(CYOutput &out) const;
1105 CYExpression *case_;
1106 CYStatement *statements_;
1108 CYClause(CYExpression *_case, CYStatement *statements) :
1110 statements_(statements)
1114 void Replace(CYContext &context);
1115 virtual void Output(CYOutput &out) const;
1122 CYExpression *value_;
1124 CYElement(CYExpression *value, CYElement *next) :
1125 CYNext<CYElement>(next),
1130 void Replace(CYContext &context);
1131 void Output(CYOutput &out) const;
1137 CYElement *elements_;
1139 CYArray(CYElement *elements = NULL) :
1144 virtual CYExpression *Replace(CYContext &context);
1145 virtual void Output(CYOutput &out, CYFlags flags) const;
1152 CYPropertyName *name_;
1153 CYExpression *value_;
1155 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1156 CYNext<CYProperty>(next),
1162 void Replace(CYContext &context);
1163 virtual void Output(CYOutput &out) const;
1166 struct CYDeclaration :
1169 CYIdentifier *identifier_;
1170 CYExpression *initialiser_;
1172 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1173 identifier_(identifier),
1174 initialiser_(initialiser)
1178 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1180 virtual const char *ForEachIn() const;
1181 virtual CYExpression *ForEachIn(CYContext &out);
1183 virtual CYExpression *Replace(CYContext &context);
1184 virtual CYAssignment *Assignment(CYContext &context);
1186 virtual void Output(CYOutput &out, CYFlags flags) const;
1189 struct CYDeclarations :
1190 CYNext<CYDeclarations>,
1194 CYDeclaration *declaration_;
1196 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1197 CYNext<CYDeclarations>(next),
1198 declaration_(declaration)
1202 virtual void For(CYOutput &out) const;
1204 virtual CYCompound *Replace(CYContext &context);
1205 CYProperty *Property(CYContext &context);
1207 virtual void Output(CYOutput &out) const;
1208 virtual void Output(CYOutput &out, CYFlags flags) const;
1214 CYDeclarations *declarations_;
1216 CYVar(CYDeclarations *declarations) :
1217 declarations_(declarations)
1221 virtual CYStatement *Replace(CYContext &context);
1222 virtual void Output(CYOutput &out, CYFlags flags) const;
1228 CYDeclarations *declarations_;
1231 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1232 declarations_(declarations),
1237 virtual CYStatement *Replace(CYContext &context);
1238 virtual void Output(CYOutput &out, CYFlags flags) const;
1244 CYForInitialiser *initialiser_;
1245 CYExpression *test_;
1246 CYExpression *increment_;
1249 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1250 initialiser_(initialiser),
1252 increment_(increment),
1257 virtual CYStatement *Replace(CYContext &context);
1258 virtual void Output(CYOutput &out, CYFlags flags) const;
1264 CYForInInitialiser *initialiser_;
1268 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1269 initialiser_(initialiser),
1275 virtual CYStatement *Replace(CYContext &context);
1276 virtual void Output(CYOutput &out, CYFlags flags) const;
1279 struct CYForEachIn :
1282 CYForInInitialiser *initialiser_;
1286 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1287 initialiser_(initialiser),
1293 virtual CYStatement *Replace(CYContext &context);
1294 virtual void Output(CYOutput &out, CYFlags flags) const;
1300 CYProperty *properties_;
1302 CYObject(CYProperty *properties = NULL) :
1303 properties_(properties)
1307 virtual CYExpression *Replace(CYContext &context);
1308 void Output(CYOutput &out, CYFlags flags) const;
1314 CYExpression *object_;
1315 CYExpression *property_;
1317 CYMember(CYExpression *object, CYExpression *property) :
1323 void SetLeft(CYExpression *object) {
1327 void Replace_(CYContext &context);
1330 struct CYDirectMember :
1333 CYDirectMember(CYExpression *object, CYExpression *property) :
1334 CYMember(object, property)
1341 virtual CYExpression *Replace(CYContext &context);
1342 virtual void Output(CYOutput &out, CYFlags flags) const;
1345 struct CYIndirectMember :
1348 CYIndirectMember(CYExpression *object, CYExpression *property) :
1349 CYMember(object, property)
1356 virtual CYExpression *Replace(CYContext &context);
1357 virtual void Output(CYOutput &out, CYFlags flags) const;
1366 CYExpression *constructor_;
1367 CYArgument *arguments_;
1369 New(CYExpression *constructor, CYArgument *arguments) :
1370 constructor_(constructor),
1371 arguments_(arguments)
1375 virtual unsigned Precedence() const {
1376 return arguments_ == NULL ? 2 : 1;
1381 virtual CYExpression *Replace(CYContext &context);
1382 virtual void Output(CYOutput &out, CYFlags flags) const;
1384 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1392 CYExpression *function_;
1393 CYArgument *arguments_;
1395 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1396 function_(function),
1397 arguments_(arguments)
1404 virtual CYExpression *Replace(CYContext &context);
1405 virtual void Output(CYOutput &out, CYFlags flags) const;
1407 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1412 struct CYRubyBlock :
1415 CYExpression *call_;
1418 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1427 virtual CYExpression *Replace(CYContext &context);
1428 virtual void Output(CYOutput &out, CYFlags flags) const;
1434 CYExpression *test_;
1436 CYStatement *false_;
1438 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1445 virtual CYStatement *Replace(CYContext &context);
1446 virtual void Output(CYOutput &out, CYFlags flags) const;
1452 CYExpression *test_;
1455 CYDoWhile(CYExpression *test, CYStatement *code) :
1461 virtual CYStatement *Replace(CYContext &context);
1462 virtual void Output(CYOutput &out, CYFlags flags) const;
1468 CYExpression *test_;
1471 CYWhile(CYExpression *test, CYStatement *code) :
1477 virtual CYStatement *Replace(CYContext &context);
1478 virtual void Output(CYOutput &out, CYFlags flags) const;
1481 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
1483 CYIdentifier *name_;
1484 CYFunctionParameter *parameters_;
1486 CYNonLocal *nonlocal_;
1488 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1490 parameters_(parameters),
1496 virtual ~CYFunction() {
1499 void Inject(CYContext &context);
1500 virtual void Replace_(CYContext &context, bool outer);
1501 virtual void Output(CYOutput &out, CYFlags flags) const;
1504 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
1505 struct CYFunctionExpression :
1509 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1510 CYFunction(name, parameters, statements)
1517 virtual CYExpression *Replace(CYContext &context);
1518 virtual void Output(CYOutput &out, CYFlags flags) const;
1521 // XXX: this should derive from CYAnonymousFunctionExpression
1523 CYFunctionExpression
1525 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1526 CYFunctionExpression(NULL, parameters, statements)
1530 virtual CYExpression *Replace(CYContext &context);
1531 virtual void Output(CYOutput &out, CYFlags flags) const;
1534 // XXX: this should derive from CYNamedFunction
1535 struct CYFunctionStatement :
1539 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1540 CYFunction(name, parameters, statements)
1544 virtual CYStatement *Replace(CYContext &context);
1545 virtual void Output(CYOutput &out, CYFlags flags) const;
1551 CYExpression *expression_;
1553 CYExpress(CYExpression *expression) :
1554 expression_(expression)
1556 if (expression == NULL)
1560 virtual CYStatement *Collapse(CYContext &context);
1561 virtual CYStatement *Replace(CYContext &context);
1562 virtual void Output(CYOutput &out, CYFlags flags) const;
1568 CYIdentifier *label_;
1570 CYContinue(CYIdentifier *label) :
1575 virtual CYStatement *Replace(CYContext &context);
1576 virtual void Output(CYOutput &out, CYFlags flags) const;
1582 CYIdentifier *label_;
1584 CYBreak(CYIdentifier *label) :
1589 virtual CYStatement *Replace(CYContext &context);
1590 virtual void Output(CYOutput &out, CYFlags flags) const;
1596 CYExpression *value_;
1598 CYReturn(CYExpression *value) :
1603 virtual CYStatement *Replace(CYContext &context);
1604 virtual void Output(CYOutput &out, CYFlags flags) const;
1610 virtual CYStatement *Collapse(CYContext &context);
1611 virtual CYStatement *Replace(CYContext &context);
1612 virtual void Output(CYOutput &out, CYFlags flags) const;
1620 CYFinally(CYStatement *statements) :
1625 void Replace(CYContext &context);
1626 virtual void Output(CYOutput &out) const;
1635 CYIdentifier *name_;
1638 Catch(CYIdentifier *name, CYStatement *statements) :
1644 void Replace(CYContext &context);
1645 virtual void Output(CYOutput &out) const;
1653 CYFinally *finally_;
1655 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1662 virtual CYStatement *Replace(CYContext &context);
1663 virtual void Output(CYOutput &out, CYFlags flags) const;
1669 CYExpression *value_;
1671 Throw(CYExpression *value = NULL) :
1676 virtual CYStatement *Replace(CYContext &context);
1677 virtual void Output(CYOutput &out, CYFlags flags) const;
1685 CYExpression *scope_;
1688 CYWith(CYExpression *scope, CYStatement *code) :
1694 virtual CYStatement *Replace(CYContext &context);
1695 virtual void Output(CYOutput &out, CYFlags flags) const;
1701 CYExpression *value_;
1704 CYSwitch(CYExpression *value, CYClause *clauses) :
1710 virtual CYStatement *Replace(CYContext &context);
1711 virtual void Output(CYOutput &out, CYFlags flags) const;
1714 struct CYCondition :
1717 CYExpression *test_;
1718 CYExpression *true_;
1719 CYExpression *false_;
1721 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1730 virtual CYExpression *Replace(CYContext &context);
1731 virtual void Output(CYOutput &out, CYFlags flags) const;
1734 struct CYAddressOf :
1737 CYAddressOf(CYExpression *rhs) :
1742 virtual const char *Operator() const {
1748 virtual CYExpression *Replace(CYContext &context);
1754 CYIndirect(CYExpression *rhs) :
1759 virtual const char *Operator() const {
1765 virtual CYExpression *Replace(CYContext &context);
1769 virtual CYExpression *Replace(CYContext &context);
1771 #define CYPostfix_(op, name, args...) \
1772 struct CY ## name : \
1775 CY ## name(CYExpression *lhs) : \
1780 virtual const char *Operator() const { \
1785 #define CYPrefix_(alphabetic, op, name, args...) \
1786 struct CY ## name : \
1789 CY ## name(CYExpression *rhs) : \
1794 CYAlphabetic(alphabetic) \
1796 virtual const char *Operator() const { \
1801 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1802 struct CY ## name : \
1805 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1810 CYAlphabetic(alphabetic) \
1811 CYPrecedence(precedence) \
1813 virtual const char *Operator() const { \
1818 #define CYAssignment_(op, name, args...) \
1819 struct CY ## name ## Assign : \
1822 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1823 CYAssignment(lhs, rhs) \
1827 virtual const char *Operator() const { \
1832 CYPostfix_("++", PostIncrement)
1833 CYPostfix_("--", PostDecrement)
1835 CYPrefix_(true, "delete", Delete)
1836 CYPrefix_(true, "void", Void)
1837 CYPrefix_(true, "typeof", TypeOf)
1838 CYPrefix_(false, "++", PreIncrement)
1839 CYPrefix_(false, "--", PreDecrement)
1840 CYPrefix_(false, "+", Affirm)
1841 CYPrefix_(false, "-", Negate)
1842 CYPrefix_(false, "~", BitwiseNot)
1843 CYPrefix_(false, "!", LogicalNot)
1845 CYInfix_(false, 5, "*", Multiply)
1846 CYInfix_(false, 5, "/", Divide)
1847 CYInfix_(false, 5, "%", Modulus)
1848 CYInfix_(false, 6, "+", Add, CYReplace)
1849 CYInfix_(false, 6, "-", Subtract)
1850 CYInfix_(false, 7, "<<", ShiftLeft)
1851 CYInfix_(false, 7, ">>", ShiftRightSigned)
1852 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1853 CYInfix_(false, 8, "<", Less)
1854 CYInfix_(false, 8, ">", Greater)
1855 CYInfix_(false, 8, "<=", LessOrEqual)
1856 CYInfix_(false, 8, ">=", GreaterOrEqual)
1857 CYInfix_(true, 8, "instanceof", InstanceOf)
1858 CYInfix_(true, 8, "in", In)
1859 CYInfix_(false, 9, "==", Equal)
1860 CYInfix_(false, 9, "!=", NotEqual)
1861 CYInfix_(false, 9, "===", Identical)
1862 CYInfix_(false, 9, "!==", NotIdentical)
1863 CYInfix_(false, 10, "&", BitwiseAnd)
1864 CYInfix_(false, 11, "^", BitwiseXOr)
1865 CYInfix_(false, 12, "|", BitwiseOr)
1866 CYInfix_(false, 13, "&&", LogicalAnd)
1867 CYInfix_(false, 14, "||", LogicalOr)
1869 CYAssignment_("=", )
1870 CYAssignment_("*=", Multiply)
1871 CYAssignment_("/=", Divide)
1872 CYAssignment_("%=", Modulus)
1873 CYAssignment_("+=", Add)
1874 CYAssignment_("-=", Subtract)
1875 CYAssignment_("<<=", ShiftLeft)
1876 CYAssignment_(">>=", ShiftRightSigned)
1877 CYAssignment_(">>>=", ShiftRightUnsigned)
1878 CYAssignment_("&=", BitwiseAnd)
1879 CYAssignment_("^=", BitwiseXOr)
1880 CYAssignment_("|=", BitwiseOr)
1882 #endif/*CYPARSER_HPP*/