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