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