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