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