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