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