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