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