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