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