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