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