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