]> git.saurik.com Git - cycript.git/blame - Parser.hpp
Drastic performance enhancement by using a perfect hash instead of an sqlite3 database.
[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
0a356474
JF
328 virtual ~CYScope() {
329 }
330
a86e34d0
JF
331 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
332 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
6a981250 333 void Merge(CYContext &context, CYIdentifier *identifier);
029bc65b
JF
334 void Scope(CYContext &context, CYStatement *&statements);
335};
336
3b52fd1a 337struct CYProgram :
029bc65b 338 CYScope,
3b52fd1a 339 CYThing
63b4c5a8 340{
3b52fd1a 341 CYStatement *statements_;
14ec9e00 342 CYIdentifierAddressVector rename_;
9e562cfc 343
3b52fd1a
JF
344 CYProgram(CYStatement *statements) :
345 statements_(statements)
9e562cfc
JF
346 {
347 }
cf7d4c69 348
3b52fd1a 349 virtual void Replace(CYContext &context);
3b52fd1a 350 virtual void Output(CYOutput &out) const;
9e562cfc
JF
351};
352
6a981250
JF
353struct CYContext :
354 CYScope
355{
356 apr_pool_t *pool_;
357 CYOptions &options_;
358 CYScope *scope_;
359 CYProgram *program_;
360
361 CYContext(apr_pool_t *pool, CYOptions &options) :
362 pool_(pool),
363 options_(options),
364 scope_(this),
365 program_(NULL)
366 {
367 }
368
0a356474
JF
369 virtual ~CYContext() {
370 }
371
6a981250
JF
372 template <typename Type_>
373 void Replace(Type_ *&value) {
374 for (;;) if (value == NULL)
375 break;
376 else {
377 Type_ *replace(value->Replace(*this));
378 if (replace != value)
379 value = replace;
380 else break;
381 }
382 }
383};
384
9e562cfc 385struct CYBlock :
3b52fd1a
JF
386 CYStatement,
387 CYThing
9e562cfc
JF
388{
389 CYStatement *statements_;
029bc65b 390 CYScope *scope_;
9e562cfc 391
029bc65b
JF
392 CYBlock(CYStatement *statements, CYScope *scope = NULL) :
393 statements_(statements),
394 scope_(scope)
9e562cfc 395 {
cf7d4c69 396 }
9e562cfc 397
4644480a
JF
398 operator CYStatement *() const {
399 return statements_;
400 }
401
029bc65b
JF
402 void AddPrev(CYStatement *statement) {
403 CYStatement *last(statement);
404 while (last->next_ != NULL)
405 last = last->next_;
406 last->SetNext(statements_);
407 statements_ = statement;
408 }
409
3b52fd1a
JF
410 virtual CYStatement *Replace(CYContext &context);
411
412 virtual void Output(CYOutput &out) const;
fb98ac0c 413 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
414};
415
db5e2840
JF
416enum CYState {
417 CYClear,
418 CYRestricted,
419 CYNewLine
420};
421
5999c315
JF
422class CYDriver {
423 public:
424 CYPool pool_;
e7ed5354 425
db5e2840 426 CYState state_;
e7ed5354
JF
427 void *scanner_;
428
429 const char *data_;
430 size_t size_;
48e3be8a 431 FILE *file_;
e7ed5354 432
b10bd496
JF
433 bool strict_;
434
63cd45c9 435 enum Condition {
697d6fd2 436 RegExpCondition,
691e4717
JF
437 XMLContentCondition,
438 XMLTagCondition,
63cd45c9
JF
439 };
440
5999c315 441 std::string filename_;
e7ed5354 442
5befe15e 443 struct Error {
b10bd496 444 bool warning_;
5befe15e
JF
445 cy::location location_;
446 std::string message_;
447 };
448
449 typedef std::vector<Error> Errors;
450
3b52fd1a 451 CYProgram *program_;
5befe15e 452 Errors errors_;
5999c315
JF
453
454 private:
455 void ScannerInit();
456 void ScannerDestroy();
457
458 public:
459 CYDriver(const std::string &filename);
460 ~CYDriver();
63cd45c9 461
691e4717
JF
462 Condition GetCondition();
463 void SetCondition(Condition condition);
464
465 void PushCondition(Condition condition);
466 void PopCondition();
b10bd496
JF
467
468 void Warning(const cy::location &location, const char *message);
5999c315
JF
469};
470
cac61857 471struct CYForInitialiser {
7c6c5b0a
JF
472 virtual ~CYForInitialiser() {
473 }
474
652ec1ba 475 virtual void For(CYOutput &out) const = 0;
029bc65b 476 virtual CYExpression *Replace(CYContext &context) = 0;
dea834b0
JF
477};
478
cac61857 479struct CYForInInitialiser {
7c6c5b0a
JF
480 virtual ~CYForInInitialiser() {
481 }
482
652ec1ba 483 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
75b0a457 484 virtual const char *ForEachIn() const = 0;
3b52fd1a 485 virtual CYExpression *ForEachIn(CYContext &out) = 0;
029bc65b 486 virtual CYExpression *Replace(CYContext &context) = 0;
b09da87b
JF
487};
488
4644480a
JF
489struct CYNumber;
490struct CYString;
491
cf7d4c69 492struct CYExpression :
5999c315 493 CYNext<CYExpression>,
cf7d4c69 494 CYForInitialiser,
e5bc40db 495 CYForInInitialiser,
96a7e5c2
JF
496 CYClassName,
497 CYThing
63b4c5a8 498{
d35a3b07 499 virtual unsigned Precedence() const = 0;
75b0a457 500
fb98ac0c
JF
501 virtual bool RightHand() const {
502 return true;
503 }
504
652ec1ba
JF
505 virtual void For(CYOutput &out) const;
506 virtual void ForIn(CYOutput &out, CYFlags flags) const;
75b0a457 507
cac61857 508 virtual const char *ForEachIn() const;
3b52fd1a 509 virtual CYExpression *ForEachIn(CYContext &out);
75b0a457 510
96a7e5c2 511 virtual void Output(CYOutput &out) const;
652ec1ba
JF
512 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
513 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
dea834b0 514
3b52fd1a 515 virtual CYExpression *ClassName(CYContext &context, bool object);
652ec1ba 516 virtual void ClassName(CYOutput &out, bool object) const;
e5bc40db 517
3b52fd1a
JF
518 CYExpression *ReplaceAll(CYContext &context);
519
520 virtual CYExpression *Replace(CYContext &context) = 0;
521
4644480a
JF
522 virtual CYExpression *Primitive(CYContext &context) {
523 return this;
524 }
525
526 virtual CYNumber *Number(CYContext &context) {
527 return NULL;
528 }
529
530 virtual CYString *String(CYContext &context) {
531 return NULL;
532 }
533
dea834b0
JF
534 virtual const char *Word() const {
535 return NULL;
536 }
63b4c5a8
JF
537};
538
b09da87b
JF
539#define CYAlphabetic(value) \
540 virtual bool Alphabetic() const { \
541 return value; \
542 }
543
d35a3b07
JF
544#define CYPrecedence(value) \
545 virtual unsigned Precedence() const { \
546 return value; \
547 }
548
fb98ac0c
JF
549#define CYRightHand(value) \
550 virtual bool RightHand() const { \
551 return value; \
552 }
553
d35a3b07
JF
554struct CYCompound :
555 CYExpression
556{
557 CYExpression *expressions_;
558
029bc65b 559 CYCompound(CYExpression *expressions = NULL) :
d35a3b07
JF
560 expressions_(expressions)
561 {
562 }
563
564 void AddPrev(CYExpression *expression) {
565 CYExpression *last(expression);
566 while (last->next_ != NULL)
567 last = last->next_;
568 last->SetNext(expressions_);
569 expressions_ = expression;
570 }
571
572 CYPrecedence(17)
573
3b52fd1a 574 virtual CYExpression *Replace(CYContext &context);
652ec1ba 575 void Output(CYOutput &out, CYFlags flags) const;
d35a3b07 576};
5999c315 577
3b52fd1a
JF
578struct CYFunctionParameter :
579 CYNext<CYFunctionParameter>,
580 CYThing
581{
582 CYIdentifier *name_;
583
584 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
585 CYNext<CYFunctionParameter>(next),
586 name_(name)
587 {
588 }
589
029bc65b 590 void Replace(CYContext &context);
3b52fd1a
JF
591 virtual void Output(CYOutput &out) const;
592};
593
75b0a457 594struct CYComprehension :
96a7e5c2
JF
595 CYNext<CYComprehension>,
596 CYThing
75b0a457 597{
75b0a457
JF
598 virtual const char *Name() const = 0;
599
3b52fd1a
JF
600 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
601 CYFunctionParameter *Parameters(CYContext &context) const;
602 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 603 virtual void Output(CYOutput &out) const = 0;
75b0a457
JF
604};
605
606struct CYForInComprehension :
607 CYComprehension
608{
609 CYIdentifier *name_;
610 CYExpression *set_;
611
612 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
613 name_(name),
614 set_(set)
615 {
616 }
617
618 virtual const char *Name() const {
029bc65b 619 return name_->Word();
75b0a457
JF
620 }
621
3b52fd1a
JF
622 virtual CYFunctionParameter *Parameter(CYContext &context) const;
623 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 624 virtual void Output(CYOutput &out) const;
75b0a457
JF
625};
626
627struct CYForEachInComprehension :
628 CYComprehension
629{
630 CYIdentifier *name_;
631 CYExpression *set_;
632
633 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
634 name_(name),
635 set_(set)
636 {
637 }
638
639 virtual const char *Name() const {
029bc65b 640 return name_->Word();
75b0a457
JF
641 }
642
3b52fd1a
JF
643 virtual CYFunctionParameter *Parameter(CYContext &context) const;
644 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 645 virtual void Output(CYOutput &out) const;
75b0a457
JF
646};
647
648struct CYIfComprehension :
649 CYComprehension
650{
651 CYExpression *test_;
652
653 CYIfComprehension(CYExpression *test) :
654 test_(test)
655 {
656 }
657
658 virtual const char *Name() const {
659 return NULL;
660 }
661
3b52fd1a
JF
662 virtual CYFunctionParameter *Parameter(CYContext &context) const;
663 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 664 virtual void Output(CYOutput &out) const;
75b0a457
JF
665};
666
667struct CYArrayComprehension :
668 CYExpression
669{
670 CYExpression *expression_;
671 CYComprehension *comprehensions_;
672
673 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
674 expression_(expression),
675 comprehensions_(comprehensions)
676 {
677 }
678
679 CYPrecedence(0)
680
3b52fd1a 681 virtual CYExpression *Replace(CYContext &context);
652ec1ba 682 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
683};
684
cf7d4c69
JF
685struct CYLiteral :
686 CYExpression
63b4c5a8 687{
d35a3b07 688 CYPrecedence(0)
fb98ac0c 689 CYRightHand(false)
cf7d4c69 690};
63b4c5a8 691
3b52fd1a
JF
692struct CYTrivial :
693 CYLiteral
694{
695 virtual CYExpression *Replace(CYContext &context);
696};
697
478d4ed0
JF
698struct CYMagic :
699 CYExpression
700{
701 CYPrecedence(0)
fb98ac0c 702 CYRightHand(false)
478d4ed0
JF
703};
704
dea834b0
JF
705struct CYRange {
706 uint64_t lo_;
707 uint64_t hi_;
708
709 CYRange(uint64_t lo, uint64_t hi) :
710 lo_(lo), hi_(hi)
711 {
712 }
713
714 bool operator [](uint8_t value) const {
715 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
716 }
717
718 void operator()(uint8_t value) {
719 if (value >> 7)
720 return;
721 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
722 }
723};
724
283e7e33 725extern CYRange DigitRange_;
dea834b0
JF
726extern CYRange WordStartRange_;
727extern CYRange WordEndRange_;
728
cf7d4c69 729struct CYString :
3b52fd1a 730 CYTrivial,
e5bc40db 731 CYPropertyName
cf7d4c69
JF
732{
733 const char *value_;
5999c315 734 size_t size_;
cf7d4c69 735
3b52fd1a
JF
736 CYString() :
737 value_(NULL),
738 size_(0)
739 {
740 }
741
742 CYString(const char *value) :
743 value_(value),
744 size_(strlen(value))
745 {
746 }
747
5999c315
JF
748 CYString(const char *value, size_t size) :
749 value_(value),
750 size_(size)
cf7d4c69
JF
751 {
752 }
753
3b52fd1a 754 CYString(const CYWord *word) :
029bc65b 755 value_(word->Word()),
5999c315 756 size_(strlen(value_))
cf7d4c69
JF
757 {
758 }
759
5999c315 760 const char *Value() const {
cf7d4c69
JF
761 return value_;
762 }
763
11c1cc16 764 virtual const char *Word() const;
dea834b0 765
4644480a
JF
766 virtual CYNumber *Number(CYContext &context);
767 virtual CYString *String(CYContext &context);
768
5db9a7f5 769 CYString *Concat(CYContext &out, CYString *rhs) const;
652ec1ba
JF
770 virtual void Output(CYOutput &out, CYFlags flags) const;
771 virtual void PropertyName(CYOutput &out) const;
63b4c5a8
JF
772};
773
cf7d4c69 774struct CYNumber :
3b52fd1a 775 CYTrivial,
e5bc40db 776 CYPropertyName
cf7d4c69 777{
5999c315
JF
778 double value_;
779
780 CYNumber(double value) :
781 value_(value)
782 {
783 }
784
785 double Value() const {
786 return value_;
cf7d4c69
JF
787 }
788
4644480a
JF
789 virtual CYNumber *Number(CYContext &context);
790 virtual CYString *String(CYContext &context);
791
652ec1ba
JF
792 virtual void Output(CYOutput &out, CYFlags flags) const;
793 virtual void PropertyName(CYOutput &out) const;
cf7d4c69
JF
794};
795
63cd45c9 796struct CYRegEx :
3b52fd1a 797 CYTrivial
63cd45c9
JF
798{
799 const char *value_;
800
801 CYRegEx(const char *value) :
802 value_(value)
803 {
804 }
805
806 const char *Value() const {
807 return value_;
808 }
809
810 virtual void Output(CYOutput &out, CYFlags flags) const;
811};
812
cf7d4c69
JF
813struct CYNull :
814 CYWord,
3b52fd1a 815 CYTrivial
cf7d4c69
JF
816{
817 CYNull() :
818 CYWord("null")
819 {
820 }
5999c315 821
4644480a
JF
822 virtual CYNumber *Number(CYContext &context);
823 virtual CYString *String(CYContext &context);
824
652ec1ba 825 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
826};
827
828struct CYThis :
829 CYWord,
478d4ed0 830 CYMagic
cf7d4c69
JF
831{
832 CYThis() :
833 CYWord("this")
834 {
835 }
5999c315 836
3b52fd1a 837 virtual CYExpression *Replace(CYContext &context);
652ec1ba 838 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
839};
840
841struct CYBoolean :
3b52fd1a 842 CYTrivial
cf7d4c69 843{
5999c315 844 virtual bool Value() const = 0;
652ec1ba 845 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
846};
847
848struct CYFalse :
849 CYWord,
850 CYBoolean
851{
852 CYFalse() :
853 CYWord("false")
854 {
855 }
5999c315 856
11c1cc16
JF
857 virtual bool Value() const {
858 return false;
859 }
4644480a
JF
860
861 virtual CYNumber *Number(CYContext &context);
862 virtual CYString *String(CYContext &context);
cf7d4c69
JF
863};
864
865struct CYTrue :
866 CYWord,
867 CYBoolean
868{
869 CYTrue() :
870 CYWord("true")
871 {
872 }
5999c315 873
11c1cc16
JF
874 virtual bool Value() const {
875 return true;
876 }
4644480a
JF
877
878 virtual CYNumber *Number(CYContext &context);
879 virtual CYString *String(CYContext &context);
cf7d4c69
JF
880};
881
882struct CYVariable :
883 CYExpression
884{
885 CYIdentifier *name_;
886
887 CYVariable(CYIdentifier *name) :
888 name_(name)
889 {
890 }
5999c315 891
d35a3b07 892 CYPrecedence(0)
fb98ac0c 893 CYRightHand(false)
d35a3b07 894
3b52fd1a 895 virtual CYExpression *Replace(CYContext &context);
652ec1ba 896 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
897};
898
899struct CYPrefix :
63b4c5a8
JF
900 CYExpression
901{
902 CYExpression *rhs_;
903
cf7d4c69 904 CYPrefix(CYExpression *rhs) :
63b4c5a8
JF
905 rhs_(rhs)
906 {
907 }
5999c315 908
b09da87b 909 virtual bool Alphabetic() const = 0;
5999c315
JF
910 virtual const char *Operator() const = 0;
911
3b52fd1a
JF
912 CYPrecedence(4)
913
914 virtual CYExpression *Replace(CYContext &context);
652ec1ba 915 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
916};
917
cf7d4c69 918struct CYInfix :
63b4c5a8
JF
919 CYExpression
920{
921 CYExpression *lhs_;
922 CYExpression *rhs_;
923
cf7d4c69 924 CYInfix(CYExpression *lhs, CYExpression *rhs) :
63b4c5a8
JF
925 lhs_(lhs),
926 rhs_(rhs)
927 {
928 }
5999c315 929
0ff9f149
JF
930 void SetLeft(CYExpression *lhs) {
931 lhs_ = lhs;
932 }
933
b09da87b 934 virtual bool Alphabetic() const = 0;
5999c315
JF
935 virtual const char *Operator() const = 0;
936
3b52fd1a 937 virtual CYExpression *Replace(CYContext &context);
652ec1ba 938 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
939};
940
cf7d4c69 941struct CYPostfix :
63b4c5a8
JF
942 CYExpression
943{
944 CYExpression *lhs_;
945
cf7d4c69 946 CYPostfix(CYExpression *lhs) :
63b4c5a8
JF
947 lhs_(lhs)
948 {
949 }
5999c315
JF
950
951 virtual const char *Operator() const = 0;
952
3b52fd1a
JF
953 CYPrecedence(3)
954
955 virtual CYExpression *Replace(CYContext &context);
652ec1ba 956 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
957};
958
cf7d4c69 959struct CYAssignment :
d35a3b07 960 CYExpression
cf7d4c69 961{
d35a3b07
JF
962 CYExpression *lhs_;
963 CYExpression *rhs_;
964
cf7d4c69 965 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
d35a3b07
JF
966 lhs_(lhs),
967 rhs_(rhs)
cf7d4c69
JF
968 {
969 }
5999c315 970
0ff9f149
JF
971 void SetLeft(CYExpression *lhs) {
972 lhs_ = lhs;
973 }
974
5999c315 975 virtual const char *Operator() const = 0;
d35a3b07 976
4de0686f
JF
977 CYPrecedence(16)
978
3b52fd1a 979 virtual CYExpression *Replace(CYContext &context);
652ec1ba 980 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
981};
982
62014ea9 983struct CYArgument :
96a7e5c2
JF
984 CYNext<CYArgument>,
985 CYThing
62014ea9 986{
cf7d4c69
JF
987 CYWord *name_;
988 CYExpression *value_;
cf7d4c69 989
3b52fd1a
JF
990 CYArgument(CYExpression *value, CYArgument *next = NULL) :
991 CYNext<CYArgument>(next),
992 name_(NULL),
993 value_(value)
994 {
995 }
996
cf7d4c69 997 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
62014ea9 998 CYNext<CYArgument>(next),
cf7d4c69 999 name_(name),
62014ea9 1000 value_(value)
cf7d4c69
JF
1001 {
1002 }
5999c315 1003
3b52fd1a 1004 void Replace(CYContext &context);
652ec1ba 1005 void Output(CYOutput &out) const;
cf7d4c69
JF
1006};
1007
1008struct CYBlank :
1009 public CYWord
1010{
1011 CYBlank() :
1012 CYWord("")
1013 {
1014 }
1015};
1016
5999c315
JF
1017struct CYClause :
1018 CYThing,
1019 CYNext<CYClause>
1020{
cf7d4c69 1021 CYExpression *case_;
3b52fd1a 1022 CYStatement *statements_;
cf7d4c69 1023
3b52fd1a 1024 CYClause(CYExpression *_case, CYStatement *statements) :
cf7d4c69 1025 case_(_case),
3b52fd1a 1026 statements_(statements)
cf7d4c69
JF
1027 {
1028 }
1029
fa389b0f 1030 void Replace(CYContext &context);
652ec1ba 1031 virtual void Output(CYOutput &out) const;
cf7d4c69
JF
1032};
1033
62014ea9 1034struct CYElement :
96a7e5c2
JF
1035 CYNext<CYElement>,
1036 CYThing
62014ea9 1037{
cf7d4c69 1038 CYExpression *value_;
cf7d4c69
JF
1039
1040 CYElement(CYExpression *value, CYElement *next) :
62014ea9
JF
1041 CYNext<CYElement>(next),
1042 value_(value)
cf7d4c69
JF
1043 {
1044 }
5999c315 1045
3b52fd1a 1046 void Replace(CYContext &context);
652ec1ba 1047 void Output(CYOutput &out) const;
5befe15e
JF
1048};
1049
1050struct CYArray :
1051 CYLiteral
1052{
1053 CYElement *elements_;
1054
3b52fd1a 1055 CYArray(CYElement *elements = NULL) :
5befe15e
JF
1056 elements_(elements)
1057 {
1058 }
1059
3b52fd1a 1060 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1061 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1062};
1063
550ee46a
JF
1064struct CYProperty :
1065 CYNext<CYProperty>,
1066 CYThing
1067{
1068 CYPropertyName *name_;
1069 CYExpression *value_;
1070
1071 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1072 CYNext<CYProperty>(next),
1073 name_(name),
1074 value_(value)
1075 {
1076 }
1077
1078 void Replace(CYContext &context);
1079 virtual void Output(CYOutput &out) const;
1080};
1081
cf7d4c69
JF
1082struct CYDeclaration :
1083 CYForInInitialiser
1084{
1085 CYIdentifier *identifier_;
1086 CYExpression *initialiser_;
1087
550ee46a 1088 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
cf7d4c69
JF
1089 identifier_(identifier),
1090 initialiser_(initialiser)
1091 {
1092 }
5999c315 1093
652ec1ba 1094 virtual void ForIn(CYOutput &out, CYFlags flags) const;
75b0a457 1095
cac61857 1096 virtual const char *ForEachIn() const;
3b52fd1a
JF
1097 virtual CYExpression *ForEachIn(CYContext &out);
1098
029bc65b
JF
1099 virtual CYExpression *Replace(CYContext &context);
1100 virtual CYAssignment *Assignment(CYContext &context);
75b0a457 1101
652ec1ba 1102 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1103};
1104
1105struct CYDeclarations :
cac61857 1106 CYNext<CYDeclarations>,
029bc65b
JF
1107 CYThing,
1108 CYForInitialiser
cf7d4c69
JF
1109{
1110 CYDeclaration *declaration_;
cf7d4c69 1111
cacd1a88 1112 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
cac61857
JF
1113 CYNext<CYDeclarations>(next),
1114 declaration_(declaration)
1115 {
1116 }
1117
652ec1ba 1118 virtual void For(CYOutput &out) const;
96a7e5c2 1119
029bc65b 1120 virtual CYCompound *Replace(CYContext &context);
550ee46a 1121 CYProperty *Property(CYContext &context);
3b52fd1a 1122
96a7e5c2 1123 virtual void Output(CYOutput &out) const;
652ec1ba 1124 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1125};
1126
1127struct CYVar :
1128 CYStatement
1129{
1130 CYDeclarations *declarations_;
1131
1132 CYVar(CYDeclarations *declarations) :
1133 declarations_(declarations)
1134 {
1135 }
1136
3b52fd1a 1137 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1138 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1139};
1140
1141struct CYLet :
1142 CYStatement
1143{
1144 CYDeclarations *declarations_;
3b52fd1a 1145 CYBlock code_;
cac61857
JF
1146
1147 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1148 declarations_(declarations),
3b52fd1a 1149 code_(statements)
cf7d4c69
JF
1150 {
1151 }
5999c315 1152
3b52fd1a 1153 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1154 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1155};
1156
cf7d4c69
JF
1157struct CYFor :
1158 CYStatement
1159{
1160 CYForInitialiser *initialiser_;
1161 CYExpression *test_;
1162 CYExpression *increment_;
1163 CYStatement *code_;
1164
1165 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1166 initialiser_(initialiser),
1167 test_(test),
1168 increment_(increment),
1169 code_(code)
1170 {
1171 }
5999c315 1172
3b52fd1a 1173 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1174 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1175};
1176
1177struct CYForIn :
1178 CYStatement
1179{
1180 CYForInInitialiser *initialiser_;
1181 CYExpression *set_;
1182 CYStatement *code_;
1183
1184 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1185 initialiser_(initialiser),
1186 set_(set),
1187 code_(code)
1188 {
1189 }
5999c315 1190
3b52fd1a 1191 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1192 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1193};
1194
75b0a457
JF
1195struct CYForEachIn :
1196 CYStatement
1197{
1198 CYForInInitialiser *initialiser_;
1199 CYExpression *set_;
1200 CYStatement *code_;
1201
1202 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1203 initialiser_(initialiser),
1204 set_(set),
1205 code_(code)
1206 {
1207 }
1208
3b52fd1a 1209 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1210 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
1211};
1212
693d501b
JF
1213struct CYObject :
1214 CYLiteral
1215{
3b52fd1a 1216 CYProperty *properties_;
693d501b 1217
3b52fd1a
JF
1218 CYObject(CYProperty *properties) :
1219 properties_(properties)
693d501b
JF
1220 {
1221 }
1222
3b52fd1a 1223 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1224 void Output(CYOutput &out, CYFlags flags) const;
693d501b
JF
1225};
1226
cf7d4c69
JF
1227struct CYMember :
1228 CYExpression
1229{
1230 CYExpression *object_;
1231 CYExpression *property_;
1232
1233 CYMember(CYExpression *object, CYExpression *property) :
1234 object_(object),
1235 property_(property)
1236 {
1237 }
5999c315 1238
9b5527f0
JF
1239 void SetLeft(CYExpression *object) {
1240 object_ = object;
1241 }
3b52fd1a
JF
1242
1243 void Replace_(CYContext &context);
9b5527f0
JF
1244};
1245
1246struct CYDirectMember :
1247 CYMember
1248{
1249 CYDirectMember(CYExpression *object, CYExpression *property) :
1250 CYMember(object, property)
1251 {
1252 }
1253
1254 CYPrecedence(1)
fb98ac0c 1255 CYRightHand(false)
9b5527f0 1256
3b52fd1a 1257 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1258 virtual void Output(CYOutput &out, CYFlags flags) const;
9b5527f0
JF
1259};
1260
1261struct CYIndirectMember :
1262 CYMember
1263{
1264 CYIndirectMember(CYExpression *object, CYExpression *property) :
1265 CYMember(object, property)
1266 {
1267 }
1268
d35a3b07 1269 CYPrecedence(1)
fb98ac0c 1270 CYRightHand(false)
d35a3b07 1271
3b52fd1a 1272 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1273 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1274};
1275
1276struct CYNew :
1277 CYExpression
1278{
1279 CYExpression *constructor_;
1280 CYArgument *arguments_;
1281
1282 CYNew(CYExpression *constructor, CYArgument *arguments) :
1283 constructor_(constructor),
1284 arguments_(arguments)
1285 {
1286 }
5999c315 1287
fb98ac0c
JF
1288 virtual unsigned Precedence() const {
1289 return arguments_ == NULL ? 2 : 1;
1290 }
1291
1292 CYRightHand(false)
d35a3b07 1293
3b52fd1a 1294 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1295 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1296};
1297
1298struct CYCall :
1299 CYExpression
1300{
1301 CYExpression *function_;
1302 CYArgument *arguments_;
1303
3b52fd1a 1304 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
cf7d4c69
JF
1305 function_(function),
1306 arguments_(arguments)
1307 {
1308 }
5999c315 1309
fb98ac0c
JF
1310 CYPrecedence(1)
1311 CYRightHand(false)
d35a3b07 1312
3b52fd1a 1313 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1314 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1315};
1316
1317struct CYIf :
1318 CYStatement
1319{
1320 CYExpression *test_;
1321 CYStatement *true_;
1322 CYStatement *false_;
1323
3b52fd1a 1324 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
cf7d4c69
JF
1325 test_(test),
1326 true_(_true),
1327 false_(_false)
1328 {
1329 }
5999c315 1330
3b52fd1a 1331 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1332 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1333};
1334
1335struct CYDoWhile :
1336 CYStatement
1337{
1338 CYExpression *test_;
1339 CYStatement *code_;
1340
1341 CYDoWhile(CYExpression *test, CYStatement *code) :
1342 test_(test),
1343 code_(code)
1344 {
1345 }
5999c315 1346
3b52fd1a 1347 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1348 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1349};
1350
1351struct CYWhile :
1352 CYStatement
1353{
1354 CYExpression *test_;
1355 CYStatement *code_;
1356
1357 CYWhile(CYExpression *test, CYStatement *code) :
1358 test_(test),
1359 code_(code)
1360 {
1361 }
5999c315 1362
3b52fd1a 1363 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1364 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1365};
1366
029bc65b
JF
1367struct CYFunction :
1368 CYScope
1369{
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),
029bc65b 1377 code_(statements, this)
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*/