+
+ virtual void Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYNonLocal;
+
+struct CYContext {
+ CYOptions &options_;
+
+ CYScope *scope_;
+ CYIdentifierUsageVector rename_;
+
+ CYNonLocal *nonlocal_;
+ CYNonLocal *nextlocal_;
+ unsigned unique_;
+
+ CYContext(CYOptions &options) :
+ options_(options),
+ scope_(NULL),
+ nonlocal_(NULL),
+ nextlocal_(NULL),
+ unique_(0)
+ {
+ }
+
+ virtual ~CYContext() {
+ }
+
+ template <typename Type_>
+ void ReplaceAll(Type_ *&values) {
+ Type_ **last(&values);
+ CYForEach (next, values) {
+ Replace(*last = next);
+ if (*last != NULL)
+ last = &(*last)->next_;
+ }
+ }
+
+ template <typename Type_>
+ void Replace(Type_ *&value) {
+ for (;;) if (value == NULL)
+ break;
+ else {
+ Type_ *replace(value->Replace(*this));
+ if (replace != value)
+ value = replace;
+ else break;
+ }
+ }
+
+ void NonLocal(CYStatement *&statements);
+ CYIdentifier *Unique();
+};
+
+struct CYNonLocal {
+ CYIdentifier *identifier_;
+
+ CYNonLocal() :
+ identifier_(NULL)
+ {
+ }
+
+ CYIdentifier *Target(CYContext &context) {
+ if (identifier_ == NULL)
+ identifier_ = context.Unique();
+ return identifier_;
+ }
+};
+
+struct CYBlock :
+ CYStatement,
+ CYThing
+{
+ CYStatement *statements_;
+
+ CYBlock(CYStatement *statements) :
+ statements_(statements)
+ {
+ }
+
+ operator CYStatement *() const {
+ return statements_;
+ }
+
+ void AddPrev(CYStatement *statement) {
+ CYSetLast(statement, statements_);
+ statements_ = statement;
+ }
+
+ virtual CYStatement *Replace(CYContext &context);
+
+ virtual void Output(CYOutput &out) const;
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+enum CYState {
+ CYClear,
+ CYRestricted,
+ CYNewLine
+};
+
+class CYDriver {
+ public:
+ void *scanner_;
+
+ CYState state_;
+ bool nobrace_;
+ std::stack<bool> in_;
+
+ const char *data_;
+ size_t size_;
+ FILE *file_;
+
+ bool strict_;
+
+ enum Condition {
+ RegExpCondition,
+ XMLContentCondition,
+ XMLTagCondition,
+ };
+
+ std::string filename_;
+
+ struct Error {
+ bool warning_;
+ cy::location location_;
+ std::string message_;
+ };
+
+ typedef std::vector<Error> Errors;
+
+ CYProgram *program_;
+ Errors errors_;
+
+ bool auto_;
+
+ struct Context {
+ CYExpression *context_;
+
+ Context(CYExpression *context) :
+ context_(context)
+ {
+ }
+
+ typedef std::vector<CYWord *> Words;
+ Words words_;
+ };
+
+ typedef std::vector<Context> Contexts;
+ Contexts contexts_;
+
+ CYExpression *context_;
+
+ enum Mode {
+ AutoNone,
+ AutoPrimary,
+ AutoDirect,
+ AutoIndirect,
+ AutoMessage
+ } mode_;
+
+ private:
+ void ScannerInit();
+ void ScannerDestroy();
+
+ public:
+ CYDriver(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;
+};
+
+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
+{
+ 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) :
+ 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) :
+ 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;