]> git.saurik.com Git - cycript.git/blob - Parser.hpp
Support full compilation on Mac OS X with clang++.
[cycript.git] / Parser.hpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2013 Jay Freeman (saurik)
3 */
4
5 /* GNU General Public License, Version 3 {{{ */
6 /*
7 * Cycript is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 3 of the License,
10 * or (at your option) any later version.
11 *
12 * Cycript is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU 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 struct 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 bool commented_;
510
511 enum Condition {
512 RegExpCondition,
513 XMLContentCondition,
514 XMLTagCondition,
515 };
516
517 std::string filename_;
518
519 struct Error {
520 bool warning_;
521 cy::location location_;
522 std::string message_;
523 };
524
525 typedef std::vector<Error> Errors;
526
527 CYProgram *program_;
528 Errors errors_;
529
530 bool auto_;
531
532 struct Context {
533 CYExpression *context_;
534
535 Context(CYExpression *context) :
536 context_(context)
537 {
538 }
539
540 typedef std::vector<CYWord *> Words;
541 Words words_;
542 };
543
544 typedef std::vector<Context> Contexts;
545 Contexts contexts_;
546
547 CYExpression *context_;
548
549 enum Mode {
550 AutoNone,
551 AutoPrimary,
552 AutoDirect,
553 AutoIndirect,
554 AutoMessage
555 } mode_;
556
557 private:
558 void ScannerInit();
559 void ScannerDestroy();
560
561 public:
562 CYDriver(std::istream &data, const std::string &filename = "");
563 ~CYDriver();
564
565 Condition GetCondition();
566 void SetCondition(Condition condition);
567
568 void PushCondition(Condition condition);
569 void PopCondition();
570
571 void Warning(const cy::location &location, const char *message);
572 };
573
574 struct CYForInitialiser {
575 virtual ~CYForInitialiser() {
576 }
577
578 virtual CYExpression *Replace(CYContext &context) = 0;
579 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
580 };
581
582 struct CYForInInitialiser {
583 virtual ~CYForInInitialiser() {
584 }
585
586 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
587 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value) = 0;
588
589 virtual CYExpression *Replace(CYContext &context) = 0;
590 virtual CYAssignment *Assignment(CYContext &context) = 0;
591
592 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
593 };
594
595 struct CYNumber;
596 struct CYString;
597
598 struct CYExpression :
599 CYNext<CYExpression>,
600 CYForInitialiser,
601 CYForInInitialiser,
602 CYClassName,
603 CYThing
604 {
605 virtual unsigned Precedence() const = 0;
606
607 virtual bool RightHand() const {
608 return true;
609 }
610
611 virtual void ForIn(CYOutput &out, CYFlags flags) const;
612 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
613
614 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
615
616 virtual void Output(CYOutput &out) const;
617 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
618 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
619
620 virtual CYExpression *ClassName(CYContext &context, bool object);
621 virtual void ClassName(CYOutput &out, bool object) const;
622
623 virtual CYExpression *Replace(CYContext &context) = 0;
624 virtual CYAssignment *Assignment(CYContext &context);
625
626 virtual CYExpression *Primitive(CYContext &context) {
627 return this;
628 }
629
630 virtual CYNumber *Number(CYContext &context) {
631 return NULL;
632 }
633
634 virtual CYString *String(CYContext &context) {
635 return NULL;
636 }
637
638 virtual const char *Word() const {
639 return NULL;
640 }
641 };
642
643 #define CYAlphabetic(value) \
644 virtual bool Alphabetic() const { \
645 return value; \
646 }
647
648 #define CYPrecedence(value) \
649 static const unsigned Precedence_ = value; \
650 virtual unsigned Precedence() const { \
651 return Precedence_; \
652 }
653
654 #define CYRightHand(value) \
655 virtual bool RightHand() const { \
656 return value; \
657 }
658
659 struct CYCompound :
660 CYExpression
661 {
662 CYExpression *expressions_;
663
664 CYCompound(CYExpression *expressions = NULL) :
665 expressions_(expressions)
666 {
667 }
668
669 void AddPrev(CYExpression *expression) {
670 CYSetLast(expression) = expressions_;
671 expressions_ = expression;
672 }
673
674 CYPrecedence(17)
675
676 virtual CYExpression *Replace(CYContext &context);
677 void Output(CYOutput &out, CYFlags flags) const;
678
679 virtual CYExpression *Primitive(CYContext &context);
680 };
681
682 struct CYDeclaration;
683
684 struct CYFunctionParameter :
685 CYNext<CYFunctionParameter>,
686 CYThing
687 {
688 CYForInInitialiser *initialiser_;
689
690 CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
691 CYNext<CYFunctionParameter>(next),
692 initialiser_(initialiser)
693 {
694 }
695
696 void Replace(CYContext &context, CYBlock &code);
697 void Output(CYOutput &out) const;
698 };
699
700 struct CYComprehension :
701 CYNext<CYComprehension>,
702 CYThing
703 {
704 CYComprehension(CYComprehension *next = NULL) :
705 CYNext<CYComprehension>(next)
706 {
707 }
708
709 virtual const char *Name() const = 0;
710
711 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
712 CYFunctionParameter *Parameters(CYContext &context) const;
713 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
714 virtual void Output(CYOutput &out) const = 0;
715 };
716
717 struct CYForInComprehension :
718 CYComprehension
719 {
720 CYIdentifier *name_;
721 CYExpression *set_;
722
723 CYForInComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
724 CYComprehension(next),
725 name_(name),
726 set_(set)
727 {
728 }
729
730 virtual const char *Name() const {
731 return name_->Word();
732 }
733
734 virtual CYFunctionParameter *Parameter(CYContext &context) const;
735 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
736 virtual void Output(CYOutput &out) const;
737 };
738
739 struct CYForOfComprehension :
740 CYComprehension
741 {
742 CYIdentifier *name_;
743 CYExpression *set_;
744
745 CYForOfComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
746 CYComprehension(next),
747 name_(name),
748 set_(set)
749 {
750 }
751
752 virtual const char *Name() const {
753 return name_->Word();
754 }
755
756 virtual CYFunctionParameter *Parameter(CYContext &context) const;
757 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
758 virtual void Output(CYOutput &out) const;
759 };
760
761 struct CYIfComprehension :
762 CYComprehension
763 {
764 CYExpression *test_;
765
766 CYIfComprehension(CYExpression *test) :
767 test_(test)
768 {
769 }
770
771 virtual const char *Name() const {
772 return NULL;
773 }
774
775 virtual CYFunctionParameter *Parameter(CYContext &context) const;
776 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
777 virtual void Output(CYOutput &out) const;
778 };
779
780 struct CYArrayComprehension :
781 CYExpression
782 {
783 CYExpression *expression_;
784 CYComprehension *comprehensions_;
785
786 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
787 expression_(expression),
788 comprehensions_(comprehensions)
789 {
790 }
791
792 CYPrecedence(0)
793
794 virtual CYExpression *Replace(CYContext &context);
795 virtual void Output(CYOutput &out, CYFlags flags) const;
796 };
797
798 struct CYLiteral :
799 CYExpression
800 {
801 CYPrecedence(0)
802 CYRightHand(false)
803 };
804
805 struct CYTrivial :
806 CYLiteral
807 {
808 virtual CYExpression *Replace(CYContext &context);
809 };
810
811 struct CYMagic :
812 CYExpression
813 {
814 CYPrecedence(0)
815 CYRightHand(false)
816 };
817
818 struct CYRange {
819 uint64_t lo_;
820 uint64_t hi_;
821
822 CYRange(uint64_t lo, uint64_t hi) :
823 lo_(lo), hi_(hi)
824 {
825 }
826
827 bool operator [](uint8_t value) const {
828 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
829 }
830
831 void operator()(uint8_t value) {
832 if (value >> 7)
833 return;
834 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
835 }
836 };
837
838 extern CYRange DigitRange_;
839 extern CYRange WordStartRange_;
840 extern CYRange WordEndRange_;
841
842 struct CYString :
843 CYTrivial,
844 CYPropertyName
845 {
846 const char *value_;
847 size_t size_;
848
849 CYString() :
850 value_(NULL),
851 size_(0)
852 {
853 }
854
855 CYString(const char *value) :
856 value_(value),
857 size_(strlen(value))
858 {
859 }
860
861 CYString(const char *value, size_t size) :
862 value_(value),
863 size_(size)
864 {
865 }
866
867 CYString(const CYWord *word) :
868 value_(word->Word()),
869 size_(strlen(value_))
870 {
871 }
872
873 const char *Value() const {
874 return value_;
875 }
876
877 virtual const char *Word() const;
878
879 virtual CYNumber *Number(CYContext &context);
880 virtual CYString *String(CYContext &context);
881
882 CYString *Concat(CYContext &out, CYString *rhs) const;
883 virtual void Output(CYOutput &out, CYFlags flags) const;
884 virtual void PropertyName(CYOutput &out) const;
885 };
886
887 struct CYNumber :
888 CYTrivial,
889 CYPropertyName
890 {
891 double value_;
892
893 CYNumber(double value) :
894 value_(value)
895 {
896 }
897
898 double Value() const {
899 return value_;
900 }
901
902 virtual CYNumber *Number(CYContext &context);
903 virtual CYString *String(CYContext &context);
904
905 virtual void Output(CYOutput &out, CYFlags flags) const;
906 virtual void PropertyName(CYOutput &out) const;
907 };
908
909 struct CYRegEx :
910 CYTrivial
911 {
912 const char *value_;
913
914 CYRegEx(const char *value) :
915 value_(value)
916 {
917 }
918
919 const char *Value() const {
920 return value_;
921 }
922
923 virtual void Output(CYOutput &out, CYFlags flags) const;
924 };
925
926 struct CYNull :
927 CYWord,
928 CYTrivial
929 {
930 CYNull() :
931 CYWord("null")
932 {
933 }
934
935 virtual CYNumber *Number(CYContext &context);
936 virtual CYString *String(CYContext &context);
937
938 virtual void Output(CYOutput &out, CYFlags flags) const;
939 };
940
941 struct CYThis :
942 CYWord,
943 CYMagic
944 {
945 CYThis() :
946 CYWord("this")
947 {
948 }
949
950 virtual CYExpression *Replace(CYContext &context);
951 virtual void Output(CYOutput &out, CYFlags flags) const;
952 };
953
954 struct CYBoolean :
955 CYTrivial
956 {
957 virtual bool Value() const = 0;
958 virtual void Output(CYOutput &out, CYFlags flags) const;
959 };
960
961 struct CYFalse :
962 CYWord,
963 CYBoolean
964 {
965 CYFalse() :
966 CYWord("false")
967 {
968 }
969
970 virtual bool Value() const {
971 return false;
972 }
973
974 virtual CYNumber *Number(CYContext &context);
975 virtual CYString *String(CYContext &context);
976 };
977
978 struct CYTrue :
979 CYWord,
980 CYBoolean
981 {
982 CYTrue() :
983 CYWord("true")
984 {
985 }
986
987 virtual bool Value() const {
988 return true;
989 }
990
991 virtual CYNumber *Number(CYContext &context);
992 virtual CYString *String(CYContext &context);
993 };
994
995 struct CYVariable :
996 CYExpression
997 {
998 CYIdentifier *name_;
999
1000 CYVariable(CYIdentifier *name) :
1001 name_(name)
1002 {
1003 }
1004
1005 CYVariable(const char *name) :
1006 name_(new($pool) CYIdentifier(name))
1007 {
1008 }
1009
1010 CYPrecedence(0)
1011 CYRightHand(false)
1012
1013 virtual CYExpression *Replace(CYContext &context);
1014 virtual void Output(CYOutput &out, CYFlags flags) const;
1015 };
1016
1017 struct CYPrefix :
1018 CYExpression
1019 {
1020 CYExpression *rhs_;
1021
1022 CYPrefix(CYExpression *rhs) :
1023 rhs_(rhs)
1024 {
1025 }
1026
1027 virtual bool Alphabetic() const = 0;
1028 virtual const char *Operator() const = 0;
1029
1030 CYPrecedence(4)
1031
1032 virtual CYExpression *Replace(CYContext &context);
1033 virtual void Output(CYOutput &out, CYFlags flags) const;
1034 };
1035
1036 struct CYInfix :
1037 CYExpression
1038 {
1039 CYExpression *lhs_;
1040 CYExpression *rhs_;
1041
1042 CYInfix(CYExpression *lhs, CYExpression *rhs) :
1043 lhs_(lhs),
1044 rhs_(rhs)
1045 {
1046 }
1047
1048 void SetLeft(CYExpression *lhs) {
1049 lhs_ = lhs;
1050 }
1051
1052 virtual bool Alphabetic() const = 0;
1053 virtual const char *Operator() const = 0;
1054
1055 virtual CYExpression *Replace(CYContext &context);
1056 virtual void Output(CYOutput &out, CYFlags flags) const;
1057 };
1058
1059 struct CYPostfix :
1060 CYExpression
1061 {
1062 CYExpression *lhs_;
1063
1064 CYPostfix(CYExpression *lhs) :
1065 lhs_(lhs)
1066 {
1067 }
1068
1069 virtual const char *Operator() const = 0;
1070
1071 CYPrecedence(3)
1072
1073 virtual CYExpression *Replace(CYContext &context);
1074 virtual void Output(CYOutput &out, CYFlags flags) const;
1075 };
1076
1077 struct CYAssignment :
1078 CYExpression
1079 {
1080 CYExpression *lhs_;
1081 CYExpression *rhs_;
1082
1083 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1084 lhs_(lhs),
1085 rhs_(rhs)
1086 {
1087 }
1088
1089 void SetLeft(CYExpression *lhs) {
1090 lhs_ = lhs;
1091 }
1092
1093 virtual const char *Operator() const = 0;
1094
1095 CYPrecedence(16)
1096
1097 virtual CYExpression *Replace(CYContext &context);
1098 virtual void Output(CYOutput &out, CYFlags flags) const;
1099 };
1100
1101 struct CYArgument :
1102 CYNext<CYArgument>,
1103 CYThing
1104 {
1105 CYWord *name_;
1106 CYExpression *value_;
1107
1108 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1109 CYNext<CYArgument>(next),
1110 name_(NULL),
1111 value_(value)
1112 {
1113 }
1114
1115 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1116 CYNext<CYArgument>(next),
1117 name_(name),
1118 value_(value)
1119 {
1120 }
1121
1122 CYArgument *Replace(CYContext &context);
1123 void Output(CYOutput &out) const;
1124 };
1125
1126 struct CYBlank :
1127 public CYWord
1128 {
1129 CYBlank() :
1130 CYWord("")
1131 {
1132 }
1133 };
1134
1135 struct CYClause :
1136 CYThing,
1137 CYNext<CYClause>
1138 {
1139 CYExpression *case_;
1140 CYStatement *statements_;
1141
1142 CYClause(CYExpression *_case, CYStatement *statements) :
1143 case_(_case),
1144 statements_(statements)
1145 {
1146 }
1147
1148 void Replace(CYContext &context);
1149 virtual void Output(CYOutput &out) const;
1150 };
1151
1152 struct CYElement :
1153 CYNext<CYElement>,
1154 CYThing
1155 {
1156 CYExpression *value_;
1157
1158 CYElement(CYExpression *value, CYElement *next) :
1159 CYNext<CYElement>(next),
1160 value_(value)
1161 {
1162 }
1163
1164 void Replace(CYContext &context);
1165 void Output(CYOutput &out) const;
1166 };
1167
1168 struct CYArray :
1169 CYLiteral
1170 {
1171 CYElement *elements_;
1172
1173 CYArray(CYElement *elements = NULL) :
1174 elements_(elements)
1175 {
1176 }
1177
1178 virtual CYExpression *Replace(CYContext &context);
1179 virtual void Output(CYOutput &out, CYFlags flags) const;
1180 };
1181
1182 struct CYProperty :
1183 CYNext<CYProperty>,
1184 CYThing
1185 {
1186 CYPropertyName *name_;
1187 CYExpression *value_;
1188
1189 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1190 CYNext<CYProperty>(next),
1191 name_(name),
1192 value_(value)
1193 {
1194 }
1195
1196 void Replace(CYContext &context);
1197 virtual void Output(CYOutput &out) const;
1198 };
1199
1200 struct CYDeclaration :
1201 CYForInInitialiser
1202 {
1203 CYIdentifier *identifier_;
1204 CYExpression *initialiser_;
1205
1206 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1207 identifier_(identifier),
1208 initialiser_(initialiser)
1209 {
1210 }
1211
1212 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1213 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
1214
1215 virtual CYExpression *Replace(CYContext &context);
1216
1217 virtual CYAssignment *Assignment(CYContext &context);
1218 CYVariable *Variable(CYContext &context);
1219
1220 virtual void Output(CYOutput &out, CYFlags flags) const;
1221 };
1222
1223 struct CYDeclarations :
1224 CYNext<CYDeclarations>,
1225 CYThing
1226 {
1227 CYDeclaration *declaration_;
1228
1229 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1230 CYNext<CYDeclarations>(next),
1231 declaration_(declaration)
1232 {
1233 }
1234
1235 void Replace(CYContext &context);
1236
1237 CYCompound *Compound(CYContext &context);
1238 CYProperty *Property(CYContext &context);
1239 CYArgument *Argument(CYContext &context);
1240 CYFunctionParameter *Parameter(CYContext &context);
1241
1242 virtual void Output(CYOutput &out) const;
1243 virtual void Output(CYOutput &out, CYFlags flags) const;
1244 };
1245
1246 struct CYForDeclarations :
1247 CYForInitialiser
1248 {
1249 CYDeclarations *declarations_;
1250
1251 CYForDeclarations(CYDeclarations *declarations) :
1252 declarations_(declarations)
1253 {
1254 }
1255
1256 virtual CYCompound *Replace(CYContext &context);
1257 virtual void Output(CYOutput &out, CYFlags flags) const;
1258 };
1259
1260 struct CYVar :
1261 CYStatement
1262 {
1263 CYDeclarations *declarations_;
1264
1265 CYVar(CYDeclarations *declarations) :
1266 declarations_(declarations)
1267 {
1268 }
1269
1270 virtual CYStatement *Replace(CYContext &context);
1271 virtual void Output(CYOutput &out, CYFlags flags) const;
1272 };
1273
1274 struct CYLetStatement :
1275 CYStatement
1276 {
1277 CYDeclarations *declarations_;
1278 CYStatement *code_;
1279
1280 CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
1281 declarations_(declarations),
1282 code_(code)
1283 {
1284 }
1285
1286 virtual CYStatement *Replace(CYContext &context);
1287 virtual void Output(CYOutput &out, CYFlags flags) const;
1288 };
1289
1290 struct CYFor :
1291 CYStatement
1292 {
1293 CYForInitialiser *initialiser_;
1294 CYExpression *test_;
1295 CYExpression *increment_;
1296 CYStatement *code_;
1297
1298 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1299 initialiser_(initialiser),
1300 test_(test),
1301 increment_(increment),
1302 code_(code)
1303 {
1304 }
1305
1306 virtual CYStatement *Replace(CYContext &context);
1307 virtual void Output(CYOutput &out, CYFlags flags) const;
1308 };
1309
1310 struct CYForIn :
1311 CYStatement
1312 {
1313 CYForInInitialiser *initialiser_;
1314 CYExpression *set_;
1315 CYStatement *code_;
1316
1317 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1318 initialiser_(initialiser),
1319 set_(set),
1320 code_(code)
1321 {
1322 }
1323
1324 virtual CYStatement *Replace(CYContext &context);
1325 virtual void Output(CYOutput &out, CYFlags flags) const;
1326 };
1327
1328 struct CYForOf :
1329 CYStatement
1330 {
1331 CYForInInitialiser *initialiser_;
1332 CYExpression *set_;
1333 CYStatement *code_;
1334
1335 CYForOf(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1336 initialiser_(initialiser),
1337 set_(set),
1338 code_(code)
1339 {
1340 }
1341
1342 virtual CYStatement *Replace(CYContext &context);
1343 virtual void Output(CYOutput &out, CYFlags flags) const;
1344 };
1345
1346 struct CYObject :
1347 CYLiteral
1348 {
1349 CYProperty *properties_;
1350
1351 CYObject(CYProperty *properties = NULL) :
1352 properties_(properties)
1353 {
1354 }
1355
1356 virtual CYExpression *Replace(CYContext &context);
1357 void Output(CYOutput &out, CYFlags flags) const;
1358 };
1359
1360 struct CYMember :
1361 CYExpression
1362 {
1363 CYExpression *object_;
1364 CYExpression *property_;
1365
1366 CYMember(CYExpression *object, CYExpression *property) :
1367 object_(object),
1368 property_(property)
1369 {
1370 }
1371
1372 void SetLeft(CYExpression *object) {
1373 object_ = object;
1374 }
1375 };
1376
1377 struct CYDirectMember :
1378 CYMember
1379 {
1380 CYDirectMember(CYExpression *object, CYExpression *property) :
1381 CYMember(object, property)
1382 {
1383 }
1384
1385 CYPrecedence(1)
1386 CYRightHand(false)
1387
1388 virtual CYExpression *Replace(CYContext &context);
1389 virtual void Output(CYOutput &out, CYFlags flags) const;
1390 };
1391
1392 struct CYIndirectMember :
1393 CYMember
1394 {
1395 CYIndirectMember(CYExpression *object, CYExpression *property) :
1396 CYMember(object, property)
1397 {
1398 }
1399
1400 CYPrecedence(1)
1401 CYRightHand(false)
1402
1403 virtual CYExpression *Replace(CYContext &context);
1404 virtual void Output(CYOutput &out, CYFlags flags) const;
1405 };
1406
1407 namespace cy {
1408 namespace Syntax {
1409
1410 struct New :
1411 CYExpression
1412 {
1413 CYExpression *constructor_;
1414 CYArgument *arguments_;
1415
1416 New(CYExpression *constructor, CYArgument *arguments) :
1417 constructor_(constructor),
1418 arguments_(arguments)
1419 {
1420 }
1421
1422 virtual unsigned Precedence() const {
1423 return arguments_ == NULL ? 2 : 1;
1424 }
1425
1426 CYRightHand(false)
1427
1428 virtual CYExpression *Replace(CYContext &context);
1429 virtual void Output(CYOutput &out, CYFlags flags) const;
1430
1431 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1432 };
1433
1434 } }
1435
1436 struct CYCall :
1437 CYExpression
1438 {
1439 CYExpression *function_;
1440 CYArgument *arguments_;
1441
1442 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1443 function_(function),
1444 arguments_(arguments)
1445 {
1446 }
1447
1448 CYPrecedence(1)
1449 CYRightHand(false)
1450
1451 virtual CYExpression *Replace(CYContext &context);
1452 virtual void Output(CYOutput &out, CYFlags flags) const;
1453
1454 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1455 };
1456
1457 struct CYRubyProc;
1458
1459 struct CYRubyBlock :
1460 CYExpression
1461 {
1462 CYExpression *call_;
1463 CYRubyProc *proc_;
1464
1465 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1466 call_(call),
1467 proc_(proc)
1468 {
1469 }
1470
1471 CYPrecedence(1)
1472 CYRightHand(false)
1473
1474 virtual CYExpression *Replace(CYContext &context);
1475 virtual void Output(CYOutput &out, CYFlags flags) const;
1476 };
1477
1478 struct CYIf :
1479 CYStatement
1480 {
1481 CYExpression *test_;
1482 CYStatement *true_;
1483 CYStatement *false_;
1484
1485 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1486 test_(test),
1487 true_(_true),
1488 false_(_false)
1489 {
1490 }
1491
1492 virtual CYStatement *Replace(CYContext &context);
1493 virtual void Output(CYOutput &out, CYFlags flags) const;
1494 };
1495
1496 struct CYDoWhile :
1497 CYStatement
1498 {
1499 CYExpression *test_;
1500 CYStatement *code_;
1501
1502 CYDoWhile(CYExpression *test, CYStatement *code) :
1503 test_(test),
1504 code_(code)
1505 {
1506 }
1507
1508 virtual CYStatement *Replace(CYContext &context);
1509 virtual void Output(CYOutput &out, CYFlags flags) const;
1510 };
1511
1512 struct CYWhile :
1513 CYStatement
1514 {
1515 CYExpression *test_;
1516 CYStatement *code_;
1517
1518 CYWhile(CYExpression *test, CYStatement *code) :
1519 test_(test),
1520 code_(code)
1521 {
1522 }
1523
1524 virtual CYStatement *Replace(CYContext &context);
1525 virtual void Output(CYOutput &out, CYFlags flags) const;
1526 };
1527
1528 // XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
1529 struct CYFunction {
1530 CYIdentifier *name_;
1531 CYFunctionParameter *parameters_;
1532 CYBlock code_;
1533
1534 CYNonLocal *nonlocal_;
1535 CYThisScope this_;
1536
1537 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1538 name_(name),
1539 parameters_(parameters),
1540 code_(statements),
1541 nonlocal_(NULL)
1542 {
1543 }
1544
1545 virtual ~CYFunction() {
1546 }
1547
1548 void Inject(CYContext &context);
1549 virtual void Replace_(CYContext &context, bool outer);
1550 virtual void Output(CYOutput &out, CYFlags flags) const;
1551 };
1552
1553 // XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
1554 struct CYFunctionExpression :
1555 CYFunction,
1556 CYExpression
1557 {
1558 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1559 CYFunction(name, parameters, statements)
1560 {
1561 }
1562
1563 CYPrecedence(0)
1564 CYRightHand(false)
1565
1566 virtual CYExpression *Replace(CYContext &context);
1567 virtual void Output(CYOutput &out, CYFlags flags) const;
1568 };
1569
1570 // XXX: this should derive from CYAnonymousFunction
1571 struct CYFatArrow :
1572 CYFunction,
1573 CYExpression
1574 {
1575 CYFatArrow(CYFunctionParameter *parameters, CYStatement *statements) :
1576 CYFunction(NULL, parameters, statements)
1577 {
1578 }
1579
1580 CYPrecedence(0)
1581 CYRightHand(false)
1582
1583 virtual CYExpression *Replace(CYContext &context);
1584 virtual void Output(CYOutput &out, CYFlags flags) const;
1585 };
1586
1587 // XXX: this should derive from CYAnonymousFunctionExpression
1588 struct CYRubyProc :
1589 CYFunctionExpression
1590 {
1591 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1592 CYFunctionExpression(NULL, parameters, statements)
1593 {
1594 }
1595
1596 virtual CYExpression *Replace(CYContext &context);
1597 virtual void Output(CYOutput &out, CYFlags flags) const;
1598 };
1599
1600 // XXX: this should derive from CYNamedFunction
1601 struct CYFunctionStatement :
1602 CYFunction,
1603 CYStatement
1604 {
1605 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1606 CYFunction(name, parameters, statements)
1607 {
1608 }
1609
1610 virtual CYStatement *Replace(CYContext &context);
1611 virtual void Output(CYOutput &out, CYFlags flags) const;
1612 };
1613
1614 struct CYExpress :
1615 CYStatement
1616 {
1617 CYExpression *expression_;
1618
1619 CYExpress(CYExpression *expression) :
1620 expression_(expression)
1621 {
1622 if (expression == NULL)
1623 throw;
1624 }
1625
1626 virtual CYStatement *Replace(CYContext &context);
1627 virtual void Output(CYOutput &out, CYFlags flags) const;
1628 };
1629
1630 struct CYContinue :
1631 CYStatement
1632 {
1633 CYIdentifier *label_;
1634
1635 CYContinue(CYIdentifier *label) :
1636 label_(label)
1637 {
1638 }
1639
1640 virtual CYStatement *Replace(CYContext &context);
1641 virtual void Output(CYOutput &out, CYFlags flags) const;
1642 };
1643
1644 struct CYBreak :
1645 CYStatement
1646 {
1647 CYIdentifier *label_;
1648
1649 CYBreak(CYIdentifier *label) :
1650 label_(label)
1651 {
1652 }
1653
1654 virtual CYStatement *Replace(CYContext &context);
1655 virtual void Output(CYOutput &out, CYFlags flags) const;
1656 };
1657
1658 struct CYReturn :
1659 CYStatement
1660 {
1661 CYExpression *value_;
1662
1663 CYReturn(CYExpression *value) :
1664 value_(value)
1665 {
1666 }
1667
1668 virtual CYStatement *Replace(CYContext &context);
1669 virtual void Output(CYOutput &out, CYFlags flags) const;
1670 };
1671
1672 struct CYEmpty :
1673 CYStatement
1674 {
1675 virtual CYStatement *Replace(CYContext &context);
1676 virtual void Output(CYOutput &out, CYFlags flags) const;
1677 };
1678
1679 struct CYFinally :
1680 CYThing
1681 {
1682 CYBlock code_;
1683
1684 CYFinally(CYStatement *statements) :
1685 code_(statements)
1686 {
1687 }
1688
1689 void Replace(CYContext &context);
1690 virtual void Output(CYOutput &out) const;
1691 };
1692
1693 namespace cy {
1694 namespace Syntax {
1695
1696 struct Catch :
1697 CYThing
1698 {
1699 CYIdentifier *name_;
1700 CYBlock code_;
1701
1702 Catch(CYIdentifier *name, CYStatement *statements) :
1703 name_(name),
1704 code_(statements)
1705 {
1706 }
1707
1708 void Replace(CYContext &context);
1709 virtual void Output(CYOutput &out) const;
1710 };
1711
1712 struct Try :
1713 CYStatement
1714 {
1715 CYBlock code_;
1716 Catch *catch_;
1717 CYFinally *finally_;
1718
1719 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1720 code_(statements),
1721 catch_(_catch),
1722 finally_(finally)
1723 {
1724 }
1725
1726 virtual CYStatement *Replace(CYContext &context);
1727 virtual void Output(CYOutput &out, CYFlags flags) const;
1728 };
1729
1730 struct Throw :
1731 CYStatement
1732 {
1733 CYExpression *value_;
1734
1735 Throw(CYExpression *value = NULL) :
1736 value_(value)
1737 {
1738 }
1739
1740 virtual CYStatement *Replace(CYContext &context);
1741 virtual void Output(CYOutput &out, CYFlags flags) const;
1742 };
1743
1744 } }
1745
1746 struct CYWith :
1747 CYStatement
1748 {
1749 CYExpression *scope_;
1750 CYStatement *code_;
1751
1752 CYWith(CYExpression *scope, CYStatement *code) :
1753 scope_(scope),
1754 code_(code)
1755 {
1756 }
1757
1758 virtual CYStatement *Replace(CYContext &context);
1759 virtual void Output(CYOutput &out, CYFlags flags) const;
1760 };
1761
1762 struct CYSwitch :
1763 CYStatement
1764 {
1765 CYExpression *value_;
1766 CYClause *clauses_;
1767
1768 CYSwitch(CYExpression *value, CYClause *clauses) :
1769 value_(value),
1770 clauses_(clauses)
1771 {
1772 }
1773
1774 virtual CYStatement *Replace(CYContext &context);
1775 virtual void Output(CYOutput &out, CYFlags flags) const;
1776 };
1777
1778 struct CYDebugger :
1779 CYStatement
1780 {
1781 CYDebugger()
1782 {
1783 }
1784
1785 virtual CYStatement *Replace(CYContext &context);
1786 virtual void Output(CYOutput &out, CYFlags flags) const;
1787 };
1788
1789 struct CYCondition :
1790 CYExpression
1791 {
1792 CYExpression *test_;
1793 CYExpression *true_;
1794 CYExpression *false_;
1795
1796 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1797 test_(test),
1798 true_(_true),
1799 false_(_false)
1800 {
1801 }
1802
1803 CYPrecedence(15)
1804
1805 virtual CYExpression *Replace(CYContext &context);
1806 virtual void Output(CYOutput &out, CYFlags flags) const;
1807 };
1808
1809 struct CYAddressOf :
1810 CYPrefix
1811 {
1812 CYAddressOf(CYExpression *rhs) :
1813 CYPrefix(rhs)
1814 {
1815 }
1816
1817 virtual const char *Operator() const {
1818 return "&";
1819 }
1820
1821 CYAlphabetic(false)
1822
1823 virtual CYExpression *Replace(CYContext &context);
1824 };
1825
1826 struct CYIndirect :
1827 CYPrefix
1828 {
1829 CYIndirect(CYExpression *rhs) :
1830 CYPrefix(rhs)
1831 {
1832 }
1833
1834 virtual const char *Operator() const {
1835 return "*";
1836 }
1837
1838 CYAlphabetic(false)
1839
1840 virtual CYExpression *Replace(CYContext &context);
1841 };
1842
1843 #define CYReplace \
1844 virtual CYExpression *Replace(CYContext &context);
1845
1846 #define CYPostfix_(op, name, args...) \
1847 struct CY ## name : \
1848 CYPostfix \
1849 { args \
1850 CY ## name(CYExpression *lhs) : \
1851 CYPostfix(lhs) \
1852 { \
1853 } \
1854 \
1855 virtual const char *Operator() const { \
1856 return op; \
1857 } \
1858 };
1859
1860 #define CYPrefix_(alphabetic, op, name, args...) \
1861 struct CY ## name : \
1862 CYPrefix \
1863 { args \
1864 CY ## name(CYExpression *rhs) : \
1865 CYPrefix(rhs) \
1866 { \
1867 } \
1868 \
1869 CYAlphabetic(alphabetic) \
1870 \
1871 virtual const char *Operator() const { \
1872 return op; \
1873 } \
1874 };
1875
1876 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1877 struct CY ## name : \
1878 CYInfix \
1879 { args \
1880 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1881 CYInfix(lhs, rhs) \
1882 { \
1883 } \
1884 \
1885 CYAlphabetic(alphabetic) \
1886 CYPrecedence(precedence) \
1887 \
1888 virtual const char *Operator() const { \
1889 return op; \
1890 } \
1891 };
1892
1893 #define CYAssignment_(op, name, args...) \
1894 struct CY ## name ## Assign : \
1895 CYAssignment \
1896 { args \
1897 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1898 CYAssignment(lhs, rhs) \
1899 { \
1900 } \
1901 \
1902 virtual const char *Operator() const { \
1903 return op; \
1904 } \
1905 };
1906
1907 CYPostfix_("++", PostIncrement)
1908 CYPostfix_("--", PostDecrement)
1909
1910 CYPrefix_(true, "delete", Delete)
1911 CYPrefix_(true, "void", Void)
1912 CYPrefix_(true, "typeof", TypeOf)
1913 CYPrefix_(false, "++", PreIncrement)
1914 CYPrefix_(false, "--", PreDecrement)
1915 CYPrefix_(false, "+", Affirm)
1916 CYPrefix_(false, "-", Negate)
1917 CYPrefix_(false, "~", BitwiseNot)
1918 CYPrefix_(false, "!", LogicalNot)
1919
1920 CYInfix_(false, 5, "*", Multiply)
1921 CYInfix_(false, 5, "/", Divide)
1922 CYInfix_(false, 5, "%", Modulus)
1923 CYInfix_(false, 6, "+", Add, CYReplace)
1924 CYInfix_(false, 6, "-", Subtract)
1925 CYInfix_(false, 7, "<<", ShiftLeft)
1926 CYInfix_(false, 7, ">>", ShiftRightSigned)
1927 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1928 CYInfix_(false, 8, "<", Less)
1929 CYInfix_(false, 8, ">", Greater)
1930 CYInfix_(false, 8, "<=", LessOrEqual)
1931 CYInfix_(false, 8, ">=", GreaterOrEqual)
1932 CYInfix_(true, 8, "instanceof", InstanceOf)
1933 CYInfix_(true, 8, "in", In)
1934 CYInfix_(false, 9, "==", Equal)
1935 CYInfix_(false, 9, "!=", NotEqual)
1936 CYInfix_(false, 9, "===", Identical)
1937 CYInfix_(false, 9, "!==", NotIdentical)
1938 CYInfix_(false, 10, "&", BitwiseAnd)
1939 CYInfix_(false, 11, "^", BitwiseXOr)
1940 CYInfix_(false, 12, "|", BitwiseOr)
1941 CYInfix_(false, 13, "&&", LogicalAnd)
1942 CYInfix_(false, 14, "||", LogicalOr)
1943
1944 CYAssignment_("=", )
1945 CYAssignment_("*=", Multiply)
1946 CYAssignment_("/=", Divide)
1947 CYAssignment_("%=", Modulus)
1948 CYAssignment_("+=", Add)
1949 CYAssignment_("-=", Subtract)
1950 CYAssignment_("<<=", ShiftLeft)
1951 CYAssignment_(">>=", ShiftRightSigned)
1952 CYAssignment_(">>>=", ShiftRightUnsigned)
1953 CYAssignment_("&=", BitwiseAnd)
1954 CYAssignment_("^=", BitwiseXOr)
1955 CYAssignment_("|=", BitwiseOr)
1956
1957 #endif/*CYCRIPT_PARSER_HPP*/