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