]> git.saurik.com Git - cycript.git/blame - Parser.hpp
Merge CYStatement::ReplaceAll with the new CYCompound::Replace version of CYExpressio...
[cycript.git] / Parser.hpp
CommitLineData
b3378a02
JF
1/* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2010 Jay Freeman (saurik)
b4aa79af
JF
3*/
4
b3378a02 5/* GNU Lesser General Public License, Version 3 {{{ */
b4aa79af 6/*
b3378a02
JF
7 * Cycript is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
b4aa79af 11 *
b3378a02
JF
12 * Cycript is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
b4aa79af 16 *
b3378a02
JF
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
19**/
b4aa79af
JF
20/* }}} */
21
63b4c5a8
JF
22#ifndef CYPARSER_HPP
23#define CYPARSER_HPP
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
5befe15e 35#include "location.hh"
5999c315 36#include "Pooling.hpp"
029bc65b
JF
37#include "Options.hpp"
38
39class CYContext;
924f67b2 40
5999c315
JF
41template <typename Type_>
42struct CYNext {
43 Type_ *next_;
63b4c5a8 44
5999c315
JF
45 CYNext() :
46 next_(NULL)
47 {
48 }
cf7d4c69 49
62014ea9
JF
50 CYNext(Type_ *next) :
51 next_(next)
52 {
53 }
54
5999c315 55 void SetNext(Type_ *next) {
cf7d4c69
JF
56 next_ = next;
57 }
58};
59
5999c315 60struct CYThing {
7c6c5b0a
JF
61 virtual ~CYThing() {
62 }
63
652ec1ba 64 virtual void Output(struct CYOutput &out) const = 0;
5999c315
JF
65};
66
652ec1ba
JF
67struct CYOutput {
68 std::ostream &out_;
029bc65b 69 CYOptions &options_;
11c1cc16
JF
70 bool pretty_;
71 unsigned indent_;
320ce753 72 bool right_;
652ec1ba 73
96a7e5c2
JF
74 enum {
75 NoMode,
76 NoLetter,
c0bc320e 77 NoPlus,
96a7e5c2
JF
78 NoHyphen,
79 Terminated
80 } mode_;
81
029bc65b 82 CYOutput(std::ostream &out, CYOptions &options) :
11c1cc16 83 out_(out),
029bc65b 84 options_(options),
11c1cc16 85 pretty_(false),
96a7e5c2 86 indent_(0),
320ce753 87 right_(false),
96a7e5c2 88 mode_(NoMode)
652ec1ba
JF
89 {
90 }
91
96a7e5c2 92 void Check(char value);
1fdca2fa 93 void Terminate();
652ec1ba 94
96a7e5c2
JF
95 CYOutput &operator <<(char rhs);
96 CYOutput &operator <<(const char *rhs);
97
98 _finline CYOutput &operator <<(const CYThing *rhs) {
99 if (rhs != NULL)
100 rhs->Output(*this);
652ec1ba
JF
101 return *this;
102 }
103
104 _finline CYOutput &operator <<(const CYThing &rhs) {
105 rhs.Output(*this);
106 return *this;
107 }
108};
5999c315 109
e5bc40db 110struct CYPropertyName {
652ec1ba 111 virtual void PropertyName(CYOutput &out) const = 0;
7c6c5b0a
JF
112
113 virtual ~CYPropertyName() {
114 }
e5bc40db
JF
115};
116
3b52fd1a
JF
117struct CYExpression;
118
119enum CYNeeded {
120 CYNever = -1,
121 CYSometimes = 0,
122 CYAlways = 1,
123};
124
125enum CYFlags {
126 CYNoFlags = 0,
127 CYNoBrace = (1 << 0),
128 CYNoFunction = (1 << 1),
129 CYNoIn = (1 << 2),
130 CYNoCall = (1 << 3),
131 CYNoRightHand = (1 << 4),
132 CYNoDangle = (1 << 5),
9561f209 133 CYNoInteger = (1 << 6),
3b52fd1a
JF
134 CYNoBF = (CYNoBrace | CYNoFunction),
135};
136
3b52fd1a
JF
137struct CYStatement :
138 CYNext<CYStatement>
139{
7c6c5b0a
JF
140 virtual ~CYStatement() {
141 }
142
3b52fd1a
JF
143 void Single(CYOutput &out, CYFlags flags) const;
144 void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
145
029bc65b 146 virtual CYStatement *Collapse(CYContext &context);
3b52fd1a
JF
147 virtual CYStatement *Replace(CYContext &context) = 0;
148
149 private:
150 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
151};
152
153struct CYStatements {
154 CYStatement *first_;
155 CYStatement *last_;
156
157 CYStatements() :
158 first_(NULL),
159 last_(NULL)
160 {
161 }
162
163 operator CYStatement *() const {
164 return first_;
165 }
166
167 CYStatements &operator ->*(CYStatement *next) {
168 if (next != NULL)
169 if (first_ == NULL) {
170 first_ = next;
171 last_ = next;
172 } else for (;; last_ = last_->next_)
173 if (last_->next_ == NULL) {
174 last_->next_ = next;
175 last_ = next;
176 break;
177 }
178 return *this;
179 }
180};
181
e5bc40db 182struct CYClassName {
7c6c5b0a
JF
183 virtual ~CYClassName() {
184 }
185
3b52fd1a 186 virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
652ec1ba 187 virtual void ClassName(CYOutput &out, bool object) const = 0;
63b4c5a8
JF
188};
189
cf7d4c69 190struct CYWord :
e5bc40db
JF
191 CYThing,
192 CYPropertyName,
193 CYClassName
63b4c5a8 194{
cf7d4c69
JF
195 const char *word_;
196
197 CYWord(const char *word) :
198 word_(word)
199 {
200 }
201
029bc65b
JF
202 void Set(const char *value) {
203 word_ = value;
cf7d4c69
JF
204 }
205
029bc65b 206 virtual const char *Word() const;
652ec1ba 207 virtual void Output(CYOutput &out) const;
e5bc40db 208
3b52fd1a 209 virtual CYExpression *ClassName(CYContext &context, bool object);
652ec1ba
JF
210 virtual void ClassName(CYOutput &out, bool object) const;
211 virtual void PropertyName(CYOutput &out) const;
63b4c5a8
JF
212};
213
652ec1ba 214_finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
029bc65b
JF
215 lhs << &rhs << '=';
216 return lhs << rhs.Word();
652ec1ba
JF
217}
218
cf7d4c69 219struct CYIdentifier :
14ec9e00 220 CYNext<CYIdentifier>,
cf7d4c69 221 CYWord
63b4c5a8 222{
029bc65b 223 CYIdentifier *replace_;
6a981250 224 size_t offset_;
e013809d 225 size_t usage_;
029bc65b 226
5999c315 227 CYIdentifier(const char *word) :
029bc65b 228 CYWord(word),
6a981250 229 replace_(NULL),
e013809d
JF
230 offset_(0),
231 usage_(0)
5999c315 232 {
cf7d4c69 233 }
029bc65b
JF
234
235 virtual const char *Word() const;
236 CYIdentifier *Replace(CYContext &context);
63b4c5a8
JF
237};
238
320ce753
JF
239struct CYComment :
240 CYStatement
241{
242 const char *value_;
243
244 CYComment(const char *value) :
245 value_(value)
246 {
247 }
248
249 virtual CYStatement *Replace(CYContext &context);
250 virtual void Output(CYOutput &out, CYFlags flags) const;
251};
252
62014ea9 253struct CYLabel :
3b52fd1a 254 CYStatement
62014ea9 255{
9e562cfc 256 CYIdentifier *name_;
3b52fd1a 257 CYStatement *statement_;
cf7d4c69 258
3b52fd1a
JF
259 CYLabel(CYIdentifier *name, CYStatement *statement) :
260 name_(name),
261 statement_(statement)
cf7d4c69
JF
262 {
263 }
fb98ac0c 264
3b52fd1a
JF
265 virtual CYStatement *Replace(CYContext &context);
266 virtual void Output(CYOutput &out, CYFlags flags) const;
fb98ac0c
JF
267};
268
14ec9e00 269struct CYCStringLess :
029bc65b
JF
270 std::binary_function<const char *, const char *, bool>
271{
272 _finline bool operator ()(const char *lhs, const char *rhs) const {
273 return strcmp(lhs, rhs) < 0;
274 }
275};
276
277struct CYIdentifierValueLess :
278 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
279{
280 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
14ec9e00 281 return CYCStringLess()(lhs->Word(), rhs->Word());
029bc65b
JF
282 }
283};
284
285enum CYIdentifierFlags {
286 CYIdentifierArgument,
14ec9e00
JF
287 CYIdentifierVariable,
288 CYIdentifierOther,
289 CYIdentifierMagic,
daf22a65 290 CYIdentifierCatch,
029bc65b
JF
291};
292
14ec9e00 293typedef std::set<const char *, CYCStringLess> CYCStringSet;
029bc65b 294typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
029bc65b
JF
295typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
296
e013809d
JF
297struct CYIdentifierUsage {
298 CYIdentifier *identifier_;
299 size_t usage_;
300};
301
302typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
303
daf22a65
JF
304// XXX: strategy pattern, maybe subclass
305enum CYScopeType {
306 CYScopeCatch,
307 CYScopeFunction,
308 CYScopeProgram,
309};
310
029bc65b 311struct CYScope {
daf22a65
JF
312 CYScopeType type_;
313
314 CYContext &context_;
315 CYStatement *&statements_;
316
029bc65b 317 CYScope *parent_;
a86e34d0 318
a846a8cd 319 CYIdentifierAddressFlagsMap internal_;
a86e34d0 320 CYIdentifierValueSet identifiers_;
029bc65b 321
daf22a65 322 CYScope(CYScopeType type, CYContext &context, CYStatement *&statements);
029bc65b 323
daf22a65 324 void Close();
0a356474 325
a86e34d0
JF
326 void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
327 virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
6a981250 328 void Merge(CYContext &context, CYIdentifier *identifier);
029bc65b
JF
329 void Scope(CYContext &context, CYStatement *&statements);
330};
331
3b52fd1a
JF
332struct CYProgram :
333 CYThing
63b4c5a8 334{
3b52fd1a 335 CYStatement *statements_;
9e562cfc 336
3b52fd1a
JF
337 CYProgram(CYStatement *statements) :
338 statements_(statements)
9e562cfc
JF
339 {
340 }
cf7d4c69 341
3b52fd1a 342 virtual void Replace(CYContext &context);
3b52fd1a 343 virtual void Output(CYOutput &out) const;
9e562cfc
JF
344};
345
ab2aa221
JF
346struct CYNonLocal;
347
2c81c6df 348struct CYContext {
6a981250 349 CYOptions &options_;
ab2aa221 350
6a981250 351 CYScope *scope_;
a846a8cd 352 CYIdentifierUsageVector rename_;
6a981250 353
ab2aa221 354 CYNonLocal *nonlocal_;
06293152 355 CYNonLocal *nextlocal_;
ab2aa221
JF
356 unsigned unique_;
357
2eb8215d 358 CYContext(CYOptions &options) :
6a981250 359 options_(options),
ab2aa221
JF
360 scope_(NULL),
361 nonlocal_(NULL),
06293152 362 nextlocal_(NULL),
ab2aa221 363 unique_(0)
6a981250
JF
364 {
365 }
366
0a356474
JF
367 virtual ~CYContext() {
368 }
369
cde20a5a
JF
370 template <typename Type_>
371 void ReplaceAll(Type_ *&values) {
372 Type_ **last(&values);
373 for (Type_ *next(values); next != NULL; next = next->next_) {
374 Replace(*last);
375 last = &(*last)->next_;
376 }
377 }
378
6a981250
JF
379 template <typename Type_>
380 void Replace(Type_ *&value) {
381 for (;;) if (value == NULL)
382 break;
383 else {
384 Type_ *replace(value->Replace(*this));
385 if (replace != value)
386 value = replace;
387 else break;
388 }
389 }
ab2aa221
JF
390
391 void NonLocal(CYStatement *&statements);
392 CYIdentifier *Unique();
393};
394
395struct CYNonLocal {
396 CYIdentifier *identifier_;
397
398 CYNonLocal() :
399 identifier_(NULL)
400 {
401 }
402
403 CYIdentifier *Target(CYContext &context) {
404 if (identifier_ == NULL)
405 identifier_ = context.Unique();
406 return identifier_;
407 }
6a981250
JF
408};
409
9e562cfc 410struct CYBlock :
3b52fd1a
JF
411 CYStatement,
412 CYThing
9e562cfc
JF
413{
414 CYStatement *statements_;
415
a846a8cd
JF
416 CYBlock(CYStatement *statements) :
417 statements_(statements)
9e562cfc 418 {
cf7d4c69 419 }
9e562cfc 420
4644480a
JF
421 operator CYStatement *() const {
422 return statements_;
423 }
424
029bc65b
JF
425 void AddPrev(CYStatement *statement) {
426 CYStatement *last(statement);
427 while (last->next_ != NULL)
428 last = last->next_;
429 last->SetNext(statements_);
430 statements_ = statement;
431 }
432
3b52fd1a
JF
433 virtual CYStatement *Replace(CYContext &context);
434
435 virtual void Output(CYOutput &out) const;
fb98ac0c 436 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
437};
438
db5e2840
JF
439enum CYState {
440 CYClear,
441 CYRestricted,
442 CYNewLine
443};
444
5999c315
JF
445class CYDriver {
446 public:
db5e2840 447 CYState state_;
e7ed5354
JF
448 void *scanner_;
449
450 const char *data_;
451 size_t size_;
48e3be8a 452 FILE *file_;
e7ed5354 453
b10bd496
JF
454 bool strict_;
455
63cd45c9 456 enum Condition {
697d6fd2 457 RegExpCondition,
691e4717
JF
458 XMLContentCondition,
459 XMLTagCondition,
63cd45c9
JF
460 };
461
5999c315 462 std::string filename_;
e7ed5354 463
5befe15e 464 struct Error {
b10bd496 465 bool warning_;
5befe15e
JF
466 cy::location location_;
467 std::string message_;
468 };
469
470 typedef std::vector<Error> Errors;
471
3b52fd1a 472 CYProgram *program_;
5befe15e 473 Errors errors_;
5999c315 474
7e5391fd
JF
475 bool auto_;
476
477 struct Context {
478 CYExpression *context_;
479
480 Context(CYExpression *context) :
481 context_(context)
482 {
483 }
484
485 typedef std::vector<CYWord *> Words;
486 Words words_;
487 };
488
489 typedef std::vector<Context> Contexts;
490 Contexts contexts_;
491
492 CYExpression *context_;
493
494 enum Mode {
495 AutoNone,
496 AutoPrimary,
497 AutoDirect,
498 AutoIndirect,
499 AutoMessage
500 } mode_;
501
5999c315
JF
502 private:
503 void ScannerInit();
504 void ScannerDestroy();
505
506 public:
2eb8215d 507 CYDriver(const std::string &filename = "");
5999c315 508 ~CYDriver();
63cd45c9 509
691e4717
JF
510 Condition GetCondition();
511 void SetCondition(Condition condition);
512
513 void PushCondition(Condition condition);
514 void PopCondition();
b10bd496
JF
515
516 void Warning(const cy::location &location, const char *message);
5999c315
JF
517};
518
cac61857 519struct CYForInitialiser {
7c6c5b0a
JF
520 virtual ~CYForInitialiser() {
521 }
522
652ec1ba 523 virtual void For(CYOutput &out) const = 0;
029bc65b 524 virtual CYExpression *Replace(CYContext &context) = 0;
dea834b0
JF
525};
526
cac61857 527struct CYForInInitialiser {
7c6c5b0a
JF
528 virtual ~CYForInInitialiser() {
529 }
530
652ec1ba 531 virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
75b0a457 532 virtual const char *ForEachIn() const = 0;
3b52fd1a 533 virtual CYExpression *ForEachIn(CYContext &out) = 0;
029bc65b 534 virtual CYExpression *Replace(CYContext &context) = 0;
b09da87b
JF
535};
536
4644480a
JF
537struct CYNumber;
538struct CYString;
539
cf7d4c69 540struct CYExpression :
5999c315 541 CYNext<CYExpression>,
cf7d4c69 542 CYForInitialiser,
e5bc40db 543 CYForInInitialiser,
96a7e5c2
JF
544 CYClassName,
545 CYThing
63b4c5a8 546{
d35a3b07 547 virtual unsigned Precedence() const = 0;
75b0a457 548
fb98ac0c
JF
549 virtual bool RightHand() const {
550 return true;
551 }
552
652ec1ba
JF
553 virtual void For(CYOutput &out) const;
554 virtual void ForIn(CYOutput &out, CYFlags flags) const;
75b0a457 555
cac61857 556 virtual const char *ForEachIn() const;
3b52fd1a 557 virtual CYExpression *ForEachIn(CYContext &out);
75b0a457 558
6c093cce
JF
559 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
560
96a7e5c2 561 virtual void Output(CYOutput &out) const;
652ec1ba
JF
562 virtual void Output(CYOutput &out, CYFlags flags) const = 0;
563 void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
dea834b0 564
3b52fd1a 565 virtual CYExpression *ClassName(CYContext &context, bool object);
652ec1ba 566 virtual void ClassName(CYOutput &out, bool object) const;
e5bc40db 567
3b52fd1a
JF
568 virtual CYExpression *Replace(CYContext &context) = 0;
569
4644480a
JF
570 virtual CYExpression *Primitive(CYContext &context) {
571 return this;
572 }
573
574 virtual CYNumber *Number(CYContext &context) {
575 return NULL;
576 }
577
578 virtual CYString *String(CYContext &context) {
579 return NULL;
580 }
581
dea834b0
JF
582 virtual const char *Word() const {
583 return NULL;
584 }
63b4c5a8
JF
585};
586
b09da87b
JF
587#define CYAlphabetic(value) \
588 virtual bool Alphabetic() const { \
589 return value; \
590 }
591
d35a3b07 592#define CYPrecedence(value) \
8351aa30 593 static const unsigned Precedence_ = value; \
d35a3b07 594 virtual unsigned Precedence() const { \
8351aa30 595 return Precedence_; \
d35a3b07
JF
596 }
597
fb98ac0c
JF
598#define CYRightHand(value) \
599 virtual bool RightHand() const { \
600 return value; \
601 }
602
d35a3b07
JF
603struct CYCompound :
604 CYExpression
605{
606 CYExpression *expressions_;
607
029bc65b 608 CYCompound(CYExpression *expressions = NULL) :
d35a3b07
JF
609 expressions_(expressions)
610 {
611 }
612
613 void AddPrev(CYExpression *expression) {
614 CYExpression *last(expression);
615 while (last->next_ != NULL)
616 last = last->next_;
617 last->SetNext(expressions_);
618 expressions_ = expression;
619 }
620
621 CYPrecedence(17)
622
3b52fd1a 623 virtual CYExpression *Replace(CYContext &context);
652ec1ba 624 void Output(CYOutput &out, CYFlags flags) const;
d35a3b07 625};
5999c315 626
3b52fd1a
JF
627struct CYFunctionParameter :
628 CYNext<CYFunctionParameter>,
629 CYThing
630{
631 CYIdentifier *name_;
632
633 CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
634 CYNext<CYFunctionParameter>(next),
635 name_(name)
636 {
637 }
638
4e11a430
JF
639 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
640 virtual void Output(CYOutput &out) const;
641};
642
643struct CYOptionalFunctionParameter :
644 CYFunctionParameter
645{
646 CYExpression *initializer_;
647
648 CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
649 CYFunctionParameter(name, next),
650 initializer_(initializer)
651 {
652 }
653
654 virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
3b52fd1a
JF
655 virtual void Output(CYOutput &out) const;
656};
657
75b0a457 658struct CYComprehension :
96a7e5c2
JF
659 CYNext<CYComprehension>,
660 CYThing
75b0a457 661{
75b0a457
JF
662 virtual const char *Name() const = 0;
663
3b52fd1a
JF
664 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
665 CYFunctionParameter *Parameters(CYContext &context) const;
666 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 667 virtual void Output(CYOutput &out) const = 0;
75b0a457
JF
668};
669
670struct CYForInComprehension :
671 CYComprehension
672{
673 CYIdentifier *name_;
674 CYExpression *set_;
675
676 CYForInComprehension(CYIdentifier *name, CYExpression *set) :
677 name_(name),
678 set_(set)
679 {
680 }
681
682 virtual const char *Name() const {
029bc65b 683 return name_->Word();
75b0a457
JF
684 }
685
3b52fd1a
JF
686 virtual CYFunctionParameter *Parameter(CYContext &context) const;
687 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 688 virtual void Output(CYOutput &out) const;
75b0a457
JF
689};
690
691struct CYForEachInComprehension :
692 CYComprehension
693{
694 CYIdentifier *name_;
695 CYExpression *set_;
696
697 CYForEachInComprehension(CYIdentifier *name, CYExpression *set) :
698 name_(name),
699 set_(set)
700 {
701 }
702
703 virtual const char *Name() const {
029bc65b 704 return name_->Word();
75b0a457
JF
705 }
706
3b52fd1a
JF
707 virtual CYFunctionParameter *Parameter(CYContext &context) const;
708 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 709 virtual void Output(CYOutput &out) const;
75b0a457
JF
710};
711
712struct CYIfComprehension :
713 CYComprehension
714{
715 CYExpression *test_;
716
717 CYIfComprehension(CYExpression *test) :
718 test_(test)
719 {
720 }
721
722 virtual const char *Name() const {
723 return NULL;
724 }
725
3b52fd1a
JF
726 virtual CYFunctionParameter *Parameter(CYContext &context) const;
727 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 728 virtual void Output(CYOutput &out) const;
75b0a457
JF
729};
730
731struct CYArrayComprehension :
732 CYExpression
733{
734 CYExpression *expression_;
735 CYComprehension *comprehensions_;
736
737 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
738 expression_(expression),
739 comprehensions_(comprehensions)
740 {
741 }
742
743 CYPrecedence(0)
744
3b52fd1a 745 virtual CYExpression *Replace(CYContext &context);
652ec1ba 746 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
747};
748
cf7d4c69
JF
749struct CYLiteral :
750 CYExpression
63b4c5a8 751{
d35a3b07 752 CYPrecedence(0)
fb98ac0c 753 CYRightHand(false)
cf7d4c69 754};
63b4c5a8 755
3b52fd1a
JF
756struct CYTrivial :
757 CYLiteral
758{
759 virtual CYExpression *Replace(CYContext &context);
760};
761
478d4ed0
JF
762struct CYMagic :
763 CYExpression
764{
765 CYPrecedence(0)
fb98ac0c 766 CYRightHand(false)
478d4ed0
JF
767};
768
dea834b0
JF
769struct CYRange {
770 uint64_t lo_;
771 uint64_t hi_;
772
773 CYRange(uint64_t lo, uint64_t hi) :
774 lo_(lo), hi_(hi)
775 {
776 }
777
778 bool operator [](uint8_t value) const {
779 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
780 }
781
782 void operator()(uint8_t value) {
783 if (value >> 7)
784 return;
785 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
786 }
787};
788
283e7e33 789extern CYRange DigitRange_;
dea834b0
JF
790extern CYRange WordStartRange_;
791extern CYRange WordEndRange_;
792
cf7d4c69 793struct CYString :
3b52fd1a 794 CYTrivial,
e5bc40db 795 CYPropertyName
cf7d4c69
JF
796{
797 const char *value_;
5999c315 798 size_t size_;
cf7d4c69 799
3b52fd1a
JF
800 CYString() :
801 value_(NULL),
802 size_(0)
803 {
804 }
805
806 CYString(const char *value) :
807 value_(value),
808 size_(strlen(value))
809 {
810 }
811
5999c315
JF
812 CYString(const char *value, size_t size) :
813 value_(value),
814 size_(size)
cf7d4c69
JF
815 {
816 }
817
3b52fd1a 818 CYString(const CYWord *word) :
029bc65b 819 value_(word->Word()),
5999c315 820 size_(strlen(value_))
cf7d4c69
JF
821 {
822 }
823
5999c315 824 const char *Value() const {
cf7d4c69
JF
825 return value_;
826 }
827
11c1cc16 828 virtual const char *Word() const;
dea834b0 829
4644480a
JF
830 virtual CYNumber *Number(CYContext &context);
831 virtual CYString *String(CYContext &context);
832
5db9a7f5 833 CYString *Concat(CYContext &out, CYString *rhs) const;
652ec1ba
JF
834 virtual void Output(CYOutput &out, CYFlags flags) const;
835 virtual void PropertyName(CYOutput &out) const;
63b4c5a8
JF
836};
837
cf7d4c69 838struct CYNumber :
3b52fd1a 839 CYTrivial,
e5bc40db 840 CYPropertyName
cf7d4c69 841{
5999c315
JF
842 double value_;
843
844 CYNumber(double value) :
845 value_(value)
846 {
847 }
848
849 double Value() const {
850 return value_;
cf7d4c69
JF
851 }
852
4644480a
JF
853 virtual CYNumber *Number(CYContext &context);
854 virtual CYString *String(CYContext &context);
855
652ec1ba
JF
856 virtual void Output(CYOutput &out, CYFlags flags) const;
857 virtual void PropertyName(CYOutput &out) const;
cf7d4c69
JF
858};
859
63cd45c9 860struct CYRegEx :
3b52fd1a 861 CYTrivial
63cd45c9
JF
862{
863 const char *value_;
864
865 CYRegEx(const char *value) :
866 value_(value)
867 {
868 }
869
870 const char *Value() const {
871 return value_;
872 }
873
874 virtual void Output(CYOutput &out, CYFlags flags) const;
875};
876
cf7d4c69
JF
877struct CYNull :
878 CYWord,
3b52fd1a 879 CYTrivial
cf7d4c69
JF
880{
881 CYNull() :
882 CYWord("null")
883 {
884 }
5999c315 885
4644480a
JF
886 virtual CYNumber *Number(CYContext &context);
887 virtual CYString *String(CYContext &context);
888
652ec1ba 889 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
890};
891
892struct CYThis :
893 CYWord,
478d4ed0 894 CYMagic
cf7d4c69
JF
895{
896 CYThis() :
897 CYWord("this")
898 {
899 }
5999c315 900
3b52fd1a 901 virtual CYExpression *Replace(CYContext &context);
652ec1ba 902 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
903};
904
905struct CYBoolean :
3b52fd1a 906 CYTrivial
cf7d4c69 907{
5999c315 908 virtual bool Value() const = 0;
652ec1ba 909 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
910};
911
912struct CYFalse :
913 CYWord,
914 CYBoolean
915{
916 CYFalse() :
917 CYWord("false")
918 {
919 }
5999c315 920
11c1cc16
JF
921 virtual bool Value() const {
922 return false;
923 }
4644480a
JF
924
925 virtual CYNumber *Number(CYContext &context);
926 virtual CYString *String(CYContext &context);
cf7d4c69
JF
927};
928
929struct CYTrue :
930 CYWord,
931 CYBoolean
932{
933 CYTrue() :
934 CYWord("true")
935 {
936 }
5999c315 937
11c1cc16
JF
938 virtual bool Value() const {
939 return true;
940 }
4644480a
JF
941
942 virtual CYNumber *Number(CYContext &context);
943 virtual CYString *String(CYContext &context);
cf7d4c69
JF
944};
945
946struct CYVariable :
947 CYExpression
948{
949 CYIdentifier *name_;
950
951 CYVariable(CYIdentifier *name) :
952 name_(name)
953 {
954 }
5999c315 955
2eb8215d
JF
956 CYVariable(const char *name) :
957 name_(new($pool) CYIdentifier(name))
958 {
959 }
960
d35a3b07 961 CYPrecedence(0)
fb98ac0c 962 CYRightHand(false)
d35a3b07 963
3b52fd1a 964 virtual CYExpression *Replace(CYContext &context);
652ec1ba 965 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
966};
967
968struct CYPrefix :
63b4c5a8
JF
969 CYExpression
970{
971 CYExpression *rhs_;
972
cf7d4c69 973 CYPrefix(CYExpression *rhs) :
63b4c5a8
JF
974 rhs_(rhs)
975 {
976 }
5999c315 977
b09da87b 978 virtual bool Alphabetic() const = 0;
5999c315
JF
979 virtual const char *Operator() const = 0;
980
3b52fd1a
JF
981 CYPrecedence(4)
982
983 virtual CYExpression *Replace(CYContext &context);
652ec1ba 984 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
985};
986
cf7d4c69 987struct CYInfix :
63b4c5a8
JF
988 CYExpression
989{
990 CYExpression *lhs_;
991 CYExpression *rhs_;
992
cf7d4c69 993 CYInfix(CYExpression *lhs, CYExpression *rhs) :
63b4c5a8
JF
994 lhs_(lhs),
995 rhs_(rhs)
996 {
997 }
5999c315 998
0ff9f149
JF
999 void SetLeft(CYExpression *lhs) {
1000 lhs_ = lhs;
1001 }
1002
b09da87b 1003 virtual bool Alphabetic() const = 0;
5999c315
JF
1004 virtual const char *Operator() const = 0;
1005
3b52fd1a 1006 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1007 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
1008};
1009
cf7d4c69 1010struct CYPostfix :
63b4c5a8
JF
1011 CYExpression
1012{
1013 CYExpression *lhs_;
1014
cf7d4c69 1015 CYPostfix(CYExpression *lhs) :
63b4c5a8
JF
1016 lhs_(lhs)
1017 {
1018 }
5999c315
JF
1019
1020 virtual const char *Operator() const = 0;
1021
3b52fd1a
JF
1022 CYPrecedence(3)
1023
1024 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1025 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
1026};
1027
cf7d4c69 1028struct CYAssignment :
d35a3b07 1029 CYExpression
cf7d4c69 1030{
d35a3b07
JF
1031 CYExpression *lhs_;
1032 CYExpression *rhs_;
1033
cf7d4c69 1034 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
d35a3b07
JF
1035 lhs_(lhs),
1036 rhs_(rhs)
cf7d4c69
JF
1037 {
1038 }
5999c315 1039
0ff9f149
JF
1040 void SetLeft(CYExpression *lhs) {
1041 lhs_ = lhs;
1042 }
1043
5999c315 1044 virtual const char *Operator() const = 0;
d35a3b07 1045
4de0686f
JF
1046 CYPrecedence(16)
1047
3b52fd1a 1048 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1049 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1050};
1051
62014ea9 1052struct CYArgument :
96a7e5c2
JF
1053 CYNext<CYArgument>,
1054 CYThing
62014ea9 1055{
cf7d4c69
JF
1056 CYWord *name_;
1057 CYExpression *value_;
cf7d4c69 1058
3b52fd1a
JF
1059 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1060 CYNext<CYArgument>(next),
1061 name_(NULL),
1062 value_(value)
1063 {
1064 }
1065
cf7d4c69 1066 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
62014ea9 1067 CYNext<CYArgument>(next),
cf7d4c69 1068 name_(name),
62014ea9 1069 value_(value)
cf7d4c69
JF
1070 {
1071 }
5999c315 1072
3b52fd1a 1073 void Replace(CYContext &context);
652ec1ba 1074 void Output(CYOutput &out) const;
cf7d4c69
JF
1075};
1076
1077struct CYBlank :
1078 public CYWord
1079{
1080 CYBlank() :
1081 CYWord("")
1082 {
1083 }
1084};
1085
5999c315
JF
1086struct CYClause :
1087 CYThing,
1088 CYNext<CYClause>
1089{
cf7d4c69 1090 CYExpression *case_;
3b52fd1a 1091 CYStatement *statements_;
cf7d4c69 1092
3b52fd1a 1093 CYClause(CYExpression *_case, CYStatement *statements) :
cf7d4c69 1094 case_(_case),
3b52fd1a 1095 statements_(statements)
cf7d4c69
JF
1096 {
1097 }
1098
fa389b0f 1099 void Replace(CYContext &context);
652ec1ba 1100 virtual void Output(CYOutput &out) const;
cf7d4c69
JF
1101};
1102
62014ea9 1103struct CYElement :
96a7e5c2
JF
1104 CYNext<CYElement>,
1105 CYThing
62014ea9 1106{
cf7d4c69 1107 CYExpression *value_;
cf7d4c69
JF
1108
1109 CYElement(CYExpression *value, CYElement *next) :
62014ea9
JF
1110 CYNext<CYElement>(next),
1111 value_(value)
cf7d4c69
JF
1112 {
1113 }
5999c315 1114
3b52fd1a 1115 void Replace(CYContext &context);
652ec1ba 1116 void Output(CYOutput &out) const;
5befe15e
JF
1117};
1118
1119struct CYArray :
1120 CYLiteral
1121{
1122 CYElement *elements_;
1123
3b52fd1a 1124 CYArray(CYElement *elements = NULL) :
5befe15e
JF
1125 elements_(elements)
1126 {
1127 }
1128
3b52fd1a 1129 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1130 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1131};
1132
550ee46a
JF
1133struct CYProperty :
1134 CYNext<CYProperty>,
1135 CYThing
1136{
1137 CYPropertyName *name_;
1138 CYExpression *value_;
1139
1140 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1141 CYNext<CYProperty>(next),
1142 name_(name),
1143 value_(value)
1144 {
1145 }
1146
1147 void Replace(CYContext &context);
1148 virtual void Output(CYOutput &out) const;
1149};
1150
cf7d4c69
JF
1151struct CYDeclaration :
1152 CYForInInitialiser
1153{
1154 CYIdentifier *identifier_;
1155 CYExpression *initialiser_;
1156
550ee46a 1157 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
cf7d4c69
JF
1158 identifier_(identifier),
1159 initialiser_(initialiser)
1160 {
1161 }
5999c315 1162
652ec1ba 1163 virtual void ForIn(CYOutput &out, CYFlags flags) const;
75b0a457 1164
cac61857 1165 virtual const char *ForEachIn() const;
3b52fd1a
JF
1166 virtual CYExpression *ForEachIn(CYContext &out);
1167
029bc65b
JF
1168 virtual CYExpression *Replace(CYContext &context);
1169 virtual CYAssignment *Assignment(CYContext &context);
75b0a457 1170
652ec1ba 1171 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1172};
1173
1174struct CYDeclarations :
cac61857 1175 CYNext<CYDeclarations>,
029bc65b
JF
1176 CYThing,
1177 CYForInitialiser
cf7d4c69
JF
1178{
1179 CYDeclaration *declaration_;
cf7d4c69 1180
cacd1a88 1181 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
cac61857
JF
1182 CYNext<CYDeclarations>(next),
1183 declaration_(declaration)
1184 {
1185 }
1186
652ec1ba 1187 virtual void For(CYOutput &out) const;
96a7e5c2 1188
029bc65b 1189 virtual CYCompound *Replace(CYContext &context);
550ee46a 1190 CYProperty *Property(CYContext &context);
3b52fd1a 1191
96a7e5c2 1192 virtual void Output(CYOutput &out) const;
652ec1ba 1193 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1194};
1195
1196struct CYVar :
1197 CYStatement
1198{
1199 CYDeclarations *declarations_;
1200
1201 CYVar(CYDeclarations *declarations) :
1202 declarations_(declarations)
1203 {
1204 }
1205
3b52fd1a 1206 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1207 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1208};
1209
1210struct CYLet :
1211 CYStatement
1212{
1213 CYDeclarations *declarations_;
3b52fd1a 1214 CYBlock code_;
cac61857
JF
1215
1216 CYLet(CYDeclarations *declarations, CYStatement *statements) :
1217 declarations_(declarations),
3b52fd1a 1218 code_(statements)
cf7d4c69
JF
1219 {
1220 }
5999c315 1221
3b52fd1a 1222 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1223 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1224};
1225
cf7d4c69
JF
1226struct CYFor :
1227 CYStatement
1228{
1229 CYForInitialiser *initialiser_;
1230 CYExpression *test_;
1231 CYExpression *increment_;
1232 CYStatement *code_;
1233
1234 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1235 initialiser_(initialiser),
1236 test_(test),
1237 increment_(increment),
1238 code_(code)
1239 {
1240 }
5999c315 1241
3b52fd1a 1242 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1243 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1244};
1245
1246struct CYForIn :
1247 CYStatement
1248{
1249 CYForInInitialiser *initialiser_;
1250 CYExpression *set_;
1251 CYStatement *code_;
1252
1253 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1254 initialiser_(initialiser),
1255 set_(set),
1256 code_(code)
1257 {
1258 }
5999c315 1259
3b52fd1a 1260 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1261 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1262};
1263
75b0a457
JF
1264struct CYForEachIn :
1265 CYStatement
1266{
1267 CYForInInitialiser *initialiser_;
1268 CYExpression *set_;
1269 CYStatement *code_;
1270
1271 CYForEachIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1272 initialiser_(initialiser),
1273 set_(set),
1274 code_(code)
1275 {
1276 }
1277
3b52fd1a 1278 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1279 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
1280};
1281
693d501b
JF
1282struct CYObject :
1283 CYLiteral
1284{
3b52fd1a 1285 CYProperty *properties_;
693d501b 1286
ab2aa221 1287 CYObject(CYProperty *properties = NULL) :
3b52fd1a 1288 properties_(properties)
693d501b
JF
1289 {
1290 }
1291
3b52fd1a 1292 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1293 void Output(CYOutput &out, CYFlags flags) const;
693d501b
JF
1294};
1295
cf7d4c69
JF
1296struct CYMember :
1297 CYExpression
1298{
1299 CYExpression *object_;
1300 CYExpression *property_;
1301
1302 CYMember(CYExpression *object, CYExpression *property) :
1303 object_(object),
1304 property_(property)
1305 {
1306 }
5999c315 1307
9b5527f0
JF
1308 void SetLeft(CYExpression *object) {
1309 object_ = object;
1310 }
3b52fd1a
JF
1311
1312 void Replace_(CYContext &context);
9b5527f0
JF
1313};
1314
1315struct CYDirectMember :
1316 CYMember
1317{
1318 CYDirectMember(CYExpression *object, CYExpression *property) :
1319 CYMember(object, property)
1320 {
1321 }
1322
1323 CYPrecedence(1)
fb98ac0c 1324 CYRightHand(false)
9b5527f0 1325
3b52fd1a 1326 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1327 virtual void Output(CYOutput &out, CYFlags flags) const;
9b5527f0
JF
1328};
1329
1330struct CYIndirectMember :
1331 CYMember
1332{
1333 CYIndirectMember(CYExpression *object, CYExpression *property) :
1334 CYMember(object, property)
1335 {
1336 }
1337
d35a3b07 1338 CYPrecedence(1)
fb98ac0c 1339 CYRightHand(false)
d35a3b07 1340
3b52fd1a 1341 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1342 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1343};
1344
2eb8215d
JF
1345namespace cy {
1346namespace Syntax {
1347
1348struct New :
cf7d4c69
JF
1349 CYExpression
1350{
1351 CYExpression *constructor_;
1352 CYArgument *arguments_;
1353
2eb8215d 1354 New(CYExpression *constructor, CYArgument *arguments) :
cf7d4c69
JF
1355 constructor_(constructor),
1356 arguments_(arguments)
1357 {
1358 }
5999c315 1359
fb98ac0c
JF
1360 virtual unsigned Precedence() const {
1361 return arguments_ == NULL ? 2 : 1;
1362 }
1363
1364 CYRightHand(false)
d35a3b07 1365
3b52fd1a 1366 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1367 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1368
1369 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
cf7d4c69
JF
1370};
1371
2eb8215d
JF
1372} }
1373
cf7d4c69
JF
1374struct CYCall :
1375 CYExpression
1376{
1377 CYExpression *function_;
1378 CYArgument *arguments_;
1379
3b52fd1a 1380 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
cf7d4c69
JF
1381 function_(function),
1382 arguments_(arguments)
1383 {
1384 }
5999c315 1385
fb98ac0c
JF
1386 CYPrecedence(1)
1387 CYRightHand(false)
d35a3b07 1388
3b52fd1a 1389 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1390 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1391
1392 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1393};
1394
1395struct CYRubyProc;
1396
1397struct CYRubyBlock :
1398 CYExpression
1399{
1400 CYExpression *call_;
1401 CYRubyProc *proc_;
1402
1403 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1404 call_(call),
1405 proc_(proc)
1406 {
1407 }
1408
1409 CYPrecedence(1)
1410 CYRightHand(false)
1411
1412 virtual CYExpression *Replace(CYContext &context);
1413 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1414};
1415
1416struct CYIf :
1417 CYStatement
1418{
1419 CYExpression *test_;
1420 CYStatement *true_;
1421 CYStatement *false_;
1422
3b52fd1a 1423 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
cf7d4c69
JF
1424 test_(test),
1425 true_(_true),
1426 false_(_false)
1427 {
1428 }
5999c315 1429
3b52fd1a 1430 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1431 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1432};
1433
1434struct CYDoWhile :
1435 CYStatement
1436{
1437 CYExpression *test_;
1438 CYStatement *code_;
1439
1440 CYDoWhile(CYExpression *test, CYStatement *code) :
1441 test_(test),
1442 code_(code)
1443 {
1444 }
5999c315 1445
3b52fd1a 1446 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1447 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1448};
1449
1450struct CYWhile :
1451 CYStatement
1452{
1453 CYExpression *test_;
1454 CYStatement *code_;
1455
1456 CYWhile(CYExpression *test, CYStatement *code) :
1457 test_(test),
1458 code_(code)
1459 {
1460 }
5999c315 1461
3b52fd1a 1462 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1463 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1464};
1465
6c093cce 1466// XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
a846a8cd 1467struct CYFunction {
cf7d4c69 1468 CYIdentifier *name_;
b09da87b 1469 CYFunctionParameter *parameters_;
3b52fd1a 1470 CYBlock code_;
ab2aa221 1471 CYNonLocal *nonlocal_;
cf7d4c69 1472
3b52fd1a 1473 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
cf7d4c69
JF
1474 name_(name),
1475 parameters_(parameters),
ab2aa221
JF
1476 code_(statements),
1477 nonlocal_(NULL)
cf7d4c69
JF
1478 {
1479 }
5999c315 1480
7c6c5b0a
JF
1481 virtual ~CYFunction() {
1482 }
1483
14ec9e00
JF
1484 void Inject(CYContext &context);
1485 virtual void Replace_(CYContext &context, bool outer);
fb98ac0c
JF
1486 virtual void Output(CYOutput &out, CYFlags flags) const;
1487};
1488
6c093cce 1489// XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
fb98ac0c
JF
1490struct CYFunctionExpression :
1491 CYFunction,
1492 CYExpression
1493{
3b52fd1a
JF
1494 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1495 CYFunction(name, parameters, statements)
fb98ac0c
JF
1496 {
1497 }
1498
d35a3b07 1499 CYPrecedence(0)
fb98ac0c 1500 CYRightHand(false)
d35a3b07 1501
3b52fd1a 1502 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1503 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1504};
1505
6c093cce
JF
1506// XXX: this should derive from CYAnonymousFunctionExpression
1507struct CYRubyProc :
1508 CYFunctionExpression
1509{
1510 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1511 CYFunctionExpression(NULL, parameters, statements)
1512 {
1513 }
1514
1515 virtual CYExpression *Replace(CYContext &context);
1516 virtual void Output(CYOutput &out, CYFlags flags) const;
1517};
1518
1519// XXX: this should derive from CYNamedFunction
fb98ac0c
JF
1520struct CYFunctionStatement :
1521 CYFunction,
b10bd496 1522 CYStatement
cf7d4c69 1523{
3b52fd1a
JF
1524 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1525 CYFunction(name, parameters, statements)
cf7d4c69
JF
1526 {
1527 }
5999c315 1528
3b52fd1a 1529 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1530 virtual void Output(CYOutput &out, CYFlags flags) const;
5999c315
JF
1531};
1532
1533struct CYExpress :
1534 CYStatement
1535{
1536 CYExpression *expression_;
1537
1538 CYExpress(CYExpression *expression) :
1539 expression_(expression)
1540 {
029bc65b
JF
1541 if (expression == NULL)
1542 throw;
5999c315
JF
1543 }
1544
029bc65b 1545 virtual CYStatement *Collapse(CYContext &context);
3b52fd1a 1546 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1547 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1548};
1549
1550struct CYContinue :
1551 CYStatement
1552{
1553 CYIdentifier *label_;
1554
1555 CYContinue(CYIdentifier *label) :
1556 label_(label)
1557 {
1558 }
5999c315 1559
3b52fd1a 1560 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1561 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1562};
1563
1564struct CYBreak :
1565 CYStatement
1566{
1567 CYIdentifier *label_;
1568
1569 CYBreak(CYIdentifier *label) :
1570 label_(label)
1571 {
1572 }
5999c315 1573
3b52fd1a 1574 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1575 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1576};
1577
1578struct CYReturn :
1579 CYStatement
1580{
1581 CYExpression *value_;
1582
1583 CYReturn(CYExpression *value) :
1584 value_(value)
1585 {
1586 }
5999c315 1587
3b52fd1a 1588 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1589 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1590};
1591
1592struct CYEmpty :
1593 CYStatement
1594{
029bc65b 1595 virtual CYStatement *Collapse(CYContext &context);
3b52fd1a 1596 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1597 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1598};
1599
96a7e5c2
JF
1600struct CYFinally :
1601 CYThing
1602{
3b52fd1a 1603 CYBlock code_;
b10bd496 1604
3b52fd1a
JF
1605 CYFinally(CYStatement *statements) :
1606 code_(statements)
b10bd496
JF
1607 {
1608 }
1609
3b52fd1a 1610 void Replace(CYContext &context);
b10bd496
JF
1611 virtual void Output(CYOutput &out) const;
1612};
1613
37954781
JF
1614namespace cy {
1615namespace Syntax {
1616
1617struct Catch :
1618 CYThing
1619{
1620 CYIdentifier *name_;
1621 CYBlock code_;
1622
1623 Catch(CYIdentifier *name, CYStatement *statements) :
1624 name_(name),
1625 code_(statements)
1626 {
1627 }
1628
1629 void Replace(CYContext &context);
1630 virtual void Output(CYOutput &out) const;
1631};
1632
1633struct Try :
cf7d4c69
JF
1634 CYStatement
1635{
3b52fd1a 1636 CYBlock code_;
37954781 1637 Catch *catch_;
b10bd496 1638 CYFinally *finally_;
cf7d4c69 1639
37954781 1640 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
3b52fd1a 1641 code_(statements),
cf7d4c69
JF
1642 catch_(_catch),
1643 finally_(finally)
1644 {
1645 }
5999c315 1646
3b52fd1a 1647 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1648 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1649};
1650
37954781 1651struct Throw :
cf7d4c69
JF
1652 CYStatement
1653{
1654 CYExpression *value_;
1655
ab2aa221 1656 Throw(CYExpression *value = NULL) :
cf7d4c69
JF
1657 value_(value)
1658 {
1659 }
5999c315 1660
3b52fd1a 1661 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1662 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1663};
1664
37954781
JF
1665} }
1666
cf7d4c69
JF
1667struct CYWith :
1668 CYStatement
1669{
1670 CYExpression *scope_;
1671 CYStatement *code_;
1672
1673 CYWith(CYExpression *scope, CYStatement *code) :
1674 scope_(scope),
1675 code_(code)
1676 {
1677 }
5999c315 1678
3b52fd1a 1679 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1680 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1681};
1682
1683struct CYSwitch :
1684 CYStatement
1685{
1686 CYExpression *value_;
1687 CYClause *clauses_;
1688
1689 CYSwitch(CYExpression *value, CYClause *clauses) :
1690 value_(value),
1691 clauses_(clauses)
1692 {
1693 }
5999c315 1694
3b52fd1a 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
63b4c5a8 1867#endif/*CYPARSER_HPP*/