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