]> git.saurik.com Git - cycript.git/blob - Parser.hpp
Prefer __NSCFBoolean to non-__ for iOS compatibility.
[cycript.git] / Parser.hpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2012 Jay Freeman (saurik)
3 */
4
5 /* GNU Lesser General Public License, Version 3 {{{ */
6 /*
7 * Cycript is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * Cycript is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
19 **/
20 /* }}} */
21
22 #ifndef CYCRIPT_PARSER_HPP
23 #define CYCRIPT_PARSER_HPP
24
25 #include <iostream>
26
27 #include <stack>
28 #include <string>
29 #include <vector>
30 #include <map>
31 #include <set>
32
33 #include <cstdio>
34 #include <cstdlib>
35
36 #include "location.hh"
37
38 #include "List.hpp"
39 #include "Pooling.hpp"
40 #include "Options.hpp"
41
42 class CYContext;
43
44 struct CYThing {
45 virtual ~CYThing() {
46 }
47
48 virtual void Output(struct CYOutput &out) const = 0;
49 };
50
51 struct CYOutput {
52 std::ostream &out_;
53 CYOptions &options_;
54 bool pretty_;
55 unsigned indent_;
56 bool right_;
57
58 enum {
59 NoMode,
60 NoLetter,
61 NoPlus,
62 NoHyphen,
63 Terminated
64 } mode_;
65
66 CYOutput(std::ostream &out, CYOptions &options) :
67 out_(out),
68 options_(options),
69 pretty_(false),
70 indent_(0),
71 right_(false),
72 mode_(NoMode)
73 {
74 }
75
76 void Check(char value);
77 void Terminate();
78
79 CYOutput &operator <<(char rhs);
80 CYOutput &operator <<(const char *rhs);
81
82 _finline CYOutput &operator <<(const CYThing *rhs) {
83 if (rhs != NULL)
84 rhs->Output(*this);
85 return *this;
86 }
87
88 _finline CYOutput &operator <<(const CYThing &rhs) {
89 rhs.Output(*this);
90 return *this;
91 }
92 };
93
94 struct CYPropertyName {
95 virtual void PropertyName(CYOutput &out) const = 0;
96
97 virtual ~CYPropertyName() {
98 }
99 };
100
101 struct CYExpression;
102 struct CYAssignment;
103
104 enum CYNeeded {
105 CYNever = -1,
106 CYSometimes = 0,
107 CYAlways = 1,
108 };
109
110 enum CYFlags {
111 CYNoFlags = 0,
112 CYNoBrace = (1 << 0),
113 CYNoFunction = (1 << 1),
114 CYNoIn = (1 << 2),
115 CYNoCall = (1 << 3),
116 CYNoRightHand = (1 << 4),
117 CYNoDangle = (1 << 5),
118 CYNoInteger = (1 << 6),
119 CYNoBF = (CYNoBrace | CYNoFunction),
120 };
121
122 _finline CYFlags operator ~(CYFlags rhs) {
123 return static_cast<CYFlags>(~static_cast<unsigned>(rhs));
124 }
125
126 _finline CYFlags operator &(CYFlags lhs, CYFlags rhs) {
127 return static_cast<CYFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
128 }
129
130 _finline CYFlags operator |(CYFlags lhs, CYFlags rhs) {
131 return static_cast<CYFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
132 }
133
134 _finline CYFlags &operator |=(CYFlags &lhs, CYFlags rhs) {
135 return lhs = lhs | rhs;
136 }
137
138 _finline CYFlags CYLeft(CYFlags flags) {
139 return flags & ~(CYNoDangle | CYNoInteger);
140 }
141
142 _finline CYFlags CYRight(CYFlags flags) {
143 return flags & ~CYNoBF;
144 }
145
146 _finline CYFlags CYCenter(CYFlags flags) {
147 return CYLeft(CYRight(flags));
148 }
149
150 struct CYStatement :
151 CYNext<CYStatement>
152 {
153 virtual ~CYStatement() {
154 }
155
156 void Single(CYOutput &out, CYFlags flags) const;
157 void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
158
159 virtual CYStatement *Replace(CYContext &context) = 0;
160
161 private:
162 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
163 };
164
165 struct CYStatements {
166 CYStatement *first_;
167 CYStatement *last_;
168
169 CYStatements() :
170 first_(NULL),
171 last_(NULL)
172 {
173 }
174
175 operator CYStatement *() const {
176 return first_;
177 }
178
179 CYStatements &operator ->*(CYStatement *next) {
180 if (next != NULL)
181 if (first_ == NULL) {
182 first_ = next;
183 last_ = next;
184 } else for (;; last_ = last_->next_)
185 if (last_->next_ == NULL) {
186 last_->next_ = next;
187 last_ = next;
188 break;
189 }
190 return *this;
191 }
192 };
193
194 struct CYClassName {
195 virtual ~CYClassName() {
196 }
197
198 virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
199 virtual void ClassName(CYOutput &out, bool object) const = 0;
200 };
201
202 struct CYWord :
203 CYThing,
204 CYPropertyName,
205 CYClassName
206 {
207 const char *word_;
208
209 CYWord(const char *word) :
210 word_(word)
211 {
212 }
213
214 void Set(const char *value) {
215 word_ = value;
216 }
217
218 virtual const char *Word() const;
219 virtual void Output(CYOutput &out) const;
220
221 virtual CYExpression *ClassName(CYContext &context, bool object);
222 virtual void ClassName(CYOutput &out, bool object) const;
223 virtual void PropertyName(CYOutput &out) const;
224 };
225
226 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
227 lhs << &rhs << '=';
228 return lhs << rhs.Word();
229 }
230
231 struct CYIdentifier :
232 CYNext<CYIdentifier>,
233 CYWord
234 {
235 CYIdentifier *replace_;
236 size_t offset_;
237 size_t usage_;
238
239 CYIdentifier(const char *word) :
240 CYWord(word),
241 replace_(NULL),
242 offset_(0),
243 usage_(0)
244 {
245 }
246
247 virtual const char *Word() const;
248 CYIdentifier *Replace(CYContext &context);
249 };
250
251 struct CYComment :
252 CYStatement
253 {
254 const char *value_;
255
256 CYComment(const char *value) :
257 value_(value)
258 {
259 }
260
261 virtual CYStatement *Replace(CYContext &context);
262 virtual void Output(CYOutput &out, CYFlags flags) const;
263 };
264
265 struct CYLabel :
266 CYStatement
267 {
268 CYIdentifier *name_;
269 CYStatement *statement_;
270
271 CYLabel(CYIdentifier *name, CYStatement *statement) :
272 name_(name),
273 statement_(statement)
274 {
275 }
276
277 virtual CYStatement *Replace(CYContext &context);
278 virtual void Output(CYOutput &out, CYFlags flags) const;
279 };
280
281 struct CYCStringLess :
282 std::binary_function<const char *, const char *, bool>
283 {
284 _finline bool operator ()(const char *lhs, const char *rhs) const {
285 return strcmp(lhs, rhs) < 0;
286 }
287 };
288
289 struct CYIdentifierValueLess :
290 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
291 {
292 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
293 return CYCStringLess()(lhs->Word(), rhs->Word());
294 }
295 };
296
297 enum CYIdentifierFlags {
298 CYIdentifierArgument,
299 CYIdentifierVariable,
300 CYIdentifierOther,
301 CYIdentifierMagic,
302 CYIdentifierCatch,
303 };
304
305 typedef std::set<const char *, CYCStringLess> CYCStringSet;
306 typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
307 typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
308
309 struct CYIdentifierUsage {
310 CYIdentifier *identifier_;
311 size_t usage_;
312 };
313
314 typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
315
316 struct CYScope {
317 bool transparent_;
318
319 CYContext &context_;
320 CYStatement *&statements_;
321
322 CYScope *parent_;
323
324 CYIdentifierAddressFlagsMap internal_;
325 CYIdentifierValueSet identifiers_;
326
327 CYScope(bool transparent, CYContext &context, CYStatement *&statements);
328 virtual ~CYScope();
329
330 void Close();
331
332 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
333 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
334 void Merge(CYContext &context, CYIdentifier *identifier);
335 void Scope(CYContext &context, CYStatement *&statements);
336 };
337
338 struct CYProgram :
339 CYThing
340 {
341 CYStatement *statements_;
342
343 CYProgram(CYStatement *statements) :
344 statements_(statements)
345 {
346 }
347
348 virtual void Replace(CYContext &context);
349 virtual void Output(CYOutput &out) const;
350 };
351
352 struct CYNonLocal;
353 struct CYThisScope;
354
355 struct CYContext {
356 CYOptions &options_;
357
358 CYScope *scope_;
359 CYThisScope *this_;
360
361 CYIdentifierUsageVector rename_;
362
363 CYNonLocal *nonlocal_;
364 CYNonLocal *nextlocal_;
365 unsigned unique_;
366
367 CYContext(CYOptions &options) :
368 options_(options),
369 scope_(NULL),
370 this_(NULL),
371 nonlocal_(NULL),
372 nextlocal_(NULL),
373 unique_(0)
374 {
375 }
376
377 virtual ~CYContext() {
378 }
379
380 template <typename Type_>
381 void ReplaceAll(Type_ *&values) {
382 Type_ **last(&values);
383 CYForEach (next, values) {
384 Replace(*last = next);
385 if (*last != NULL)
386 last = &(*last)->next_;
387 }
388 }
389
390 template <typename Type_>
391 void Replace(Type_ *&value) {
392 for (;;) if (value == NULL)
393 break;
394 else {
395 Type_ *replace(value->Replace(*this));
396 if (replace != value)
397 value = replace;
398 else break;
399 }
400 }
401
402 void NonLocal(CYStatement *&statements);
403 CYIdentifier *Unique();
404 };
405
406 struct CYNonLocal {
407 CYIdentifier *identifier_;
408
409 CYNonLocal() :
410 identifier_(NULL)
411 {
412 }
413
414 CYIdentifier *Target(CYContext &context) {
415 if (identifier_ == NULL)
416 identifier_ = context.Unique();
417 return identifier_;
418 }
419 };
420
421 struct CYThisScope :
422 CYNext<CYThisScope>
423 {
424 CYIdentifier *identifier_;
425
426 CYThisScope() :
427 identifier_(NULL)
428 {
429 }
430
431 CYIdentifier *Identifier(CYContext &context) {
432 if (next_ != NULL)
433 return next_->Identifier(context);
434 if (identifier_ == NULL)
435 identifier_ = context.Unique();
436 return identifier_;
437 }
438 };
439
440 struct CYBlock :
441 CYStatement,
442 CYThing
443 {
444 CYStatement *statements_;
445
446 CYBlock(CYStatement *statements) :
447 statements_(statements)
448 {
449 }
450
451 operator CYStatement *() const {
452 return statements_;
453 }
454
455 void AddPrev(CYStatement *statement) {
456 CYSetLast(statement) = statements_;
457 statements_ = statement;
458 }
459
460 virtual CYStatement *Replace(CYContext &context);
461
462 virtual void Output(CYOutput &out) const;
463 virtual void Output(CYOutput &out, CYFlags flags) const;
464 };
465
466 enum CYState {
467 CYClear,
468 CYRestricted,
469 CYNewLine
470 };
471
472 class CYStream :
473 public std::istream
474 {
475 private:
476 class CYBuffer :
477 public std::streambuf
478 {
479 public:
480 CYBuffer(const char *start, const char *end) {
481 setg(const_cast<char *>(start), const_cast<char *>(start), const_cast<char *>(end));
482 }
483 } buffer_;
484
485 public:
486 CYStream(const char *start, const char *end) :
487 std::istream(&buffer_),
488 buffer_(start, end)
489 {
490 }
491 };
492
493 class CYDriver {
494 public:
495 void *scanner_;
496
497 CYState state_;
498 std::stack<bool> in_;
499
500 struct {
501 bool AtImplementation;
502 bool Function;
503 bool OpenBrace;
504 } no_;
505
506 std::istream &data_;
507
508 bool strict_;
509
510 enum Condition {
511 RegExpCondition,
512 XMLContentCondition,
513 XMLTagCondition,
514 };
515
516 std::string filename_;
517
518 struct Error {
519 bool warning_;
520 cy::location location_;
521 std::string message_;
522 };
523
524 typedef std::vector<Error> Errors;
525
526 CYProgram *program_;
527 Errors errors_;
528
529 bool auto_;
530
531 struct Context {
532 CYExpression *context_;
533
534 Context(CYExpression *context) :
535 context_(context)
536 {
537 }
538
539 typedef std::vector<CYWord *> Words;
540 Words words_;
541 };
542
543 typedef std::vector<Context> Contexts;
544 Contexts contexts_;
545
546 CYExpression *context_;
547
548 enum Mode {
549 AutoNone,
550 AutoPrimary,
551 AutoDirect,
552 AutoIndirect,
553 AutoMessage
554 } mode_;
555
556 private:
557 void ScannerInit();
558 void ScannerDestroy();
559
560 public:
561 CYDriver(std::istream &data, const std::string &filename = "");
562 ~CYDriver();
563
564 Condition GetCondition();
565 void SetCondition(Condition condition);
566
567 void PushCondition(Condition condition);
568 void PopCondition();
569
570 void Warning(const cy::location &location, const char *message);
571 };
572
573 struct CYForInitialiser {
574 virtual ~CYForInitialiser() {
575 }
576
577 virtual CYExpression *Replace(CYContext &context) = 0;
578 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
579 };
580
581 struct CYForInInitialiser {
582 virtual ~CYForInInitialiser() {
583 }
584
585 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
586 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value) = 0;
587
588 virtual CYExpression *Replace(CYContext &context) = 0;
589 virtual CYAssignment *Assignment(CYContext &context) = 0;
590
591 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
592 };
593
594 struct CYNumber;
595 struct CYString;
596
597 struct CYExpression :
598 CYNext<CYExpression>,
599 CYForInitialiser,
600 CYForInInitialiser,
601 CYClassName,
602 CYThing
603 {
604 virtual unsigned Precedence() const = 0;
605
606 virtual bool RightHand() const {
607 return true;
608 }
609
610 virtual void ForIn(CYOutput &out, CYFlags flags) const;
611 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
612
613 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
614
615 virtual void Output(CYOutput &out) const;
616 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
617 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
618
619 virtual CYExpression *ClassName(CYContext &context, bool object);
620 virtual void ClassName(CYOutput &out, bool object) const;
621
622 virtual CYExpression *Replace(CYContext &context) = 0;
623 virtual CYAssignment *Assignment(CYContext &context);
624
625 virtual CYExpression *Primitive(CYContext &context) {
626 return this;
627 }
628
629 virtual CYNumber *Number(CYContext &context) {
630 return NULL;
631 }
632
633 virtual CYString *String(CYContext &context) {
634 return NULL;
635 }
636
637 virtual const char *Word() const {
638 return NULL;
639 }
640 };
641
642 #define CYAlphabetic(value) \
643 virtual bool Alphabetic() const { \
644 return value; \
645 }
646
647 #define CYPrecedence(value) \
648 static const unsigned Precedence_ = value; \
649 virtual unsigned Precedence() const { \
650 return Precedence_; \
651 }
652
653 #define CYRightHand(value) \
654 virtual bool RightHand() const { \
655 return value; \
656 }
657
658 struct CYCompound :
659 CYExpression
660 {
661 CYExpression *expressions_;
662
663 CYCompound(CYExpression *expressions = NULL) :
664 expressions_(expressions)
665 {
666 }
667
668 void AddPrev(CYExpression *expression) {
669 CYSetLast(expression) = expressions_;
670 expressions_ = expression;
671 }
672
673 CYPrecedence(17)
674
675 virtual CYExpression *Replace(CYContext &context);
676 void Output(CYOutput &out, CYFlags flags) const;
677
678 virtual CYExpression *Primitive(CYContext &context);
679 };
680
681 struct CYDeclaration;
682
683 struct CYFunctionParameter :
684 CYNext<CYFunctionParameter>,
685 CYThing
686 {
687 CYForInInitialiser *initialiser_;
688
689 CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
690 CYNext<CYFunctionParameter>(next),
691 initialiser_(initialiser)
692 {
693 }
694
695 void Replace(CYContext &context, CYBlock &code);
696 void Output(CYOutput &out) const;
697 };
698
699 struct CYComprehension :
700 CYNext<CYComprehension>,
701 CYThing
702 {
703 CYComprehension(CYComprehension *next = NULL) :
704 CYNext<CYComprehension>(next)
705 {
706 }
707
708 virtual const char *Name() const = 0;
709
710 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
711 CYFunctionParameter *Parameters(CYContext &context) const;
712 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
713 virtual void Output(CYOutput &out) const = 0;
714 };
715
716 struct CYForInComprehension :
717 CYComprehension
718 {
719 CYIdentifier *name_;
720 CYExpression *set_;
721
722 CYForInComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
723 CYComprehension(next),
724 name_(name),
725 set_(set)
726 {
727 }
728
729 virtual const char *Name() const {
730 return name_->Word();
731 }
732
733 virtual CYFunctionParameter *Parameter(CYContext &context) const;
734 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
735 virtual void Output(CYOutput &out) const;
736 };
737
738 struct CYForOfComprehension :
739 CYComprehension
740 {
741 CYIdentifier *name_;
742 CYExpression *set_;
743
744 CYForOfComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
745 CYComprehension(next),
746 name_(name),
747 set_(set)
748 {
749 }
750
751 virtual const char *Name() const {
752 return name_->Word();
753 }
754
755 virtual CYFunctionParameter *Parameter(CYContext &context) const;
756 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
757 virtual void Output(CYOutput &out) const;
758 };
759
760 struct CYIfComprehension :
761 CYComprehension
762 {
763 CYExpression *test_;
764
765 CYIfComprehension(CYExpression *test) :
766 test_(test)
767 {
768 }
769
770 virtual const char *Name() const {
771 return NULL;
772 }
773
774 virtual CYFunctionParameter *Parameter(CYContext &context) const;
775 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
776 virtual void Output(CYOutput &out) const;
777 };
778
779 struct CYArrayComprehension :
780 CYExpression
781 {
782 CYExpression *expression_;
783 CYComprehension *comprehensions_;
784
785 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
786 expression_(expression),
787 comprehensions_(comprehensions)
788 {
789 }
790
791 CYPrecedence(0)
792
793 virtual CYExpression *Replace(CYContext &context);
794 virtual void Output(CYOutput &out, CYFlags flags) const;
795 };
796
797 struct CYLiteral :
798 CYExpression
799 {
800 CYPrecedence(0)
801 CYRightHand(false)
802 };
803
804 struct CYTrivial :
805 CYLiteral
806 {
807 virtual CYExpression *Replace(CYContext &context);
808 };
809
810 struct CYMagic :
811 CYExpression
812 {
813 CYPrecedence(0)
814 CYRightHand(false)
815 };
816
817 struct CYRange {
818 uint64_t lo_;
819 uint64_t hi_;
820
821 CYRange(uint64_t lo, uint64_t hi) :
822 lo_(lo), hi_(hi)
823 {
824 }
825
826 bool operator [](uint8_t value) const {
827 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
828 }
829
830 void operator()(uint8_t value) {
831 if (value >> 7)
832 return;
833 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
834 }
835 };
836
837 extern CYRange DigitRange_;
838 extern CYRange WordStartRange_;
839 extern CYRange WordEndRange_;
840
841 struct CYString :
842 CYTrivial,
843 CYPropertyName
844 {
845 const char *value_;
846 size_t size_;
847
848 CYString() :
849 value_(NULL),
850 size_(0)
851 {
852 }
853
854 CYString(const char *value) :
855 value_(value),
856 size_(strlen(value))
857 {
858 }
859
860 CYString(const char *value, size_t size) :
861 value_(value),
862 size_(size)
863 {
864 }
865
866 CYString(const CYWord *word) :
867 value_(word->Word()),
868 size_(strlen(value_))
869 {
870 }
871
872 const char *Value() const {
873 return value_;
874 }
875
876 virtual const char *Word() const;
877
878 virtual CYNumber *Number(CYContext &context);
879 virtual CYString *String(CYContext &context);
880
881 CYString *Concat(CYContext &out, CYString *rhs) const;
882 virtual void Output(CYOutput &out, CYFlags flags) const;
883 virtual void PropertyName(CYOutput &out) const;
884 };
885
886 struct CYNumber :
887 CYTrivial,
888 CYPropertyName
889 {
890 double value_;
891
892 CYNumber(double value) :
893 value_(value)
894 {
895 }
896
897 double Value() const {
898 return value_;
899 }
900
901 virtual CYNumber *Number(CYContext &context);
902 virtual CYString *String(CYContext &context);
903
904 virtual void Output(CYOutput &out, CYFlags flags) const;
905 virtual void PropertyName(CYOutput &out) const;
906 };
907
908 struct CYRegEx :
909 CYTrivial
910 {
911 const char *value_;
912
913 CYRegEx(const char *value) :
914 value_(value)
915 {
916 }
917
918 const char *Value() const {
919 return value_;
920 }
921
922 virtual void Output(CYOutput &out, CYFlags flags) const;
923 };
924
925 struct CYNull :
926 CYWord,
927 CYTrivial
928 {
929 CYNull() :
930 CYWord("null")
931 {
932 }
933
934 virtual CYNumber *Number(CYContext &context);
935 virtual CYString *String(CYContext &context);
936
937 virtual void Output(CYOutput &out, CYFlags flags) const;
938 };
939
940 struct CYThis :
941 CYWord,
942 CYMagic
943 {
944 CYThis() :
945 CYWord("this")
946 {
947 }
948
949 virtual CYExpression *Replace(CYContext &context);
950 virtual void Output(CYOutput &out, CYFlags flags) const;
951 };
952
953 struct CYBoolean :
954 CYTrivial
955 {
956 virtual bool Value() const = 0;
957 virtual void Output(CYOutput &out, CYFlags flags) const;
958 };
959
960 struct CYFalse :
961 CYWord,
962 CYBoolean
963 {
964 CYFalse() :
965 CYWord("false")
966 {
967 }
968
969 virtual bool Value() const {
970 return false;
971 }
972
973 virtual CYNumber *Number(CYContext &context);
974 virtual CYString *String(CYContext &context);
975 };
976
977 struct CYTrue :
978 CYWord,
979 CYBoolean
980 {
981 CYTrue() :
982 CYWord("true")
983 {
984 }
985
986 virtual bool Value() const {
987 return true;
988 }
989
990 virtual CYNumber *Number(CYContext &context);
991 virtual CYString *String(CYContext &context);
992 };
993
994 struct CYVariable :
995 CYExpression
996 {
997 CYIdentifier *name_;
998
999 CYVariable(CYIdentifier *name) :
1000 name_(name)
1001 {
1002 }
1003
1004 CYVariable(const char *name) :
1005 name_(new($pool) CYIdentifier(name))
1006 {
1007 }
1008
1009 CYPrecedence(0)
1010 CYRightHand(false)
1011
1012 virtual CYExpression *Replace(CYContext &context);
1013 virtual void Output(CYOutput &out, CYFlags flags) const;
1014 };
1015
1016 struct CYPrefix :
1017 CYExpression
1018 {
1019 CYExpression *rhs_;
1020
1021 CYPrefix(CYExpression *rhs) :
1022 rhs_(rhs)
1023 {
1024 }
1025
1026 virtual bool Alphabetic() const = 0;
1027 virtual const char *Operator() const = 0;
1028
1029 CYPrecedence(4)
1030
1031 virtual CYExpression *Replace(CYContext &context);
1032 virtual void Output(CYOutput &out, CYFlags flags) const;
1033 };
1034
1035 struct CYInfix :
1036 CYExpression
1037 {
1038 CYExpression *lhs_;
1039 CYExpression *rhs_;
1040
1041 CYInfix(CYExpression *lhs, CYExpression *rhs) :
1042 lhs_(lhs),
1043 rhs_(rhs)
1044 {
1045 }
1046
1047 void SetLeft(CYExpression *lhs) {
1048 lhs_ = lhs;
1049 }
1050
1051 virtual bool Alphabetic() const = 0;
1052 virtual const char *Operator() const = 0;
1053
1054 virtual CYExpression *Replace(CYContext &context);
1055 virtual void Output(CYOutput &out, CYFlags flags) const;
1056 };
1057
1058 struct CYPostfix :
1059 CYExpression
1060 {
1061 CYExpression *lhs_;
1062
1063 CYPostfix(CYExpression *lhs) :
1064 lhs_(lhs)
1065 {
1066 }
1067
1068 virtual const char *Operator() const = 0;
1069
1070 CYPrecedence(3)
1071
1072 virtual CYExpression *Replace(CYContext &context);
1073 virtual void Output(CYOutput &out, CYFlags flags) const;
1074 };
1075
1076 struct CYAssignment :
1077 CYExpression
1078 {
1079 CYExpression *lhs_;
1080 CYExpression *rhs_;
1081
1082 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1083 lhs_(lhs),
1084 rhs_(rhs)
1085 {
1086 }
1087
1088 void SetLeft(CYExpression *lhs) {
1089 lhs_ = lhs;
1090 }
1091
1092 virtual const char *Operator() const = 0;
1093
1094 CYPrecedence(16)
1095
1096 virtual CYExpression *Replace(CYContext &context);
1097 virtual void Output(CYOutput &out, CYFlags flags) const;
1098 };
1099
1100 struct CYArgument :
1101 CYNext<CYArgument>,
1102 CYThing
1103 {
1104 CYWord *name_;
1105 CYExpression *value_;
1106
1107 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1108 CYNext<CYArgument>(next),
1109 name_(NULL),
1110 value_(value)
1111 {
1112 }
1113
1114 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1115 CYNext<CYArgument>(next),
1116 name_(name),
1117 value_(value)
1118 {
1119 }
1120
1121 CYArgument *Replace(CYContext &context);
1122 void Output(CYOutput &out) const;
1123 };
1124
1125 struct CYBlank :
1126 public CYWord
1127 {
1128 CYBlank() :
1129 CYWord("")
1130 {
1131 }
1132 };
1133
1134 struct CYClause :
1135 CYThing,
1136 CYNext<CYClause>
1137 {
1138 CYExpression *case_;
1139 CYStatement *statements_;
1140
1141 CYClause(CYExpression *_case, CYStatement *statements) :
1142 case_(_case),
1143 statements_(statements)
1144 {
1145 }
1146
1147 void Replace(CYContext &context);
1148 virtual void Output(CYOutput &out) const;
1149 };
1150
1151 struct CYElement :
1152 CYNext<CYElement>,
1153 CYThing
1154 {
1155 CYExpression *value_;
1156
1157 CYElement(CYExpression *value, CYElement *next) :
1158 CYNext<CYElement>(next),
1159 value_(value)
1160 {
1161 }
1162
1163 void Replace(CYContext &context);
1164 void Output(CYOutput &out) const;
1165 };
1166
1167 struct CYArray :
1168 CYLiteral
1169 {
1170 CYElement *elements_;
1171
1172 CYArray(CYElement *elements = NULL) :
1173 elements_(elements)
1174 {
1175 }
1176
1177 virtual CYExpression *Replace(CYContext &context);
1178 virtual void Output(CYOutput &out, CYFlags flags) const;
1179 };
1180
1181 struct CYProperty :
1182 CYNext<CYProperty>,
1183 CYThing
1184 {
1185 CYPropertyName *name_;
1186 CYExpression *value_;
1187
1188 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1189 CYNext<CYProperty>(next),
1190 name_(name),
1191 value_(value)
1192 {
1193 }
1194
1195 void Replace(CYContext &context);
1196 virtual void Output(CYOutput &out) const;
1197 };
1198
1199 struct CYDeclaration :
1200 CYForInInitialiser
1201 {
1202 CYIdentifier *identifier_;
1203 CYExpression *initialiser_;
1204
1205 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1206 identifier_(identifier),
1207 initialiser_(initialiser)
1208 {
1209 }
1210
1211 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1212 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
1213
1214 virtual CYExpression *Replace(CYContext &context);
1215
1216 virtual CYAssignment *Assignment(CYContext &context);
1217 CYVariable *Variable(CYContext &context);
1218
1219 virtual void Output(CYOutput &out, CYFlags flags) const;
1220 };
1221
1222 struct CYDeclarations :
1223 CYNext<CYDeclarations>,
1224 CYThing
1225 {
1226 CYDeclaration *declaration_;
1227
1228 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1229 CYNext<CYDeclarations>(next),
1230 declaration_(declaration)
1231 {
1232 }
1233
1234 void Replace(CYContext &context);
1235
1236 CYCompound *Compound(CYContext &context);
1237 CYProperty *Property(CYContext &context);
1238 CYArgument *Argument(CYContext &context);
1239 CYFunctionParameter *Parameter(CYContext &context);
1240
1241 virtual void Output(CYOutput &out) const;
1242 virtual void Output(CYOutput &out, CYFlags flags) const;
1243 };
1244
1245 struct CYForDeclarations :
1246 CYForInitialiser
1247 {
1248 CYDeclarations *declarations_;
1249
1250 CYForDeclarations(CYDeclarations *declarations) :
1251 declarations_(declarations)
1252 {
1253 }
1254
1255 virtual CYCompound *Replace(CYContext &context);
1256 virtual void Output(CYOutput &out, CYFlags flags) const;
1257 };
1258
1259 struct CYVar :
1260 CYStatement
1261 {
1262 CYDeclarations *declarations_;
1263
1264 CYVar(CYDeclarations *declarations) :
1265 declarations_(declarations)
1266 {
1267 }
1268
1269 virtual CYStatement *Replace(CYContext &context);
1270 virtual void Output(CYOutput &out, CYFlags flags) const;
1271 };
1272
1273 struct CYLetStatement :
1274 CYStatement
1275 {
1276 CYDeclarations *declarations_;
1277 CYStatement *code_;
1278
1279 CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
1280 declarations_(declarations),
1281 code_(code)
1282 {
1283 }
1284
1285 virtual CYStatement *Replace(CYContext &context);
1286 virtual void Output(CYOutput &out, CYFlags flags) const;
1287 };
1288
1289 struct CYFor :
1290 CYStatement
1291 {
1292 CYForInitialiser *initialiser_;
1293 CYExpression *test_;
1294 CYExpression *increment_;
1295 CYStatement *code_;
1296
1297 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1298 initialiser_(initialiser),
1299 test_(test),
1300 increment_(increment),
1301 code_(code)
1302 {
1303 }
1304
1305 virtual CYStatement *Replace(CYContext &context);
1306 virtual void Output(CYOutput &out, CYFlags flags) const;
1307 };
1308
1309 struct CYForIn :
1310 CYStatement
1311 {
1312 CYForInInitialiser *initialiser_;
1313 CYExpression *set_;
1314 CYStatement *code_;
1315
1316 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1317 initialiser_(initialiser),
1318 set_(set),
1319 code_(code)
1320 {
1321 }
1322
1323 virtual CYStatement *Replace(CYContext &context);
1324 virtual void Output(CYOutput &out, CYFlags flags) const;
1325 };
1326
1327 struct CYForOf :
1328 CYStatement
1329 {
1330 CYForInInitialiser *initialiser_;
1331 CYExpression *set_;
1332 CYStatement *code_;
1333
1334 CYForOf(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1335 initialiser_(initialiser),
1336 set_(set),
1337 code_(code)
1338 {
1339 }
1340
1341 virtual CYStatement *Replace(CYContext &context);
1342 virtual void Output(CYOutput &out, CYFlags flags) const;
1343 };
1344
1345 struct CYObject :
1346 CYLiteral
1347 {
1348 CYProperty *properties_;
1349
1350 CYObject(CYProperty *properties = NULL) :
1351 properties_(properties)
1352 {
1353 }
1354
1355 virtual CYExpression *Replace(CYContext &context);
1356 void Output(CYOutput &out, CYFlags flags) const;
1357 };
1358
1359 struct CYMember :
1360 CYExpression
1361 {
1362 CYExpression *object_;
1363 CYExpression *property_;
1364
1365 CYMember(CYExpression *object, CYExpression *property) :
1366 object_(object),
1367 property_(property)
1368 {
1369 }
1370
1371 void SetLeft(CYExpression *object) {
1372 object_ = object;
1373 }
1374 };
1375
1376 struct CYDirectMember :
1377 CYMember
1378 {
1379 CYDirectMember(CYExpression *object, CYExpression *property) :
1380 CYMember(object, property)
1381 {
1382 }
1383
1384 CYPrecedence(1)
1385 CYRightHand(false)
1386
1387 virtual CYExpression *Replace(CYContext &context);
1388 virtual void Output(CYOutput &out, CYFlags flags) const;
1389 };
1390
1391 struct CYIndirectMember :
1392 CYMember
1393 {
1394 CYIndirectMember(CYExpression *object, CYExpression *property) :
1395 CYMember(object, property)
1396 {
1397 }
1398
1399 CYPrecedence(1)
1400 CYRightHand(false)
1401
1402 virtual CYExpression *Replace(CYContext &context);
1403 virtual void Output(CYOutput &out, CYFlags flags) const;
1404 };
1405
1406 namespace cy {
1407 namespace Syntax {
1408
1409 struct New :
1410 CYExpression
1411 {
1412 CYExpression *constructor_;
1413 CYArgument *arguments_;
1414
1415 New(CYExpression *constructor, CYArgument *arguments) :
1416 constructor_(constructor),
1417 arguments_(arguments)
1418 {
1419 }
1420
1421 virtual unsigned Precedence() const {
1422 return arguments_ == NULL ? 2 : 1;
1423 }
1424
1425 CYRightHand(false)
1426
1427 virtual CYExpression *Replace(CYContext &context);
1428 virtual void Output(CYOutput &out, CYFlags flags) const;
1429
1430 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1431 };
1432
1433 } }
1434
1435 struct CYCall :
1436 CYExpression
1437 {
1438 CYExpression *function_;
1439 CYArgument *arguments_;
1440
1441 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1442 function_(function),
1443 arguments_(arguments)
1444 {
1445 }
1446
1447 CYPrecedence(1)
1448 CYRightHand(false)
1449
1450 virtual CYExpression *Replace(CYContext &context);
1451 virtual void Output(CYOutput &out, CYFlags flags) const;
1452
1453 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1454 };
1455
1456 struct CYRubyProc;
1457
1458 struct CYRubyBlock :
1459 CYExpression
1460 {
1461 CYExpression *call_;
1462 CYRubyProc *proc_;
1463
1464 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1465 call_(call),
1466 proc_(proc)
1467 {
1468 }
1469
1470 CYPrecedence(1)
1471 CYRightHand(false)
1472
1473 virtual CYExpression *Replace(CYContext &context);
1474 virtual void Output(CYOutput &out, CYFlags flags) const;
1475 };
1476
1477 struct CYIf :
1478 CYStatement
1479 {
1480 CYExpression *test_;
1481 CYStatement *true_;
1482 CYStatement *false_;
1483
1484 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1485 test_(test),
1486 true_(_true),
1487 false_(_false)
1488 {
1489 }
1490
1491 virtual CYStatement *Replace(CYContext &context);
1492 virtual void Output(CYOutput &out, CYFlags flags) const;
1493 };
1494
1495 struct CYDoWhile :
1496 CYStatement
1497 {
1498 CYExpression *test_;
1499 CYStatement *code_;
1500
1501 CYDoWhile(CYExpression *test, CYStatement *code) :
1502 test_(test),
1503 code_(code)
1504 {
1505 }
1506
1507 virtual CYStatement *Replace(CYContext &context);
1508 virtual void Output(CYOutput &out, CYFlags flags) const;
1509 };
1510
1511 struct CYWhile :
1512 CYStatement
1513 {
1514 CYExpression *test_;
1515 CYStatement *code_;
1516
1517 CYWhile(CYExpression *test, CYStatement *code) :
1518 test_(test),
1519 code_(code)
1520 {
1521 }
1522
1523 virtual CYStatement *Replace(CYContext &context);
1524 virtual void Output(CYOutput &out, CYFlags flags) const;
1525 };
1526
1527 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
1528 struct CYFunction {
1529 CYIdentifier *name_;
1530 CYFunctionParameter *parameters_;
1531 CYBlock code_;
1532
1533 CYNonLocal *nonlocal_;
1534 CYThisScope this_;
1535
1536 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1537 name_(name),
1538 parameters_(parameters),
1539 code_(statements),
1540 nonlocal_(NULL)
1541 {
1542 }
1543
1544 virtual ~CYFunction() {
1545 }
1546
1547 void Inject(CYContext &context);
1548 virtual void Replace_(CYContext &context, bool outer);
1549 virtual void Output(CYOutput &out, CYFlags flags) const;
1550 };
1551
1552 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
1553 struct CYFunctionExpression :
1554 CYFunction,
1555 CYExpression
1556 {
1557 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1558 CYFunction(name, parameters, statements)
1559 {
1560 }
1561
1562 CYPrecedence(0)
1563 CYRightHand(false)
1564
1565 virtual CYExpression *Replace(CYContext &context);
1566 virtual void Output(CYOutput &out, CYFlags flags) const;
1567 };
1568
1569 // XXX: this should derive from CYAnonymousFunction
1570 struct CYFatArrow :
1571 CYFunction,
1572 CYExpression
1573 {
1574 CYFatArrow(CYFunctionParameter *parameters, CYStatement *statements) :
1575 CYFunction(NULL, parameters, statements)
1576 {
1577 }
1578
1579 CYPrecedence(0)
1580 CYRightHand(false)
1581
1582 virtual CYExpression *Replace(CYContext &context);
1583 virtual void Output(CYOutput &out, CYFlags flags) const;
1584 };
1585
1586 // XXX: this should derive from CYAnonymousFunctionExpression
1587 struct CYRubyProc :
1588 CYFunctionExpression
1589 {
1590 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1591 CYFunctionExpression(NULL, parameters, statements)
1592 {
1593 }
1594
1595 virtual CYExpression *Replace(CYContext &context);
1596 virtual void Output(CYOutput &out, CYFlags flags) const;
1597 };
1598
1599 // XXX: this should derive from CYNamedFunction
1600 struct CYFunctionStatement :
1601 CYFunction,
1602 CYStatement
1603 {
1604 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1605 CYFunction(name, parameters, statements)
1606 {
1607 }
1608
1609 virtual CYStatement *Replace(CYContext &context);
1610 virtual void Output(CYOutput &out, CYFlags flags) const;
1611 };
1612
1613 struct CYExpress :
1614 CYStatement
1615 {
1616 CYExpression *expression_;
1617
1618 CYExpress(CYExpression *expression) :
1619 expression_(expression)
1620 {
1621 if (expression == NULL)
1622 throw;
1623 }
1624
1625 virtual CYStatement *Replace(CYContext &context);
1626 virtual void Output(CYOutput &out, CYFlags flags) const;
1627 };
1628
1629 struct CYContinue :
1630 CYStatement
1631 {
1632 CYIdentifier *label_;
1633
1634 CYContinue(CYIdentifier *label) :
1635 label_(label)
1636 {
1637 }
1638
1639 virtual CYStatement *Replace(CYContext &context);
1640 virtual void Output(CYOutput &out, CYFlags flags) const;
1641 };
1642
1643 struct CYBreak :
1644 CYStatement
1645 {
1646 CYIdentifier *label_;
1647
1648 CYBreak(CYIdentifier *label) :
1649 label_(label)
1650 {
1651 }
1652
1653 virtual CYStatement *Replace(CYContext &context);
1654 virtual void Output(CYOutput &out, CYFlags flags) const;
1655 };
1656
1657 struct CYReturn :
1658 CYStatement
1659 {
1660 CYExpression *value_;
1661
1662 CYReturn(CYExpression *value) :
1663 value_(value)
1664 {
1665 }
1666
1667 virtual CYStatement *Replace(CYContext &context);
1668 virtual void Output(CYOutput &out, CYFlags flags) const;
1669 };
1670
1671 struct CYEmpty :
1672 CYStatement
1673 {
1674 virtual CYStatement *Replace(CYContext &context);
1675 virtual void Output(CYOutput &out, CYFlags flags) const;
1676 };
1677
1678 struct CYFinally :
1679 CYThing
1680 {
1681 CYBlock code_;
1682
1683 CYFinally(CYStatement *statements) :
1684 code_(statements)
1685 {
1686 }
1687
1688 void Replace(CYContext &context);
1689 virtual void Output(CYOutput &out) const;
1690 };
1691
1692 namespace cy {
1693 namespace Syntax {
1694
1695 struct Catch :
1696 CYThing
1697 {
1698 CYIdentifier *name_;
1699 CYBlock code_;
1700
1701 Catch(CYIdentifier *name, CYStatement *statements) :
1702 name_(name),
1703 code_(statements)
1704 {
1705 }
1706
1707 void Replace(CYContext &context);
1708 virtual void Output(CYOutput &out) const;
1709 };
1710
1711 struct Try :
1712 CYStatement
1713 {
1714 CYBlock code_;
1715 Catch *catch_;
1716 CYFinally *finally_;
1717
1718 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1719 code_(statements),
1720 catch_(_catch),
1721 finally_(finally)
1722 {
1723 }
1724
1725 virtual CYStatement *Replace(CYContext &context);
1726 virtual void Output(CYOutput &out, CYFlags flags) const;
1727 };
1728
1729 struct Throw :
1730 CYStatement
1731 {
1732 CYExpression *value_;
1733
1734 Throw(CYExpression *value = NULL) :
1735 value_(value)
1736 {
1737 }
1738
1739 virtual CYStatement *Replace(CYContext &context);
1740 virtual void Output(CYOutput &out, CYFlags flags) const;
1741 };
1742
1743 } }
1744
1745 struct CYWith :
1746 CYStatement
1747 {
1748 CYExpression *scope_;
1749 CYStatement *code_;
1750
1751 CYWith(CYExpression *scope, CYStatement *code) :
1752 scope_(scope),
1753 code_(code)
1754 {
1755 }
1756
1757 virtual CYStatement *Replace(CYContext &context);
1758 virtual void Output(CYOutput &out, CYFlags flags) const;
1759 };
1760
1761 struct CYSwitch :
1762 CYStatement
1763 {
1764 CYExpression *value_;
1765 CYClause *clauses_;
1766
1767 CYSwitch(CYExpression *value, CYClause *clauses) :
1768 value_(value),
1769 clauses_(clauses)
1770 {
1771 }
1772
1773 virtual CYStatement *Replace(CYContext &context);
1774 virtual void Output(CYOutput &out, CYFlags flags) const;
1775 };
1776
1777 struct CYDebugger :
1778 CYStatement
1779 {
1780 CYDebugger()
1781 {
1782 }
1783
1784 virtual CYStatement *Replace(CYContext &context);
1785 virtual void Output(CYOutput &out, CYFlags flags) const;
1786 };
1787
1788 struct CYCondition :
1789 CYExpression
1790 {
1791 CYExpression *test_;
1792 CYExpression *true_;
1793 CYExpression *false_;
1794
1795 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1796 test_(test),
1797 true_(_true),
1798 false_(_false)
1799 {
1800 }
1801
1802 CYPrecedence(15)
1803
1804 virtual CYExpression *Replace(CYContext &context);
1805 virtual void Output(CYOutput &out, CYFlags flags) const;
1806 };
1807
1808 struct CYAddressOf :
1809 CYPrefix
1810 {
1811 CYAddressOf(CYExpression *rhs) :
1812 CYPrefix(rhs)
1813 {
1814 }
1815
1816 virtual const char *Operator() const {
1817 return "&";
1818 }
1819
1820 CYAlphabetic(false)
1821
1822 virtual CYExpression *Replace(CYContext &context);
1823 };
1824
1825 struct CYIndirect :
1826 CYPrefix
1827 {
1828 CYIndirect(CYExpression *rhs) :
1829 CYPrefix(rhs)
1830 {
1831 }
1832
1833 virtual const char *Operator() const {
1834 return "*";
1835 }
1836
1837 CYAlphabetic(false)
1838
1839 virtual CYExpression *Replace(CYContext &context);
1840 };
1841
1842 #define CYReplace \
1843 virtual CYExpression *Replace(CYContext &context);
1844
1845 #define CYPostfix_(op, name, args...) \
1846 struct CY ## name : \
1847 CYPostfix \
1848 { args \
1849 CY ## name(CYExpression *lhs) : \
1850 CYPostfix(lhs) \
1851 { \
1852 } \
1853 \
1854 virtual const char *Operator() const { \
1855 return op; \
1856 } \
1857 };
1858
1859 #define CYPrefix_(alphabetic, op, name, args...) \
1860 struct CY ## name : \
1861 CYPrefix \
1862 { args \
1863 CY ## name(CYExpression *rhs) : \
1864 CYPrefix(rhs) \
1865 { \
1866 } \
1867 \
1868 CYAlphabetic(alphabetic) \
1869 \
1870 virtual const char *Operator() const { \
1871 return op; \
1872 } \
1873 };
1874
1875 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1876 struct CY ## name : \
1877 CYInfix \
1878 { args \
1879 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1880 CYInfix(lhs, rhs) \
1881 { \
1882 } \
1883 \
1884 CYAlphabetic(alphabetic) \
1885 CYPrecedence(precedence) \
1886 \
1887 virtual const char *Operator() const { \
1888 return op; \
1889 } \
1890 };
1891
1892 #define CYAssignment_(op, name, args...) \
1893 struct CY ## name ## Assign : \
1894 CYAssignment \
1895 { args \
1896 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1897 CYAssignment(lhs, rhs) \
1898 { \
1899 } \
1900 \
1901 virtual const char *Operator() const { \
1902 return op; \
1903 } \
1904 };
1905
1906 CYPostfix_("++", PostIncrement)
1907 CYPostfix_("--", PostDecrement)
1908
1909 CYPrefix_(true, "delete", Delete)
1910 CYPrefix_(true, "void", Void)
1911 CYPrefix_(true, "typeof", TypeOf)
1912 CYPrefix_(false, "++", PreIncrement)
1913 CYPrefix_(false, "--", PreDecrement)
1914 CYPrefix_(false, "+", Affirm)
1915 CYPrefix_(false, "-", Negate)
1916 CYPrefix_(false, "~", BitwiseNot)
1917 CYPrefix_(false, "!", LogicalNot)
1918
1919 CYInfix_(false, 5, "*", Multiply)
1920 CYInfix_(false, 5, "/", Divide)
1921 CYInfix_(false, 5, "%", Modulus)
1922 CYInfix_(false, 6, "+", Add, CYReplace)
1923 CYInfix_(false, 6, "-", Subtract)
1924 CYInfix_(false, 7, "<<", ShiftLeft)
1925 CYInfix_(false, 7, ">>", ShiftRightSigned)
1926 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1927 CYInfix_(false, 8, "<", Less)
1928 CYInfix_(false, 8, ">", Greater)
1929 CYInfix_(false, 8, "<=", LessOrEqual)
1930 CYInfix_(false, 8, ">=", GreaterOrEqual)
1931 CYInfix_(true, 8, "instanceof", InstanceOf)
1932 CYInfix_(true, 8, "in", In)
1933 CYInfix_(false, 9, "==", Equal)
1934 CYInfix_(false, 9, "!=", NotEqual)
1935 CYInfix_(false, 9, "===", Identical)
1936 CYInfix_(false, 9, "!==", NotIdentical)
1937 CYInfix_(false, 10, "&", BitwiseAnd)
1938 CYInfix_(false, 11, "^", BitwiseXOr)
1939 CYInfix_(false, 12, "|", BitwiseOr)
1940 CYInfix_(false, 13, "&&", LogicalAnd)
1941 CYInfix_(false, 14, "||", LogicalOr)
1942
1943 CYAssignment_("=", )
1944 CYAssignment_("*=", Multiply)
1945 CYAssignment_("/=", Divide)
1946 CYAssignment_("%=", Modulus)
1947 CYAssignment_("+=", Add)
1948 CYAssignment_("-=", Subtract)
1949 CYAssignment_("<<=", ShiftLeft)
1950 CYAssignment_(">>=", ShiftRightSigned)
1951 CYAssignment_(">>>=", ShiftRightUnsigned)
1952 CYAssignment_("&=", BitwiseAnd)
1953 CYAssignment_("^=", BitwiseXOr)
1954 CYAssignment_("|=", BitwiseOr)
1955
1956 #endif/*CYCRIPT_PARSER_HPP*/