]> git.saurik.com Git - cycript.git/blob - Parser.hpp
Add optional parameter support.
[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 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
620 virtual void Output(CYOutput &out) const;
621 };
622
623 struct CYOptionalFunctionParameter :
624 CYFunctionParameter
625 {
626 CYExpression *initializer_;
627
628 CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
629 CYFunctionParameter(name, next),
630 initializer_(initializer)
631 {
632 }
633
634 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
635 virtual void Output(CYOutput &out) const;
636 };
637
638 struct CYComprehension :
639 CYNext<CYComprehension>,
640 CYThing
641 {
642 virtual const char *Name() const = 0;
643
644 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
645 CYFunctionParameter *Parameters(CYContext &context) const;
646 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
647 virtual void Output(CYOutput &out) const = 0;
648 };
649
650 struct CYForInComprehension :
651 CYComprehension
652 {
653 CYIdentifier *name_;
654 CYExpression *set_;
655
656 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
657 name_(name),
658 set_(set)
659 {
660 }
661
662 virtual const char *Name() const {
663 return name_->Word();
664 }
665
666 virtual CYFunctionParameter *Parameter(CYContext &context) const;
667 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
668 virtual void Output(CYOutput &out) const;
669 };
670
671 struct CYForEachInComprehension :
672 CYComprehension
673 {
674 CYIdentifier *name_;
675 CYExpression *set_;
676
677 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
678 name_(name),
679 set_(set)
680 {
681 }
682
683 virtual const char *Name() const {
684 return name_->Word();
685 }
686
687 virtual CYFunctionParameter *Parameter(CYContext &context) const;
688 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
689 virtual void Output(CYOutput &out) const;
690 };
691
692 struct CYIfComprehension :
693 CYComprehension
694 {
695 CYExpression *test_;
696
697 CYIfComprehension(CYExpression *test) :
698 test_(test)
699 {
700 }
701
702 virtual const char *Name() const {
703 return NULL;
704 }
705
706 virtual CYFunctionParameter *Parameter(CYContext &context) const;
707 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
708 virtual void Output(CYOutput &out) const;
709 };
710
711 struct CYArrayComprehension :
712 CYExpression
713 {
714 CYExpression *expression_;
715 CYComprehension *comprehensions_;
716
717 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
718 expression_(expression),
719 comprehensions_(comprehensions)
720 {
721 }
722
723 CYPrecedence(0)
724
725 virtual CYExpression *Replace(CYContext &context);
726 virtual void Output(CYOutput &out, CYFlags flags) const;
727 };
728
729 struct CYLiteral :
730 CYExpression
731 {
732 CYPrecedence(0)
733 CYRightHand(false)
734 };
735
736 struct CYTrivial :
737 CYLiteral
738 {
739 virtual CYExpression *Replace(CYContext &context);
740 };
741
742 struct CYMagic :
743 CYExpression
744 {
745 CYPrecedence(0)
746 CYRightHand(false)
747 };
748
749 struct CYRange {
750 uint64_t lo_;
751 uint64_t hi_;
752
753 CYRange(uint64_t lo, uint64_t hi) :
754 lo_(lo), hi_(hi)
755 {
756 }
757
758 bool operator [](uint8_t value) const {
759 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
760 }
761
762 void operator()(uint8_t value) {
763 if (value >> 7)
764 return;
765 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
766 }
767 };
768
769 extern CYRange DigitRange_;
770 extern CYRange WordStartRange_;
771 extern CYRange WordEndRange_;
772
773 struct CYString :
774 CYTrivial,
775 CYPropertyName
776 {
777 const char *value_;
778 size_t size_;
779
780 CYString() :
781 value_(NULL),
782 size_(0)
783 {
784 }
785
786 CYString(const char *value) :
787 value_(value),
788 size_(strlen(value))
789 {
790 }
791
792 CYString(const char *value, size_t size) :
793 value_(value),
794 size_(size)
795 {
796 }
797
798 CYString(const CYWord *word) :
799 value_(word->Word()),
800 size_(strlen(value_))
801 {
802 }
803
804 const char *Value() const {
805 return value_;
806 }
807
808 virtual const char *Word() const;
809
810 virtual CYNumber *Number(CYContext &context);
811 virtual CYString *String(CYContext &context);
812
813 CYString *Concat(CYContext &out, CYString *rhs) const;
814 virtual void Output(CYOutput &out, CYFlags flags) const;
815 virtual void PropertyName(CYOutput &out) const;
816 };
817
818 struct CYNumber :
819 CYTrivial,
820 CYPropertyName
821 {
822 double value_;
823
824 CYNumber(double value) :
825 value_(value)
826 {
827 }
828
829 double Value() const {
830 return value_;
831 }
832
833 virtual CYNumber *Number(CYContext &context);
834 virtual CYString *String(CYContext &context);
835
836 virtual void Output(CYOutput &out, CYFlags flags) const;
837 virtual void PropertyName(CYOutput &out) const;
838 };
839
840 struct CYRegEx :
841 CYTrivial
842 {
843 const char *value_;
844
845 CYRegEx(const char *value) :
846 value_(value)
847 {
848 }
849
850 const char *Value() const {
851 return value_;
852 }
853
854 virtual void Output(CYOutput &out, CYFlags flags) const;
855 };
856
857 struct CYNull :
858 CYWord,
859 CYTrivial
860 {
861 CYNull() :
862 CYWord("null")
863 {
864 }
865
866 virtual CYNumber *Number(CYContext &context);
867 virtual CYString *String(CYContext &context);
868
869 virtual void Output(CYOutput &out, CYFlags flags) const;
870 };
871
872 struct CYThis :
873 CYWord,
874 CYMagic
875 {
876 CYThis() :
877 CYWord("this")
878 {
879 }
880
881 virtual CYExpression *Replace(CYContext &context);
882 virtual void Output(CYOutput &out, CYFlags flags) const;
883 };
884
885 struct CYBoolean :
886 CYTrivial
887 {
888 virtual bool Value() const = 0;
889 virtual void Output(CYOutput &out, CYFlags flags) const;
890 };
891
892 struct CYFalse :
893 CYWord,
894 CYBoolean
895 {
896 CYFalse() :
897 CYWord("false")
898 {
899 }
900
901 virtual bool Value() const {
902 return false;
903 }
904
905 virtual CYNumber *Number(CYContext &context);
906 virtual CYString *String(CYContext &context);
907 };
908
909 struct CYTrue :
910 CYWord,
911 CYBoolean
912 {
913 CYTrue() :
914 CYWord("true")
915 {
916 }
917
918 virtual bool Value() const {
919 return true;
920 }
921
922 virtual CYNumber *Number(CYContext &context);
923 virtual CYString *String(CYContext &context);
924 };
925
926 struct CYVariable :
927 CYExpression
928 {
929 CYIdentifier *name_;
930
931 CYVariable(CYIdentifier *name) :
932 name_(name)
933 {
934 }
935
936 CYPrecedence(0)
937 CYRightHand(false)
938
939 virtual CYExpression *Replace(CYContext &context);
940 virtual void Output(CYOutput &out, CYFlags flags) const;
941 };
942
943 struct CYPrefix :
944 CYExpression
945 {
946 CYExpression *rhs_;
947
948 CYPrefix(CYExpression *rhs) :
949 rhs_(rhs)
950 {
951 }
952
953 virtual bool Alphabetic() const = 0;
954 virtual const char *Operator() const = 0;
955
956 CYPrecedence(4)
957
958 virtual CYExpression *Replace(CYContext &context);
959 virtual void Output(CYOutput &out, CYFlags flags) const;
960 };
961
962 struct CYInfix :
963 CYExpression
964 {
965 CYExpression *lhs_;
966 CYExpression *rhs_;
967
968 CYInfix(CYExpression *lhs, CYExpression *rhs) :
969 lhs_(lhs),
970 rhs_(rhs)
971 {
972 }
973
974 void SetLeft(CYExpression *lhs) {
975 lhs_ = lhs;
976 }
977
978 virtual bool Alphabetic() const = 0;
979 virtual const char *Operator() const = 0;
980
981 virtual CYExpression *Replace(CYContext &context);
982 virtual void Output(CYOutput &out, CYFlags flags) const;
983 };
984
985 struct CYPostfix :
986 CYExpression
987 {
988 CYExpression *lhs_;
989
990 CYPostfix(CYExpression *lhs) :
991 lhs_(lhs)
992 {
993 }
994
995 virtual const char *Operator() const = 0;
996
997 CYPrecedence(3)
998
999 virtual CYExpression *Replace(CYContext &context);
1000 virtual void Output(CYOutput &out, CYFlags flags) const;
1001 };
1002
1003 struct CYAssignment :
1004 CYExpression
1005 {
1006 CYExpression *lhs_;
1007 CYExpression *rhs_;
1008
1009 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
1010 lhs_(lhs),
1011 rhs_(rhs)
1012 {
1013 }
1014
1015 void SetLeft(CYExpression *lhs) {
1016 lhs_ = lhs;
1017 }
1018
1019 virtual const char *Operator() const = 0;
1020
1021 CYPrecedence(16)
1022
1023 virtual CYExpression *Replace(CYContext &context);
1024 virtual void Output(CYOutput &out, CYFlags flags) const;
1025 };
1026
1027 struct CYArgument :
1028 CYNext<CYArgument>,
1029 CYThing
1030 {
1031 CYWord *name_;
1032 CYExpression *value_;
1033
1034 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1035 CYNext<CYArgument>(next),
1036 name_(NULL),
1037 value_(value)
1038 {
1039 }
1040
1041 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1042 CYNext<CYArgument>(next),
1043 name_(name),
1044 value_(value)
1045 {
1046 }
1047
1048 void Replace(CYContext &context);
1049 void Output(CYOutput &out) const;
1050 };
1051
1052 struct CYBlank :
1053 public CYWord
1054 {
1055 CYBlank() :
1056 CYWord("")
1057 {
1058 }
1059 };
1060
1061 struct CYClause :
1062 CYThing,
1063 CYNext<CYClause>
1064 {
1065 CYExpression *case_;
1066 CYStatement *statements_;
1067
1068 CYClause(CYExpression *_case, CYStatement *statements) :
1069 case_(_case),
1070 statements_(statements)
1071 {
1072 }
1073
1074 void Replace(CYContext &context);
1075 virtual void Output(CYOutput &out) const;
1076 };
1077
1078 struct CYElement :
1079 CYNext<CYElement>,
1080 CYThing
1081 {
1082 CYExpression *value_;
1083
1084 CYElement(CYExpression *value, CYElement *next) :
1085 CYNext<CYElement>(next),
1086 value_(value)
1087 {
1088 }
1089
1090 void Replace(CYContext &context);
1091 void Output(CYOutput &out) const;
1092 };
1093
1094 struct CYArray :
1095 CYLiteral
1096 {
1097 CYElement *elements_;
1098
1099 CYArray(CYElement *elements = NULL) :
1100 elements_(elements)
1101 {
1102 }
1103
1104 virtual CYExpression *Replace(CYContext &context);
1105 virtual void Output(CYOutput &out, CYFlags flags) const;
1106 };
1107
1108 struct CYProperty :
1109 CYNext<CYProperty>,
1110 CYThing
1111 {
1112 CYPropertyName *name_;
1113 CYExpression *value_;
1114
1115 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1116 CYNext<CYProperty>(next),
1117 name_(name),
1118 value_(value)
1119 {
1120 }
1121
1122 void Replace(CYContext &context);
1123 virtual void Output(CYOutput &out) const;
1124 };
1125
1126 struct CYDeclaration :
1127 CYForInInitialiser
1128 {
1129 CYIdentifier *identifier_;
1130 CYExpression *initialiser_;
1131
1132 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
1133 identifier_(identifier),
1134 initialiser_(initialiser)
1135 {
1136 }
1137
1138 virtual void ForIn(CYOutput &out, CYFlags flags) const;
1139
1140 virtual const char *ForEachIn() const;
1141 virtual CYExpression *ForEachIn(CYContext &out);
1142
1143 virtual CYExpression *Replace(CYContext &context);
1144 virtual CYAssignment *Assignment(CYContext &context);
1145
1146 virtual void Output(CYOutput &out, CYFlags flags) const;
1147 };
1148
1149 struct CYDeclarations :
1150 CYNext<CYDeclarations>,
1151 CYThing,
1152 CYForInitialiser
1153 {
1154 CYDeclaration *declaration_;
1155
1156 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
1157 CYNext<CYDeclarations>(next),
1158 declaration_(declaration)
1159 {
1160 }
1161
1162 virtual void For(CYOutput &out) const;
1163
1164 virtual CYCompound *Replace(CYContext &context);
1165 CYProperty *Property(CYContext &context);
1166
1167 virtual void Output(CYOutput &out) const;
1168 virtual void Output(CYOutput &out, CYFlags flags) const;
1169 };
1170
1171 struct CYVar :
1172 CYStatement
1173 {
1174 CYDeclarations *declarations_;
1175
1176 CYVar(CYDeclarations *declarations) :
1177 declarations_(declarations)
1178 {
1179 }
1180
1181 virtual CYStatement *Replace(CYContext &context);
1182 virtual void Output(CYOutput &out, CYFlags flags) const;
1183 };
1184
1185 struct CYLet :
1186 CYStatement
1187 {
1188 CYDeclarations *declarations_;
1189 CYBlock code_;
1190
1191 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1192 declarations_(declarations),
1193 code_(statements)
1194 {
1195 }
1196
1197 virtual CYStatement *Replace(CYContext &context);
1198 virtual void Output(CYOutput &out, CYFlags flags) const;
1199 };
1200
1201 struct CYFor :
1202 CYStatement
1203 {
1204 CYForInitialiser *initialiser_;
1205 CYExpression *test_;
1206 CYExpression *increment_;
1207 CYStatement *code_;
1208
1209 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1210 initialiser_(initialiser),
1211 test_(test),
1212 increment_(increment),
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 CYForIn :
1222 CYStatement
1223 {
1224 CYForInInitialiser *initialiser_;
1225 CYExpression *set_;
1226 CYStatement *code_;
1227
1228 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1229 initialiser_(initialiser),
1230 set_(set),
1231 code_(code)
1232 {
1233 }
1234
1235 virtual CYStatement *Replace(CYContext &context);
1236 virtual void Output(CYOutput &out, CYFlags flags) const;
1237 };
1238
1239 struct CYForEachIn :
1240 CYStatement
1241 {
1242 CYForInInitialiser *initialiser_;
1243 CYExpression *set_;
1244 CYStatement *code_;
1245
1246 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1247 initialiser_(initialiser),
1248 set_(set),
1249 code_(code)
1250 {
1251 }
1252
1253 virtual CYStatement *Replace(CYContext &context);
1254 virtual void Output(CYOutput &out, CYFlags flags) const;
1255 };
1256
1257 struct CYObject :
1258 CYLiteral
1259 {
1260 CYProperty *properties_;
1261
1262 CYObject(CYProperty *properties) :
1263 properties_(properties)
1264 {
1265 }
1266
1267 virtual CYExpression *Replace(CYContext &context);
1268 void Output(CYOutput &out, CYFlags flags) const;
1269 };
1270
1271 struct CYMember :
1272 CYExpression
1273 {
1274 CYExpression *object_;
1275 CYExpression *property_;
1276
1277 CYMember(CYExpression *object, CYExpression *property) :
1278 object_(object),
1279 property_(property)
1280 {
1281 }
1282
1283 void SetLeft(CYExpression *object) {
1284 object_ = object;
1285 }
1286
1287 void Replace_(CYContext &context);
1288 };
1289
1290 struct CYDirectMember :
1291 CYMember
1292 {
1293 CYDirectMember(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 CYIndirectMember :
1306 CYMember
1307 {
1308 CYIndirectMember(CYExpression *object, CYExpression *property) :
1309 CYMember(object, property)
1310 {
1311 }
1312
1313 CYPrecedence(1)
1314 CYRightHand(false)
1315
1316 virtual CYExpression *Replace(CYContext &context);
1317 virtual void Output(CYOutput &out, CYFlags flags) const;
1318 };
1319
1320 struct CYNew :
1321 CYExpression
1322 {
1323 CYExpression *constructor_;
1324 CYArgument *arguments_;
1325
1326 CYNew(CYExpression *constructor, CYArgument *arguments) :
1327 constructor_(constructor),
1328 arguments_(arguments)
1329 {
1330 }
1331
1332 virtual unsigned Precedence() const {
1333 return arguments_ == NULL ? 2 : 1;
1334 }
1335
1336 CYRightHand(false)
1337
1338 virtual CYExpression *Replace(CYContext &context);
1339 virtual void Output(CYOutput &out, CYFlags flags) const;
1340 };
1341
1342 struct CYCall :
1343 CYExpression
1344 {
1345 CYExpression *function_;
1346 CYArgument *arguments_;
1347
1348 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1349 function_(function),
1350 arguments_(arguments)
1351 {
1352 }
1353
1354 CYPrecedence(1)
1355 CYRightHand(false)
1356
1357 virtual CYExpression *Replace(CYContext &context);
1358 virtual void Output(CYOutput &out, CYFlags flags) const;
1359 };
1360
1361 struct CYIf :
1362 CYStatement
1363 {
1364 CYExpression *test_;
1365 CYStatement *true_;
1366 CYStatement *false_;
1367
1368 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1369 test_(test),
1370 true_(_true),
1371 false_(_false)
1372 {
1373 }
1374
1375 virtual CYStatement *Replace(CYContext &context);
1376 virtual void Output(CYOutput &out, CYFlags flags) const;
1377 };
1378
1379 struct CYDoWhile :
1380 CYStatement
1381 {
1382 CYExpression *test_;
1383 CYStatement *code_;
1384
1385 CYDoWhile(CYExpression *test, CYStatement *code) :
1386 test_(test),
1387 code_(code)
1388 {
1389 }
1390
1391 virtual CYStatement *Replace(CYContext &context);
1392 virtual void Output(CYOutput &out, CYFlags flags) const;
1393 };
1394
1395 struct CYWhile :
1396 CYStatement
1397 {
1398 CYExpression *test_;
1399 CYStatement *code_;
1400
1401 CYWhile(CYExpression *test, CYStatement *code) :
1402 test_(test),
1403 code_(code)
1404 {
1405 }
1406
1407 virtual CYStatement *Replace(CYContext &context);
1408 virtual void Output(CYOutput &out, CYFlags flags) const;
1409 };
1410
1411 struct CYFunction {
1412 CYIdentifier *name_;
1413 CYFunctionParameter *parameters_;
1414 CYBlock code_;
1415
1416 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1417 name_(name),
1418 parameters_(parameters),
1419 code_(statements)
1420 {
1421 }
1422
1423 virtual ~CYFunction() {
1424 }
1425
1426 void Inject(CYContext &context);
1427 virtual void Replace_(CYContext &context, bool outer);
1428 virtual void Output(CYOutput &out, CYFlags flags) const;
1429 };
1430
1431 struct CYFunctionExpression :
1432 CYFunction,
1433 CYExpression
1434 {
1435 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1436 CYFunction(name, parameters, statements)
1437 {
1438 }
1439
1440 CYPrecedence(0)
1441 CYRightHand(false)
1442
1443 virtual CYExpression *Replace(CYContext &context);
1444 virtual void Output(CYOutput &out, CYFlags flags) const;
1445 };
1446
1447 struct CYFunctionStatement :
1448 CYFunction,
1449 CYStatement
1450 {
1451 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1452 CYFunction(name, parameters, statements)
1453 {
1454 }
1455
1456 virtual CYStatement *Replace(CYContext &context);
1457 virtual void Output(CYOutput &out, CYFlags flags) const;
1458 };
1459
1460 struct CYExpress :
1461 CYStatement
1462 {
1463 CYExpression *expression_;
1464
1465 CYExpress(CYExpression *expression) :
1466 expression_(expression)
1467 {
1468 if (expression == NULL)
1469 throw;
1470 }
1471
1472 virtual CYStatement *Collapse(CYContext &context);
1473 virtual CYStatement *Replace(CYContext &context);
1474 virtual void Output(CYOutput &out, CYFlags flags) const;
1475 };
1476
1477 struct CYContinue :
1478 CYStatement
1479 {
1480 CYIdentifier *label_;
1481
1482 CYContinue(CYIdentifier *label) :
1483 label_(label)
1484 {
1485 }
1486
1487 virtual CYStatement *Replace(CYContext &context);
1488 virtual void Output(CYOutput &out, CYFlags flags) const;
1489 };
1490
1491 struct CYBreak :
1492 CYStatement
1493 {
1494 CYIdentifier *label_;
1495
1496 CYBreak(CYIdentifier *label) :
1497 label_(label)
1498 {
1499 }
1500
1501 virtual CYStatement *Replace(CYContext &context);
1502 virtual void Output(CYOutput &out, CYFlags flags) const;
1503 };
1504
1505 struct CYReturn :
1506 CYStatement
1507 {
1508 CYExpression *value_;
1509
1510 CYReturn(CYExpression *value) :
1511 value_(value)
1512 {
1513 }
1514
1515 virtual CYStatement *Replace(CYContext &context);
1516 virtual void Output(CYOutput &out, CYFlags flags) const;
1517 };
1518
1519 struct CYEmpty :
1520 CYStatement
1521 {
1522 virtual CYStatement *Collapse(CYContext &context);
1523 virtual CYStatement *Replace(CYContext &context);
1524 virtual void Output(CYOutput &out, CYFlags flags) const;
1525 };
1526
1527 struct CYFinally :
1528 CYThing
1529 {
1530 CYBlock code_;
1531
1532 CYFinally(CYStatement *statements) :
1533 code_(statements)
1534 {
1535 }
1536
1537 void Replace(CYContext &context);
1538 virtual void Output(CYOutput &out) const;
1539 };
1540
1541 namespace cy {
1542 namespace Syntax {
1543
1544 struct Catch :
1545 CYThing
1546 {
1547 CYIdentifier *name_;
1548 CYBlock code_;
1549
1550 Catch(CYIdentifier *name, CYStatement *statements) :
1551 name_(name),
1552 code_(statements)
1553 {
1554 }
1555
1556 void Replace(CYContext &context);
1557 virtual void Output(CYOutput &out) const;
1558 };
1559
1560 struct Try :
1561 CYStatement
1562 {
1563 CYBlock code_;
1564 Catch *catch_;
1565 CYFinally *finally_;
1566
1567 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
1568 code_(statements),
1569 catch_(_catch),
1570 finally_(finally)
1571 {
1572 }
1573
1574 virtual CYStatement *Replace(CYContext &context);
1575 virtual void Output(CYOutput &out, CYFlags flags) const;
1576 };
1577
1578 struct Throw :
1579 CYStatement
1580 {
1581 CYExpression *value_;
1582
1583 Throw(CYExpression *value) :
1584 value_(value)
1585 {
1586 }
1587
1588 virtual CYStatement *Replace(CYContext &context);
1589 virtual void Output(CYOutput &out, CYFlags flags) const;
1590 };
1591
1592 } }
1593
1594 struct CYWith :
1595 CYStatement
1596 {
1597 CYExpression *scope_;
1598 CYStatement *code_;
1599
1600 CYWith(CYExpression *scope, CYStatement *code) :
1601 scope_(scope),
1602 code_(code)
1603 {
1604 }
1605
1606 virtual CYStatement *Replace(CYContext &context);
1607 virtual void Output(CYOutput &out, CYFlags flags) const;
1608 };
1609
1610 struct CYSwitch :
1611 CYStatement
1612 {
1613 CYExpression *value_;
1614 CYClause *clauses_;
1615
1616 CYSwitch(CYExpression *value, CYClause *clauses) :
1617 value_(value),
1618 clauses_(clauses)
1619 {
1620 }
1621
1622 virtual CYStatement *Replace(CYContext &context);
1623 virtual void Output(CYOutput &out, CYFlags flags) const;
1624 };
1625
1626 struct CYCondition :
1627 CYExpression
1628 {
1629 CYExpression *test_;
1630 CYExpression *true_;
1631 CYExpression *false_;
1632
1633 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
1634 test_(test),
1635 true_(_true),
1636 false_(_false)
1637 {
1638 }
1639
1640 CYPrecedence(15)
1641
1642 virtual CYExpression *Replace(CYContext &context);
1643 virtual void Output(CYOutput &out, CYFlags flags) const;
1644 };
1645
1646 struct CYAddressOf :
1647 CYPrefix
1648 {
1649 CYAddressOf(CYExpression *rhs) :
1650 CYPrefix(rhs)
1651 {
1652 }
1653
1654 virtual const char *Operator() const {
1655 return "&";
1656 }
1657
1658 CYAlphabetic(false)
1659
1660 virtual CYExpression *Replace(CYContext &context);
1661 };
1662
1663 struct CYIndirect :
1664 CYPrefix
1665 {
1666 CYIndirect(CYExpression *rhs) :
1667 CYPrefix(rhs)
1668 {
1669 }
1670
1671 virtual const char *Operator() const {
1672 return "*";
1673 }
1674
1675 CYAlphabetic(false)
1676
1677 virtual CYExpression *Replace(CYContext &context);
1678 };
1679
1680 #define CYReplace \
1681 virtual CYExpression *Replace(CYContext &context);
1682
1683 #define CYPostfix_(op, name, args...) \
1684 struct CY ## name : \
1685 CYPostfix \
1686 { args \
1687 CY ## name(CYExpression *lhs) : \
1688 CYPostfix(lhs) \
1689 { \
1690 } \
1691 \
1692 virtual const char *Operator() const { \
1693 return op; \
1694 } \
1695 };
1696
1697 #define CYPrefix_(alphabetic, op, name, args...) \
1698 struct CY ## name : \
1699 CYPrefix \
1700 { args \
1701 CY ## name(CYExpression *rhs) : \
1702 CYPrefix(rhs) \
1703 { \
1704 } \
1705 \
1706 CYAlphabetic(alphabetic) \
1707 \
1708 virtual const char *Operator() const { \
1709 return op; \
1710 } \
1711 };
1712
1713 #define CYInfix_(alphabetic, precedence, op, name, args...) \
1714 struct CY ## name : \
1715 CYInfix \
1716 { args \
1717 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1718 CYInfix(lhs, rhs) \
1719 { \
1720 } \
1721 \
1722 CYAlphabetic(alphabetic) \
1723 CYPrecedence(precedence) \
1724 \
1725 virtual const char *Operator() const { \
1726 return op; \
1727 } \
1728 };
1729
1730 #define CYAssignment_(op, name, args...) \
1731 struct CY ## name ## Assign : \
1732 CYAssignment \
1733 { args \
1734 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1735 CYAssignment(lhs, rhs) \
1736 { \
1737 } \
1738 \
1739 virtual const char *Operator() const { \
1740 return op; \
1741 } \
1742 };
1743
1744 CYPostfix_("++", PostIncrement)
1745 CYPostfix_("--", PostDecrement)
1746
1747 CYPrefix_(true, "delete", Delete)
1748 CYPrefix_(true, "void", Void)
1749 CYPrefix_(true, "typeof", TypeOf)
1750 CYPrefix_(false, "++", PreIncrement)
1751 CYPrefix_(false, "--", PreDecrement)
1752 CYPrefix_(false, "+", Affirm)
1753 CYPrefix_(false, "-", Negate)
1754 CYPrefix_(false, "~", BitwiseNot)
1755 CYPrefix_(false, "!", LogicalNot)
1756
1757 CYInfix_(false, 5, "*", Multiply)
1758 CYInfix_(false, 5, "/", Divide)
1759 CYInfix_(false, 5, "%", Modulus)
1760 CYInfix_(false, 6, "+", Add, CYReplace)
1761 CYInfix_(false, 6, "-", Subtract)
1762 CYInfix_(false, 7, "<<", ShiftLeft)
1763 CYInfix_(false, 7, ">>", ShiftRightSigned)
1764 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1765 CYInfix_(false, 8, "<", Less)
1766 CYInfix_(false, 8, ">", Greater)
1767 CYInfix_(false, 8, "<=", LessOrEqual)
1768 CYInfix_(false, 8, ">=", GreaterOrEqual)
1769 CYInfix_(true, 8, "instanceof", InstanceOf)
1770 CYInfix_(true, 8, "in", In)
1771 CYInfix_(false, 9, "==", Equal)
1772 CYInfix_(false, 9, "!=", NotEqual)
1773 CYInfix_(false, 9, "===", Identical)
1774 CYInfix_(false, 9, "!==", NotIdentical)
1775 CYInfix_(false, 10, "&", BitwiseAnd)
1776 CYInfix_(false, 11, "^", BitwiseXOr)
1777 CYInfix_(false, 12, "|", BitwiseOr)
1778 CYInfix_(false, 13, "&&", LogicalAnd)
1779 CYInfix_(false, 14, "||", LogicalOr)
1780
1781 CYAssignment_("=", )
1782 CYAssignment_("*=", Multiply)
1783 CYAssignment_("/=", Divide)
1784 CYAssignment_("%=", Modulus)
1785 CYAssignment_("+=", Add)
1786 CYAssignment_("-=", Subtract)
1787 CYAssignment_("<<=", ShiftLeft)
1788 CYAssignment_(">>=", ShiftRightSigned)
1789 CYAssignment_(">>>=", ShiftRightUnsigned)
1790 CYAssignment_("&=", BitwiseAnd)
1791 CYAssignment_("^=", BitwiseXOr)
1792 CYAssignment_("|=", BitwiseOr)
1793
1794 #endif/*CYPARSER_HPP*/