+ public:
+ CYDriver(std::istream &data, const std::string &filename = "");
+ ~CYDriver();
+
+ Condition GetCondition();
+ void SetCondition(Condition condition);
+
+ void PushCondition(Condition condition);
+ void PopCondition();
+
+ void Warning(const cy::location &location, const char *message);
+};
+
+struct CYForInitialiser {
+ virtual ~CYForInitialiser() {
+ }
+
+ virtual CYExpression *Replace(CYContext &context) = 0;
+ virtual void Output(CYOutput &out, CYFlags flags) const = 0;
+};
+
+struct CYForInInitialiser {
+ virtual ~CYForInInitialiser() {
+ }
+
+ virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
+ virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value) = 0;
+
+ virtual CYExpression *Replace(CYContext &context) = 0;
+ virtual CYAssignment *Assignment(CYContext &context) = 0;
+
+ virtual void Output(CYOutput &out, CYFlags flags) const = 0;
+};
+
+struct CYNumber;
+struct CYString;
+
+struct CYExpression :
+ CYNext<CYExpression>,
+ CYForInitialiser,
+ CYForInInitialiser,
+ CYClassName,
+ CYThing
+{
+ virtual unsigned Precedence() const = 0;
+
+ virtual bool RightHand() const {
+ return true;
+ }
+
+ virtual void ForIn(CYOutput &out, CYFlags flags) const;
+ virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
+
+ virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
+
+ virtual void Output(CYOutput &out) const;
+ virtual void Output(CYOutput &out, CYFlags flags) const = 0;
+ void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
+
+ virtual CYExpression *ClassName(CYContext &context, bool object);
+ virtual void ClassName(CYOutput &out, bool object) const;
+
+ virtual CYExpression *Replace(CYContext &context) = 0;
+ virtual CYAssignment *Assignment(CYContext &context);
+
+ virtual CYExpression *Primitive(CYContext &context) {
+ return this;
+ }
+
+ virtual CYNumber *Number(CYContext &context) {
+ return NULL;
+ }
+
+ virtual CYString *String(CYContext &context) {
+ return NULL;
+ }
+
+ virtual const char *Word() const {
+ return NULL;
+ }
+};
+
+#define CYAlphabetic(value) \
+ virtual bool Alphabetic() const { \
+ return value; \
+ }
+
+#define CYPrecedence(value) \
+ static const unsigned Precedence_ = value; \
+ virtual unsigned Precedence() const { \
+ return Precedence_; \
+ }
+
+#define CYRightHand(value) \
+ virtual bool RightHand() const { \
+ return value; \
+ }
+
+struct CYCompound :
+ CYExpression
+{
+ CYExpression *expressions_;
+
+ CYCompound(CYExpression *expressions = NULL) :
+ expressions_(expressions)
+ {
+ }
+
+ void AddPrev(CYExpression *expression) {
+ CYSetLast(expression) = expressions_;
+ expressions_ = expression;
+ }
+
+ CYPrecedence(17)
+
+ virtual CYExpression *Replace(CYContext &context);
+ void Output(CYOutput &out, CYFlags flags) const;
+
+ virtual CYExpression *Primitive(CYContext &context);
+};
+
+struct CYDeclaration;
+
+struct CYFunctionParameter :
+ CYNext<CYFunctionParameter>,
+ CYThing
+{
+ CYForInInitialiser *initialiser_;
+
+ CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
+ CYNext<CYFunctionParameter>(next),
+ initialiser_(initialiser)
+ {
+ }
+
+ void Replace(CYContext &context, CYBlock &code);
+ void Output(CYOutput &out) const;
+};
+
+struct CYComprehension :
+ CYNext<CYComprehension>,
+ CYThing
+{
+ CYComprehension(CYComprehension *next = NULL) :
+ CYNext<CYComprehension>(next)
+ {
+ }
+
+ virtual const char *Name() const = 0;
+
+ virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
+ CYFunctionParameter *Parameters(CYContext &context) const;
+ virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
+ virtual void Output(CYOutput &out) const = 0;
+};
+
+struct CYForInComprehension :
+ CYComprehension
+{
+ CYIdentifier *name_;
+ CYExpression *set_;
+
+ CYForInComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
+ CYComprehension(next),
+ name_(name),
+ set_(set)
+ {
+ }
+
+ virtual const char *Name() const {
+ return name_->Word();
+ }
+
+ virtual CYFunctionParameter *Parameter(CYContext &context) const;
+ virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYForOfComprehension :
+ CYComprehension
+{
+ CYIdentifier *name_;
+ CYExpression *set_;
+
+ CYForOfComprehension(CYIdentifier *name, CYExpression *set, CYComprehension *next = NULL) :
+ CYComprehension(next),
+ name_(name),
+ set_(set)
+ {
+ }
+
+ virtual const char *Name() const {
+ return name_->Word();
+ }
+
+ virtual CYFunctionParameter *Parameter(CYContext &context) const;
+ virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYIfComprehension :
+ CYComprehension
+{
+ CYExpression *test_;
+
+ CYIfComprehension(CYExpression *test) :
+ test_(test)
+ {
+ }
+
+ virtual const char *Name() const {
+ return NULL;
+ }
+
+ virtual CYFunctionParameter *Parameter(CYContext &context) const;
+ virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
+ virtual void Output(CYOutput &out) const;