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