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