]> git.saurik.com Git - cycript.git/blame - Syntax.hpp
Avoid crashing when the user types a mismatched }.
[cycript.git] / Syntax.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
20052ff7
JF
22#ifndef CYCRIPT_SYNTAX_HPP
23#define CYCRIPT_SYNTAX_HPP
24
25#include <cstdio>
26#include <cstdlib>
63b4c5a8 27
efd689d8 28#include <streambuf>
5999c315 29#include <string>
c3c20102 30#include <vector>
029bc65b
JF
31#include <map>
32#include <set>
cf7d4c69 33
da2af935 34#include "List.hpp"
00b4cb83 35#include "Location.hpp"
029bc65b 36#include "Options.hpp"
20052ff7 37#include "Pooling.hpp"
029bc65b 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
3b52fd1a
JF
617 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
618 CYFunctionParameter *Parameters(CYContext &context) const;
619 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 620 virtual void Output(CYOutput &out) const = 0;
75b0a457
JF
621};
622
623struct CYForInComprehension :
624 CYComprehension
625{
4e3c9056 626 CYDeclaration *declaration_;
75b0a457
JF
627 CYExpression *set_;
628
4e3c9056 629 CYForInComprehension(CYDeclaration *declaration, CYExpression *set, CYComprehension *next = NULL) :
c2529502 630 CYComprehension(next),
4e3c9056 631 declaration_(declaration),
75b0a457
JF
632 set_(set)
633 {
634 }
635
3b52fd1a
JF
636 virtual CYFunctionParameter *Parameter(CYContext &context) const;
637 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 638 virtual void Output(CYOutput &out) const;
75b0a457
JF
639};
640
d5618df7 641struct CYForOfComprehension :
75b0a457
JF
642 CYComprehension
643{
4e3c9056 644 CYDeclaration *declaration_;
75b0a457
JF
645 CYExpression *set_;
646
4e3c9056 647 CYForOfComprehension(CYDeclaration *declaration, CYExpression *set, CYComprehension *next = NULL) :
c2529502 648 CYComprehension(next),
4e3c9056 649 declaration_(declaration),
75b0a457
JF
650 set_(set)
651 {
652 }
653
3b52fd1a
JF
654 virtual CYFunctionParameter *Parameter(CYContext &context) const;
655 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 656 virtual void Output(CYOutput &out) const;
75b0a457
JF
657};
658
659struct CYIfComprehension :
660 CYComprehension
661{
662 CYExpression *test_;
663
b3aa25d8
JF
664 CYIfComprehension(CYExpression *test, CYComprehension *next = NULL) :
665 CYComprehension(next),
75b0a457
JF
666 test_(test)
667 {
668 }
669
3b52fd1a
JF
670 virtual CYFunctionParameter *Parameter(CYContext &context) const;
671 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 672 virtual void Output(CYOutput &out) const;
75b0a457
JF
673};
674
675struct CYArrayComprehension :
676 CYExpression
677{
678 CYExpression *expression_;
679 CYComprehension *comprehensions_;
680
681 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
682 expression_(expression),
683 comprehensions_(comprehensions)
684 {
685 }
686
687 CYPrecedence(0)
688
3b52fd1a 689 virtual CYExpression *Replace(CYContext &context);
652ec1ba 690 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
691};
692
cf7d4c69
JF
693struct CYLiteral :
694 CYExpression
63b4c5a8 695{
d35a3b07 696 CYPrecedence(0)
fb98ac0c 697 CYRightHand(false)
fd5cdf97
JF
698
699 virtual CYExpression *Primitive(CYContext &context) {
700 return this;
701 }
cf7d4c69 702};
63b4c5a8 703
3b52fd1a
JF
704struct CYTrivial :
705 CYLiteral
706{
707 virtual CYExpression *Replace(CYContext &context);
708};
709
478d4ed0
JF
710struct CYMagic :
711 CYExpression
712{
713 CYPrecedence(0)
fb98ac0c 714 CYRightHand(false)
478d4ed0
JF
715};
716
dea834b0
JF
717struct CYRange {
718 uint64_t lo_;
719 uint64_t hi_;
720
721 CYRange(uint64_t lo, uint64_t hi) :
722 lo_(lo), hi_(hi)
723 {
724 }
725
726 bool operator [](uint8_t value) const {
727 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
728 }
729
730 void operator()(uint8_t value) {
731 if (value >> 7)
732 return;
733 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
734 }
735};
736
283e7e33 737extern CYRange DigitRange_;
dea834b0
JF
738extern CYRange WordStartRange_;
739extern CYRange WordEndRange_;
740
cf7d4c69 741struct CYString :
3b52fd1a 742 CYTrivial,
e5bc40db 743 CYPropertyName
cf7d4c69
JF
744{
745 const char *value_;
5999c315 746 size_t size_;
cf7d4c69 747
3b52fd1a
JF
748 CYString() :
749 value_(NULL),
750 size_(0)
751 {
752 }
753
754 CYString(const char *value) :
755 value_(value),
756 size_(strlen(value))
757 {
758 }
759
5999c315
JF
760 CYString(const char *value, size_t size) :
761 value_(value),
762 size_(size)
cf7d4c69
JF
763 {
764 }
765
3b52fd1a 766 CYString(const CYWord *word) :
029bc65b 767 value_(word->Word()),
5999c315 768 size_(strlen(value_))
cf7d4c69
JF
769 {
770 }
771
5999c315 772 const char *Value() const {
cf7d4c69
JF
773 return value_;
774 }
775
11c1cc16 776 virtual const char *Word() const;
dea834b0 777
4644480a
JF
778 virtual CYNumber *Number(CYContext &context);
779 virtual CYString *String(CYContext &context);
780
5db9a7f5 781 CYString *Concat(CYContext &out, CYString *rhs) const;
652ec1ba
JF
782 virtual void Output(CYOutput &out, CYFlags flags) const;
783 virtual void PropertyName(CYOutput &out) const;
63b4c5a8
JF
784};
785
fc8fc33d 786struct CYElementValue;
b900e1a4
JF
787
788struct CYSpan :
789 CYNext<CYSpan>
790{
791 CYExpression *expression_;
792 CYString *string_;
793
794 CYSpan(CYExpression *expression, CYString *string, CYSpan *next) :
795 CYNext<CYSpan>(next),
796 expression_(expression),
797 string_(string)
798 {
799 }
800
fc8fc33d 801 CYElementValue *Replace(CYContext &context);
b900e1a4
JF
802};
803
804struct CYTemplate :
805 CYExpression
806{
807 CYString *string_;
808 CYSpan *spans_;
809
810 CYTemplate(CYString *string, CYSpan *spans) :
811 string_(string),
812 spans_(spans)
813 {
814 }
815
816 CYPrecedence(0)
817 CYRightHand(false)
818
819 virtual CYExpression *Replace(CYContext &context);
820 virtual void Output(CYOutput &out, CYFlags flags) const;
821};
822
cf7d4c69 823struct CYNumber :
3b52fd1a 824 CYTrivial,
e5bc40db 825 CYPropertyName
cf7d4c69 826{
5999c315
JF
827 double value_;
828
829 CYNumber(double value) :
830 value_(value)
831 {
832 }
833
834 double Value() const {
835 return value_;
cf7d4c69
JF
836 }
837
4644480a
JF
838 virtual CYNumber *Number(CYContext &context);
839 virtual CYString *String(CYContext &context);
840
652ec1ba
JF
841 virtual void Output(CYOutput &out, CYFlags flags) const;
842 virtual void PropertyName(CYOutput &out) const;
cf7d4c69
JF
843};
844
63cd45c9 845struct CYRegEx :
3b52fd1a 846 CYTrivial
63cd45c9
JF
847{
848 const char *value_;
c8a2a786 849 size_t size_;
63cd45c9 850
c8a2a786
JF
851 CYRegEx(const char *value, size_t size) :
852 value_(value),
853 size_(size)
63cd45c9
JF
854 {
855 }
856
857 const char *Value() const {
858 return value_;
859 }
860
861 virtual void Output(CYOutput &out, CYFlags flags) const;
862};
863
cf7d4c69 864struct CYNull :
3b52fd1a 865 CYTrivial
cf7d4c69 866{
4644480a
JF
867 virtual CYNumber *Number(CYContext &context);
868 virtual CYString *String(CYContext &context);
869
652ec1ba 870 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
871};
872
873struct CYThis :
478d4ed0 874 CYMagic
cf7d4c69 875{
3b52fd1a 876 virtual CYExpression *Replace(CYContext &context);
652ec1ba 877 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
878};
879
880struct CYBoolean :
3b52fd1a 881 CYTrivial
cf7d4c69 882{
5999c315 883 virtual bool Value() const = 0;
652ec1ba 884 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
885};
886
887struct CYFalse :
cf7d4c69
JF
888 CYBoolean
889{
11c1cc16
JF
890 virtual bool Value() const {
891 return false;
892 }
4644480a
JF
893
894 virtual CYNumber *Number(CYContext &context);
895 virtual CYString *String(CYContext &context);
cf7d4c69
JF
896};
897
898struct CYTrue :
cf7d4c69
JF
899 CYBoolean
900{
11c1cc16
JF
901 virtual bool Value() const {
902 return true;
903 }
4644480a
JF
904
905 virtual CYNumber *Number(CYContext &context);
906 virtual CYString *String(CYContext &context);
cf7d4c69
JF
907};
908
909struct CYVariable :
910 CYExpression
911{
912 CYIdentifier *name_;
913
914 CYVariable(CYIdentifier *name) :
915 name_(name)
916 {
917 }
5999c315 918
2eb8215d
JF
919 CYVariable(const char *name) :
920 name_(new($pool) CYIdentifier(name))
921 {
922 }
923
d35a3b07 924 CYPrecedence(0)
fb98ac0c 925 CYRightHand(false)
d35a3b07 926
3b52fd1a 927 virtual CYExpression *Replace(CYContext &context);
652ec1ba 928 virtual void Output(CYOutput &out, CYFlags flags) const;
0afc9ba3
JF
929
930 virtual CYFunctionParameter *Parameter() const;
cf7d4c69
JF
931};
932
933struct CYPrefix :
63b4c5a8
JF
934 CYExpression
935{
936 CYExpression *rhs_;
937
cf7d4c69 938 CYPrefix(CYExpression *rhs) :
63b4c5a8
JF
939 rhs_(rhs)
940 {
941 }
5999c315 942
b09da87b 943 virtual bool Alphabetic() const = 0;
5999c315
JF
944 virtual const char *Operator() const = 0;
945
3b52fd1a
JF
946 CYPrecedence(4)
947
948 virtual CYExpression *Replace(CYContext &context);
652ec1ba 949 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
950};
951
cf7d4c69 952struct CYInfix :
63b4c5a8
JF
953 CYExpression
954{
955 CYExpression *lhs_;
956 CYExpression *rhs_;
957
cf7d4c69 958 CYInfix(CYExpression *lhs, CYExpression *rhs) :
63b4c5a8
JF
959 lhs_(lhs),
960 rhs_(rhs)
961 {
962 }
5999c315 963
0ff9f149
JF
964 void SetLeft(CYExpression *lhs) {
965 lhs_ = lhs;
966 }
967
b09da87b 968 virtual bool Alphabetic() const = 0;
5999c315
JF
969 virtual const char *Operator() const = 0;
970
3b52fd1a 971 virtual CYExpression *Replace(CYContext &context);
652ec1ba 972 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
973};
974
cf7d4c69 975struct CYPostfix :
63b4c5a8
JF
976 CYExpression
977{
978 CYExpression *lhs_;
979
cf7d4c69 980 CYPostfix(CYExpression *lhs) :
63b4c5a8
JF
981 lhs_(lhs)
982 {
983 }
5999c315
JF
984
985 virtual const char *Operator() const = 0;
986
3b52fd1a
JF
987 CYPrecedence(3)
988
989 virtual CYExpression *Replace(CYContext &context);
652ec1ba 990 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
991};
992
cf7d4c69 993struct CYAssignment :
d35a3b07 994 CYExpression
cf7d4c69 995{
d35a3b07
JF
996 CYExpression *lhs_;
997 CYExpression *rhs_;
998
cf7d4c69 999 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
d35a3b07
JF
1000 lhs_(lhs),
1001 rhs_(rhs)
cf7d4c69
JF
1002 {
1003 }
5999c315 1004
0ff9f149
JF
1005 void SetLeft(CYExpression *lhs) {
1006 lhs_ = lhs;
1007 }
1008
5999c315 1009 virtual const char *Operator() const = 0;
d35a3b07 1010
4de0686f
JF
1011 CYPrecedence(16)
1012
3b52fd1a 1013 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1014 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1015};
1016
62014ea9 1017struct CYArgument :
96a7e5c2
JF
1018 CYNext<CYArgument>,
1019 CYThing
62014ea9 1020{
cf7d4c69
JF
1021 CYWord *name_;
1022 CYExpression *value_;
cf7d4c69 1023
3b52fd1a
JF
1024 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1025 CYNext<CYArgument>(next),
1026 name_(NULL),
1027 value_(value)
1028 {
1029 }
1030
cf7d4c69 1031 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
62014ea9 1032 CYNext<CYArgument>(next),
cf7d4c69 1033 name_(name),
62014ea9 1034 value_(value)
cf7d4c69
JF
1035 {
1036 }
5999c315 1037
5192746c 1038 CYArgument *Replace(CYContext &context);
652ec1ba 1039 void Output(CYOutput &out) const;
cf7d4c69
JF
1040};
1041
5999c315
JF
1042struct CYClause :
1043 CYThing,
1044 CYNext<CYClause>
1045{
cf7d4c69 1046 CYExpression *case_;
b0385401 1047 CYStatement *code_;
cf7d4c69 1048
b0385401 1049 CYClause(CYExpression *_case, CYStatement *code) :
cf7d4c69 1050 case_(_case),
b0385401 1051 code_(code)
cf7d4c69
JF
1052 {
1053 }
1054
fa389b0f 1055 void Replace(CYContext &context);
652ec1ba 1056 virtual void Output(CYOutput &out) const;
cf7d4c69
JF
1057};
1058
62014ea9 1059struct CYElement :
96a7e5c2 1060 CYThing
fc8fc33d
JF
1061{
1062 virtual bool Elision() const = 0;
1063
1064 virtual void Replace(CYContext &context) = 0;
1065};
1066
1067struct CYElementValue :
1068 CYNext<CYElement>,
1069 CYElement
62014ea9 1070{
cf7d4c69 1071 CYExpression *value_;
cf7d4c69 1072
fc8fc33d 1073 CYElementValue(CYExpression *value, CYElement *next) :
62014ea9
JF
1074 CYNext<CYElement>(next),
1075 value_(value)
cf7d4c69
JF
1076 {
1077 }
5999c315 1078
fc8fc33d
JF
1079 virtual bool Elision() const {
1080 return value_ == NULL;
1081 }
1082
1083 virtual void Replace(CYContext &context);
1084 virtual void Output(CYOutput &out) const;
1085};
1086
1087struct CYElementSpread :
1088 CYElement
1089{
1090 CYExpression *value_;
1091
1092 CYElementSpread(CYExpression *value) :
1093 value_(value)
1094 {
1095 }
1096
1097 virtual bool Elision() const {
1098 return false;
1099 }
1100
1101 virtual void Replace(CYContext &context);
1102 virtual void Output(CYOutput &out) const;
5befe15e
JF
1103};
1104
1105struct CYArray :
1106 CYLiteral
1107{
1108 CYElement *elements_;
1109
3b52fd1a 1110 CYArray(CYElement *elements = NULL) :
5befe15e
JF
1111 elements_(elements)
1112 {
1113 }
1114
3b52fd1a 1115 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1116 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1117};
1118
550ee46a
JF
1119struct CYProperty :
1120 CYNext<CYProperty>,
1121 CYThing
1122{
1123 CYPropertyName *name_;
1124 CYExpression *value_;
1125
1126 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1127 CYNext<CYProperty>(next),
1128 name_(name),
1129 value_(value)
1130 {
1131 }
1132
1133 void Replace(CYContext &context);
1134 virtual void Output(CYOutput &out) const;
1135};
1136
cf7d4c69 1137struct CYDeclaration :
a7d8b413 1138 CYForInInitializer
cf7d4c69
JF
1139{
1140 CYIdentifier *identifier_;
1141 CYExpression *initialiser_;
1142
550ee46a 1143 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
cf7d4c69
JF
1144 identifier_(identifier),
1145 initialiser_(initialiser)
1146 {
1147 }
5999c315 1148
652ec1ba 1149 virtual void ForIn(CYOutput &out, CYFlags flags) const;
ad3b38bb 1150 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
3b52fd1a 1151
029bc65b 1152 virtual CYExpression *Replace(CYContext &context);
15b88a33 1153
029bc65b 1154 virtual CYAssignment *Assignment(CYContext &context);
15b88a33 1155 CYVariable *Variable(CYContext &context);
75b0a457 1156
652ec1ba 1157 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1158};
1159
1160struct CYDeclarations :
cac61857 1161 CYNext<CYDeclarations>,
15b88a33 1162 CYThing
cf7d4c69
JF
1163{
1164 CYDeclaration *declaration_;
cf7d4c69 1165
cacd1a88 1166 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
cac61857
JF
1167 CYNext<CYDeclarations>(next),
1168 declaration_(declaration)
1169 {
1170 }
1171
15b88a33 1172 void Replace(CYContext &context);
96a7e5c2 1173
b0385401 1174 CYExpression *Expression(CYContext &context);
550ee46a 1175 CYProperty *Property(CYContext &context);
15b88a33
JF
1176 CYArgument *Argument(CYContext &context);
1177 CYFunctionParameter *Parameter(CYContext &context);
3b52fd1a 1178
96a7e5c2 1179 virtual void Output(CYOutput &out) const;
652ec1ba 1180 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1181};
1182
15b88a33 1183struct CYForDeclarations :
a7d8b413 1184 CYForInitializer
15b88a33
JF
1185{
1186 CYDeclarations *declarations_;
1187
1188 CYForDeclarations(CYDeclarations *declarations) :
1189 declarations_(declarations)
1190 {
1191 }
1192
b0385401 1193 virtual CYExpression *Replace(CYContext &context);
15b88a33
JF
1194 virtual void Output(CYOutput &out, CYFlags flags) const;
1195};
1196
cac61857
JF
1197struct CYVar :
1198 CYStatement
1199{
1200 CYDeclarations *declarations_;
1201
1202 CYVar(CYDeclarations *declarations) :
1203 declarations_(declarations)
1204 {
1205 }
1206
efd689d8
JF
1207 CYCompact(None)
1208
3b52fd1a 1209 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1210 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1211};
1212
c8a0500b 1213struct CYLetStatement :
cac61857
JF
1214 CYStatement
1215{
1216 CYDeclarations *declarations_;
15b88a33 1217 CYStatement *code_;
cac61857 1218
c8a0500b 1219 CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
cac61857 1220 declarations_(declarations),
15b88a33 1221 code_(code)
cf7d4c69
JF
1222 {
1223 }
5999c315 1224
efd689d8
JF
1225 CYCompact(Long)
1226
3b52fd1a 1227 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1228 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1229};
1230
cf7d4c69
JF
1231struct CYFor :
1232 CYStatement
1233{
a7d8b413 1234 CYForInitializer *initialiser_;
cf7d4c69
JF
1235 CYExpression *test_;
1236 CYExpression *increment_;
1237 CYStatement *code_;
1238
a7d8b413 1239 CYFor(CYForInitializer *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
cf7d4c69
JF
1240 initialiser_(initialiser),
1241 test_(test),
1242 increment_(increment),
1243 code_(code)
1244 {
1245 }
5999c315 1246
efd689d8
JF
1247 CYCompact(Long)
1248
3b52fd1a 1249 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1250 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1251};
1252
1253struct CYForIn :
1254 CYStatement
1255{
a7d8b413 1256 CYForInInitializer *initialiser_;
cf7d4c69
JF
1257 CYExpression *set_;
1258 CYStatement *code_;
1259
a7d8b413 1260 CYForIn(CYForInInitializer *initialiser, CYExpression *set, CYStatement *code) :
cf7d4c69
JF
1261 initialiser_(initialiser),
1262 set_(set),
1263 code_(code)
1264 {
1265 }
5999c315 1266
efd689d8
JF
1267 CYCompact(Long)
1268
3b52fd1a 1269 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1270 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1271};
1272
d5618df7 1273struct CYForOf :
75b0a457
JF
1274 CYStatement
1275{
a7d8b413 1276 CYForInInitializer *initialiser_;
75b0a457
JF
1277 CYExpression *set_;
1278 CYStatement *code_;
1279
a7d8b413 1280 CYForOf(CYForInInitializer *initialiser, CYExpression *set, CYStatement *code) :
75b0a457
JF
1281 initialiser_(initialiser),
1282 set_(set),
1283 code_(code)
1284 {
1285 }
1286
efd689d8
JF
1287 CYCompact(Long)
1288
3b52fd1a 1289 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1290 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
1291};
1292
693d501b
JF
1293struct CYObject :
1294 CYLiteral
1295{
3b52fd1a 1296 CYProperty *properties_;
693d501b 1297
ab2aa221 1298 CYObject(CYProperty *properties = NULL) :
3b52fd1a 1299 properties_(properties)
693d501b
JF
1300 {
1301 }
1302
3b52fd1a 1303 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1304 void Output(CYOutput &out, CYFlags flags) const;
693d501b
JF
1305};
1306
cf7d4c69
JF
1307struct CYMember :
1308 CYExpression
1309{
1310 CYExpression *object_;
1311 CYExpression *property_;
1312
1313 CYMember(CYExpression *object, CYExpression *property) :
1314 object_(object),
1315 property_(property)
1316 {
1317 }
5999c315 1318
9b5527f0
JF
1319 void SetLeft(CYExpression *object) {
1320 object_ = object;
1321 }
1322};
1323
1324struct CYDirectMember :
1325 CYMember
1326{
1327 CYDirectMember(CYExpression *object, CYExpression *property) :
1328 CYMember(object, property)
1329 {
1330 }
1331
1332 CYPrecedence(1)
fb98ac0c 1333 CYRightHand(false)
9b5527f0 1334
3b52fd1a 1335 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1336 virtual void Output(CYOutput &out, CYFlags flags) const;
9b5527f0
JF
1337};
1338
1339struct CYIndirectMember :
1340 CYMember
1341{
1342 CYIndirectMember(CYExpression *object, CYExpression *property) :
1343 CYMember(object, property)
1344 {
1345 }
1346
d35a3b07 1347 CYPrecedence(1)
fb98ac0c 1348 CYRightHand(false)
d35a3b07 1349
3b52fd1a 1350 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1351 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1352};
1353
2eb8215d
JF
1354namespace cy {
1355namespace Syntax {
1356
1357struct New :
cf7d4c69
JF
1358 CYExpression
1359{
1360 CYExpression *constructor_;
1361 CYArgument *arguments_;
1362
2eb8215d 1363 New(CYExpression *constructor, CYArgument *arguments) :
cf7d4c69
JF
1364 constructor_(constructor),
1365 arguments_(arguments)
1366 {
1367 }
5999c315 1368
9a39f705 1369 virtual int Precedence() const {
fb98ac0c
JF
1370 return arguments_ == NULL ? 2 : 1;
1371 }
1372
1373 CYRightHand(false)
d35a3b07 1374
3b52fd1a 1375 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1376 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1377
1378 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
cf7d4c69
JF
1379};
1380
2eb8215d
JF
1381} }
1382
cf7d4c69
JF
1383struct CYCall :
1384 CYExpression
1385{
1386 CYExpression *function_;
1387 CYArgument *arguments_;
1388
3b52fd1a 1389 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
cf7d4c69
JF
1390 function_(function),
1391 arguments_(arguments)
1392 {
1393 }
5999c315 1394
fb98ac0c
JF
1395 CYPrecedence(1)
1396 CYRightHand(false)
d35a3b07 1397
3b52fd1a 1398 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1399 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1400
1401 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1402};
1403
1404struct CYRubyProc;
1405
1406struct CYRubyBlock :
1407 CYExpression
1408{
1409 CYExpression *call_;
1410 CYRubyProc *proc_;
1411
1412 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1413 call_(call),
1414 proc_(proc)
1415 {
1416 }
1417
1418 CYPrecedence(1)
1419 CYRightHand(false)
1420
1421 virtual CYExpression *Replace(CYContext &context);
1422 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1423};
1424
1425struct CYIf :
1426 CYStatement
1427{
1428 CYExpression *test_;
1429 CYStatement *true_;
1430 CYStatement *false_;
1431
3b52fd1a 1432 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
cf7d4c69
JF
1433 test_(test),
1434 true_(_true),
1435 false_(_false)
1436 {
1437 }
5999c315 1438
efd689d8
JF
1439 CYCompact(Long)
1440
3b52fd1a 1441 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1442 virtual void Output(CYOutput &out, CYFlags flags) const;
12e37ba3
JF
1443
1444 virtual CYStatement *Return();
cf7d4c69
JF
1445};
1446
1447struct CYDoWhile :
1448 CYStatement
1449{
1450 CYExpression *test_;
1451 CYStatement *code_;
1452
1453 CYDoWhile(CYExpression *test, CYStatement *code) :
1454 test_(test),
1455 code_(code)
1456 {
1457 }
5999c315 1458
efd689d8
JF
1459 CYCompact(None)
1460
3b52fd1a 1461 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1462 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1463};
1464
1465struct CYWhile :
1466 CYStatement
1467{
1468 CYExpression *test_;
1469 CYStatement *code_;
1470
1471 CYWhile(CYExpression *test, CYStatement *code) :
1472 test_(test),
1473 code_(code)
1474 {
1475 }
5999c315 1476
efd689d8
JF
1477 CYCompact(Long)
1478
3b52fd1a 1479 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1480 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1481};
1482
6c093cce 1483// XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
a846a8cd 1484struct CYFunction {
cf7d4c69 1485 CYIdentifier *name_;
b09da87b 1486 CYFunctionParameter *parameters_;
b0385401 1487 CYStatement *code_;
a0be43fc 1488
ab2aa221 1489 CYNonLocal *nonlocal_;
12e37ba3 1490 bool implicit_;
a0be43fc 1491 CYThisScope this_;
cf7d4c69 1492
b0385401 1493 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
cf7d4c69
JF
1494 name_(name),
1495 parameters_(parameters),
b0385401 1496 code_(code),
12e37ba3
JF
1497 nonlocal_(NULL),
1498 implicit_(false)
cf7d4c69
JF
1499 {
1500 }
5999c315 1501
14ec9e00
JF
1502 void Inject(CYContext &context);
1503 virtual void Replace_(CYContext &context, bool outer);
fb98ac0c
JF
1504 virtual void Output(CYOutput &out, CYFlags flags) const;
1505};
1506
6c093cce 1507// XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
fb98ac0c
JF
1508struct CYFunctionExpression :
1509 CYFunction,
1510 CYExpression
1511{
b0385401
JF
1512 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
1513 CYFunction(name, parameters, code)
fb98ac0c
JF
1514 {
1515 }
1516
a0be43fc
JF
1517 CYPrecedence(0)
1518 CYRightHand(false)
1519
1520 virtual CYExpression *Replace(CYContext &context);
1521 virtual void Output(CYOutput &out, CYFlags flags) const;
1522};
1523
1524// XXX: this should derive from CYAnonymousFunction
1525struct CYFatArrow :
1526 CYFunction,
1527 CYExpression
1528{
b0385401
JF
1529 CYFatArrow(CYFunctionParameter *parameters, CYStatement *code) :
1530 CYFunction(NULL, parameters, code)
a0be43fc
JF
1531 {
1532 }
1533
d35a3b07 1534 CYPrecedence(0)
fb98ac0c 1535 CYRightHand(false)
d35a3b07 1536
3b52fd1a 1537 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1538 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1539};
1540
6c093cce
JF
1541// XXX: this should derive from CYAnonymousFunctionExpression
1542struct CYRubyProc :
1543 CYFunctionExpression
1544{
b0385401
JF
1545 CYRubyProc(CYFunctionParameter *parameters, CYStatement *code) :
1546 CYFunctionExpression(NULL, parameters, code)
6c093cce
JF
1547 {
1548 }
1549
1550 virtual CYExpression *Replace(CYContext &context);
1551 virtual void Output(CYOutput &out, CYFlags flags) const;
1552};
1553
1554// XXX: this should derive from CYNamedFunction
fb98ac0c
JF
1555struct CYFunctionStatement :
1556 CYFunction,
b10bd496 1557 CYStatement
cf7d4c69 1558{
b0385401
JF
1559 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
1560 CYFunction(name, parameters, code)
cf7d4c69
JF
1561 {
1562 }
5999c315 1563
efd689d8
JF
1564 CYCompact(None)
1565
3b52fd1a 1566 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1567 virtual void Output(CYOutput &out, CYFlags flags) const;
5999c315
JF
1568};
1569
1570struct CYExpress :
1571 CYStatement
1572{
1573 CYExpression *expression_;
1574
1575 CYExpress(CYExpression *expression) :
1576 expression_(expression)
1577 {
fd5cdf97 1578 if (expression_ == NULL)
029bc65b 1579 throw;
5999c315
JF
1580 }
1581
efd689d8
JF
1582 CYCompact(None)
1583
3b52fd1a 1584 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1585 virtual void Output(CYOutput &out, CYFlags flags) const;
12e37ba3
JF
1586
1587 virtual CYStatement *Return();
cf7d4c69
JF
1588};
1589
1590struct CYContinue :
1591 CYStatement
1592{
1593 CYIdentifier *label_;
1594
1595 CYContinue(CYIdentifier *label) :
1596 label_(label)
1597 {
1598 }
5999c315 1599
efd689d8
JF
1600 CYCompact(Short)
1601
3b52fd1a 1602 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1603 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1604};
1605
1606struct CYBreak :
1607 CYStatement
1608{
1609 CYIdentifier *label_;
1610
1611 CYBreak(CYIdentifier *label) :
1612 label_(label)
1613 {
1614 }
5999c315 1615
efd689d8
JF
1616 CYCompact(Short)
1617
3b52fd1a 1618 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1619 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1620};
1621
1622struct CYReturn :
1623 CYStatement
1624{
1625 CYExpression *value_;
1626
1627 CYReturn(CYExpression *value) :
1628 value_(value)
1629 {
1630 }
5999c315 1631
efd689d8
JF
1632 CYCompact(None)
1633
3b52fd1a 1634 virtual CYStatement *Replace(CYContext &context);
9d2b125d
JF
1635 virtual void Output(CYOutput &out, CYFlags flags) const;
1636};
1637
1638struct CYYieldGenerator :
1639 CYExpression
1640{
1641 CYExpression *value_;
1642
1643 CYYieldGenerator(CYExpression *value) :
1644 value_(value)
1645 {
1646 }
1647
1648 CYPrecedence(0)
1649
1650 virtual CYExpression *Replace(CYContext &context);
1651 virtual void Output(CYOutput &out, CYFlags flags) const;
1652};
1653
1654struct CYYieldValue :
1655 CYExpression
1656{
1657 CYExpression *value_;
1658
1659 CYYieldValue(CYExpression *value) :
1660 value_(value)
1661 {
1662 }
1663
1664 CYPrecedence(0)
1665
1666 virtual CYExpression *Replace(CYContext &context);
fb98ac0c 1667 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1668};
1669
1670struct CYEmpty :
1671 CYStatement
1672{
efd689d8
JF
1673 CYCompact(Short)
1674
3b52fd1a 1675 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1676 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1677};
1678
96a7e5c2
JF
1679struct CYFinally :
1680 CYThing
1681{
b0385401 1682 CYStatement *code_;
b10bd496 1683
b0385401
JF
1684 CYFinally(CYStatement *code) :
1685 code_(code)
b10bd496
JF
1686 {
1687 }
1688
3b52fd1a 1689 void Replace(CYContext &context);
b10bd496
JF
1690 virtual void Output(CYOutput &out) const;
1691};
1692
3fe283c5
JF
1693struct CYTypeSpecifier :
1694 CYThing
1695{
1696 virtual CYExpression *Replace(CYContext &context) = 0;
1697};
1698
03db6a67
JF
1699struct CYTypeError :
1700 CYTypeSpecifier
1701{
1702 CYTypeError() {
1703 }
1704
1705 virtual CYExpression *Replace(CYContext &context);
1706 virtual void Output(CYOutput &out) const;
1707};
1708
3fe283c5
JF
1709struct CYTypeVoid :
1710 CYTypeSpecifier
1711{
1712 CYTypeVoid() {
1713 }
1714
1715 virtual CYExpression *Replace(CYContext &context);
1716 virtual void Output(CYOutput &out) const;
1717};
1718
1719struct CYTypeVariable :
1720 CYTypeSpecifier
1721{
1722 CYIdentifier *name_;
1723
1724 CYTypeVariable(CYIdentifier *name) :
1725 name_(name)
1726 {
1727 }
1728
1729 CYTypeVariable(const char *name) :
1730 name_(new($pool) CYIdentifier(name))
1731 {
1732 }
1733
1734 virtual CYExpression *Replace(CYContext &context);
1735 virtual void Output(CYOutput &out) const;
1736};
1737
1738struct CYTypeUnsigned :
1739 CYTypeSpecifier
1740{
1741 CYTypeSpecifier *specifier_;
1742
1743 CYTypeUnsigned(CYTypeSpecifier *specifier) :
1744 specifier_(specifier)
1745 {
1746 }
1747
1748 virtual CYExpression *Replace(CYContext &context);
1749 virtual void Output(CYOutput &out) const;
1750};
1751
1752struct CYTypeSigned :
1753 CYTypeSpecifier
1754{
1755 CYTypeSpecifier *specifier_;
1756
1757 CYTypeSigned(CYTypeSpecifier *specifier) :
1758 specifier_(specifier)
1759 {
1760 }
1761
1762 virtual CYExpression *Replace(CYContext &context);
1763 virtual void Output(CYOutput &out) const;
1764};
1765
1766struct CYTypeLong :
1767 CYTypeSpecifier
1768{
1769 CYTypeSpecifier *specifier_;
1770
1771 CYTypeLong(CYTypeSpecifier *specifier) :
1772 specifier_(specifier)
1773 {
1774 }
1775
1776 virtual CYExpression *Replace(CYContext &context);
1777 virtual void Output(CYOutput &out) const;
1778};
1779
1780struct CYTypeShort :
1781 CYTypeSpecifier
1782{
1783 CYTypeSpecifier *specifier_;
1784
1785 CYTypeShort(CYTypeSpecifier *specifier) :
1786 specifier_(specifier)
1787 {
1788 }
1789
1790 virtual CYExpression *Replace(CYContext &context);
1791 virtual void Output(CYOutput &out) const;
1792};
1793
00b4cb83
JF
1794struct CYTypeFunctionWith;
1795
690cf1a8
JF
1796struct CYTypeModifier :
1797 CYNext<CYTypeModifier>
1798{
1799 CYTypeModifier(CYTypeModifier *next) :
1800 CYNext<CYTypeModifier>(next)
1801 {
1802 }
1803
9a39f705
JF
1804 virtual int Precedence() const = 0;
1805
1806 virtual CYExpression *Replace_(CYContext &context, CYExpression *type) = 0;
1807 CYExpression *Replace(CYContext &context, CYExpression *type);
1808
1809 virtual void Output(CYOutput &out, CYIdentifier *identifier) const = 0;
1810 void Output(CYOutput &out, int precedence, CYIdentifier *identifier) const;
00b4cb83
JF
1811
1812 virtual CYTypeFunctionWith *Function() { return NULL; }
690cf1a8
JF
1813};
1814
1815struct CYTypeArrayOf :
1816 CYTypeModifier
1817{
1818 CYExpression *size_;
1819
1820 CYTypeArrayOf(CYExpression *size, CYTypeModifier *next = NULL) :
1821 CYTypeModifier(next),
1822 size_(size)
1823 {
1824 }
1825
9a39f705 1826 CYPrecedence(1)
690cf1a8 1827
9a39f705
JF
1828 virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
1829 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
690cf1a8
JF
1830};
1831
1832struct CYTypeConstant :
1833 CYTypeModifier
1834{
1835 CYTypeConstant(CYTypeModifier *next = NULL) :
1836 CYTypeModifier(next)
1837 {
1838 }
1839
9a39f705 1840 CYPrecedence(0)
690cf1a8 1841
9a39f705
JF
1842 virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
1843 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
690cf1a8
JF
1844};
1845
1846struct CYTypePointerTo :
1847 CYTypeModifier
1848{
1849 CYTypePointerTo(CYTypeModifier *next = NULL) :
1850 CYTypeModifier(next)
1851 {
1852 }
1853
9a39f705 1854 CYPrecedence(0)
690cf1a8 1855
9a39f705
JF
1856 virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
1857 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
690cf1a8
JF
1858};
1859
9a39f705 1860struct CYTypeVolatile :
690cf1a8
JF
1861 CYTypeModifier
1862{
9a39f705
JF
1863 CYTypeVolatile(CYTypeModifier *next = NULL) :
1864 CYTypeModifier(next)
690cf1a8
JF
1865 {
1866 }
1867
9a39f705 1868 CYPrecedence(0)
690cf1a8 1869
9a39f705
JF
1870 virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
1871 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
690cf1a8
JF
1872};
1873
1874struct CYTypedIdentifier :
60097023
JF
1875 CYNext<CYTypedIdentifier>,
1876 CYThing
690cf1a8 1877{
00b4cb83 1878 CYLocation location_;
690cf1a8 1879 CYIdentifier *identifier_;
3fe283c5 1880 CYTypeSpecifier *specifier_;
9a39f705 1881 CYTypeModifier *modifier_;
690cf1a8 1882
00b4cb83
JF
1883 CYTypedIdentifier(const CYLocation &location, CYIdentifier *identifier = NULL) :
1884 location_(location),
690cf1a8 1885 identifier_(identifier),
3fe283c5 1886 specifier_(NULL),
9a39f705 1887 modifier_(NULL)
690cf1a8
JF
1888 {
1889 }
60097023 1890
3fe283c5 1891 CYTypedIdentifier(CYTypeSpecifier *specifier, CYTypeModifier *modifier = NULL) :
9a39f705 1892 identifier_(NULL),
3fe283c5 1893 specifier_(specifier),
9a39f705
JF
1894 modifier_(modifier)
1895 {
1896 }
1897
1898 inline CYTypedIdentifier *Modify(CYTypeModifier *modifier) {
1899 CYSetLast(modifier_) = modifier;
1900 return this;
1901 }
1902
1903 virtual CYExpression *Replace(CYContext &context);
60097023 1904 virtual void Output(CYOutput &out) const;
00b4cb83
JF
1905
1906 CYTypeFunctionWith *Function();
690cf1a8
JF
1907};
1908
9a39f705
JF
1909struct CYEncodedType :
1910 CYExpression
1911{
1912 CYTypedIdentifier *typed_;
1913
1914 CYEncodedType(CYTypedIdentifier *typed) :
1915 typed_(typed)
1916 {
1917 }
1918
1919 CYPrecedence(1)
1920
1921 virtual CYExpression *Replace(CYContext &context);
1922 virtual void Output(CYOutput &out, CYFlags flags) const;
1923};
1924
690cf1a8 1925struct CYTypedParameter :
9a39f705
JF
1926 CYNext<CYTypedParameter>,
1927 CYThing
690cf1a8
JF
1928{
1929 CYTypedIdentifier *typed_;
1930
1931 CYTypedParameter(CYTypedIdentifier *typed, CYTypedParameter *next) :
1932 CYNext<CYTypedParameter>(next),
1933 typed_(typed)
1934 {
1935 }
1936
663c538f 1937 CYArgument *Argument(CYContext &context);
690cf1a8
JF
1938 CYFunctionParameter *Parameters(CYContext &context);
1939 CYExpression *TypeSignature(CYContext &context, CYExpression *prefix);
9a39f705
JF
1940
1941 virtual void Output(CYOutput &out) const;
690cf1a8
JF
1942};
1943
1944struct CYLambda :
1945 CYExpression
1946{
9a39f705 1947 CYTypedIdentifier *typed_;
690cf1a8 1948 CYTypedParameter *parameters_;
b0385401 1949 CYStatement *code_;
690cf1a8 1950
b0385401 1951 CYLambda(CYTypedIdentifier *typed, CYTypedParameter *parameters, CYStatement *code) :
9a39f705 1952 typed_(typed),
690cf1a8 1953 parameters_(parameters),
b0385401 1954 code_(code)
690cf1a8
JF
1955 {
1956 }
1957
1958 CYPrecedence(1)
1959
1960 virtual CYExpression *Replace(CYContext &context);
1961 virtual void Output(CYOutput &out, CYFlags flags) const;
1962};
1963
7b750785
JF
1964struct CYModule :
1965 CYNext<CYModule>,
1966 CYThing
1967{
1968 CYWord *part_;
1969
1970 CYModule(CYWord *part, CYModule *next = NULL) :
1971 CYNext<CYModule>(next),
1972 part_(part)
1973 {
1974 }
1975
1976 CYString *Replace(CYContext &context, const char *separator) const;
1977 void Output(CYOutput &out) const;
1978};
1979
1980struct CYImport :
1981 CYStatement
1982{
1983 CYModule *module_;
1984
1985 CYImport(CYModule *module) :
1986 module_(module)
1987 {
1988 }
1989
efd689d8
JF
1990 CYCompact(None)
1991
7b750785
JF
1992 virtual CYStatement *Replace(CYContext &context);
1993 virtual void Output(CYOutput &out, CYFlags flags) const;
1994};
1995
c5587ed7
JF
1996struct CYExternal :
1997 CYStatement
1998{
1999 CYString *abi_;
2000 CYTypedIdentifier *typed_;
2001
2002 CYExternal(CYString *abi, CYTypedIdentifier *typed) :
2003 abi_(abi),
2004 typed_(typed)
2005 {
2006 }
2007
efd689d8
JF
2008 CYCompact(None)
2009
c5587ed7
JF
2010 virtual CYStatement *Replace(CYContext &context);
2011 virtual void Output(CYOutput &out, CYFlags flags) const;
2012};
2013
60097023
JF
2014struct CYTypeDefinition :
2015 CYStatement
2016{
2017 CYTypedIdentifier *typed_;
2018
2019 CYTypeDefinition(CYTypedIdentifier *typed) :
2020 typed_(typed)
2021 {
2022 }
2023
efd689d8
JF
2024 CYCompact(None)
2025
60097023
JF
2026 virtual CYStatement *Replace(CYContext &context);
2027 virtual void Output(CYOutput &out, CYFlags flags) const;
2028};
2029
3fe16be7
JF
2030struct CYTypeBlockWith :
2031 CYTypeModifier
2032{
2033 CYTypedParameter *parameters_;
2034
2035 CYTypeBlockWith(CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
2036 CYTypeModifier(next),
2037 parameters_(parameters)
2038 {
2039 }
2040
2041 CYPrecedence(0)
2042
2043 virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
2044 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
2045};
2046
663c538f
JF
2047struct CYTypeFunctionWith :
2048 CYTypeModifier
2049{
2050 CYTypedParameter *parameters_;
2051
2052 CYTypeFunctionWith(CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
2053 CYTypeModifier(next),
2054 parameters_(parameters)
2055 {
2056 }
2057
9a39f705 2058 CYPrecedence(1)
663c538f 2059
9a39f705
JF
2060 virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
2061 virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
00b4cb83
JF
2062
2063 virtual CYTypeFunctionWith *Function() { return this; }
663c538f
JF
2064};
2065
37954781
JF
2066namespace cy {
2067namespace Syntax {
2068
2069struct Catch :
2070 CYThing
2071{
2072 CYIdentifier *name_;
b0385401 2073 CYStatement *code_;
37954781 2074
b0385401 2075 Catch(CYIdentifier *name, CYStatement *code) :
37954781 2076 name_(name),
b0385401 2077 code_(code)
37954781
JF
2078 {
2079 }
2080
2081 void Replace(CYContext &context);
2082 virtual void Output(CYOutput &out) const;
2083};
2084
2085struct Try :
cf7d4c69
JF
2086 CYStatement
2087{
b0385401 2088 CYStatement *code_;
37954781 2089 Catch *catch_;
b10bd496 2090 CYFinally *finally_;
cf7d4c69 2091
b0385401
JF
2092 Try(CYStatement *code, Catch *_catch, CYFinally *finally) :
2093 code_(code),
cf7d4c69
JF
2094 catch_(_catch),
2095 finally_(finally)
2096 {
2097 }
5999c315 2098
efd689d8
JF
2099 CYCompact(Short)
2100
3b52fd1a 2101 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 2102 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
2103};
2104
37954781 2105struct Throw :
cf7d4c69
JF
2106 CYStatement
2107{
2108 CYExpression *value_;
2109
ab2aa221 2110 Throw(CYExpression *value = NULL) :
cf7d4c69
JF
2111 value_(value)
2112 {
2113 }
5999c315 2114
efd689d8
JF
2115 CYCompact(None)
2116
3b52fd1a 2117 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 2118 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
2119};
2120
37954781
JF
2121} }
2122
cf7d4c69
JF
2123struct CYWith :
2124 CYStatement
2125{
2126 CYExpression *scope_;
2127 CYStatement *code_;
2128
2129 CYWith(CYExpression *scope, CYStatement *code) :
2130 scope_(scope),
2131 code_(code)
2132 {
2133 }
5999c315 2134
efd689d8
JF
2135 CYCompact(Long)
2136
3b52fd1a 2137 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 2138 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
2139};
2140
2141struct CYSwitch :
2142 CYStatement
2143{
2144 CYExpression *value_;
2145 CYClause *clauses_;
2146
2147 CYSwitch(CYExpression *value, CYClause *clauses) :
2148 value_(value),
2149 clauses_(clauses)
2150 {
2151 }
5999c315 2152
efd689d8
JF
2153 CYCompact(Long)
2154
3b52fd1a 2155 virtual CYStatement *Replace(CYContext &context);
c8a0500b
JF
2156 virtual void Output(CYOutput &out, CYFlags flags) const;
2157};
2158
2159struct CYDebugger :
2160 CYStatement
2161{
2162 CYDebugger()
2163 {
2164 }
2165
efd689d8
JF
2166 CYCompact(None)
2167
c8a0500b 2168 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 2169 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
2170};
2171
2172struct CYCondition :
2173 CYExpression
2174{
2175 CYExpression *test_;
2176 CYExpression *true_;
2177 CYExpression *false_;
2178
2179 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
91a416e4 2180 test_(test),
cf7d4c69
JF
2181 true_(_true),
2182 false_(_false)
2183 {
2184 }
5999c315 2185
d35a3b07
JF
2186 CYPrecedence(15)
2187
3b52fd1a 2188 virtual CYExpression *Replace(CYContext &context);
652ec1ba 2189 virtual void Output(CYOutput &out, CYFlags flags) const;
5999c315
JF
2190};
2191
2192struct CYAddressOf :
2193 CYPrefix
2194{
2195 CYAddressOf(CYExpression *rhs) :
2196 CYPrefix(rhs)
2197 {
2198 }
2199
2200 virtual const char *Operator() const {
2201 return "&";
2202 }
2203
b09da87b 2204 CYAlphabetic(false)
d35a3b07 2205
3b52fd1a 2206 virtual CYExpression *Replace(CYContext &context);
5999c315
JF
2207};
2208
2209struct CYIndirect :
2210 CYPrefix
2211{
2212 CYIndirect(CYExpression *rhs) :
2213 CYPrefix(rhs)
2214 {
2215 }
2216
2217 virtual const char *Operator() const {
561ac418 2218 return "*";
5999c315
JF
2219 }
2220
b09da87b 2221 CYAlphabetic(false)
d35a3b07 2222
3b52fd1a 2223 virtual CYExpression *Replace(CYContext &context);
cf7d4c69
JF
2224};
2225
4644480a
JF
2226#define CYReplace \
2227 virtual CYExpression *Replace(CYContext &context);
2228
2229#define CYPostfix_(op, name, args...) \
cf7d4c69
JF
2230 struct CY ## name : \
2231 CYPostfix \
4644480a 2232 { args \
cf7d4c69
JF
2233 CY ## name(CYExpression *lhs) : \
2234 CYPostfix(lhs) \
2235 { \
2236 } \
5999c315
JF
2237 \
2238 virtual const char *Operator() const { \
2239 return op; \
2240 } \
cf7d4c69
JF
2241 };
2242
4644480a 2243#define CYPrefix_(alphabetic, op, name, args...) \
cf7d4c69
JF
2244 struct CY ## name : \
2245 CYPrefix \
4644480a 2246 { args \
cf7d4c69
JF
2247 CY ## name(CYExpression *rhs) : \
2248 CYPrefix(rhs) \
2249 { \
2250 } \
d35a3b07 2251 \
b09da87b 2252 CYAlphabetic(alphabetic) \
5999c315
JF
2253 \
2254 virtual const char *Operator() const { \
2255 return op; \
2256 } \
cf7d4c69
JF
2257 };
2258
4644480a 2259#define CYInfix_(alphabetic, precedence, op, name, args...) \
cf7d4c69
JF
2260 struct CY ## name : \
2261 CYInfix \
4644480a 2262 { args \
cf7d4c69
JF
2263 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
2264 CYInfix(lhs, rhs) \
2265 { \
2266 } \
d35a3b07 2267 \
b09da87b 2268 CYAlphabetic(alphabetic) \
d35a3b07 2269 CYPrecedence(precedence) \
5999c315
JF
2270 \
2271 virtual const char *Operator() const { \
2272 return op; \
2273 } \
cf7d4c69
JF
2274 };
2275
4644480a 2276#define CYAssignment_(op, name, args...) \
cf7d4c69
JF
2277 struct CY ## name ## Assign : \
2278 CYAssignment \
4644480a 2279 { args \
cf7d4c69
JF
2280 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
2281 CYAssignment(lhs, rhs) \
2282 { \
2283 } \
5999c315
JF
2284 \
2285 virtual const char *Operator() const { \
2286 return op; \
2287 } \
cf7d4c69
JF
2288 };
2289
2290CYPostfix_("++", PostIncrement)
2291CYPostfix_("--", PostDecrement)
2292
b09da87b
JF
2293CYPrefix_(true, "delete", Delete)
2294CYPrefix_(true, "void", Void)
2295CYPrefix_(true, "typeof", TypeOf)
2296CYPrefix_(false, "++", PreIncrement)
2297CYPrefix_(false, "--", PreDecrement)
c0bc320e 2298CYPrefix_(false, "+", Affirm)
b09da87b
JF
2299CYPrefix_(false, "-", Negate)
2300CYPrefix_(false, "~", BitwiseNot)
2301CYPrefix_(false, "!", LogicalNot)
2302
62f398e4 2303CYInfix_(false, 5, "*", Multiply, CYReplace)
b09da87b
JF
2304CYInfix_(false, 5, "/", Divide)
2305CYInfix_(false, 5, "%", Modulus)
4644480a 2306CYInfix_(false, 6, "+", Add, CYReplace)
b09da87b
JF
2307CYInfix_(false, 6, "-", Subtract)
2308CYInfix_(false, 7, "<<", ShiftLeft)
2309CYInfix_(false, 7, ">>", ShiftRightSigned)
2310CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
2311CYInfix_(false, 8, "<", Less)
2312CYInfix_(false, 8, ">", Greater)
2313CYInfix_(false, 8, "<=", LessOrEqual)
2314CYInfix_(false, 8, ">=", GreaterOrEqual)
2315CYInfix_(true, 8, "instanceof", InstanceOf)
2316CYInfix_(true, 8, "in", In)
2317CYInfix_(false, 9, "==", Equal)
2318CYInfix_(false, 9, "!=", NotEqual)
2319CYInfix_(false, 9, "===", Identical)
2320CYInfix_(false, 9, "!==", NotIdentical)
2321CYInfix_(false, 10, "&", BitwiseAnd)
2322CYInfix_(false, 11, "^", BitwiseXOr)
2323CYInfix_(false, 12, "|", BitwiseOr)
2324CYInfix_(false, 13, "&&", LogicalAnd)
2325CYInfix_(false, 14, "||", LogicalOr)
cf7d4c69
JF
2326
2327CYAssignment_("=", )
2328CYAssignment_("*=", Multiply)
2329CYAssignment_("/=", Divide)
2330CYAssignment_("%=", Modulus)
2331CYAssignment_("+=", Add)
2332CYAssignment_("-=", Subtract)
2333CYAssignment_("<<=", ShiftLeft)
2334CYAssignment_(">>=", ShiftRightSigned)
2335CYAssignment_(">>>=", ShiftRightUnsigned)
2336CYAssignment_("&=", BitwiseAnd)
2337CYAssignment_("^=", BitwiseXOr)
2338CYAssignment_("|=", BitwiseOr)
2339
c5fa2867 2340#endif/*CYCRIPT_PARSER_HPP*/