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