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