]> git.saurik.com Git - cycript.git/blob - Syntax.hpp
Finally provide totally legit support for structs.
[cycript.git] / Syntax.hpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2015 Jay Freeman (saurik)
3 */
4
5 /* GNU Affero General Public License, Version 3 {{{ */
6 /*
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20 /* }}} */
21
22 #ifndef CYCRIPT_SYNTAX_HPP
23 #define CYCRIPT_SYNTAX_HPP
24
25 #include <cstdio>
26 #include <cstdlib>
27
28 #include <streambuf>
29 #include <string>
30 #include <vector>
31
32 #include "List.hpp"
33 #include "Location.hpp"
34 #include "Options.hpp"
35 #include "Pooling.hpp"
36
37 struct CYContext;
38
39 struct CYThing {
40 virtual void Output(struct CYOutput &out) const = 0;
41 };
42
43 struct CYOutput {
44 std::streambuf &out_;
45 CYPosition position_;
46
47 CYOptions &options_;
48 bool pretty_;
49 unsigned indent_;
50 unsigned recent_;
51 bool right_;
52
53 enum {
54 NoMode,
55 NoLetter,
56 NoPlus,
57 NoHyphen,
58 Terminated
59 } mode_;
60
61 CYOutput(std::streambuf &out, CYOptions &options) :
62 out_(out),
63 options_(options),
64 pretty_(false),
65 indent_(0),
66 recent_(0),
67 right_(false),
68 mode_(NoMode)
69 {
70 }
71
72 void Check(char value);
73 void Terminate();
74
75 _finline void operator ()(char value) {
76 _assert(out_.sputc(value) != EOF);
77 recent_ = indent_;
78 if (value == '\n')
79 position_.Lines(1);
80 else
81 position_.Columns(1);
82 }
83
84 _finline void operator ()(const char *data, std::streamsize size) {
85 _assert(out_.sputn(data, size) == size);
86 recent_ = indent_;
87 position_.Columns(size);
88 }
89
90 _finline void operator ()(const char *data) {
91 return operator ()(data, strlen(data));
92 }
93
94 CYOutput &operator <<(char rhs);
95 CYOutput &operator <<(const char *rhs);
96
97 _finline CYOutput &operator <<(const CYThing *rhs) {
98 if (rhs != NULL)
99 rhs->Output(*this);
100 return *this;
101 }
102
103 _finline CYOutput &operator <<(const CYThing &rhs) {
104 rhs.Output(*this);
105 return *this;
106 }
107 };
108
109 struct CYExpression;
110 struct CYAssignment;
111
112 struct CYPropertyName {
113 virtual bool Computed() const {
114 return false;
115 }
116
117 virtual bool Constructor() const {
118 return false;
119 }
120
121 virtual CYExpression *PropertyName(CYContext &context) = 0;
122 virtual void PropertyName(CYOutput &out) const = 0;
123 };
124
125 enum CYNeeded {
126 CYNever = -1,
127 CYSometimes = 0,
128 CYAlways = 1,
129 };
130
131 enum CYFlags {
132 CYNoFlags = 0,
133 CYNoBrace = (1 << 0),
134 CYNoFunction = (1 << 1),
135 CYNoClass = (1 << 2),
136 CYNoIn = (1 << 3),
137 CYNoCall = (1 << 4),
138 CYNoRightHand = (1 << 5),
139 CYNoDangle = (1 << 6),
140 CYNoInteger = (1 << 7),
141 CYNoBFC = (CYNoBrace | CYNoFunction | CYNoClass),
142 };
143
144 _finline CYFlags operator ~(CYFlags rhs) {
145 return static_cast<CYFlags>(~static_cast<unsigned>(rhs));
146 }
147
148 _finline CYFlags operator &(CYFlags lhs, CYFlags rhs) {
149 return static_cast<CYFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
150 }
151
152 _finline CYFlags operator |(CYFlags lhs, CYFlags rhs) {
153 return static_cast<CYFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
154 }
155
156 _finline CYFlags &operator |=(CYFlags &lhs, CYFlags rhs) {
157 return lhs = lhs | rhs;
158 }
159
160 _finline CYFlags CYLeft(CYFlags flags) {
161 return flags & ~(CYNoDangle | CYNoInteger);
162 }
163
164 _finline CYFlags CYRight(CYFlags flags) {
165 return flags & ~CYNoBFC;
166 }
167
168 _finline CYFlags CYCenter(CYFlags flags) {
169 return CYLeft(CYRight(flags));
170 }
171
172 enum CYCompactType {
173 CYCompactNone,
174 CYCompactLong,
175 CYCompactShort,
176 };
177
178 #define CYCompact(type) \
179 virtual CYCompactType Compact() const { \
180 return CYCompact ## type; \
181 }
182
183 struct CYStatement :
184 CYNext<CYStatement>,
185 CYThing
186 {
187 void Single(CYOutput &out, CYFlags flags, CYCompactType request) const;
188 void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
189 virtual void Output(CYOutput &out) const;
190
191 virtual CYStatement *Replace(CYContext &context) = 0;
192
193 virtual CYCompactType Compact() const = 0;
194 virtual CYStatement *Return();
195
196 private:
197 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
198 };
199
200 typedef CYList<CYStatement> CYStatements;
201
202 struct CYForInitializer :
203 CYStatement
204 {
205 virtual CYForInitializer *Replace(CYContext &context) = 0;
206 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
207 };
208
209 struct CYWord :
210 CYThing,
211 CYPropertyName
212 {
213 const char *word_;
214
215 CYWord(const char *word) :
216 word_(word)
217 {
218 }
219
220 virtual bool Constructor() const {
221 return strcmp(word_, "constructor") == 0;
222 }
223
224 virtual const char *Word() const;
225 virtual void Output(CYOutput &out) const;
226
227 virtual CYExpression *PropertyName(CYContext &context);
228 virtual void PropertyName(CYOutput &out) const;
229 };
230
231 _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
232 lhs << &rhs << '=';
233 return lhs << rhs.Word();
234 }
235
236 enum CYIdentifierKind {
237 CYIdentifierArgument,
238 CYIdentifierCatch,
239 CYIdentifierGlobal,
240 CYIdentifierLexical,
241 CYIdentifierMagic,
242 CYIdentifierOther,
243 CYIdentifierVariable,
244 };
245
246 struct CYIdentifier :
247 CYNext<CYIdentifier>,
248 CYWord
249 {
250 CYLocation location_;
251 size_t offset_;
252 size_t usage_;
253
254 CYIdentifier(const char *word) :
255 CYWord(word),
256 offset_(0),
257 usage_(0)
258 {
259 }
260
261 virtual const char *Word() const;
262 CYIdentifier *Replace(CYContext &context, CYIdentifierKind);
263 };
264
265 struct CYLabel :
266 CYStatement
267 {
268 CYIdentifier *name_;
269 CYStatement *statement_;
270
271 CYLabel(CYIdentifier *name, CYStatement *statement) :
272 name_(name),
273 statement_(statement)
274 {
275 }
276
277 CYCompact(Short)
278
279 virtual CYStatement *Replace(CYContext &context);
280 virtual void Output(CYOutput &out, CYFlags flags) const;
281 };
282
283 struct CYCStringLess :
284 std::binary_function<const char *, const char *, bool>
285 {
286 _finline bool operator ()(const char *lhs, const char *rhs) const {
287 return strcmp(lhs, rhs) < 0;
288 }
289 };
290
291 struct CYIdentifierValueLess :
292 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
293 {
294 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
295 return CYCStringLess()(lhs->Word(), rhs->Word());
296 }
297 };
298
299 struct CYIdentifierFlags :
300 CYNext<CYIdentifierFlags>
301 {
302 CYIdentifier *identifier_;
303 CYIdentifierKind kind_;
304 unsigned count_;
305 unsigned offset_;
306
307 CYIdentifierFlags(CYIdentifier *identifier, CYIdentifierKind kind, CYIdentifierFlags *next = NULL) :
308 CYNext<CYIdentifierFlags>(next),
309 identifier_(identifier),
310 kind_(kind),
311 count_(0),
312 offset_(0)
313 {
314 }
315 };
316
317 struct CYScope {
318 bool transparent_;
319 CYScope *parent_;
320 bool damaged_;
321 CYIdentifierFlags *shadow_;
322
323 CYIdentifierFlags *internal_;
324
325 CYScope(bool transparent, CYContext &context);
326
327 CYIdentifierFlags *Lookup(CYContext &context, const char *word);
328 CYIdentifierFlags *Lookup(CYContext &context, CYIdentifier *identifier);
329
330 CYIdentifierFlags *Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierKind kind);
331 void Merge(CYContext &context, const CYIdentifierFlags *flags);
332
333 void Close(CYContext &context, CYStatement *&statements);
334 void Close(CYContext &context);
335 void Damage();
336 };
337
338 struct CYScript :
339 CYThing
340 {
341 CYStatement *code_;
342
343 CYScript(CYStatement *code) :
344 code_(code)
345 {
346 }
347
348 virtual void Replace(CYContext &context);
349 virtual void Output(CYOutput &out) const;
350 };
351
352 struct CYNonLocal;
353 struct CYThisScope;
354
355 struct CYContext {
356 CYOptions &options_;
357
358 CYScope *scope_;
359 CYThisScope *this_;
360 CYIdentifier *super_;
361
362 CYNonLocal *nonlocal_;
363 CYNonLocal *nextlocal_;
364 unsigned unique_;
365
366 std::vector<CYIdentifier *> replace_;
367
368 CYContext(CYOptions &options) :
369 options_(options),
370 scope_(NULL),
371 this_(NULL),
372 super_(NULL),
373 nonlocal_(NULL),
374 nextlocal_(NULL),
375 unique_(0)
376 {
377 }
378
379 void ReplaceAll(CYStatement *&statement) {
380 if (statement == NULL)
381 return;
382 CYStatement *next(statement->next_);
383
384 Replace(statement);
385 ReplaceAll(next);
386
387 if (statement == NULL)
388 statement = next;
389 else
390 statement->SetNext(next);
391 }
392
393 template <typename Type_>
394 void Replace(Type_ *&value) {
395 for (;;) if (value == NULL)
396 break;
397 else {
398 Type_ *replace(value->Replace(*this));
399 if (replace != value)
400 value = replace;
401 else break;
402 }
403 }
404
405 void NonLocal(CYStatement *&statements);
406 CYIdentifier *Unique();
407 };
408
409 struct CYNonLocal {
410 CYIdentifier *identifier_;
411
412 CYNonLocal() :
413 identifier_(NULL)
414 {
415 }
416
417 CYIdentifier *Target(CYContext &context) {
418 if (identifier_ == NULL)
419 identifier_ = context.Unique();
420 return identifier_;
421 }
422 };
423
424 struct CYThisScope :
425 CYNext<CYThisScope>
426 {
427 CYIdentifier *identifier_;
428
429 CYThisScope() :
430 identifier_(NULL)
431 {
432 }
433
434 CYIdentifier *Identifier(CYContext &context) {
435 if (next_ != NULL)
436 return next_->Identifier(context);
437 if (identifier_ == NULL)
438 identifier_ = context.Unique();
439 return identifier_;
440 }
441 };
442
443 struct CYBlock :
444 CYStatement
445 {
446 CYStatement *code_;
447
448 CYBlock(CYStatement *code) :
449 code_(code)
450 {
451 }
452
453 CYCompact(Short)
454
455 virtual CYStatement *Replace(CYContext &context);
456
457 virtual void Output(CYOutput &out, CYFlags flags) const;
458
459 virtual CYStatement *Return();
460 };
461
462 struct CYTarget;
463 struct CYVar;
464
465 struct CYForInInitializer {
466 virtual CYStatement *Initialize(CYContext &context, CYExpression *value) = 0;
467
468 virtual CYTarget *Replace(CYContext &context) = 0;
469 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
470 };
471
472 struct CYFunctionParameter;
473
474 struct CYNumber;
475 struct CYString;
476
477 struct CYExpression :
478 CYThing
479 {
480 virtual int Precedence() const = 0;
481
482 virtual bool RightHand() const {
483 return true;
484 }
485
486 virtual bool Eval() const {
487 return false;
488 }
489
490 virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
491
492 virtual void Output(CYOutput &out) const;
493 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
494 void Output(CYOutput &out, int precedence, CYFlags flags) const;
495
496 virtual CYExpression *Replace(CYContext &context) = 0;
497
498 virtual CYExpression *Primitive(CYContext &context) {
499 return NULL;
500 }
501
502 virtual CYFunctionParameter *Parameter() const;
503
504 virtual CYNumber *Number(CYContext &context) {
505 return NULL;
506 }
507
508 virtual CYString *String(CYContext &context) {
509 return NULL;
510 }
511
512 virtual const char *Word() const {
513 return NULL;
514 }
515 };
516
517 struct CYTarget :
518 CYExpression,
519 CYForInInitializer
520 {
521 virtual bool RightHand() const {
522 return false;
523 }
524
525 virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
526
527 virtual CYTarget *Replace(CYContext &context) = 0;
528 using CYExpression::Output;
529 };
530
531 #define CYAlphabetic(value) \
532 virtual bool Alphabetic() const { \
533 return value; \
534 }
535
536 #define CYPrecedence(value) \
537 static const int Precedence_ = value; \
538 virtual int Precedence() const { \
539 return Precedence_; \
540 }
541
542 struct CYCompound :
543 CYExpression
544 {
545 CYExpression *expression_;
546 CYExpression *next_;
547
548 CYCompound(CYExpression *expression, CYExpression *next) :
549 expression_(expression),
550 next_(next)
551 {
552 _assert(expression_ != NULL);
553 _assert(next != NULL);
554 }
555
556 CYPrecedence(17)
557
558 virtual CYExpression *Replace(CYContext &context);
559 void Output(CYOutput &out, CYFlags flags) const;
560
561 virtual CYFunctionParameter *Parameter() const;
562 };
563
564 struct CYParenthetical :
565 CYTarget
566 {
567 CYExpression *expression_;
568
569 CYParenthetical(CYExpression *expression) :
570 expression_(expression)
571 {
572 }
573
574 CYPrecedence(0)
575
576 virtual CYTarget *Replace(CYContext &context);
577 void Output(CYOutput &out, CYFlags flags) const;
578 };
579
580 struct CYBinding;
581
582 struct CYFunctionParameter :
583 CYNext<CYFunctionParameter>,
584 CYThing
585 {
586 CYBinding *binding_;
587
588 CYFunctionParameter(CYBinding *binding, CYFunctionParameter *next = NULL) :
589 CYNext<CYFunctionParameter>(next),
590 binding_(binding)
591 {
592 }
593
594 void Replace(CYContext &context, CYStatement *&statements);
595 void Output(CYOutput &out) const;
596 };
597
598 struct CYComprehension :
599 CYNext<CYComprehension>,
600 CYThing
601 {
602 CYComprehension(CYComprehension *next = NULL) :
603 CYNext<CYComprehension>(next)
604 {
605 }
606
607 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
608 CYFunctionParameter *Parameters(CYContext &context) const;
609 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
610 virtual void Output(CYOutput &out) const = 0;
611 };
612
613 struct CYForInComprehension :
614 CYComprehension
615 {
616 CYBinding *binding_;
617 CYExpression *iterable_;
618
619 CYForInComprehension(CYBinding *binding, CYExpression *iterable, CYComprehension *next = NULL) :
620 CYComprehension(next),
621 binding_(binding),
622 iterable_(iterable)
623 {
624 }
625
626 virtual CYFunctionParameter *Parameter(CYContext &context) const;
627 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
628 virtual void Output(CYOutput &out) const;
629 };
630
631 struct CYForOfComprehension :
632 CYComprehension
633 {
634 CYBinding *binding_;
635 CYExpression *iterable_;
636
637 CYForOfComprehension(CYBinding *binding, CYExpression *iterable, CYComprehension *next = NULL) :
638 CYComprehension(next),
639 binding_(binding),
640 iterable_(iterable)
641 {
642 }
643
644 virtual CYFunctionParameter *Parameter(CYContext &context) const;
645 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
646 virtual void Output(CYOutput &out) const;
647 };
648
649 struct CYIfComprehension :
650 CYComprehension
651 {
652 CYExpression *test_;
653
654 CYIfComprehension(CYExpression *test, CYComprehension *next = NULL) :
655 CYComprehension(next),
656 test_(test)
657 {
658 }
659
660 virtual CYFunctionParameter *Parameter(CYContext &context) const;
661 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
662 virtual void Output(CYOutput &out) const;
663 };
664
665 struct CYArrayComprehension :
666 CYTarget
667 {
668 CYExpression *expression_;
669 CYComprehension *comprehensions_;
670
671 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
672 expression_(expression),
673 comprehensions_(comprehensions)
674 {
675 }
676
677 CYPrecedence(0)
678
679 virtual CYTarget *Replace(CYContext &context);
680 virtual void Output(CYOutput &out, CYFlags flags) const;
681 };
682
683 struct CYLiteral :
684 CYTarget
685 {
686 CYLocation location_;
687
688 CYPrecedence(0)
689
690 virtual CYExpression *Primitive(CYContext &context) {
691 return this;
692 }
693 };
694
695 struct CYTrivial :
696 CYLiteral
697 {
698 virtual CYTarget *Replace(CYContext &context);
699 };
700
701 struct CYMagic :
702 CYTarget
703 {
704 CYPrecedence(0)
705 };
706
707 struct CYRange {
708 uint64_t lo_;
709 uint64_t hi_;
710
711 CYRange(uint64_t lo, uint64_t hi) :
712 lo_(lo), hi_(hi)
713 {
714 }
715
716 bool operator [](uint8_t value) const {
717 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
718 }
719
720 void operator()(uint8_t value) {
721 if (value >> 7)
722 return;
723 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
724 }
725 };
726
727 extern CYRange DigitRange_;
728 extern CYRange WordStartRange_;
729 extern CYRange WordEndRange_;
730
731 struct CYString :
732 CYTrivial,
733 CYPropertyName
734 {
735 const char *value_;
736 size_t size_;
737
738 CYString() :
739 value_(NULL),
740 size_(0)
741 {
742 }
743
744 CYString(const char *value) :
745 value_(value),
746 size_(strlen(value))
747 {
748 }
749
750 CYString(const char *value, size_t size) :
751 value_(value),
752 size_(size)
753 {
754 }
755
756 CYString(const CYWord *word) :
757 value_(word->Word()),
758 size_(strlen(value_))
759 {
760 }
761
762 const char *Value() const {
763 return value_;
764 }
765
766 virtual const char *Word() const;
767
768 virtual CYNumber *Number(CYContext &context);
769 virtual CYString *String(CYContext &context);
770
771 CYString *Concat(CYContext &out, CYString *rhs) const;
772 virtual void Output(CYOutput &out, CYFlags flags) const;
773
774 virtual CYExpression *PropertyName(CYContext &context);
775 virtual void PropertyName(CYOutput &out) const;
776 };
777
778 struct CYElementValue;
779
780 struct CYSpan :
781 CYNext<CYSpan>
782 {
783 CYExpression *expression_;
784 CYString *string_;
785
786 CYSpan(CYExpression *expression, CYString *string, CYSpan *next) :
787 CYNext<CYSpan>(next),
788 expression_(expression),
789 string_(string)
790 {
791 }
792
793 CYElementValue *Replace(CYContext &context);
794 };
795
796 struct CYTemplate :
797 CYTarget
798 {
799 CYString *string_;
800 CYSpan *spans_;
801
802 CYTemplate(CYString *string, CYSpan *spans) :
803 string_(string),
804 spans_(spans)
805 {
806 }
807
808 CYPrecedence(0)
809
810 virtual CYTarget *Replace(CYContext &context);
811 virtual void Output(CYOutput &out, CYFlags flags) const;
812 };
813
814 struct CYNumber :
815 CYTrivial,
816 CYPropertyName
817 {
818 double value_;
819
820 CYNumber(double value) :
821 value_(value)
822 {
823 }
824
825 double Value() const {
826 return value_;
827 }
828
829 virtual CYNumber *Number(CYContext &context);
830 virtual CYString *String(CYContext &context);
831
832 virtual void Output(CYOutput &out, CYFlags flags) const;
833
834 virtual CYExpression *PropertyName(CYContext &context);
835 virtual void PropertyName(CYOutput &out) const;
836 };
837
838 struct CYComputed :
839 CYPropertyName
840 {
841 CYExpression *expression_;
842
843 CYComputed(CYExpression *expression) :
844 expression_(expression)
845 {
846 }
847
848 virtual bool Computed() const {
849 return true;
850 }
851
852 virtual CYExpression *PropertyName(CYContext &context);
853 virtual void PropertyName(CYOutput &out) const;
854 };
855
856 struct CYRegEx :
857 CYTrivial
858 {
859 const char *value_;
860 size_t size_;
861
862 CYRegEx(const char *value, size_t size) :
863 value_(value),
864 size_(size)
865 {
866 }
867
868 const char *Value() const {
869 return value_;
870 }
871
872 virtual void Output(CYOutput &out, CYFlags flags) const;
873 };
874
875 struct CYNull :
876 CYTrivial
877 {
878 virtual CYNumber *Number(CYContext &context);
879 virtual CYString *String(CYContext &context);
880
881 virtual void Output(CYOutput &out, CYFlags flags) const;
882 };
883
884 struct CYThis :
885 CYMagic
886 {
887 virtual CYTarget *Replace(CYContext &context);
888 virtual void Output(CYOutput &out, CYFlags flags) const;
889 };
890
891 struct CYBoolean :
892 CYTrivial
893 {
894 CYPrecedence(4)
895
896 virtual bool RightHand() const {
897 return true;
898 }
899
900 virtual bool Value() const = 0;
901 virtual void Output(CYOutput &out, CYFlags flags) const;
902 };
903
904 struct CYFalse :
905 CYBoolean
906 {
907 virtual bool Value() const {
908 return false;
909 }
910
911 virtual CYNumber *Number(CYContext &context);
912 virtual CYString *String(CYContext &context);
913 };
914
915 struct CYTrue :
916 CYBoolean
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 CYTarget
928 {
929 CYIdentifier *name_;
930
931 CYVariable(CYIdentifier *name) :
932 name_(name)
933 {
934 }
935
936 CYVariable(const char *name) :
937 name_(new($pool) CYIdentifier(name))
938 {
939 }
940
941 CYPrecedence(0)
942
943 virtual bool Eval() const {
944 return strcmp(name_->Word(), "eval") == 0;
945 }
946
947 virtual CYTarget *Replace(CYContext &context);
948 virtual void Output(CYOutput &out, CYFlags flags) const;
949
950 virtual CYFunctionParameter *Parameter() const;
951 };
952
953 struct CYPrefix :
954 CYExpression
955 {
956 CYExpression *rhs_;
957
958 CYPrefix(CYExpression *rhs) :
959 rhs_(rhs)
960 {
961 }
962
963 virtual bool Alphabetic() const = 0;
964 virtual const char *Operator() const = 0;
965
966 CYPrecedence(4)
967
968 virtual CYExpression *Replace(CYContext &context);
969 virtual void Output(CYOutput &out, CYFlags flags) const;
970 };
971
972 struct CYInfix :
973 CYExpression
974 {
975 CYExpression *lhs_;
976 CYExpression *rhs_;
977
978 CYInfix(CYExpression *lhs, CYExpression *rhs) :
979 lhs_(lhs),
980 rhs_(rhs)
981 {
982 }
983
984 void SetLeft(CYExpression *lhs) {
985 lhs_ = lhs;
986 }
987
988 virtual bool Alphabetic() const = 0;
989 virtual const char *Operator() const = 0;
990
991 virtual CYExpression *Replace(CYContext &context);
992 virtual void Output(CYOutput &out, CYFlags flags) const;
993 };
994
995 struct CYPostfix :
996 CYExpression
997 {
998 CYExpression *lhs_;
999
1000 CYPostfix(CYExpression *lhs) :
1001 lhs_(lhs)
1002 {
1003 }
1004
1005 virtual const char *Operator() const = 0;
1006
1007 CYPrecedence(3)
1008
1009 virtual CYExpression *Replace(CYContext &context);
1010 virtual void Output(CYOutput &out, CYFlags flags) const;
1011 };
1012
1013 struct CYAssignment :
1014 CYExpression
1015 {
1016 CYTarget *lhs_;
1017 CYExpression *rhs_;
1018
1019 CYAssignment(CYTarget *lhs, CYExpression *rhs) :
1020 lhs_(lhs),
1021 rhs_(rhs)
1022 {
1023 }
1024
1025 void SetRight(CYExpression *rhs) {
1026 rhs_ = rhs;
1027 }
1028
1029 virtual const char *Operator() const = 0;
1030
1031 CYPrecedence(16)
1032
1033 virtual CYExpression *Replace(CYContext &context);
1034 virtual void Output(CYOutput &out, CYFlags flags) const;
1035 };
1036
1037 struct CYArgument :
1038 CYNext<CYArgument>,
1039 CYThing
1040 {
1041 CYWord *name_;
1042 CYExpression *value_;
1043
1044 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1045 CYNext<CYArgument>(next),
1046 name_(NULL),
1047 value_(value)
1048 {
1049 }
1050
1051 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
1052 CYNext<CYArgument>(next),
1053 name_(name),
1054 value_(value)
1055 {
1056 }
1057
1058 CYArgument *Replace(CYContext &context);
1059 void Output(CYOutput &out) const;
1060 };
1061
1062 struct CYClause :
1063 CYThing,
1064 CYNext<CYClause>
1065 {
1066 CYExpression *value_;
1067 CYStatement *code_;
1068
1069 CYClause(CYExpression *value, CYStatement *code) :
1070 value_(value),
1071 code_(code)
1072 {
1073 }
1074
1075 void Replace(CYContext &context);
1076 virtual void Output(CYOutput &out) const;
1077 };
1078
1079 struct CYElement :
1080 CYThing
1081 {
1082 virtual bool Elision() const = 0;
1083
1084 virtual void Replace(CYContext &context) = 0;
1085 };
1086
1087 struct CYElementValue :
1088 CYNext<CYElement>,
1089 CYElement
1090 {
1091 CYExpression *value_;
1092
1093 CYElementValue(CYExpression *value, CYElement *next = NULL) :
1094 CYNext<CYElement>(next),
1095 value_(value)
1096 {
1097 }
1098
1099 virtual bool Elision() const {
1100 return value_ == NULL;
1101 }
1102
1103 virtual void Replace(CYContext &context);
1104 virtual void Output(CYOutput &out) const;
1105 };
1106
1107 struct CYElementSpread :
1108 CYElement
1109 {
1110 CYExpression *value_;
1111
1112 CYElementSpread(CYExpression *value) :
1113 value_(value)
1114 {
1115 }
1116
1117 virtual bool Elision() const {
1118 return false;
1119 }
1120
1121 virtual void Replace(CYContext &context);
1122 virtual void Output(CYOutput &out) const;
1123 };
1124
1125 struct CYArray :
1126 CYLiteral
1127 {
1128 CYElement *elements_;
1129
1130 CYArray(CYElement *elements = NULL) :
1131 elements_(elements)
1132 {
1133 }
1134
1135 virtual CYTarget *Replace(CYContext &context);
1136 virtual void Output(CYOutput &out, CYFlags flags) const;
1137 };
1138
1139 struct CYBinding {
1140 CYIdentifier *identifier_;
1141 CYExpression *initializer_;
1142
1143 CYBinding(CYIdentifier *identifier, CYExpression *initializer = NULL) :
1144 identifier_(identifier),
1145 initializer_(initializer)
1146 {
1147 }
1148
1149 CYTarget *Target(CYContext &context);
1150
1151 virtual CYAssignment *Replace(CYContext &context, CYIdentifierKind kind);
1152 virtual void Output(CYOutput &out, CYFlags flags) const;
1153 };
1154
1155 struct CYForLexical :
1156 CYForInInitializer
1157 {
1158 bool constant_;
1159 CYBinding *binding_;
1160
1161 CYForLexical(bool constant, CYBinding *binding) :
1162 constant_(constant),
1163 binding_(binding)
1164 {
1165 }
1166
1167 virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
1168
1169 virtual CYTarget *Replace(CYContext &context);
1170 virtual void Output(CYOutput &out, CYFlags flags) const;
1171 };
1172
1173 struct CYForVariable :
1174 CYForInInitializer
1175 {
1176 CYBinding *binding_;
1177
1178 CYForVariable(CYBinding *binding) :
1179 binding_(binding)
1180 {
1181 }
1182
1183 virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
1184
1185 virtual CYTarget *Replace(CYContext &context);
1186 virtual void Output(CYOutput &out, CYFlags flags) const;
1187 };
1188
1189 struct CYBindings :
1190 CYNext<CYBindings>,
1191 CYThing
1192 {
1193 CYBinding *binding_;
1194
1195 CYBindings(CYBinding *binding, CYBindings *next = NULL) :
1196 CYNext<CYBindings>(next),
1197 binding_(binding)
1198 {
1199 }
1200
1201 CYExpression *Replace(CYContext &context, CYIdentifierKind kind);
1202
1203 CYArgument *Argument(CYContext &context);
1204 CYFunctionParameter *Parameter(CYContext &context);
1205
1206 virtual void Output(CYOutput &out) const;
1207 virtual void Output(CYOutput &out, CYFlags flags) const;
1208 };
1209
1210 struct CYVar :
1211 CYForInitializer
1212 {
1213 CYBindings *bindings_;
1214
1215 CYVar(CYBindings *bindings) :
1216 bindings_(bindings)
1217 {
1218 }
1219
1220 CYCompact(None)
1221
1222 virtual CYForInitializer *Replace(CYContext &context);
1223 virtual void Output(CYOutput &out, CYFlags flags) const;
1224 };
1225
1226 struct CYLexical :
1227 CYForInitializer
1228 {
1229 bool constant_;
1230 CYBindings *bindings_;
1231
1232 CYLexical(bool constant, CYBindings *bindings) :
1233 constant_(constant),
1234 bindings_(bindings)
1235 {
1236 }
1237
1238 CYCompact(None)
1239
1240 virtual CYForInitializer *Replace(CYContext &context);
1241 virtual void Output(CYOutput &out, CYFlags flags) const;
1242 };
1243
1244 struct CYBuilder {
1245 CYList<CYBindings> bindings_;
1246 CYList<CYStatement> statements_;
1247
1248 operator bool() const {
1249 return statements_ != NULL;
1250 }
1251 };
1252
1253 struct CYProperty :
1254 CYNext<CYProperty>,
1255 CYThing
1256 {
1257 CYPropertyName *name_;
1258
1259 CYProperty(CYPropertyName *name, CYProperty *next = NULL) :
1260 CYNext<CYProperty>(next),
1261 name_(name)
1262 {
1263 }
1264
1265 virtual bool Update() const;
1266
1267 CYProperty *ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update);
1268 void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool protect);
1269
1270 virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) = 0;
1271
1272 virtual void Replace(CYContext &context) = 0;
1273 virtual void Output(CYOutput &out) const;
1274 };
1275
1276 struct CYPropertyValue :
1277 CYProperty
1278 {
1279 CYExpression *value_;
1280
1281 CYPropertyValue(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1282 CYProperty(name, next),
1283 value_(value)
1284 {
1285 }
1286
1287 virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect);
1288 virtual void Replace(CYContext &context);
1289 virtual void Output(CYOutput &out) const;
1290 };
1291
1292 struct CYFor :
1293 CYStatement
1294 {
1295 CYForInitializer *initializer_;
1296 CYExpression *test_;
1297 CYExpression *increment_;
1298 CYStatement *code_;
1299
1300 CYFor(CYForInitializer *initializer, CYExpression *test, CYExpression *increment, CYStatement *code) :
1301 initializer_(initializer),
1302 test_(test),
1303 increment_(increment),
1304 code_(code)
1305 {
1306 }
1307
1308 CYCompact(Long)
1309
1310 virtual CYStatement *Replace(CYContext &context);
1311 virtual void Output(CYOutput &out, CYFlags flags) const;
1312 };
1313
1314 struct CYForIn :
1315 CYStatement
1316 {
1317 CYForInInitializer *initializer_;
1318 CYExpression *iterable_;
1319 CYStatement *code_;
1320
1321 CYForIn(CYForInInitializer *initializer, CYExpression *iterable, CYStatement *code) :
1322 initializer_(initializer),
1323 iterable_(iterable),
1324 code_(code)
1325 {
1326 }
1327
1328 CYCompact(Long)
1329
1330 virtual CYStatement *Replace(CYContext &context);
1331 virtual void Output(CYOutput &out, CYFlags flags) const;
1332 };
1333
1334 struct CYForInitialized :
1335 CYStatement
1336 {
1337 CYBinding *binding_;
1338 CYExpression *iterable_;
1339 CYStatement *code_;
1340
1341 CYForInitialized(CYBinding *binding, CYExpression *iterable, CYStatement *code) :
1342 binding_(binding),
1343 iterable_(iterable),
1344 code_(code)
1345 {
1346 }
1347
1348 CYCompact(Long)
1349
1350 virtual CYStatement *Replace(CYContext &context);
1351 virtual void Output(CYOutput &out, CYFlags flags) const;
1352 };
1353
1354 struct CYForOf :
1355 CYStatement
1356 {
1357 CYForInInitializer *initializer_;
1358 CYExpression *iterable_;
1359 CYStatement *code_;
1360
1361 CYForOf(CYForInInitializer *initializer, CYExpression *iterable, CYStatement *code) :
1362 initializer_(initializer),
1363 iterable_(iterable),
1364 code_(code)
1365 {
1366 }
1367
1368 CYCompact(Long)
1369
1370 virtual CYStatement *Replace(CYContext &context);
1371 virtual void Output(CYOutput &out, CYFlags flags) const;
1372 };
1373
1374 struct CYObject :
1375 CYLiteral
1376 {
1377 CYProperty *properties_;
1378
1379 CYObject(CYProperty *properties = NULL) :
1380 properties_(properties)
1381 {
1382 }
1383
1384 virtual CYTarget *Replace(CYContext &context);
1385 void Output(CYOutput &out, CYFlags flags) const;
1386 };
1387
1388 struct CYMember :
1389 CYTarget
1390 {
1391 CYExpression *object_;
1392 CYExpression *property_;
1393
1394 CYMember(CYExpression *object, CYExpression *property) :
1395 object_(object),
1396 property_(property)
1397 {
1398 }
1399
1400 void SetLeft(CYExpression *object) {
1401 object_ = object;
1402 }
1403 };
1404
1405 struct CYDirectMember :
1406 CYMember
1407 {
1408 CYDirectMember(CYExpression *object, CYExpression *property) :
1409 CYMember(object, property)
1410 {
1411 }
1412
1413 CYPrecedence(1)
1414
1415 virtual CYTarget *Replace(CYContext &context);
1416 virtual void Output(CYOutput &out, CYFlags flags) const;
1417 };
1418
1419 struct CYIndirectMember :
1420 CYMember
1421 {
1422 CYIndirectMember(CYExpression *object, CYExpression *property) :
1423 CYMember(object, property)
1424 {
1425 }
1426
1427 CYPrecedence(1)
1428
1429 virtual CYTarget *Replace(CYContext &context);
1430 virtual void Output(CYOutput &out, CYFlags flags) const;
1431 };
1432
1433 namespace cy {
1434 namespace Syntax {
1435
1436 struct New :
1437 CYTarget
1438 {
1439 CYExpression *constructor_;
1440 CYArgument *arguments_;
1441
1442 New(CYExpression *constructor, CYArgument *arguments = NULL) :
1443 constructor_(constructor),
1444 arguments_(arguments)
1445 {
1446 }
1447
1448 virtual int Precedence() const {
1449 return arguments_ == NULL ? 2 : 1;
1450 }
1451
1452
1453 virtual CYTarget *Replace(CYContext &context);
1454 virtual void Output(CYOutput &out, CYFlags flags) const;
1455
1456 virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
1457 };
1458
1459 } }
1460
1461 struct CYApply :
1462 CYTarget
1463 {
1464 CYArgument *arguments_;
1465
1466 CYApply(CYArgument *arguments = NULL) :
1467 arguments_(arguments)
1468 {
1469 }
1470
1471 CYPrecedence(1)
1472
1473 virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
1474 };
1475
1476 struct CYCall :
1477 CYApply
1478 {
1479 CYExpression *function_;
1480
1481 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
1482 CYApply(arguments),
1483 function_(function)
1484 {
1485 }
1486
1487 virtual void Output(CYOutput &out, CYFlags flags) const;
1488 virtual CYTarget *Replace(CYContext &context);
1489 };
1490
1491 struct CYEval :
1492 CYApply
1493 {
1494 CYEval(CYArgument *arguments) :
1495 CYApply(arguments)
1496 {
1497 }
1498
1499 virtual void Output(CYOutput &out, CYFlags flags) const;
1500 virtual CYTarget *Replace(CYContext &context);
1501 };
1502
1503 struct CYRubyProc;
1504
1505 struct CYRubyBlock :
1506 CYTarget
1507 {
1508 CYExpression *call_;
1509 CYRubyProc *proc_;
1510
1511 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1512 call_(call),
1513 proc_(proc)
1514 {
1515 }
1516
1517 CYPrecedence(1)
1518
1519 virtual CYTarget *Replace(CYContext &context);
1520 virtual void Output(CYOutput &out, CYFlags flags) const;
1521
1522 virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
1523 };
1524
1525 struct CYIf :
1526 CYStatement
1527 {
1528 CYExpression *test_;
1529 CYStatement *true_;
1530 CYStatement *false_;
1531
1532 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
1533 test_(test),
1534 true_(_true),
1535 false_(_false)
1536 {
1537 }
1538
1539 CYCompact(Long)
1540
1541 virtual CYStatement *Replace(CYContext &context);
1542 virtual void Output(CYOutput &out, CYFlags flags) const;
1543
1544 virtual CYStatement *Return();
1545 };
1546
1547 struct CYDoWhile :
1548 CYStatement
1549 {
1550 CYExpression *test_;
1551 CYStatement *code_;
1552
1553 CYDoWhile(CYExpression *test, CYStatement *code) :
1554 test_(test),
1555 code_(code)
1556 {
1557 }
1558
1559 CYCompact(None)
1560
1561 virtual CYStatement *Replace(CYContext &context);
1562 virtual void Output(CYOutput &out, CYFlags flags) const;
1563 };
1564
1565 struct CYWhile :
1566 CYStatement
1567 {
1568 CYExpression *test_;
1569 CYStatement *code_;
1570
1571 CYWhile(CYExpression *test, CYStatement *code) :
1572 test_(test),
1573 code_(code)
1574 {
1575 }
1576
1577 CYCompact(Long)
1578
1579 virtual CYStatement *Replace(CYContext &context);
1580 virtual void Output(CYOutput &out, CYFlags flags) const;
1581 };
1582
1583 struct CYFunction {
1584 CYFunctionParameter *parameters_;
1585 CYStatement *code_;
1586
1587 CYNonLocal *nonlocal_;
1588 bool implicit_;
1589 CYThisScope this_;
1590 CYIdentifier *super_;
1591
1592 CYFunction(CYFunctionParameter *parameters, CYStatement *code) :
1593 parameters_(parameters),
1594 code_(code),
1595 nonlocal_(NULL),
1596 implicit_(false),
1597 super_(NULL)
1598 {
1599 }
1600
1601 void Replace(CYContext &context);
1602 void Output(CYOutput &out) const;
1603 };
1604
1605 struct CYFunctionExpression :
1606 CYFunction,
1607 CYTarget
1608 {
1609 CYIdentifier *name_;
1610
1611 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
1612 CYFunction(parameters, code),
1613 name_(name)
1614 {
1615 }
1616
1617 CYPrecedence(0)
1618
1619 CYTarget *Replace(CYContext &context) override;
1620 virtual void Output(CYOutput &out, CYFlags flags) const;
1621 };
1622
1623 struct CYFatArrow :
1624 CYFunction,
1625 CYExpression
1626 {
1627 CYFatArrow(CYFunctionParameter *parameters, CYStatement *code) :
1628 CYFunction(parameters, code)
1629 {
1630 }
1631
1632 CYPrecedence(0)
1633
1634 CYExpression *Replace(CYContext &context) override;
1635 virtual void Output(CYOutput &out, CYFlags flags) const;
1636 };
1637
1638 struct CYRubyProc :
1639 CYFunction,
1640 CYTarget
1641 {
1642 CYRubyProc(CYFunctionParameter *parameters, CYStatement *code) :
1643 CYFunction(parameters, code)
1644 {
1645 }
1646
1647 CYPrecedence(0)
1648
1649 CYTarget *Replace(CYContext &context) override;
1650 virtual void Output(CYOutput &out, CYFlags flags) const;
1651 };
1652
1653 struct CYFunctionStatement :
1654 CYFunction,
1655 CYStatement
1656 {
1657 CYIdentifier *name_;
1658
1659 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
1660 CYFunction(parameters, code),
1661 name_(name)
1662 {
1663 }
1664
1665 CYCompact(None)
1666
1667 CYStatement *Replace(CYContext &context) override;
1668 virtual void Output(CYOutput &out, CYFlags flags) const;
1669 };
1670
1671 struct CYPropertyMethod;
1672
1673 struct CYMethod :
1674 CYFunction,
1675 CYProperty
1676 {
1677 CYMethod(CYPropertyName *name, CYFunctionParameter *parameters, CYStatement *code, CYProperty *next = NULL) :
1678 CYFunction(parameters, code),
1679 CYProperty(name, next)
1680 {
1681 }
1682
1683 virtual CYFunctionExpression *Constructor();
1684
1685 using CYProperty::Replace;
1686 virtual void Replace(CYContext &context);
1687 };
1688
1689 struct CYPropertyGetter :
1690 CYMethod
1691 {
1692 CYPropertyGetter(CYPropertyName *name, CYStatement *code, CYProperty *next = NULL) :
1693 CYMethod(name, NULL, code, next)
1694 {
1695 }
1696
1697 virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect);
1698 virtual void Output(CYOutput &out) const;
1699 };
1700
1701 struct CYPropertySetter :
1702 CYMethod
1703 {
1704 CYPropertySetter(CYPropertyName *name, CYFunctionParameter *parameters, CYStatement *code, CYProperty *next = NULL) :
1705 CYMethod(name, parameters, code, next)
1706 {
1707 }
1708
1709 virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect);
1710 virtual void Output(CYOutput &out) const;
1711 };
1712
1713 struct CYPropertyMethod :
1714 CYMethod
1715 {
1716 CYPropertyMethod(CYPropertyName *name, CYFunctionParameter *parameters, CYStatement *code, CYProperty *next = NULL) :
1717 CYMethod(name, parameters, code, next)
1718 {
1719 }
1720
1721 bool Update() const override;
1722
1723 virtual CYFunctionExpression *Constructor();
1724
1725 virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect);
1726 virtual void Output(CYOutput &out) const;
1727 };
1728
1729 struct CYClassTail :
1730 CYThing
1731 {
1732 CYExpression *extends_;
1733
1734 CYFunctionExpression *constructor_;
1735 CYList<CYProperty> instance_;
1736 CYList<CYProperty> static_;
1737
1738 CYClassTail(CYExpression *extends) :
1739 extends_(extends),
1740 constructor_(NULL)
1741 {
1742 }
1743
1744 void Output(CYOutput &out) const;
1745 };
1746
1747 struct CYClassExpression :
1748 CYTarget
1749 {
1750 CYIdentifier *name_;
1751 CYClassTail *tail_;
1752
1753 CYClassExpression(CYIdentifier *name, CYClassTail *tail) :
1754 name_(name),
1755 tail_(tail)
1756 {
1757 }
1758
1759 CYPrecedence(0)
1760
1761 CYTarget *Replace(CYContext &context) override;
1762 virtual void Output(CYOutput &out, CYFlags flags) const;
1763 };
1764
1765 struct CYClassStatement :
1766 CYStatement
1767 {
1768 CYIdentifier *name_;
1769 CYClassTail *tail_;
1770
1771 CYClassStatement(CYIdentifier *name, CYClassTail *tail) :
1772 name_(name),
1773 tail_(tail)
1774 {
1775 }
1776
1777 CYCompact(Long)
1778
1779 CYStatement *Replace(CYContext &context) override;
1780 virtual void Output(CYOutput &out, CYFlags flags) const;
1781 };
1782
1783 struct CYSuperCall :
1784 CYTarget
1785 {
1786 CYArgument *arguments_;
1787
1788 CYSuperCall(CYArgument *arguments) :
1789 arguments_(arguments)
1790 {
1791 }
1792
1793 CYPrecedence(2)
1794
1795 CYTarget *Replace(CYContext &context) override;
1796 virtual void Output(CYOutput &out, CYFlags flags) const;
1797 };
1798
1799 struct CYSuperAccess :
1800 CYTarget
1801 {
1802 CYExpression *property_;
1803
1804 CYSuperAccess(CYExpression *property) :
1805 property_(property)
1806 {
1807 }
1808
1809 CYPrecedence(1)
1810
1811 CYTarget *Replace(CYContext &context) override;
1812 virtual void Output(CYOutput &out, CYFlags flags) const;
1813 };
1814
1815 struct CYExpress :
1816 CYForInitializer
1817 {
1818 CYExpression *expression_;
1819
1820 CYExpress(CYExpression *expression) :
1821 expression_(expression)
1822 {
1823 if (expression_ == NULL)
1824 throw;
1825 }
1826
1827 CYCompact(None)
1828
1829 CYForInitializer *Replace(CYContext &context) override;
1830 virtual void Output(CYOutput &out, CYFlags flags) const;
1831
1832 virtual CYStatement *Return();
1833 };
1834
1835 struct CYContinue :
1836 CYStatement
1837 {
1838 CYIdentifier *label_;
1839
1840 CYContinue(CYIdentifier *label) :
1841 label_(label)
1842 {
1843 }
1844
1845 CYCompact(Short)
1846
1847 CYStatement *Replace(CYContext &context) override;
1848 virtual void Output(CYOutput &out, CYFlags flags) const;
1849 };
1850
1851 struct CYBreak :
1852 CYStatement
1853 {
1854 CYIdentifier *label_;
1855
1856 CYBreak(CYIdentifier *label) :
1857 label_(label)
1858 {
1859 }
1860
1861 CYCompact(Short)
1862
1863 CYStatement *Replace(CYContext &context) override;
1864 virtual void Output(CYOutput &out, CYFlags flags) const;
1865 };
1866
1867 struct CYReturn :
1868 CYStatement
1869 {
1870 CYExpression *value_;
1871
1872 CYReturn(CYExpression *value) :
1873 value_(value)
1874 {
1875 }
1876
1877 CYCompact(None)
1878
1879 CYStatement *Replace(CYContext &context) override;
1880 virtual void Output(CYOutput &out, CYFlags flags) const;
1881 };
1882
1883 struct CYYieldGenerator :
1884 CYExpression
1885 {
1886 CYExpression *value_;
1887
1888 CYYieldGenerator(CYExpression *value) :
1889 value_(value)
1890 {
1891 }
1892
1893 CYPrecedence(0)
1894
1895 CYExpression *Replace(CYContext &context) override;
1896 virtual void Output(CYOutput &out, CYFlags flags) const;
1897 };
1898
1899 struct CYYieldValue :
1900 CYExpression
1901 {
1902 CYExpression *value_;
1903
1904 CYYieldValue(CYExpression *value) :
1905 value_(value)
1906 {
1907 }
1908
1909 CYPrecedence(0)
1910
1911 virtual CYExpression *Replace(CYContext &context);
1912 virtual void Output(CYOutput &out, CYFlags flags) const;
1913 };
1914
1915 struct CYEmpty :
1916 CYForInitializer
1917 {
1918 CYCompact(Short)
1919
1920 virtual CYForInitializer *Replace(CYContext &context);
1921 virtual void Output(CYOutput &out, CYFlags flags) const;
1922 };
1923
1924 struct CYFinally :
1925 CYThing
1926 {
1927 CYStatement *code_;
1928
1929 CYFinally(CYStatement *code) :
1930 code_(code)
1931 {
1932 }
1933
1934 void Replace(CYContext &context);
1935 virtual void Output(CYOutput &out) const;
1936 };
1937
1938 struct CYTypeSpecifier :
1939 CYThing
1940 {
1941 virtual CYTarget *Replace(CYContext &context) = 0;
1942 };
1943
1944 struct CYTypeError :
1945 CYTypeSpecifier
1946 {
1947 CYTypeError() {
1948 }
1949
1950 virtual CYTarget *Replace(CYContext &context);
1951 virtual void Output(CYOutput &out) const;
1952 };
1953
1954 struct CYTypeVoid :
1955 CYTypeSpecifier
1956 {
1957 CYTypeVoid() {
1958 }
1959
1960 virtual CYTarget *Replace(CYContext &context);
1961 virtual void Output(CYOutput &out) const;
1962 };
1963
1964 struct CYTypeVariable :
1965 CYTypeSpecifier
1966 {
1967 CYIdentifier *name_;
1968
1969 CYTypeVariable(CYIdentifier *name) :
1970 name_(name)
1971 {
1972 }
1973
1974 CYTypeVariable(const char *name) :
1975 name_(new($pool) CYIdentifier(name))
1976 {
1977 }
1978
1979 virtual CYTarget *Replace(CYContext &context);
1980 virtual void Output(CYOutput &out) const;
1981 };
1982
1983 struct CYTypeUnsigned :
1984 CYTypeSpecifier
1985 {
1986 CYTypeSpecifier *specifier_;
1987
1988 CYTypeUnsigned(CYTypeSpecifier *specifier) :
1989 specifier_(specifier)
1990 {
1991 }
1992
1993 virtual CYTarget *Replace(CYContext &context);
1994 virtual void Output(CYOutput &out) const;
1995 };
1996
1997 struct CYTypeSigned :
1998 CYTypeSpecifier
1999 {
2000 CYTypeSpecifier *specifier_;
2001
2002 CYTypeSigned(CYTypeSpecifier *specifier) :
2003 specifier_(specifier)
2004 {
2005 }
2006
2007 virtual CYTarget *Replace(CYContext &context);
2008 virtual void Output(CYOutput &out) const;
2009 };
2010
2011 struct CYTypeLong :
2012 CYTypeSpecifier
2013 {
2014 CYTypeSpecifier *specifier_;
2015
2016 CYTypeLong(CYTypeSpecifier *specifier) :
2017 specifier_(specifier)
2018 {
2019 }
2020
2021 virtual CYTarget *Replace(CYContext &context);
2022 virtual void Output(CYOutput &out) const;
2023 };
2024
2025 struct CYTypeShort :
2026 CYTypeSpecifier
2027 {
2028 CYTypeSpecifier *specifier_;
2029
2030 CYTypeShort(CYTypeSpecifier *specifier) :
2031 specifier_(specifier)
2032 {
2033 }
2034
2035 virtual CYTarget *Replace(CYContext &context);
2036 virtual void Output(CYOutput &out) const;
2037 };
2038
2039 struct CYTypeFunctionWith;
2040
2041 struct CYTypeModifier :
2042 CYNext<CYTypeModifier>
2043 {
2044 CYTypeModifier(CYTypeModifier *next) :
2045 CYNext<CYTypeModifier>(next)
2046 {
2047 }
2048
2049 virtual int Precedence() const = 0;
2050
2051 virtual CYTarget *Replace_(CYContext &context, CYTarget *type) = 0;
2052 CYTarget *Replace(CYContext &context, CYTarget *type);
2053
2054 virtual void Output(CYOutput &out, CYIdentifier *identifier) const = 0;
2055 void Output(CYOutput &out, int precedence, CYIdentifier *identifier) const;
2056
2057 virtual CYTypeFunctionWith *Function() { return NULL; }
2058 };
2059
2060 struct CYTypeArrayOf :
2061 CYTypeModifier
2062 {
2063 CYExpression *size_;
2064
2065 CYTypeArrayOf(CYExpression *size, CYTypeModifier *next = NULL) :
2066 CYTypeModifier(next),
2067 size_(size)
2068 {
2069 }
2070
2071 CYPrecedence(1)
2072
2073 virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
2074 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
2075 };
2076
2077 struct CYTypeConstant :
2078 CYTypeModifier
2079 {
2080 CYTypeConstant(CYTypeModifier *next = NULL) :
2081 CYTypeModifier(next)
2082 {
2083 }
2084
2085 CYPrecedence(0)
2086
2087 virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
2088 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
2089 };
2090
2091 struct CYTypePointerTo :
2092 CYTypeModifier
2093 {
2094 CYTypePointerTo(CYTypeModifier *next = NULL) :
2095 CYTypeModifier(next)
2096 {
2097 }
2098
2099 CYPrecedence(0)
2100
2101 virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
2102 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
2103 };
2104
2105 struct CYTypeVolatile :
2106 CYTypeModifier
2107 {
2108 CYTypeVolatile(CYTypeModifier *next = NULL) :
2109 CYTypeModifier(next)
2110 {
2111 }
2112
2113 CYPrecedence(0)
2114
2115 virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
2116 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
2117 };
2118
2119 struct CYTypedIdentifier :
2120 CYNext<CYTypedIdentifier>,
2121 CYThing
2122 {
2123 CYLocation location_;
2124 CYIdentifier *identifier_;
2125 CYTypeSpecifier *specifier_;
2126 CYTypeModifier *modifier_;
2127
2128 CYTypedIdentifier(const CYLocation &location, CYIdentifier *identifier = NULL) :
2129 location_(location),
2130 identifier_(identifier),
2131 specifier_(NULL),
2132 modifier_(NULL)
2133 {
2134 }
2135
2136 CYTypedIdentifier(CYTypeSpecifier *specifier, CYTypeModifier *modifier = NULL) :
2137 identifier_(NULL),
2138 specifier_(specifier),
2139 modifier_(modifier)
2140 {
2141 }
2142
2143 inline CYTypedIdentifier *Modify(CYTypeModifier *modifier) {
2144 CYSetLast(modifier_) = modifier;
2145 return this;
2146 }
2147
2148 virtual CYTarget *Replace(CYContext &context);
2149 virtual void Output(CYOutput &out) const;
2150
2151 CYTypeFunctionWith *Function();
2152 };
2153
2154 struct CYEncodedType :
2155 CYTarget
2156 {
2157 CYTypedIdentifier *typed_;
2158
2159 CYEncodedType(CYTypedIdentifier *typed) :
2160 typed_(typed)
2161 {
2162 }
2163
2164 CYPrecedence(1)
2165
2166 virtual CYTarget *Replace(CYContext &context);
2167 virtual void Output(CYOutput &out, CYFlags flags) const;
2168 };
2169
2170 struct CYTypedParameter :
2171 CYNext<CYTypedParameter>,
2172 CYThing
2173 {
2174 CYTypedIdentifier *typed_;
2175
2176 CYTypedParameter(CYTypedIdentifier *typed, CYTypedParameter *next) :
2177 CYNext<CYTypedParameter>(next),
2178 typed_(typed)
2179 {
2180 }
2181
2182 CYArgument *Argument(CYContext &context);
2183 CYFunctionParameter *Parameters(CYContext &context);
2184 CYExpression *TypeSignature(CYContext &context, CYExpression *prefix);
2185
2186 virtual void Output(CYOutput &out) const;
2187 };
2188
2189 struct CYLambda :
2190 CYTarget
2191 {
2192 CYTypedIdentifier *typed_;
2193 CYTypedParameter *parameters_;
2194 CYStatement *code_;
2195
2196 CYLambda(CYTypedIdentifier *typed, CYTypedParameter *parameters, CYStatement *code) :
2197 typed_(typed),
2198 parameters_(parameters),
2199 code_(code)
2200 {
2201 }
2202
2203 CYPrecedence(1)
2204
2205 virtual CYTarget *Replace(CYContext &context);
2206 virtual void Output(CYOutput &out, CYFlags flags) const;
2207 };
2208
2209 struct CYModule :
2210 CYNext<CYModule>,
2211 CYThing
2212 {
2213 CYWord *part_;
2214
2215 CYModule(CYWord *part, CYModule *next = NULL) :
2216 CYNext<CYModule>(next),
2217 part_(part)
2218 {
2219 }
2220
2221 CYString *Replace(CYContext &context, const char *separator) const;
2222 void Output(CYOutput &out) const;
2223 };
2224
2225 struct CYImport :
2226 CYStatement
2227 {
2228 CYModule *module_;
2229
2230 CYImport(CYModule *module) :
2231 module_(module)
2232 {
2233 }
2234
2235 CYCompact(None)
2236
2237 virtual CYStatement *Replace(CYContext &context);
2238 virtual void Output(CYOutput &out, CYFlags flags) const;
2239 };
2240
2241 struct CYExternal :
2242 CYStatement
2243 {
2244 CYString *abi_;
2245 CYTypedIdentifier *typed_;
2246
2247 CYExternal(CYString *abi, CYTypedIdentifier *typed) :
2248 abi_(abi),
2249 typed_(typed)
2250 {
2251 }
2252
2253 CYCompact(None)
2254
2255 virtual CYStatement *Replace(CYContext &context);
2256 virtual void Output(CYOutput &out, CYFlags flags) const;
2257 };
2258
2259 struct CYTypeExpression :
2260 CYTarget
2261 {
2262 CYTypedIdentifier *typed_;
2263
2264 CYTypeExpression(CYTypedIdentifier *typed) :
2265 typed_(typed)
2266 {
2267 }
2268
2269 CYPrecedence(0)
2270
2271 virtual CYTarget *Replace(CYContext &context);
2272 virtual void Output(CYOutput &out, CYFlags flags) const;
2273 };
2274
2275 struct CYTypeDefinition :
2276 CYStatement
2277 {
2278 CYTypedIdentifier *typed_;
2279
2280 CYTypeDefinition(CYTypedIdentifier *typed) :
2281 typed_(typed)
2282 {
2283 }
2284
2285 CYCompact(None)
2286
2287 virtual CYStatement *Replace(CYContext &context);
2288 virtual void Output(CYOutput &out, CYFlags flags) const;
2289 };
2290
2291 struct CYTypeBlockWith :
2292 CYTypeModifier
2293 {
2294 CYTypedParameter *parameters_;
2295
2296 CYTypeBlockWith(CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
2297 CYTypeModifier(next),
2298 parameters_(parameters)
2299 {
2300 }
2301
2302 CYPrecedence(0)
2303
2304 virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
2305 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
2306 };
2307
2308 struct CYTypeFunctionWith :
2309 CYTypeModifier
2310 {
2311 CYTypedParameter *parameters_;
2312
2313 CYTypeFunctionWith(CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
2314 CYTypeModifier(next),
2315 parameters_(parameters)
2316 {
2317 }
2318
2319 CYPrecedence(1)
2320
2321 virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
2322 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
2323
2324 virtual CYTypeFunctionWith *Function() { return this; }
2325 };
2326
2327 struct CYTypeStructField :
2328 CYNext<CYTypeStructField>
2329 {
2330 CYTypedIdentifier *typed_;
2331
2332 CYTypeStructField(CYTypedIdentifier *typed, CYTypeStructField *next = NULL) :
2333 CYNext<CYTypeStructField>(next),
2334 typed_(typed)
2335 {
2336 }
2337 };
2338
2339 struct CYTypeStruct :
2340 CYTypeSpecifier
2341 {
2342 CYIdentifier *name_;
2343 CYTypeStructField *fields_;
2344
2345 CYTypeStruct(CYIdentifier *name, CYTypeStructField *fields) :
2346 name_(name),
2347 fields_(fields)
2348 {
2349 }
2350
2351 virtual CYTarget *Replace(CYContext &context);
2352 virtual void Output(CYOutput &out) const;
2353 };
2354
2355 namespace cy {
2356 namespace Syntax {
2357
2358 struct Catch :
2359 CYThing
2360 {
2361 CYIdentifier *name_;
2362 CYStatement *code_;
2363
2364 Catch(CYIdentifier *name, CYStatement *code) :
2365 name_(name),
2366 code_(code)
2367 {
2368 }
2369
2370 void Replace(CYContext &context);
2371 virtual void Output(CYOutput &out) const;
2372 };
2373
2374 struct Try :
2375 CYStatement
2376 {
2377 CYStatement *code_;
2378 Catch *catch_;
2379 CYFinally *finally_;
2380
2381 Try(CYStatement *code, Catch *_catch, CYFinally *finally) :
2382 code_(code),
2383 catch_(_catch),
2384 finally_(finally)
2385 {
2386 }
2387
2388 CYCompact(Short)
2389
2390 virtual CYStatement *Replace(CYContext &context);
2391 virtual void Output(CYOutput &out, CYFlags flags) const;
2392 };
2393
2394 struct Throw :
2395 CYStatement
2396 {
2397 CYExpression *value_;
2398
2399 Throw(CYExpression *value = NULL) :
2400 value_(value)
2401 {
2402 }
2403
2404 CYCompact(None)
2405
2406 virtual CYStatement *Replace(CYContext &context);
2407 virtual void Output(CYOutput &out, CYFlags flags) const;
2408 };
2409
2410 } }
2411
2412 struct CYWith :
2413 CYStatement
2414 {
2415 CYExpression *scope_;
2416 CYStatement *code_;
2417
2418 CYWith(CYExpression *scope, CYStatement *code) :
2419 scope_(scope),
2420 code_(code)
2421 {
2422 }
2423
2424 CYCompact(Long)
2425
2426 virtual CYStatement *Replace(CYContext &context);
2427 virtual void Output(CYOutput &out, CYFlags flags) const;
2428 };
2429
2430 struct CYSwitch :
2431 CYStatement
2432 {
2433 CYExpression *value_;
2434 CYClause *clauses_;
2435
2436 CYSwitch(CYExpression *value, CYClause *clauses) :
2437 value_(value),
2438 clauses_(clauses)
2439 {
2440 }
2441
2442 CYCompact(Long)
2443
2444 virtual CYStatement *Replace(CYContext &context);
2445 virtual void Output(CYOutput &out, CYFlags flags) const;
2446 };
2447
2448 struct CYDebugger :
2449 CYStatement
2450 {
2451 CYDebugger()
2452 {
2453 }
2454
2455 CYCompact(None)
2456
2457 virtual CYStatement *Replace(CYContext &context);
2458 virtual void Output(CYOutput &out, CYFlags flags) const;
2459 };
2460
2461 struct CYCondition :
2462 CYExpression
2463 {
2464 CYExpression *test_;
2465 CYExpression *true_;
2466 CYExpression *false_;
2467
2468 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
2469 test_(test),
2470 true_(_true),
2471 false_(_false)
2472 {
2473 }
2474
2475 CYPrecedence(15)
2476
2477 virtual CYExpression *Replace(CYContext &context);
2478 virtual void Output(CYOutput &out, CYFlags flags) const;
2479 };
2480
2481 struct CYAddressOf :
2482 CYPrefix
2483 {
2484 CYAddressOf(CYExpression *rhs) :
2485 CYPrefix(rhs)
2486 {
2487 }
2488
2489 virtual const char *Operator() const {
2490 return "&";
2491 }
2492
2493 CYAlphabetic(false)
2494
2495 virtual CYExpression *Replace(CYContext &context);
2496 };
2497
2498 struct CYIndirect :
2499 CYTarget
2500 {
2501 CYExpression *rhs_;
2502
2503 CYIndirect(CYExpression *rhs) :
2504 rhs_(rhs)
2505 {
2506 }
2507
2508 // XXX: this should be checked
2509 CYPrecedence(2)
2510
2511 virtual CYTarget *Replace(CYContext &context);
2512 virtual void Output(CYOutput &out, CYFlags flags) const;
2513 };
2514
2515 #define CYReplace \
2516 virtual CYExpression *Replace(CYContext &context);
2517
2518 #define CYPostfix_(op, name, args...) \
2519 struct CY ## name : \
2520 CYPostfix \
2521 { args \
2522 CY ## name(CYExpression *lhs) : \
2523 CYPostfix(lhs) \
2524 { \
2525 } \
2526 \
2527 virtual const char *Operator() const { \
2528 return op; \
2529 } \
2530 };
2531
2532 #define CYPrefix_(alphabetic, op, name, args...) \
2533 struct CY ## name : \
2534 CYPrefix \
2535 { args \
2536 CY ## name(CYExpression *rhs) : \
2537 CYPrefix(rhs) \
2538 { \
2539 } \
2540 \
2541 CYAlphabetic(alphabetic) \
2542 \
2543 virtual const char *Operator() const { \
2544 return op; \
2545 } \
2546 };
2547
2548 #define CYInfix_(alphabetic, precedence, op, name, args...) \
2549 struct CY ## name : \
2550 CYInfix \
2551 { args \
2552 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
2553 CYInfix(lhs, rhs) \
2554 { \
2555 } \
2556 \
2557 CYAlphabetic(alphabetic) \
2558 CYPrecedence(precedence) \
2559 \
2560 virtual const char *Operator() const { \
2561 return op; \
2562 } \
2563 };
2564
2565 #define CYAssignment_(op, name, args...) \
2566 struct CY ## name ## Assign : \
2567 CYAssignment \
2568 { args \
2569 CY ## name ## Assign(CYTarget *lhs, CYExpression *rhs) : \
2570 CYAssignment(lhs, rhs) \
2571 { \
2572 } \
2573 \
2574 virtual const char *Operator() const { \
2575 return op; \
2576 } \
2577 };
2578
2579 CYPostfix_("++", PostIncrement)
2580 CYPostfix_("--", PostDecrement)
2581
2582 CYPrefix_(true, "delete", Delete)
2583 CYPrefix_(true, "void", Void)
2584 CYPrefix_(true, "typeof", TypeOf)
2585 CYPrefix_(false, "++", PreIncrement)
2586 CYPrefix_(false, "--", PreDecrement)
2587 CYPrefix_(false, "+", Affirm)
2588 CYPrefix_(false, "-", Negate)
2589 CYPrefix_(false, "~", BitwiseNot)
2590 CYPrefix_(false, "!", LogicalNot)
2591
2592 CYInfix_(false, 5, "*", Multiply, CYReplace)
2593 CYInfix_(false, 5, "/", Divide)
2594 CYInfix_(false, 5, "%", Modulus)
2595 CYInfix_(false, 6, "+", Add, CYReplace)
2596 CYInfix_(false, 6, "-", Subtract)
2597 CYInfix_(false, 7, "<<", ShiftLeft)
2598 CYInfix_(false, 7, ">>", ShiftRightSigned)
2599 CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
2600 CYInfix_(false, 8, "<", Less)
2601 CYInfix_(false, 8, ">", Greater)
2602 CYInfix_(false, 8, "<=", LessOrEqual)
2603 CYInfix_(false, 8, ">=", GreaterOrEqual)
2604 CYInfix_(true, 8, "instanceof", InstanceOf)
2605 CYInfix_(true, 8, "in", In)
2606 CYInfix_(false, 9, "==", Equal)
2607 CYInfix_(false, 9, "!=", NotEqual)
2608 CYInfix_(false, 9, "===", Identical)
2609 CYInfix_(false, 9, "!==", NotIdentical)
2610 CYInfix_(false, 10, "&", BitwiseAnd)
2611 CYInfix_(false, 11, "^", BitwiseXOr)
2612 CYInfix_(false, 12, "|", BitwiseOr)
2613 CYInfix_(false, 13, "&&", LogicalAnd)
2614 CYInfix_(false, 14, "||", LogicalOr)
2615
2616 CYAssignment_("=", )
2617 CYAssignment_("*=", Multiply)
2618 CYAssignment_("/=", Divide)
2619 CYAssignment_("%=", Modulus)
2620 CYAssignment_("+=", Add)
2621 CYAssignment_("-=", Subtract)
2622 CYAssignment_("<<=", ShiftLeft)
2623 CYAssignment_(">>=", ShiftRightSigned)
2624 CYAssignment_(">>>=", ShiftRightUnsigned)
2625 CYAssignment_("&=", BitwiseAnd)
2626 CYAssignment_("^=", BitwiseXOr)
2627 CYAssignment_("|=", BitwiseOr)
2628
2629 #endif/*CYCRIPT_PARSER_HPP*/