]> git.saurik.com Git - cycript.git/blame - Parser.hpp
Refactor CYSetLast to return a reference to the eol.
[cycript.git] / Parser.hpp
CommitLineData
b3378a02 1/* Cycript - Optimizing JavaScript Compiler/Runtime
8d7447c1 2 * Copyright (C) 2009-2012 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) {
abadba19 433 CYLast(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) {
abadba19 622 CYLast(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;
e06e5ee1
JF
630
631 virtual CYExpression *Primitive(CYContext &context);
d35a3b07 632};
5999c315 633
c8a0500b
JF
634struct CYDeclaration;
635
3b52fd1a
JF
636struct CYFunctionParameter :
637 CYNext<CYFunctionParameter>,
638 CYThing
639{
c8a0500b 640 CYForInInitialiser *initialiser_;
3b52fd1a 641
c8a0500b 642 CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
3b52fd1a 643 CYNext<CYFunctionParameter>(next),
c8a0500b 644 initialiser_(initialiser)
4e11a430
JF
645 {
646 }
647
c8a0500b
JF
648 void Replace(CYContext &context, CYBlock &code);
649 void Output(CYOutput &out) const;
3b52fd1a
JF
650};
651
75b0a457 652struct CYComprehension :
96a7e5c2
JF
653 CYNext<CYComprehension>,
654 CYThing
75b0a457 655{
c2529502
JF
656 CYComprehension(CYComprehension *next = NULL) :
657 CYNext<CYComprehension>(next)
658 {
659 }
660
75b0a457
JF
661 virtual const char *Name() const = 0;
662
3b52fd1a
JF
663 virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
664 CYFunctionParameter *Parameters(CYContext &context) const;
665 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 666 virtual void Output(CYOutput &out) const = 0;
75b0a457
JF
667};
668
669struct CYForInComprehension :
670 CYComprehension
671{
672 CYIdentifier *name_;
673 CYExpression *set_;
674
c2529502
JF
675 CYForInComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
676 CYComprehension(next),
75b0a457
JF
677 name_(name),
678 set_(set)
679 {
680 }
681
682 virtual const char *Name() const {
029bc65b 683 return name_->Word();
75b0a457
JF
684 }
685
3b52fd1a
JF
686 virtual CYFunctionParameter *Parameter(CYContext &context) const;
687 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 688 virtual void Output(CYOutput &out) const;
75b0a457
JF
689};
690
d5618df7 691struct CYForOfComprehension :
75b0a457
JF
692 CYComprehension
693{
694 CYIdentifier *name_;
695 CYExpression *set_;
696
c2529502
JF
697 CYForOfComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
698 CYComprehension(next),
75b0a457
JF
699 name_(name),
700 set_(set)
701 {
702 }
703
704 virtual const char *Name() const {
029bc65b 705 return name_->Word();
75b0a457
JF
706 }
707
3b52fd1a
JF
708 virtual CYFunctionParameter *Parameter(CYContext &context) const;
709 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 710 virtual void Output(CYOutput &out) const;
75b0a457
JF
711};
712
713struct CYIfComprehension :
714 CYComprehension
715{
716 CYExpression *test_;
717
718 CYIfComprehension(CYExpression *test) :
719 test_(test)
720 {
721 }
722
723 virtual const char *Name() const {
724 return NULL;
725 }
726
3b52fd1a
JF
727 virtual CYFunctionParameter *Parameter(CYContext &context) const;
728 virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
4644480a 729 virtual void Output(CYOutput &out) const;
75b0a457
JF
730};
731
732struct CYArrayComprehension :
733 CYExpression
734{
735 CYExpression *expression_;
736 CYComprehension *comprehensions_;
737
738 CYArrayComprehension(CYExpression *expression, CYComprehension *comprehensions) :
739 expression_(expression),
740 comprehensions_(comprehensions)
741 {
742 }
743
744 CYPrecedence(0)
745
3b52fd1a 746 virtual CYExpression *Replace(CYContext &context);
652ec1ba 747 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
748};
749
cf7d4c69
JF
750struct CYLiteral :
751 CYExpression
63b4c5a8 752{
d35a3b07 753 CYPrecedence(0)
fb98ac0c 754 CYRightHand(false)
cf7d4c69 755};
63b4c5a8 756
3b52fd1a
JF
757struct CYTrivial :
758 CYLiteral
759{
760 virtual CYExpression *Replace(CYContext &context);
761};
762
478d4ed0
JF
763struct CYMagic :
764 CYExpression
765{
766 CYPrecedence(0)
fb98ac0c 767 CYRightHand(false)
478d4ed0
JF
768};
769
dea834b0
JF
770struct CYRange {
771 uint64_t lo_;
772 uint64_t hi_;
773
774 CYRange(uint64_t lo, uint64_t hi) :
775 lo_(lo), hi_(hi)
776 {
777 }
778
779 bool operator [](uint8_t value) const {
780 return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1;
781 }
782
783 void operator()(uint8_t value) {
784 if (value >> 7)
785 return;
786 (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f);
787 }
788};
789
283e7e33 790extern CYRange DigitRange_;
dea834b0
JF
791extern CYRange WordStartRange_;
792extern CYRange WordEndRange_;
793
cf7d4c69 794struct CYString :
3b52fd1a 795 CYTrivial,
e5bc40db 796 CYPropertyName
cf7d4c69
JF
797{
798 const char *value_;
5999c315 799 size_t size_;
cf7d4c69 800
3b52fd1a
JF
801 CYString() :
802 value_(NULL),
803 size_(0)
804 {
805 }
806
807 CYString(const char *value) :
808 value_(value),
809 size_(strlen(value))
810 {
811 }
812
5999c315
JF
813 CYString(const char *value, size_t size) :
814 value_(value),
815 size_(size)
cf7d4c69
JF
816 {
817 }
818
3b52fd1a 819 CYString(const CYWord *word) :
029bc65b 820 value_(word->Word()),
5999c315 821 size_(strlen(value_))
cf7d4c69
JF
822 {
823 }
824
5999c315 825 const char *Value() const {
cf7d4c69
JF
826 return value_;
827 }
828
11c1cc16 829 virtual const char *Word() const;
dea834b0 830
4644480a
JF
831 virtual CYNumber *Number(CYContext &context);
832 virtual CYString *String(CYContext &context);
833
5db9a7f5 834 CYString *Concat(CYContext &out, CYString *rhs) const;
652ec1ba
JF
835 virtual void Output(CYOutput &out, CYFlags flags) const;
836 virtual void PropertyName(CYOutput &out) const;
63b4c5a8
JF
837};
838
cf7d4c69 839struct CYNumber :
3b52fd1a 840 CYTrivial,
e5bc40db 841 CYPropertyName
cf7d4c69 842{
5999c315
JF
843 double value_;
844
845 CYNumber(double value) :
846 value_(value)
847 {
848 }
849
850 double Value() const {
851 return value_;
cf7d4c69
JF
852 }
853
4644480a
JF
854 virtual CYNumber *Number(CYContext &context);
855 virtual CYString *String(CYContext &context);
856
652ec1ba
JF
857 virtual void Output(CYOutput &out, CYFlags flags) const;
858 virtual void PropertyName(CYOutput &out) const;
cf7d4c69
JF
859};
860
63cd45c9 861struct CYRegEx :
3b52fd1a 862 CYTrivial
63cd45c9
JF
863{
864 const char *value_;
865
866 CYRegEx(const char *value) :
867 value_(value)
868 {
869 }
870
871 const char *Value() const {
872 return value_;
873 }
874
875 virtual void Output(CYOutput &out, CYFlags flags) const;
876};
877
cf7d4c69
JF
878struct CYNull :
879 CYWord,
3b52fd1a 880 CYTrivial
cf7d4c69
JF
881{
882 CYNull() :
883 CYWord("null")
884 {
885 }
5999c315 886
4644480a
JF
887 virtual CYNumber *Number(CYContext &context);
888 virtual CYString *String(CYContext &context);
889
652ec1ba 890 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
891};
892
893struct CYThis :
894 CYWord,
478d4ed0 895 CYMagic
cf7d4c69
JF
896{
897 CYThis() :
898 CYWord("this")
899 {
900 }
5999c315 901
3b52fd1a 902 virtual CYExpression *Replace(CYContext &context);
652ec1ba 903 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
904};
905
906struct CYBoolean :
3b52fd1a 907 CYTrivial
cf7d4c69 908{
5999c315 909 virtual bool Value() const = 0;
652ec1ba 910 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
911};
912
913struct CYFalse :
914 CYWord,
915 CYBoolean
916{
917 CYFalse() :
918 CYWord("false")
919 {
920 }
5999c315 921
11c1cc16
JF
922 virtual bool Value() const {
923 return false;
924 }
4644480a
JF
925
926 virtual CYNumber *Number(CYContext &context);
927 virtual CYString *String(CYContext &context);
cf7d4c69
JF
928};
929
930struct CYTrue :
931 CYWord,
932 CYBoolean
933{
934 CYTrue() :
935 CYWord("true")
936 {
937 }
5999c315 938
11c1cc16
JF
939 virtual bool Value() const {
940 return true;
941 }
4644480a
JF
942
943 virtual CYNumber *Number(CYContext &context);
944 virtual CYString *String(CYContext &context);
cf7d4c69
JF
945};
946
947struct CYVariable :
948 CYExpression
949{
950 CYIdentifier *name_;
951
952 CYVariable(CYIdentifier *name) :
953 name_(name)
954 {
955 }
5999c315 956
2eb8215d
JF
957 CYVariable(const char *name) :
958 name_(new($pool) CYIdentifier(name))
959 {
960 }
961
d35a3b07 962 CYPrecedence(0)
fb98ac0c 963 CYRightHand(false)
d35a3b07 964
3b52fd1a 965 virtual CYExpression *Replace(CYContext &context);
652ec1ba 966 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
967};
968
969struct CYPrefix :
63b4c5a8
JF
970 CYExpression
971{
972 CYExpression *rhs_;
973
cf7d4c69 974 CYPrefix(CYExpression *rhs) :
63b4c5a8
JF
975 rhs_(rhs)
976 {
977 }
5999c315 978
b09da87b 979 virtual bool Alphabetic() const = 0;
5999c315
JF
980 virtual const char *Operator() const = 0;
981
3b52fd1a
JF
982 CYPrecedence(4)
983
984 virtual CYExpression *Replace(CYContext &context);
652ec1ba 985 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
986};
987
cf7d4c69 988struct CYInfix :
63b4c5a8
JF
989 CYExpression
990{
991 CYExpression *lhs_;
992 CYExpression *rhs_;
993
cf7d4c69 994 CYInfix(CYExpression *lhs, CYExpression *rhs) :
63b4c5a8
JF
995 lhs_(lhs),
996 rhs_(rhs)
997 {
998 }
5999c315 999
0ff9f149
JF
1000 void SetLeft(CYExpression *lhs) {
1001 lhs_ = lhs;
1002 }
1003
b09da87b 1004 virtual bool Alphabetic() const = 0;
5999c315
JF
1005 virtual const char *Operator() const = 0;
1006
3b52fd1a 1007 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1008 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
1009};
1010
cf7d4c69 1011struct CYPostfix :
63b4c5a8
JF
1012 CYExpression
1013{
1014 CYExpression *lhs_;
1015
cf7d4c69 1016 CYPostfix(CYExpression *lhs) :
63b4c5a8
JF
1017 lhs_(lhs)
1018 {
1019 }
5999c315
JF
1020
1021 virtual const char *Operator() const = 0;
1022
3b52fd1a
JF
1023 CYPrecedence(3)
1024
1025 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1026 virtual void Output(CYOutput &out, CYFlags flags) const;
63b4c5a8
JF
1027};
1028
cf7d4c69 1029struct CYAssignment :
d35a3b07 1030 CYExpression
cf7d4c69 1031{
d35a3b07
JF
1032 CYExpression *lhs_;
1033 CYExpression *rhs_;
1034
cf7d4c69 1035 CYAssignment(CYExpression *lhs, CYExpression *rhs) :
d35a3b07
JF
1036 lhs_(lhs),
1037 rhs_(rhs)
cf7d4c69
JF
1038 {
1039 }
5999c315 1040
0ff9f149
JF
1041 void SetLeft(CYExpression *lhs) {
1042 lhs_ = lhs;
1043 }
1044
5999c315 1045 virtual const char *Operator() const = 0;
d35a3b07 1046
4de0686f
JF
1047 CYPrecedence(16)
1048
3b52fd1a 1049 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1050 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1051};
1052
62014ea9 1053struct CYArgument :
96a7e5c2
JF
1054 CYNext<CYArgument>,
1055 CYThing
62014ea9 1056{
cf7d4c69
JF
1057 CYWord *name_;
1058 CYExpression *value_;
cf7d4c69 1059
3b52fd1a
JF
1060 CYArgument(CYExpression *value, CYArgument *next = NULL) :
1061 CYNext<CYArgument>(next),
1062 name_(NULL),
1063 value_(value)
1064 {
1065 }
1066
cf7d4c69 1067 CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
62014ea9 1068 CYNext<CYArgument>(next),
cf7d4c69 1069 name_(name),
62014ea9 1070 value_(value)
cf7d4c69
JF
1071 {
1072 }
5999c315 1073
5192746c 1074 CYArgument *Replace(CYContext &context);
652ec1ba 1075 void Output(CYOutput &out) const;
cf7d4c69
JF
1076};
1077
1078struct CYBlank :
1079 public CYWord
1080{
1081 CYBlank() :
1082 CYWord("")
1083 {
1084 }
1085};
1086
5999c315
JF
1087struct CYClause :
1088 CYThing,
1089 CYNext<CYClause>
1090{
cf7d4c69 1091 CYExpression *case_;
3b52fd1a 1092 CYStatement *statements_;
cf7d4c69 1093
3b52fd1a 1094 CYClause(CYExpression *_case, CYStatement *statements) :
cf7d4c69 1095 case_(_case),
3b52fd1a 1096 statements_(statements)
cf7d4c69
JF
1097 {
1098 }
1099
fa389b0f 1100 void Replace(CYContext &context);
652ec1ba 1101 virtual void Output(CYOutput &out) const;
cf7d4c69
JF
1102};
1103
62014ea9 1104struct CYElement :
96a7e5c2
JF
1105 CYNext<CYElement>,
1106 CYThing
62014ea9 1107{
cf7d4c69 1108 CYExpression *value_;
cf7d4c69
JF
1109
1110 CYElement(CYExpression *value, CYElement *next) :
62014ea9
JF
1111 CYNext<CYElement>(next),
1112 value_(value)
cf7d4c69
JF
1113 {
1114 }
5999c315 1115
3b52fd1a 1116 void Replace(CYContext &context);
652ec1ba 1117 void Output(CYOutput &out) const;
5befe15e
JF
1118};
1119
1120struct CYArray :
1121 CYLiteral
1122{
1123 CYElement *elements_;
1124
3b52fd1a 1125 CYArray(CYElement *elements = NULL) :
5befe15e
JF
1126 elements_(elements)
1127 {
1128 }
1129
3b52fd1a 1130 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1131 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1132};
1133
550ee46a
JF
1134struct CYProperty :
1135 CYNext<CYProperty>,
1136 CYThing
1137{
1138 CYPropertyName *name_;
1139 CYExpression *value_;
1140
1141 CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
1142 CYNext<CYProperty>(next),
1143 name_(name),
1144 value_(value)
1145 {
1146 }
1147
1148 void Replace(CYContext &context);
1149 virtual void Output(CYOutput &out) const;
1150};
1151
cf7d4c69
JF
1152struct CYDeclaration :
1153 CYForInInitialiser
1154{
1155 CYIdentifier *identifier_;
1156 CYExpression *initialiser_;
1157
550ee46a 1158 CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
cf7d4c69
JF
1159 identifier_(identifier),
1160 initialiser_(initialiser)
1161 {
1162 }
5999c315 1163
652ec1ba 1164 virtual void ForIn(CYOutput &out, CYFlags flags) const;
ad3b38bb 1165 virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
3b52fd1a 1166
029bc65b 1167 virtual CYExpression *Replace(CYContext &context);
15b88a33 1168
029bc65b 1169 virtual CYAssignment *Assignment(CYContext &context);
15b88a33 1170 CYVariable *Variable(CYContext &context);
75b0a457 1171
652ec1ba 1172 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1173};
1174
1175struct CYDeclarations :
cac61857 1176 CYNext<CYDeclarations>,
15b88a33 1177 CYThing
cf7d4c69
JF
1178{
1179 CYDeclaration *declaration_;
cf7d4c69 1180
cacd1a88 1181 CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
cac61857
JF
1182 CYNext<CYDeclarations>(next),
1183 declaration_(declaration)
1184 {
1185 }
1186
15b88a33 1187 void Replace(CYContext &context);
96a7e5c2 1188
15b88a33 1189 CYCompound *Compound(CYContext &context);
550ee46a 1190 CYProperty *Property(CYContext &context);
15b88a33
JF
1191 CYArgument *Argument(CYContext &context);
1192 CYFunctionParameter *Parameter(CYContext &context);
3b52fd1a 1193
96a7e5c2 1194 virtual void Output(CYOutput &out) const;
652ec1ba 1195 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1196};
1197
15b88a33
JF
1198struct CYForDeclarations :
1199 CYForInitialiser
1200{
1201 CYDeclarations *declarations_;
1202
1203 CYForDeclarations(CYDeclarations *declarations) :
1204 declarations_(declarations)
1205 {
1206 }
1207
1208 virtual CYCompound *Replace(CYContext &context);
1209 virtual void Output(CYOutput &out, CYFlags flags) const;
1210};
1211
cac61857
JF
1212struct CYVar :
1213 CYStatement
1214{
1215 CYDeclarations *declarations_;
1216
1217 CYVar(CYDeclarations *declarations) :
1218 declarations_(declarations)
1219 {
1220 }
1221
3b52fd1a 1222 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1223 virtual void Output(CYOutput &out, CYFlags flags) const;
cac61857
JF
1224};
1225
c8a0500b 1226struct CYLetStatement :
cac61857
JF
1227 CYStatement
1228{
1229 CYDeclarations *declarations_;
15b88a33 1230 CYStatement *code_;
cac61857 1231
c8a0500b 1232 CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
cac61857 1233 declarations_(declarations),
15b88a33 1234 code_(code)
cf7d4c69
JF
1235 {
1236 }
5999c315 1237
3b52fd1a 1238 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1239 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1240};
1241
cf7d4c69
JF
1242struct CYFor :
1243 CYStatement
1244{
1245 CYForInitialiser *initialiser_;
1246 CYExpression *test_;
1247 CYExpression *increment_;
1248 CYStatement *code_;
1249
1250 CYFor(CYForInitialiser *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
1251 initialiser_(initialiser),
1252 test_(test),
1253 increment_(increment),
1254 code_(code)
1255 {
1256 }
5999c315 1257
3b52fd1a 1258 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1259 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1260};
1261
1262struct CYForIn :
1263 CYStatement
1264{
1265 CYForInInitialiser *initialiser_;
1266 CYExpression *set_;
1267 CYStatement *code_;
1268
1269 CYForIn(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
1270 initialiser_(initialiser),
1271 set_(set),
1272 code_(code)
1273 {
1274 }
5999c315 1275
3b52fd1a 1276 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1277 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1278};
1279
d5618df7 1280struct CYForOf :
75b0a457
JF
1281 CYStatement
1282{
1283 CYForInInitialiser *initialiser_;
1284 CYExpression *set_;
1285 CYStatement *code_;
1286
d5618df7 1287 CYForOf(CYForInInitialiser *initialiser, CYExpression *set, CYStatement *code) :
75b0a457
JF
1288 initialiser_(initialiser),
1289 set_(set),
1290 code_(code)
1291 {
1292 }
1293
3b52fd1a 1294 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1295 virtual void Output(CYOutput &out, CYFlags flags) const;
75b0a457
JF
1296};
1297
693d501b
JF
1298struct CYObject :
1299 CYLiteral
1300{
3b52fd1a 1301 CYProperty *properties_;
693d501b 1302
ab2aa221 1303 CYObject(CYProperty *properties = NULL) :
3b52fd1a 1304 properties_(properties)
693d501b
JF
1305 {
1306 }
1307
3b52fd1a 1308 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1309 void Output(CYOutput &out, CYFlags flags) const;
693d501b
JF
1310};
1311
cf7d4c69
JF
1312struct CYMember :
1313 CYExpression
1314{
1315 CYExpression *object_;
1316 CYExpression *property_;
1317
1318 CYMember(CYExpression *object, CYExpression *property) :
1319 object_(object),
1320 property_(property)
1321 {
1322 }
5999c315 1323
9b5527f0
JF
1324 void SetLeft(CYExpression *object) {
1325 object_ = object;
1326 }
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
2eb8215d
JF
1359namespace cy {
1360namespace Syntax {
1361
1362struct New :
cf7d4c69
JF
1363 CYExpression
1364{
1365 CYExpression *constructor_;
1366 CYArgument *arguments_;
1367
2eb8215d 1368 New(CYExpression *constructor, CYArgument *arguments) :
cf7d4c69
JF
1369 constructor_(constructor),
1370 arguments_(arguments)
1371 {
1372 }
5999c315 1373
fb98ac0c
JF
1374 virtual unsigned Precedence() const {
1375 return arguments_ == NULL ? 2 : 1;
1376 }
1377
1378 CYRightHand(false)
d35a3b07 1379
3b52fd1a 1380 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1381 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1382
1383 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
cf7d4c69
JF
1384};
1385
2eb8215d
JF
1386} }
1387
cf7d4c69
JF
1388struct CYCall :
1389 CYExpression
1390{
1391 CYExpression *function_;
1392 CYArgument *arguments_;
1393
3b52fd1a 1394 CYCall(CYExpression *function, CYArgument *arguments = NULL) :
cf7d4c69
JF
1395 function_(function),
1396 arguments_(arguments)
1397 {
1398 }
5999c315 1399
fb98ac0c
JF
1400 CYPrecedence(1)
1401 CYRightHand(false)
d35a3b07 1402
3b52fd1a 1403 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1404 virtual void Output(CYOutput &out, CYFlags flags) const;
6c093cce
JF
1405
1406 virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
1407};
1408
1409struct CYRubyProc;
1410
1411struct CYRubyBlock :
1412 CYExpression
1413{
1414 CYExpression *call_;
1415 CYRubyProc *proc_;
1416
1417 CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
1418 call_(call),
1419 proc_(proc)
1420 {
1421 }
1422
1423 CYPrecedence(1)
1424 CYRightHand(false)
1425
1426 virtual CYExpression *Replace(CYContext &context);
1427 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1428};
1429
1430struct CYIf :
1431 CYStatement
1432{
1433 CYExpression *test_;
1434 CYStatement *true_;
1435 CYStatement *false_;
1436
3b52fd1a 1437 CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
cf7d4c69
JF
1438 test_(test),
1439 true_(_true),
1440 false_(_false)
1441 {
1442 }
5999c315 1443
3b52fd1a 1444 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1445 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1446};
1447
1448struct CYDoWhile :
1449 CYStatement
1450{
1451 CYExpression *test_;
1452 CYStatement *code_;
1453
1454 CYDoWhile(CYExpression *test, CYStatement *code) :
1455 test_(test),
1456 code_(code)
1457 {
1458 }
5999c315 1459
3b52fd1a 1460 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1461 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1462};
1463
1464struct CYWhile :
1465 CYStatement
1466{
1467 CYExpression *test_;
1468 CYStatement *code_;
1469
1470 CYWhile(CYExpression *test, CYStatement *code) :
1471 test_(test),
1472 code_(code)
1473 {
1474 }
5999c315 1475
3b52fd1a 1476 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1477 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1478};
1479
6c093cce 1480// XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
a846a8cd 1481struct CYFunction {
cf7d4c69 1482 CYIdentifier *name_;
b09da87b 1483 CYFunctionParameter *parameters_;
3b52fd1a 1484 CYBlock code_;
ab2aa221 1485 CYNonLocal *nonlocal_;
cf7d4c69 1486
3b52fd1a 1487 CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
cf7d4c69
JF
1488 name_(name),
1489 parameters_(parameters),
ab2aa221
JF
1490 code_(statements),
1491 nonlocal_(NULL)
cf7d4c69
JF
1492 {
1493 }
5999c315 1494
7c6c5b0a
JF
1495 virtual ~CYFunction() {
1496 }
1497
14ec9e00
JF
1498 void Inject(CYContext &context);
1499 virtual void Replace_(CYContext &context, bool outer);
fb98ac0c
JF
1500 virtual void Output(CYOutput &out, CYFlags flags) const;
1501};
1502
6c093cce 1503// XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression
fb98ac0c
JF
1504struct CYFunctionExpression :
1505 CYFunction,
1506 CYExpression
1507{
3b52fd1a
JF
1508 CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1509 CYFunction(name, parameters, statements)
fb98ac0c
JF
1510 {
1511 }
1512
d35a3b07 1513 CYPrecedence(0)
fb98ac0c 1514 CYRightHand(false)
d35a3b07 1515
3b52fd1a 1516 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1517 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1518};
1519
6c093cce
JF
1520// XXX: this should derive from CYAnonymousFunctionExpression
1521struct CYRubyProc :
1522 CYFunctionExpression
1523{
1524 CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) :
1525 CYFunctionExpression(NULL, parameters, statements)
1526 {
1527 }
1528
1529 virtual CYExpression *Replace(CYContext &context);
1530 virtual void Output(CYOutput &out, CYFlags flags) const;
1531};
1532
1533// XXX: this should derive from CYNamedFunction
fb98ac0c
JF
1534struct CYFunctionStatement :
1535 CYFunction,
b10bd496 1536 CYStatement
cf7d4c69 1537{
3b52fd1a
JF
1538 CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
1539 CYFunction(name, parameters, statements)
cf7d4c69
JF
1540 {
1541 }
5999c315 1542
3b52fd1a 1543 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1544 virtual void Output(CYOutput &out, CYFlags flags) const;
5999c315
JF
1545};
1546
1547struct CYExpress :
1548 CYStatement
1549{
1550 CYExpression *expression_;
1551
1552 CYExpress(CYExpression *expression) :
1553 expression_(expression)
1554 {
029bc65b
JF
1555 if (expression == NULL)
1556 throw;
5999c315
JF
1557 }
1558
3b52fd1a 1559 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1560 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1561};
1562
1563struct CYContinue :
1564 CYStatement
1565{
1566 CYIdentifier *label_;
1567
1568 CYContinue(CYIdentifier *label) :
1569 label_(label)
1570 {
1571 }
5999c315 1572
3b52fd1a 1573 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1574 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1575};
1576
1577struct CYBreak :
1578 CYStatement
1579{
1580 CYIdentifier *label_;
1581
1582 CYBreak(CYIdentifier *label) :
1583 label_(label)
1584 {
1585 }
5999c315 1586
3b52fd1a 1587 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1588 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1589};
1590
1591struct CYReturn :
1592 CYStatement
1593{
1594 CYExpression *value_;
1595
1596 CYReturn(CYExpression *value) :
1597 value_(value)
1598 {
1599 }
5999c315 1600
3b52fd1a 1601 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1602 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1603};
1604
1605struct CYEmpty :
1606 CYStatement
1607{
3b52fd1a 1608 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1609 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1610};
1611
96a7e5c2
JF
1612struct CYFinally :
1613 CYThing
1614{
3b52fd1a 1615 CYBlock code_;
b10bd496 1616
3b52fd1a
JF
1617 CYFinally(CYStatement *statements) :
1618 code_(statements)
b10bd496
JF
1619 {
1620 }
1621
3b52fd1a 1622 void Replace(CYContext &context);
b10bd496
JF
1623 virtual void Output(CYOutput &out) const;
1624};
1625
37954781
JF
1626namespace cy {
1627namespace Syntax {
1628
1629struct Catch :
1630 CYThing
1631{
1632 CYIdentifier *name_;
1633 CYBlock code_;
1634
1635 Catch(CYIdentifier *name, CYStatement *statements) :
1636 name_(name),
1637 code_(statements)
1638 {
1639 }
1640
1641 void Replace(CYContext &context);
1642 virtual void Output(CYOutput &out) const;
1643};
1644
1645struct Try :
cf7d4c69
JF
1646 CYStatement
1647{
3b52fd1a 1648 CYBlock code_;
37954781 1649 Catch *catch_;
b10bd496 1650 CYFinally *finally_;
cf7d4c69 1651
37954781 1652 Try(CYStatement *statements, Catch *_catch, CYFinally *finally) :
3b52fd1a 1653 code_(statements),
cf7d4c69
JF
1654 catch_(_catch),
1655 finally_(finally)
1656 {
1657 }
5999c315 1658
3b52fd1a 1659 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1660 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1661};
1662
37954781 1663struct Throw :
cf7d4c69
JF
1664 CYStatement
1665{
1666 CYExpression *value_;
1667
ab2aa221 1668 Throw(CYExpression *value = NULL) :
cf7d4c69
JF
1669 value_(value)
1670 {
1671 }
5999c315 1672
3b52fd1a 1673 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1674 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1675};
1676
37954781
JF
1677} }
1678
cf7d4c69
JF
1679struct CYWith :
1680 CYStatement
1681{
1682 CYExpression *scope_;
1683 CYStatement *code_;
1684
1685 CYWith(CYExpression *scope, CYStatement *code) :
1686 scope_(scope),
1687 code_(code)
1688 {
1689 }
5999c315 1690
3b52fd1a 1691 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1692 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1693};
1694
1695struct CYSwitch :
1696 CYStatement
1697{
1698 CYExpression *value_;
1699 CYClause *clauses_;
1700
1701 CYSwitch(CYExpression *value, CYClause *clauses) :
1702 value_(value),
1703 clauses_(clauses)
1704 {
1705 }
5999c315 1706
3b52fd1a 1707 virtual CYStatement *Replace(CYContext &context);
c8a0500b
JF
1708 virtual void Output(CYOutput &out, CYFlags flags) const;
1709};
1710
1711struct CYDebugger :
1712 CYStatement
1713{
1714 CYDebugger()
1715 {
1716 }
1717
1718 virtual CYStatement *Replace(CYContext &context);
fb98ac0c 1719 virtual void Output(CYOutput &out, CYFlags flags) const;
cf7d4c69
JF
1720};
1721
1722struct CYCondition :
1723 CYExpression
1724{
1725 CYExpression *test_;
1726 CYExpression *true_;
1727 CYExpression *false_;
1728
1729 CYCondition(CYExpression *test, CYExpression *_true, CYExpression *_false) :
91a416e4 1730 test_(test),
cf7d4c69
JF
1731 true_(_true),
1732 false_(_false)
1733 {
1734 }
5999c315 1735
d35a3b07
JF
1736 CYPrecedence(15)
1737
3b52fd1a 1738 virtual CYExpression *Replace(CYContext &context);
652ec1ba 1739 virtual void Output(CYOutput &out, CYFlags flags) const;
5999c315
JF
1740};
1741
1742struct CYAddressOf :
1743 CYPrefix
1744{
1745 CYAddressOf(CYExpression *rhs) :
1746 CYPrefix(rhs)
1747 {
1748 }
1749
1750 virtual const char *Operator() const {
1751 return "&";
1752 }
1753
b09da87b 1754 CYAlphabetic(false)
d35a3b07 1755
3b52fd1a 1756 virtual CYExpression *Replace(CYContext &context);
5999c315
JF
1757};
1758
1759struct CYIndirect :
1760 CYPrefix
1761{
1762 CYIndirect(CYExpression *rhs) :
1763 CYPrefix(rhs)
1764 {
1765 }
1766
1767 virtual const char *Operator() const {
561ac418 1768 return "*";
5999c315
JF
1769 }
1770
b09da87b 1771 CYAlphabetic(false)
d35a3b07 1772
3b52fd1a 1773 virtual CYExpression *Replace(CYContext &context);
cf7d4c69
JF
1774};
1775
4644480a
JF
1776#define CYReplace \
1777 virtual CYExpression *Replace(CYContext &context);
1778
1779#define CYPostfix_(op, name, args...) \
cf7d4c69
JF
1780 struct CY ## name : \
1781 CYPostfix \
4644480a 1782 { args \
cf7d4c69
JF
1783 CY ## name(CYExpression *lhs) : \
1784 CYPostfix(lhs) \
1785 { \
1786 } \
5999c315
JF
1787 \
1788 virtual const char *Operator() const { \
1789 return op; \
1790 } \
cf7d4c69
JF
1791 };
1792
4644480a 1793#define CYPrefix_(alphabetic, op, name, args...) \
cf7d4c69
JF
1794 struct CY ## name : \
1795 CYPrefix \
4644480a 1796 { args \
cf7d4c69
JF
1797 CY ## name(CYExpression *rhs) : \
1798 CYPrefix(rhs) \
1799 { \
1800 } \
d35a3b07 1801 \
b09da87b 1802 CYAlphabetic(alphabetic) \
5999c315
JF
1803 \
1804 virtual const char *Operator() const { \
1805 return op; \
1806 } \
cf7d4c69
JF
1807 };
1808
4644480a 1809#define CYInfix_(alphabetic, precedence, op, name, args...) \
cf7d4c69
JF
1810 struct CY ## name : \
1811 CYInfix \
4644480a 1812 { args \
cf7d4c69
JF
1813 CY ## name(CYExpression *lhs, CYExpression *rhs) : \
1814 CYInfix(lhs, rhs) \
1815 { \
1816 } \
d35a3b07 1817 \
b09da87b 1818 CYAlphabetic(alphabetic) \
d35a3b07 1819 CYPrecedence(precedence) \
5999c315
JF
1820 \
1821 virtual const char *Operator() const { \
1822 return op; \
1823 } \
cf7d4c69
JF
1824 };
1825
4644480a 1826#define CYAssignment_(op, name, args...) \
cf7d4c69
JF
1827 struct CY ## name ## Assign : \
1828 CYAssignment \
4644480a 1829 { args \
cf7d4c69
JF
1830 CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
1831 CYAssignment(lhs, rhs) \
1832 { \
1833 } \
5999c315
JF
1834 \
1835 virtual const char *Operator() const { \
1836 return op; \
1837 } \
cf7d4c69
JF
1838 };
1839
1840CYPostfix_("++", PostIncrement)
1841CYPostfix_("--", PostDecrement)
1842
b09da87b
JF
1843CYPrefix_(true, "delete", Delete)
1844CYPrefix_(true, "void", Void)
1845CYPrefix_(true, "typeof", TypeOf)
1846CYPrefix_(false, "++", PreIncrement)
1847CYPrefix_(false, "--", PreDecrement)
c0bc320e 1848CYPrefix_(false, "+", Affirm)
b09da87b
JF
1849CYPrefix_(false, "-", Negate)
1850CYPrefix_(false, "~", BitwiseNot)
1851CYPrefix_(false, "!", LogicalNot)
1852
1853CYInfix_(false, 5, "*", Multiply)
1854CYInfix_(false, 5, "/", Divide)
1855CYInfix_(false, 5, "%", Modulus)
4644480a 1856CYInfix_(false, 6, "+", Add, CYReplace)
b09da87b
JF
1857CYInfix_(false, 6, "-", Subtract)
1858CYInfix_(false, 7, "<<", ShiftLeft)
1859CYInfix_(false, 7, ">>", ShiftRightSigned)
1860CYInfix_(false, 7, ">>>", ShiftRightUnsigned)
1861CYInfix_(false, 8, "<", Less)
1862CYInfix_(false, 8, ">", Greater)
1863CYInfix_(false, 8, "<=", LessOrEqual)
1864CYInfix_(false, 8, ">=", GreaterOrEqual)
1865CYInfix_(true, 8, "instanceof", InstanceOf)
1866CYInfix_(true, 8, "in", In)
1867CYInfix_(false, 9, "==", Equal)
1868CYInfix_(false, 9, "!=", NotEqual)
1869CYInfix_(false, 9, "===", Identical)
1870CYInfix_(false, 9, "!==", NotIdentical)
1871CYInfix_(false, 10, "&", BitwiseAnd)
1872CYInfix_(false, 11, "^", BitwiseXOr)
1873CYInfix_(false, 12, "|", BitwiseOr)
1874CYInfix_(false, 13, "&&", LogicalAnd)
1875CYInfix_(false, 14, "||", LogicalOr)
cf7d4c69
JF
1876
1877CYAssignment_("=", )
1878CYAssignment_("*=", Multiply)
1879CYAssignment_("/=", Divide)
1880CYAssignment_("%=", Modulus)
1881CYAssignment_("+=", Add)
1882CYAssignment_("-=", Subtract)
1883CYAssignment_("<<=", ShiftLeft)
1884CYAssignment_(">>=", ShiftRightSigned)
1885CYAssignment_(">>>=", ShiftRightUnsigned)
1886CYAssignment_("&=", BitwiseAnd)
1887CYAssignment_("^=", BitwiseXOr)
1888CYAssignment_("|=", BitwiseOr)
1889
c5fa2867 1890#endif/*CYCRIPT_PARSER_HPP*/