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