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