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