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