]> git.saurik.com Git - cycript.git/blame - Parser.hpp
Clean up dependencies now that they are tracked.
[cycript.git] / Parser.hpp
CommitLineData
b3378a02 1/* Cycript - Optimizing JavaScript Compiler/Runtime
c15969fd 2 * Copyright (C) 2009-2013 Jay Freeman (saurik)
b4aa79af
JF
3*/
4
c15969fd 5/* GNU General Public License, Version 3 {{{ */
b4aa79af 6/*
c15969fd
JF
7 * Cycript is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 3 of the License,
10 * or (at your option) any later version.
b4aa79af 11 *
c15969fd
JF
12 * Cycript is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
b4aa79af 16 *
c15969fd 17 * You should have received a copy of the GNU General Public License
b3378a02
JF
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
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"
5999c315 36#include "Pooling.hpp"
029bc65b
JF
37#include "Options.hpp"
38
01d0f64d 39struct CYContext;
924f67b2 40
5999c315 41struct CYThing {
7c6c5b0a
JF
42 virtual ~CYThing() {
43 }
44
652ec1ba 45 virtual void Output(struct CYOutput &out) const = 0;
5999c315
JF
46};
47
652ec1ba
JF
48struct CYOutput {
49 std::ostream &out_;
029bc65b 50 CYOptions &options_;
11c1cc16
JF
51 bool pretty_;
52 unsigned indent_;
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
029bc65b 63 CYOutput(std::ostream &out, CYOptions &options) :
11c1cc16 64 out_(out),
029bc65b 65 options_(options),
11c1cc16 66 pretty_(false),
96a7e5c2 67 indent_(0),
320ce753 68 right_(false),
96a7e5c2 69 mode_(NoMode)
652ec1ba
JF
70 {
71 }
72
96a7e5c2 73 void Check(char value);
1fdca2fa 74 void Terminate();
652ec1ba 75
96a7e5c2
JF
76 CYOutput &operator <<(char rhs);
77 CYOutput &operator <<(const char *rhs);
78
79 _finline CYOutput &operator <<(const CYThing *rhs) {
80 if (rhs != NULL)
81 rhs->Output(*this);
652ec1ba
JF
82 return *this;
83 }
84
85 _finline CYOutput &operator <<(const CYThing &rhs) {
86 rhs.Output(*this);
87 return *this;
88 }
89};
5999c315 90
e5bc40db 91struct CYPropertyName {
652ec1ba 92 virtual void PropertyName(CYOutput &out) const = 0;
7c6c5b0a
JF
93
94 virtual ~CYPropertyName() {
95 }
e5bc40db
JF
96};
97
3b52fd1a 98struct CYExpression;
ae65d594 99struct CYAssignment;
3b52fd1a
JF
100
101enum CYNeeded {
102 CYNever = -1,
103 CYSometimes = 0,
104 CYAlways = 1,
105};
106
107enum CYFlags {
108 CYNoFlags = 0,
109 CYNoBrace = (1 << 0),
110 CYNoFunction = (1 << 1),
111 CYNoIn = (1 << 2),
112 CYNoCall = (1 << 3),
113 CYNoRightHand = (1 << 4),
114 CYNoDangle = (1 << 5),
9561f209 115 CYNoInteger = (1 << 6),
3b52fd1a
JF
116 CYNoBF = (CYNoBrace | CYNoFunction),
117};
118
5a6d4d25
JF
119_finline CYFlags operator ~(CYFlags rhs) {
120 return static_cast<CYFlags>(~static_cast<unsigned>(rhs));
121}
122
123_finline CYFlags operator &(CYFlags lhs, CYFlags rhs) {
124 return static_cast<CYFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
125}
126
127_finline CYFlags operator |(CYFlags lhs, CYFlags rhs) {
128 return static_cast<CYFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
129}
130
131_finline CYFlags &operator |=(CYFlags &lhs, CYFlags rhs) {
132 return lhs = lhs | rhs;
133}
134
135_finline CYFlags CYLeft(CYFlags flags) {
136 return flags & ~(CYNoDangle | CYNoInteger);
137}
138
139_finline CYFlags CYRight(CYFlags flags) {
140 return flags & ~CYNoBF;
141}
142
143_finline CYFlags CYCenter(CYFlags flags) {
144 return CYLeft(CYRight(flags));
145}
146
3b52fd1a
JF
147struct CYStatement :
148 CYNext<CYStatement>
149{
7c6c5b0a
JF
150 virtual ~CYStatement() {
151 }
152
3b52fd1a
JF
153 void Single(CYOutput &out, CYFlags flags) const;
154 void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
155
3b52fd1a
JF
156 virtual CYStatement *Replace(CYContext &context) = 0;
157
158 private:
159 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
160};
161
162struct CYStatements {
163 CYStatement *first_;
164 CYStatement *last_;
165
166 CYStatements() :
167 first_(NULL),
168 last_(NULL)
169 {
170 }
171
172 operator CYStatement *() const {
173 return first_;
174 }
175
176 CYStatements &operator ->*(CYStatement *next) {
177 if (next != NULL)
178 if (first_ == NULL) {
179 first_ = next;
180 last_ = next;
181 } else for (;; last_ = last_->next_)
182 if (last_->next_ == NULL) {
183 last_->next_ = next;
184 last_ = next;
185 break;
186 }
187 return *this;
188 }
189};
190
e5bc40db 191struct CYClassName {
7c6c5b0a
JF
192 virtual ~CYClassName() {
193 }
194
3b52fd1a 195 virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
652ec1ba 196 virtual void ClassName(CYOutput &out, bool object) const = 0;
63b4c5a8
JF
197};
198
cf7d4c69 199struct CYWord :
e5bc40db
JF
200 CYThing,
201 CYPropertyName,
202 CYClassName
63b4c5a8 203{
cf7d4c69
JF
204 const char *word_;
205
206 CYWord(const char *word) :
207 word_(word)
208 {
209 }
210
029bc65b
JF
211 void Set(const char *value) {
212 word_ = value;
cf7d4c69
JF
213 }
214
029bc65b 215 virtual const char *Word() const;
652ec1ba 216 virtual void Output(CYOutput &out) const;
e5bc40db 217
3b52fd1a 218 virtual CYExpression *ClassName(CYContext &context, bool object);
652ec1ba
JF
219 virtual void ClassName(CYOutput &out, bool object) const;
220 virtual void PropertyName(CYOutput &out) const;
63b4c5a8
JF
221};
222
652ec1ba 223_finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
029bc65b
JF
224 lhs << &rhs << '=';
225 return lhs << rhs.Word();
652ec1ba
JF
226}
227
cf7d4c69 228struct CYIdentifier :
14ec9e00 229 CYNext<CYIdentifier>,
cf7d4c69 230 CYWord
63b4c5a8 231{
029bc65b 232 CYIdentifier *replace_;
6a981250 233 size_t offset_;
e013809d 234 size_t usage_;
029bc65b 235
5999c315 236 CYIdentifier(const char *word) :
029bc65b 237 CYWord(word),
6a981250 238 replace_(NULL),
e013809d
JF
239 offset_(0),
240 usage_(0)
5999c315 241 {
cf7d4c69 242 }
029bc65b
JF
243
244 virtual const char *Word() const;
245 CYIdentifier *Replace(CYContext &context);
63b4c5a8
JF
246};
247
320ce753
JF
248struct CYComment :
249 CYStatement
250{
251 const char *value_;
252
253 CYComment(const char *value) :
254 value_(value)
255 {
256 }
257
258 virtual CYStatement *Replace(CYContext &context);
259 virtual void Output(CYOutput &out, CYFlags flags) const;
260};
261
62014ea9 262struct CYLabel :
3b52fd1a 263 CYStatement
62014ea9 264{
9e562cfc 265 CYIdentifier *name_;
3b52fd1a 266 CYStatement *statement_;
cf7d4c69 267
3b52fd1a
JF
268 CYLabel(CYIdentifier *name, CYStatement *statement) :
269 name_(name),
270 statement_(statement)
cf7d4c69
JF
271 {
272 }
fb98ac0c 273
3b52fd1a
JF
274 virtual CYStatement *Replace(CYContext &context);
275 virtual void Output(CYOutput &out, CYFlags flags) const;
fb98ac0c
JF
276};
277
14ec9e00 278struct CYCStringLess :
029bc65b
JF
279 std::binary_function<const char *, const char *, bool>
280{
281 _finline bool operator ()(const char *lhs, const char *rhs) const {
282 return strcmp(lhs, rhs) < 0;
283 }
284};
285
286struct CYIdentifierValueLess :
287 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
288{
289 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
14ec9e00 290 return CYCStringLess()(lhs->Word(), rhs->Word());
029bc65b
JF
291 }
292};
293
294enum CYIdentifierFlags {
295 CYIdentifierArgument,
14ec9e00
JF
296 CYIdentifierVariable,
297 CYIdentifierOther,
298 CYIdentifierMagic,
daf22a65 299 CYIdentifierCatch,
029bc65b
JF
300};
301
14ec9e00 302typedef std::set<const char *, CYCStringLess> CYCStringSet;
029bc65b 303typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
029bc65b
JF
304typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
305
e013809d
JF
306struct CYIdentifierUsage {
307 CYIdentifier *identifier_;
308 size_t usage_;
309};
310
311typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
312
029bc65b 313struct CYScope {
61fe0c53 314 bool transparent_;
daf22a65
JF
315
316 CYContext &context_;
317 CYStatement *&statements_;
318
029bc65b 319 CYScope *parent_;
a86e34d0 320
a846a8cd 321 CYIdentifierAddressFlagsMap internal_;
a86e34d0 322 CYIdentifierValueSet identifiers_;
029bc65b 323
61fe0c53 324 CYScope(bool transparent, CYContext &context, CYStatement *&statements);
e4676127 325 virtual ~CYScope();
029bc65b 326
daf22a65 327 void Close();
0a356474 328
a86e34d0
JF
329 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
330 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
6a981250 331 void Merge(CYContext &context, CYIdentifier *identifier);
029bc65b
JF
332 void Scope(CYContext &context, CYStatement *&statements);
333};
334
3b52fd1a
JF
335struct CYProgram :
336 CYThing
63b4c5a8 337{
3b52fd1a 338 CYStatement *statements_;
9e562cfc 339
3b52fd1a
JF
340 CYProgram(CYStatement *statements) :
341 statements_(statements)
9e562cfc
JF
342 {
343 }
cf7d4c69 344
3b52fd1a 345 virtual void Replace(CYContext &context);
3b52fd1a 346 virtual void Output(CYOutput &out) const;
9e562cfc
JF
347};
348
ab2aa221 349struct CYNonLocal;
a0be43fc 350struct CYThisScope;
ab2aa221 351
2c81c6df 352struct CYContext {
6a981250 353 CYOptions &options_;
ab2aa221 354
6a981250 355 CYScope *scope_;
a0be43fc
JF
356 CYThisScope *this_;
357
a846a8cd 358 CYIdentifierUsageVector rename_;
6a981250 359
ab2aa221 360 CYNonLocal *nonlocal_;
06293152 361 CYNonLocal *nextlocal_;
ab2aa221
JF
362 unsigned unique_;
363
2eb8215d 364 CYContext(CYOptions &options) :
6a981250 365 options_(options),
ab2aa221 366 scope_(NULL),
a0be43fc 367 this_(NULL),
ab2aa221 368 nonlocal_(NULL),
06293152 369 nextlocal_(NULL),
ab2aa221 370 unique_(0)
6a981250
JF
371 {
372 }
373
0a356474
JF
374 virtual ~CYContext() {
375 }
376
cde20a5a
JF
377 template <typename Type_>
378 void ReplaceAll(Type_ *&values) {
379 Type_ **last(&values);
c2c9f509 380 CYForEach (next, values) {
0c0d1955 381 Replace(*last = next);
9cd63688
JF
382 if (*last != NULL)
383 last = &(*last)->next_;
cde20a5a
JF
384 }
385 }
386
6a981250
JF
387 template <typename Type_>
388 void Replace(Type_ *&value) {
389 for (;;) if (value == NULL)
390 break;
391 else {
392 Type_ *replace(value->Replace(*this));
393 if (replace != value)
394 value = replace;
395 else break;
396 }
397 }
ab2aa221
JF
398
399 void NonLocal(CYStatement *&statements);
400 CYIdentifier *Unique();
401};
402
403struct CYNonLocal {
404 CYIdentifier *identifier_;
405
406 CYNonLocal() :
407 identifier_(NULL)
408 {
409 }
410
411 CYIdentifier *Target(CYContext &context) {
412 if (identifier_ == NULL)
413 identifier_ = context.Unique();
414 return identifier_;
415 }
6a981250
JF
416};
417
a0be43fc
JF
418struct CYThisScope :
419 CYNext<CYThisScope>
420{
421 CYIdentifier *identifier_;
422
423 CYThisScope() :
424 identifier_(NULL)
425 {
426 }
427
428 CYIdentifier *Identifier(CYContext &context) {
429 if (next_ != NULL)
430 return next_->Identifier(context);
431 if (identifier_ == NULL)
432 identifier_ = context.Unique();
433 return identifier_;
434 }
435};
436
9e562cfc 437struct CYBlock :
3b52fd1a
JF
438 CYStatement,
439 CYThing
9e562cfc
JF
440{
441 CYStatement *statements_;
442
a846a8cd
JF
443 CYBlock(CYStatement *statements) :
444 statements_(statements)
9e562cfc 445 {
cf7d4c69 446 }
9e562cfc 447
4644480a
JF
448 operator CYStatement *() const {
449 return statements_;
450 }
451
029bc65b 452 void AddPrev(CYStatement *statement) {
bf45251b 453 CYSetLast(statement) = statements_;
029bc65b
JF
454 statements_ = statement;
455 }
456
3b52fd1a
JF
457 virtual CYStatement *Replace(CYContext &context);
458
459 virtual void Output(CYOutput &out) const;
fb98ac0c 460 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
461};
462
d3b63265
JF
463class CYStream :
464 public std::istream
465{
466 private:
467 class CYBuffer :
468 public std::streambuf
469 {
470 public:
471 CYBuffer(const char *start, const char *end) {
472 setg(const_cast<char *>(start), const_cast<char *>(start), const_cast<char *>(end));
473 }
474 } buffer_;
475
476 public:
477 CYStream(const char *start, const char *end) :
478 std::istream(&buffer_),
479 buffer_(start, end)
480 {
481 }
482};
483
cac61857 484struct CYForInitialiser {
7c6c5b0a
JF
485 virtual ~CYForInitialiser() {
486 }
487
029bc65b 488 virtual CYExpression *Replace(CYContext &context) = 0;
15b88a33 489 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
dea834b0
JF
490};
491
cac61857 492struct CYForInInitialiser {
7c6c5b0a
JF
493 virtual ~CYForInInitialiser() {
494 }
495
652ec1ba 496 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
ad3b38bb 497 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value) = 0;
b158281e 498
029bc65b 499 virtual CYExpression *Replace(CYContext &context) = 0;
ae65d594 500 virtual CYAssignment *Assignment(CYContext &context) = 0;
c8a0500b
JF
501
502 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
b09da87b
JF
503};
504
4644480a
JF
505struct CYNumber;
506struct CYString;
507
cf7d4c69 508struct CYExpression :
5999c315 509 CYNext<CYExpression>,
cf7d4c69 510 CYForInitialiser,
e5bc40db 511 CYForInInitialiser,
96a7e5c2
JF
512 CYClassName,
513 CYThing
63b4c5a8 514{
d35a3b07 515 virtual unsigned Precedence() const = 0;
75b0a457 516
fb98ac0c
JF
517 virtual bool RightHand() const {
518 return true;
519 }
520
652ec1ba 521 virtual void ForIn(CYOutput &out, CYFlags flags) const;
ad3b38bb 522 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
75b0a457 523
6c093cce
JF
524 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
525
96a7e5c2 526 virtual void Output(CYOutput &out) const;
652ec1ba
JF
527 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
528 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
dea834b0 529
3b52fd1a 530 virtual CYExpression *ClassName(CYContext &context, bool object);
652ec1ba 531 virtual void ClassName(CYOutput &out, bool object) const;
e5bc40db 532
3b52fd1a 533 virtual CYExpression *Replace(CYContext &context) = 0;
ae65d594 534 virtual CYAssignment *Assignment(CYContext &context);
3b52fd1a 535
4644480a
JF
536 virtual CYExpression *Primitive(CYContext &context) {
537 return this;
538 }
539
540 virtual CYNumber *Number(CYContext &context) {
541 return NULL;
542 }
543
544 virtual CYString *String(CYContext &context) {
545 return NULL;
546 }
547
dea834b0
JF
548 virtual const char *Word() const {
549 return NULL;
550 }
63b4c5a8
JF
551};
552
b09da87b
JF
553#define CYAlphabetic(value) \
554 virtual bool Alphabetic() const { \
555 return value; \
556 }
557
d35a3b07 558#define CYPrecedence(value) \
8351aa30 559 static const unsigned Precedence_ = value; \
d35a3b07 560 virtual unsigned Precedence() const { \
8351aa30 561 return Precedence_; \
d35a3b07
JF
562 }
563
fb98ac0c
JF
564#define CYRightHand(value) \
565 virtual bool RightHand() const { \
566 return value; \
567 }
568
d35a3b07
JF
569struct CYCompound :
570 CYExpression
571{
572 CYExpression *expressions_;
573
029bc65b 574 CYCompound(CYExpression *expressions = NULL) :
d35a3b07
JF
575 expressions_(expressions)
576 {
577 }
578
579 void AddPrev(CYExpression *expression) {
bf45251b 580 CYSetLast(expression) = expressions_;
d35a3b07
JF
581 expressions_ = expression;
582 }
583
584 CYPrecedence(17)
585
3b52fd1a 586 virtual CYExpression *Replace(CYContext &context);
652ec1ba 587 void Output(CYOutput &out, CYFlags flags) const;
e06e5ee1
JF
588
589 virtual CYExpression *Primitive(CYContext &context);
d35a3b07 590};
5999c315 591
c8a0500b
JF
592struct CYDeclaration;
593
3b52fd1a
JF
594struct CYFunctionParameter :
595 CYNext<CYFunctionParameter>,
596 CYThing
597{
c8a0500b 598 CYForInInitialiser *initialiser_;
3b52fd1a 599
c8a0500b 600 CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
3b52fd1a 601 CYNext<CYFunctionParameter>(next),
c8a0500b 602 initialiser_(initialiser)
4e11a430
JF
603 {
604 }
605
c8a0500b
JF
606 void Replace(CYContext &context, CYBlock &code);
607 void Output(CYOutput &out) const;
3b52fd1a
JF
608};
609
75b0a457 610struct CYComprehension :
96a7e5c2
JF
611 CYNext<CYComprehension>,
612 CYThing
75b0a457 613{
c2529502
JF
614 CYComprehension(CYComprehension *next = NULL) :
615 CYNext<CYComprehension>(next)
616 {
617 }
618
75b0a457
JF
619 virtual const char *Name() const = 0;
620
3b52fd1a
JF
621 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
622 CYFunctionParameter *Parameters(CYContext &context) const;
623 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 624 virtual void Output(CYOutput &out) const = 0;
75b0a457
JF
625};
626
627struct CYForInComprehension :
628 CYComprehension
629{
630 CYIdentifier *name_;
631 CYExpression *set_;
632
c2529502
JF
633 CYForInComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
634 CYComprehension(next),
75b0a457
JF
635 name_(name),
636 set_(set)
637 {
638 }
639
640 virtual const char *Name() const {
029bc65b 641 return name_->Word();
75b0a457
JF
642 }
643
3b52fd1a
JF
644 virtual CYFunctionParameter *Parameter(CYContext &context) const;
645 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 646 virtual void Output(CYOutput &out) const;
75b0a457
JF
647};
648
d5618df7 649struct CYForOfComprehension :
75b0a457
JF
650 CYComprehension
651{
652 CYIdentifier *name_;
653 CYExpression *set_;
654
c2529502
JF
655 CYForOfComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
656 CYComprehension(next),
75b0a457
JF
657 name_(name),
658 set_(set)
659 {
660 }
661
662 virtual const char *Name() const {
029bc65b 663 return name_->Word();
75b0a457
JF
664 }
665
3b52fd1a
JF
666 virtual CYFunctionParameter *Parameter(CYContext &context) const;
667 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 668 virtual void Output(CYOutput &out) const;
75b0a457
JF
669};
670
671struct CYIfComprehension :
672 CYComprehension
673{
674 CYExpression *test_;
675
676 CYIfComprehension(CYExpression *test) :
677 test_(test)
678 {
679 }
680
681 virtual const char *Name() const {
682 return NULL;
683 }
684
3b52fd1a
JF
685 virtual CYFunctionParameter *Parameter(CYContext &context) const;
686 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 687 virtual void Output(CYOutput &out) const;
75b0a457
JF
688};
689
690struct CYArrayComprehension :
691 CYExpression
692{
693 CYExpression *expression_;
694 CYComprehension *comprehensions_;
695
696 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
697 expression_(expression),
698 comprehensions_(comprehensions)
699 {
700 }
701
702 CYPrecedence(0)
703
3b52fd1a 704 virtual CYExpression *Replace(CYContext &context);
652ec1ba 705 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
706};
707
cf7d4c69
JF
708struct CYLiteral :
709 CYExpression
63b4c5a8 710{
d35a3b07 711 CYPrecedence(0)
fb98ac0c 712 CYRightHand(false)
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;
cf7d4c69
JF
925};
926
927struct CYPrefix :
63b4c5a8
JF
928 CYExpression
929{
930 CYExpression *rhs_;
931
cf7d4c69 932 CYPrefix(CYExpression *rhs) :
63b4c5a8
JF
933 rhs_(rhs)
934 {
935 }
5999c315 936
b09da87b 937 virtual bool Alphabetic() const = 0;
5999c315
JF
938 virtual const char *Operator() const = 0;
939
3b52fd1a
JF
940 CYPrecedence(4)
941
942 virtual CYExpression *Replace(CYContext &context);
652ec1ba 943 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
944};
945
cf7d4c69 946struct CYInfix :
63b4c5a8
JF
947 CYExpression
948{
949 CYExpression *lhs_;
950 CYExpression *rhs_;
951
cf7d4c69 952 CYInfix(CYExpression *lhs, CYExpression *rhs) :
63b4c5a8
JF
953 lhs_(lhs),
954 rhs_(rhs)
955 {
956 }
5999c315 957
0ff9f149
JF
958 void SetLeft(CYExpression *lhs) {
959 lhs_ = lhs;
960 }
961
b09da87b 962 virtual bool Alphabetic() const = 0;
5999c315
JF
963 virtual const char *Operator() const = 0;
964
3b52fd1a 965 virtual CYExpression *Replace(CYContext &context);
652ec1ba 966 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
967};
968
cf7d4c69 969struct CYPostfix :
63b4c5a8
JF
970 CYExpression
971{
972 CYExpression *lhs_;
973
cf7d4c69 974 CYPostfix(CYExpression *lhs) :
63b4c5a8
JF
975 lhs_(lhs)
976 {
977 }
5999c315
JF
978
979 virtual const char *Operator() const = 0;
980
3b52fd1a
JF
981 CYPrecedence(3)
982
983 virtual CYExpression *Replace(CYContext &context);
652ec1ba 984 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
985};
986
cf7d4c69 987struct CYAssignment :
d35a3b07 988 CYExpression
cf7d4c69 989{
d35a3b07
JF
990 CYExpression *lhs_;
991 CYExpression *rhs_;
992
cf7d4c69 993 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
d35a3b07
JF
994 lhs_(lhs),
995 rhs_(rhs)
cf7d4c69
JF
996 {
997 }
5999c315 998
0ff9f149
JF
999 void SetLeft(CYExpression *lhs) {
1000 lhs_ = lhs;
1001 }
1002
5999c315 1003 virtual const char *Operator() const = 0;
d35a3b07 1004
4de0686f
JF
1005 CYPrecedence(16)
1006
3b52fd1a 1007 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1008 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1009};
1010
62014ea9 1011struct CYArgument :
96a7e5c2
JF
1012 CYNext<CYArgument>,
1013 CYThing
62014ea9 1014{
cf7d4c69
JF
1015 CYWord *name_;
1016 CYExpression *value_;
cf7d4c69 1017
3b52fd1a
JF
1018 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1019 CYNext<CYArgument>(next),
1020 name_(NULL),
1021 value_(value)
1022 {
1023 }
1024
cf7d4c69 1025 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
62014ea9 1026 CYNext<CYArgument>(next),
cf7d4c69 1027 name_(name),
62014ea9 1028 value_(value)
cf7d4c69
JF
1029 {
1030 }
5999c315 1031
5192746c 1032 CYArgument *Replace(CYContext &context);
652ec1ba 1033 void Output(CYOutput &out) const;
cf7d4c69
JF
1034};
1035
1036struct CYBlank :
1037 public CYWord
1038{
1039 CYBlank() :
1040 CYWord("")
1041 {
1042 }
1043};
1044
5999c315
JF
1045struct CYClause :
1046 CYThing,
1047 CYNext<CYClause>
1048{
cf7d4c69 1049 CYExpression *case_;
3b52fd1a 1050 CYStatement *statements_;
cf7d4c69 1051
3b52fd1a 1052 CYClause(CYExpression *_case, CYStatement *statements) :
cf7d4c69 1053 case_(_case),
3b52fd1a 1054 statements_(statements)
cf7d4c69
JF
1055 {
1056 }
1057
fa389b0f 1058 void Replace(CYContext &context);
652ec1ba 1059 virtual void Output(CYOutput &out) const;
cf7d4c69
JF
1060};
1061
62014ea9 1062struct CYElement :
96a7e5c2
JF
1063 CYNext<CYElement>,
1064 CYThing
62014ea9 1065{
cf7d4c69 1066 CYExpression *value_;
cf7d4c69
JF
1067
1068 CYElement(CYExpression *value, CYElement *next) :
62014ea9
JF
1069 CYNext<CYElement>(next),
1070 value_(value)
cf7d4c69
JF
1071 {
1072 }
5999c315 1073
3b52fd1a 1074 void Replace(CYContext &context);
652ec1ba 1075 void Output(CYOutput &out) const;
5befe15e
JF
1076};
1077
1078struct CYArray :
1079 CYLiteral
1080{
1081 CYElement *elements_;
1082
3b52fd1a 1083 CYArray(CYElement *elements = NULL) :
5befe15e
JF
1084 elements_(elements)
1085 {
1086 }
1087
3b52fd1a 1088 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1089 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1090};
1091
550ee46a
JF
1092struct CYProperty :
1093 CYNext<CYProperty>,
1094 CYThing
1095{
1096 CYPropertyName *name_;
1097 CYExpression *value_;
1098
1099 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1100 CYNext<CYProperty>(next),
1101 name_(name),
1102 value_(value)
1103 {
1104 }
1105
1106 void Replace(CYContext &context);
1107 virtual void Output(CYOutput &out) const;
1108};
1109
cf7d4c69
JF
1110struct CYDeclaration :
1111 CYForInInitialiser
1112{
1113 CYIdentifier *identifier_;
1114 CYExpression *initialiser_;
1115
550ee46a 1116 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
cf7d4c69
JF
1117 identifier_(identifier),
1118 initialiser_(initialiser)
1119 {
1120 }
5999c315 1121
652ec1ba 1122 virtual void ForIn(CYOutput &out, CYFlags flags) const;
ad3b38bb 1123 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
3b52fd1a 1124
029bc65b 1125 virtual CYExpression *Replace(CYContext &context);
15b88a33 1126
029bc65b 1127 virtual CYAssignment *Assignment(CYContext &context);
15b88a33 1128 CYVariable *Variable(CYContext &context);
75b0a457 1129
652ec1ba 1130 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1131};
1132
1133struct CYDeclarations :
cac61857 1134 CYNext<CYDeclarations>,
15b88a33 1135 CYThing
cf7d4c69
JF
1136{
1137 CYDeclaration *declaration_;
cf7d4c69 1138
cacd1a88 1139 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
cac61857
JF
1140 CYNext<CYDeclarations>(next),
1141 declaration_(declaration)
1142 {
1143 }
1144
15b88a33 1145 void Replace(CYContext &context);
96a7e5c2 1146
15b88a33 1147 CYCompound *Compound(CYContext &context);
550ee46a 1148 CYProperty *Property(CYContext &context);
15b88a33
JF
1149 CYArgument *Argument(CYContext &context);
1150 CYFunctionParameter *Parameter(CYContext &context);
3b52fd1a 1151
96a7e5c2 1152 virtual void Output(CYOutput &out) const;
652ec1ba 1153 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1154};
1155
15b88a33
JF
1156struct CYForDeclarations :
1157 CYForInitialiser
1158{
1159 CYDeclarations *declarations_;
1160
1161 CYForDeclarations(CYDeclarations *declarations) :
1162 declarations_(declarations)
1163 {
1164 }
1165
1166 virtual CYCompound *Replace(CYContext &context);
1167 virtual void Output(CYOutput &out, CYFlags flags) const;
1168};
1169
cac61857
JF
1170struct CYVar :
1171 CYStatement
1172{
1173 CYDeclarations *declarations_;
1174
1175 CYVar(CYDeclarations *declarations) :
1176 declarations_(declarations)
1177 {
1178 }
1179
3b52fd1a 1180 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1181 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1182};
1183
c8a0500b 1184struct CYLetStatement :
cac61857
JF
1185 CYStatement
1186{
1187 CYDeclarations *declarations_;
15b88a33 1188 CYStatement *code_;
cac61857 1189
c8a0500b 1190 CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
cac61857 1191 declarations_(declarations),
15b88a33 1192 code_(code)
cf7d4c69
JF
1193 {
1194 }
5999c315 1195
3b52fd1a 1196 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1197 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1198};
1199
cf7d4c69
JF
1200struct CYFor :
1201 CYStatement
1202{
1203 CYForInitialiser *initialiser_;
1204 CYExpression *test_;
1205 CYExpression *increment_;
1206 CYStatement *code_;
1207
1208 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1209 initialiser_(initialiser),
1210 test_(test),
1211 increment_(increment),
1212 code_(code)
1213 {
1214 }
5999c315 1215
3b52fd1a 1216 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1217 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1218};
1219
1220struct CYForIn :
1221 CYStatement
1222{
1223 CYForInInitialiser *initialiser_;
1224 CYExpression *set_;
1225 CYStatement *code_;
1226
1227 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1228 initialiser_(initialiser),
1229 set_(set),
1230 code_(code)
1231 {
1232 }
5999c315 1233
3b52fd1a 1234 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1235 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1236};
1237
d5618df7 1238struct CYForOf :
75b0a457
JF
1239 CYStatement
1240{
1241 CYForInInitialiser *initialiser_;
1242 CYExpression *set_;
1243 CYStatement *code_;
1244
d5618df7 1245 CYForOf(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
75b0a457
JF
1246 initialiser_(initialiser),
1247 set_(set),
1248 code_(code)
1249 {
1250 }
1251
3b52fd1a 1252 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1253 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
1254};
1255
693d501b
JF
1256struct CYObject :
1257 CYLiteral
1258{
3b52fd1a 1259 CYProperty *properties_;
693d501b 1260
ab2aa221 1261 CYObject(CYProperty *properties = NULL) :
3b52fd1a 1262 properties_(properties)
693d501b
JF
1263 {
1264 }
1265
3b52fd1a 1266 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1267 void Output(CYOutput &out, CYFlags flags) const;
693d501b
JF
1268};
1269
cf7d4c69
JF
1270struct CYMember :
1271 CYExpression
1272{
1273 CYExpression *object_;
1274 CYExpression *property_;
1275
1276 CYMember(CYExpression *object, CYExpression *property) :
1277 object_(object),
1278 property_(property)
1279 {
1280 }
5999c315 1281
9b5527f0
JF
1282 void SetLeft(CYExpression *object) {
1283 object_ = object;
1284 }
1285};
1286
1287struct CYDirectMember :
1288 CYMember
1289{
1290 CYDirectMember(CYExpression *object, CYExpression *property) :
1291 CYMember(object, property)
1292 {
1293 }
1294
1295 CYPrecedence(1)
fb98ac0c 1296 CYRightHand(false)
9b5527f0 1297
3b52fd1a 1298 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1299 virtual void Output(CYOutput &out, CYFlags flags) const;
9b5527f0
JF
1300};
1301
1302struct CYIndirectMember :
1303 CYMember
1304{
1305 CYIndirectMember(CYExpression *object, CYExpression *property) :
1306 CYMember(object, property)
1307 {
1308 }
1309
d35a3b07 1310 CYPrecedence(1)
fb98ac0c 1311 CYRightHand(false)
d35a3b07 1312
3b52fd1a 1313 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1314 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1315};
1316
2eb8215d
JF
1317namespace cy {
1318namespace Syntax {
1319
1320struct New :
cf7d4c69
JF
1321 CYExpression
1322{
1323 CYExpression *constructor_;
1324 CYArgument *arguments_;
1325
2eb8215d 1326 New(CYExpression *constructor, CYArgument *arguments) :
cf7d4c69
JF
1327 constructor_(constructor),
1328 arguments_(arguments)
1329 {
1330 }
5999c315 1331
fb98ac0c
JF
1332 virtual unsigned Precedence() const {
1333 return arguments_ == NULL ? 2 : 1;
1334 }
1335
1336 CYRightHand(false)
d35a3b07 1337
3b52fd1a 1338 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1339 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1340
1341 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
cf7d4c69
JF
1342};
1343
2eb8215d
JF
1344} }
1345
cf7d4c69
JF
1346struct CYCall :
1347 CYExpression
1348{
1349 CYExpression *function_;
1350 CYArgument *arguments_;
1351
3b52fd1a 1352 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
cf7d4c69
JF
1353 function_(function),
1354 arguments_(arguments)
1355 {
1356 }
5999c315 1357
fb98ac0c
JF
1358 CYPrecedence(1)
1359 CYRightHand(false)
d35a3b07 1360
3b52fd1a 1361 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1362 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1363
1364 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1365};
1366
1367struct CYRubyProc;
1368
1369struct CYRubyBlock :
1370 CYExpression
1371{
1372 CYExpression *call_;
1373 CYRubyProc *proc_;
1374
1375 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1376 call_(call),
1377 proc_(proc)
1378 {
1379 }
1380
1381 CYPrecedence(1)
1382 CYRightHand(false)
1383
1384 virtual CYExpression *Replace(CYContext &context);
1385 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1386};
1387
1388struct CYIf :
1389 CYStatement
1390{
1391 CYExpression *test_;
1392 CYStatement *true_;
1393 CYStatement *false_;
1394
3b52fd1a 1395 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
cf7d4c69
JF
1396 test_(test),
1397 true_(_true),
1398 false_(_false)
1399 {
1400 }
5999c315 1401
3b52fd1a 1402 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1403 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1404};
1405
1406struct CYDoWhile :
1407 CYStatement
1408{
1409 CYExpression *test_;
1410 CYStatement *code_;
1411
1412 CYDoWhile(CYExpression *test, CYStatement *code) :
1413 test_(test),
1414 code_(code)
1415 {
1416 }
5999c315 1417
3b52fd1a 1418 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1419 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1420};
1421
1422struct CYWhile :
1423 CYStatement
1424{
1425 CYExpression *test_;
1426 CYStatement *code_;
1427
1428 CYWhile(CYExpression *test, CYStatement *code) :
1429 test_(test),
1430 code_(code)
1431 {
1432 }
5999c315 1433
3b52fd1a 1434 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1435 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1436};
1437
6c093cce 1438// XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
a846a8cd 1439struct CYFunction {
cf7d4c69 1440 CYIdentifier *name_;
b09da87b 1441 CYFunctionParameter *parameters_;
3b52fd1a 1442 CYBlock code_;
a0be43fc 1443
ab2aa221 1444 CYNonLocal *nonlocal_;
a0be43fc 1445 CYThisScope this_;
cf7d4c69 1446
3b52fd1a 1447 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
cf7d4c69
JF
1448 name_(name),
1449 parameters_(parameters),
ab2aa221
JF
1450 code_(statements),
1451 nonlocal_(NULL)
cf7d4c69
JF
1452 {
1453 }
5999c315 1454
7c6c5b0a
JF
1455 virtual ~CYFunction() {
1456 }
1457
14ec9e00
JF
1458 void Inject(CYContext &context);
1459 virtual void Replace_(CYContext &context, bool outer);
fb98ac0c
JF
1460 virtual void Output(CYOutput &out, CYFlags flags) const;
1461};
1462
6c093cce 1463// XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
fb98ac0c
JF
1464struct CYFunctionExpression :
1465 CYFunction,
1466 CYExpression
1467{
3b52fd1a
JF
1468 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1469 CYFunction(name, parameters, statements)
fb98ac0c
JF
1470 {
1471 }
1472
a0be43fc
JF
1473 CYPrecedence(0)
1474 CYRightHand(false)
1475
1476 virtual CYExpression *Replace(CYContext &context);
1477 virtual void Output(CYOutput &out, CYFlags flags) const;
1478};
1479
1480// XXX: this should derive from CYAnonymousFunction
1481struct CYFatArrow :
1482 CYFunction,
1483 CYExpression
1484{
1485 CYFatArrow(CYFunctionParameter *parameters, CYStatement *statements) :
1486 CYFunction(NULL, parameters, statements)
1487 {
1488 }
1489
d35a3b07 1490 CYPrecedence(0)
fb98ac0c 1491 CYRightHand(false)
d35a3b07 1492
3b52fd1a 1493 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1494 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1495};
1496
6c093cce
JF
1497// XXX: this should derive from CYAnonymousFunctionExpression
1498struct CYRubyProc :
1499 CYFunctionExpression
1500{
1501 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1502 CYFunctionExpression(NULL, parameters, statements)
1503 {
1504 }
1505
1506 virtual CYExpression *Replace(CYContext &context);
1507 virtual void Output(CYOutput &out, CYFlags flags) const;
1508};
1509
1510// XXX: this should derive from CYNamedFunction
fb98ac0c
JF
1511struct CYFunctionStatement :
1512 CYFunction,
b10bd496 1513 CYStatement
cf7d4c69 1514{
3b52fd1a
JF
1515 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1516 CYFunction(name, parameters, statements)
cf7d4c69
JF
1517 {
1518 }
5999c315 1519
3b52fd1a 1520 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1521 virtual void Output(CYOutput &out, CYFlags flags) const;
5999c315
JF
1522};
1523
1524struct CYExpress :
1525 CYStatement
1526{
1527 CYExpression *expression_;
1528
1529 CYExpress(CYExpression *expression) :
1530 expression_(expression)
1531 {
029bc65b
JF
1532 if (expression == NULL)
1533 throw;
5999c315
JF
1534 }
1535
3b52fd1a 1536 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1537 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1538};
1539
1540struct CYContinue :
1541 CYStatement
1542{
1543 CYIdentifier *label_;
1544
1545 CYContinue(CYIdentifier *label) :
1546 label_(label)
1547 {
1548 }
5999c315 1549
3b52fd1a 1550 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1551 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1552};
1553
1554struct CYBreak :
1555 CYStatement
1556{
1557 CYIdentifier *label_;
1558
1559 CYBreak(CYIdentifier *label) :
1560 label_(label)
1561 {
1562 }
5999c315 1563
3b52fd1a 1564 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1565 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1566};
1567
1568struct CYReturn :
1569 CYStatement
1570{
1571 CYExpression *value_;
1572
1573 CYReturn(CYExpression *value) :
1574 value_(value)
1575 {
1576 }
5999c315 1577
3b52fd1a 1578 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1579 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1580};
1581
1582struct CYEmpty :
1583 CYStatement
1584{
3b52fd1a 1585 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1586 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1587};
1588
96a7e5c2
JF
1589struct CYFinally :
1590 CYThing
1591{
3b52fd1a 1592 CYBlock code_;
b10bd496 1593
3b52fd1a
JF
1594 CYFinally(CYStatement *statements) :
1595 code_(statements)
b10bd496
JF
1596 {
1597 }
1598
3b52fd1a 1599 void Replace(CYContext &context);
b10bd496
JF
1600 virtual void Output(CYOutput &out) const;
1601};
1602
37954781
JF
1603namespace cy {
1604namespace Syntax {
1605
1606struct Catch :
1607 CYThing
1608{
1609 CYIdentifier *name_;
1610 CYBlock code_;
1611
1612 Catch(CYIdentifier *name, CYStatement *statements) :
1613 name_(name),
1614 code_(statements)
1615 {
1616 }
1617
1618 void Replace(CYContext &context);
1619 virtual void Output(CYOutput &out) const;
1620};
1621
1622struct Try :
cf7d4c69
JF
1623 CYStatement
1624{
3b52fd1a 1625 CYBlock code_;
37954781 1626 Catch *catch_;
b10bd496 1627 CYFinally *finally_;
cf7d4c69 1628
37954781 1629 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
3b52fd1a 1630 code_(statements),
cf7d4c69
JF
1631 catch_(_catch),
1632 finally_(finally)
1633 {
1634 }
5999c315 1635
3b52fd1a 1636 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1637 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1638};
1639
37954781 1640struct Throw :
cf7d4c69
JF
1641 CYStatement
1642{
1643 CYExpression *value_;
1644
ab2aa221 1645 Throw(CYExpression *value = NULL) :
cf7d4c69
JF
1646 value_(value)
1647 {
1648 }
5999c315 1649
3b52fd1a 1650 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1651 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1652};
1653
37954781
JF
1654} }
1655
cf7d4c69
JF
1656struct CYWith :
1657 CYStatement
1658{
1659 CYExpression *scope_;
1660 CYStatement *code_;
1661
1662 CYWith(CYExpression *scope, CYStatement *code) :
1663 scope_(scope),
1664 code_(code)
1665 {
1666 }
5999c315 1667
3b52fd1a 1668 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1669 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1670};
1671
1672struct CYSwitch :
1673 CYStatement
1674{
1675 CYExpression *value_;
1676 CYClause *clauses_;
1677
1678 CYSwitch(CYExpression *value, CYClause *clauses) :
1679 value_(value),
1680 clauses_(clauses)
1681 {
1682 }
5999c315 1683
3b52fd1a 1684 virtual CYStatement *Replace(CYContext &context);
c8a0500b
JF
1685 virtual void Output(CYOutput &out, CYFlags flags) const;
1686};
1687
1688struct CYDebugger :
1689 CYStatement
1690{
1691 CYDebugger()
1692 {
1693 }
1694
1695 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1696 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1697};
1698
1699struct CYCondition :
1700 CYExpression
1701{
1702 CYExpression *test_;
1703 CYExpression *true_;
1704 CYExpression *false_;
1705
1706 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
91a416e4 1707 test_(test),
cf7d4c69
JF
1708 true_(_true),
1709 false_(_false)
1710 {
1711 }
5999c315 1712
d35a3b07
JF
1713 CYPrecedence(15)
1714
3b52fd1a 1715 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1716 virtual void Output(CYOutput &out, CYFlags flags) const;
5999c315
JF
1717};
1718
1719struct CYAddressOf :
1720 CYPrefix
1721{
1722 CYAddressOf(CYExpression *rhs) :
1723 CYPrefix(rhs)
1724 {
1725 }
1726
1727 virtual const char *Operator() const {
1728 return "&";
1729 }
1730
b09da87b 1731 CYAlphabetic(false)
d35a3b07 1732
3b52fd1a 1733 virtual CYExpression *Replace(CYContext &context);
5999c315
JF
1734};
1735
1736struct CYIndirect :
1737 CYPrefix
1738{
1739 CYIndirect(CYExpression *rhs) :
1740 CYPrefix(rhs)
1741 {
1742 }
1743
1744 virtual const char *Operator() const {
561ac418 1745 return "*";
5999c315
JF
1746 }
1747
b09da87b 1748 CYAlphabetic(false)
d35a3b07 1749
3b52fd1a 1750 virtual CYExpression *Replace(CYContext &context);
cf7d4c69
JF
1751};
1752
4644480a
JF
1753#define CYReplace \
1754 virtual CYExpression *Replace(CYContext &context);
1755
1756#define CYPostfix_(op, name, args...) \
cf7d4c69
JF
1757 struct CY ## name : \
1758 CYPostfix \
4644480a 1759 { args \
cf7d4c69
JF
1760 CY ## name(CYExpression *lhs) : \
1761 CYPostfix(lhs) \
1762 { \
1763 } \
5999c315
JF
1764 \
1765 virtual const char *Operator() const { \
1766 return op; \
1767 } \
cf7d4c69
JF
1768 };
1769
4644480a 1770#define CYPrefix_(alphabetic, op, name, args...) \
cf7d4c69
JF
1771 struct CY ## name : \
1772 CYPrefix \
4644480a 1773 { args \
cf7d4c69
JF
1774 CY ## name(CYExpression *rhs) : \
1775 CYPrefix(rhs) \
1776 { \
1777 } \
d35a3b07 1778 \
b09da87b 1779 CYAlphabetic(alphabetic) \
5999c315
JF
1780 \
1781 virtual const char *Operator() const { \
1782 return op; \
1783 } \
cf7d4c69
JF
1784 };
1785
4644480a 1786#define CYInfix_(alphabetic, precedence, op, name, args...) \
cf7d4c69
JF
1787 struct CY ## name : \
1788 CYInfix \
4644480a 1789 { args \
cf7d4c69
JF
1790 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1791 CYInfix(lhs, rhs) \
1792 { \
1793 } \
d35a3b07 1794 \
b09da87b 1795 CYAlphabetic(alphabetic) \
d35a3b07 1796 CYPrecedence(precedence) \
5999c315
JF
1797 \
1798 virtual const char *Operator() const { \
1799 return op; \
1800 } \
cf7d4c69
JF
1801 };
1802
4644480a 1803#define CYAssignment_(op, name, args...) \
cf7d4c69
JF
1804 struct CY ## name ## Assign : \
1805 CYAssignment \
4644480a 1806 { args \
cf7d4c69
JF
1807 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1808 CYAssignment(lhs, rhs) \
1809 { \
1810 } \
5999c315
JF
1811 \
1812 virtual const char *Operator() const { \
1813 return op; \
1814 } \
cf7d4c69
JF
1815 };
1816
1817CYPostfix_("++", PostIncrement)
1818CYPostfix_("--", PostDecrement)
1819
b09da87b
JF
1820CYPrefix_(true, "delete", Delete)
1821CYPrefix_(true, "void", Void)
1822CYPrefix_(true, "typeof", TypeOf)
1823CYPrefix_(false, "++", PreIncrement)
1824CYPrefix_(false, "--", PreDecrement)
c0bc320e 1825CYPrefix_(false, "+", Affirm)
b09da87b
JF
1826CYPrefix_(false, "-", Negate)
1827CYPrefix_(false, "~", BitwiseNot)
1828CYPrefix_(false, "!", LogicalNot)
1829
1830CYInfix_(false, 5, "*", Multiply)
1831CYInfix_(false, 5, "/", Divide)
1832CYInfix_(false, 5, "%", Modulus)
4644480a 1833CYInfix_(false, 6, "+", Add, CYReplace)
b09da87b
JF
1834CYInfix_(false, 6, "-", Subtract)
1835CYInfix_(false, 7, "<<", ShiftLeft)
1836CYInfix_(false, 7, ">>", ShiftRightSigned)
1837CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1838CYInfix_(false, 8, "<", Less)
1839CYInfix_(false, 8, ">", Greater)
1840CYInfix_(false, 8, "<=", LessOrEqual)
1841CYInfix_(false, 8, ">=", GreaterOrEqual)
1842CYInfix_(true, 8, "instanceof", InstanceOf)
1843CYInfix_(true, 8, "in", In)
1844CYInfix_(false, 9, "==", Equal)
1845CYInfix_(false, 9, "!=", NotEqual)
1846CYInfix_(false, 9, "===", Identical)
1847CYInfix_(false, 9, "!==", NotIdentical)
1848CYInfix_(false, 10, "&", BitwiseAnd)
1849CYInfix_(false, 11, "^", BitwiseXOr)
1850CYInfix_(false, 12, "|", BitwiseOr)
1851CYInfix_(false, 13, "&&", LogicalAnd)
1852CYInfix_(false, 14, "||", LogicalOr)
cf7d4c69
JF
1853
1854CYAssignment_("=", )
1855CYAssignment_("*=", Multiply)
1856CYAssignment_("/=", Divide)
1857CYAssignment_("%=", Modulus)
1858CYAssignment_("+=", Add)
1859CYAssignment_("-=", Subtract)
1860CYAssignment_("<<=", ShiftLeft)
1861CYAssignment_(">>=", ShiftRightSigned)
1862CYAssignment_(">>>=", ShiftRightUnsigned)
1863CYAssignment_("&=", BitwiseAnd)
1864CYAssignment_("^=", BitwiseXOr)
1865CYAssignment_("|=", BitwiseOr)
1866
c5fa2867 1867#endif/*CYCRIPT_PARSER_HPP*/