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