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