+ CYMember(CYExpression *object, CYExpression *property) :
+ object_(object),
+ property_(property)
+ {
+ }
+
+ void SetLeft(CYExpression *object) {
+ object_ = object;
+ }
+};
+
+struct CYDirectMember :
+ CYMember
+{
+ CYDirectMember(CYExpression *object, CYExpression *property) :
+ CYMember(object, property)
+ {
+ }
+
+ CYPrecedence(1)
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYIndirectMember :
+ CYMember
+{
+ CYIndirectMember(CYExpression *object, CYExpression *property) :
+ CYMember(object, property)
+ {
+ }
+
+ CYPrecedence(1)
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+namespace cy {
+namespace Syntax {
+
+struct New :
+ CYExpression
+{
+ CYExpression *constructor_;
+ CYArgument *arguments_;
+
+ New(CYExpression *constructor, CYArgument *arguments) :
+ constructor_(constructor),
+ arguments_(arguments)
+ {
+ }
+
+ virtual int Precedence() const {
+ return arguments_ == NULL ? 2 : 1;
+ }
+
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+
+ virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
+};
+
+} }
+
+struct CYCall :
+ CYExpression
+{
+ CYExpression *function_;
+ CYArgument *arguments_;
+
+ CYCall(CYExpression *function, CYArgument *arguments = NULL) :
+ function_(function),
+ arguments_(arguments)
+ {
+ }
+
+ CYPrecedence(1)
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+
+ virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
+};
+
+struct CYRubyProc;
+
+struct CYRubyBlock :
+ CYExpression
+{
+ CYExpression *call_;
+ CYRubyProc *proc_;
+
+ CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
+ call_(call),
+ proc_(proc)
+ {
+ }
+
+ CYPrecedence(1)
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYIf :
+ CYStatement
+{
+ CYExpression *test_;
+ CYStatement *true_;
+ CYStatement *false_;
+
+ CYIf(CYExpression *test, CYStatement *_true, CYStatement *_false = NULL) :
+ test_(test),
+ true_(_true),
+ false_(_false)
+ {
+ }
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYDoWhile :
+ CYStatement
+{
+ CYExpression *test_;
+ CYStatement *code_;
+
+ CYDoWhile(CYExpression *test, CYStatement *code) :
+ test_(test),
+ code_(code)
+ {
+ }
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYWhile :
+ CYStatement
+{
+ CYExpression *test_;
+ CYStatement *code_;
+
+ CYWhile(CYExpression *test, CYStatement *code) :
+ test_(test),
+ code_(code)
+ {
+ }
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+// XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass)
+struct CYFunction {
+ CYIdentifier *name_;
+ CYFunctionParameter *parameters_;
+ CYStatement *code_;
+
+ CYNonLocal *nonlocal_;
+ CYThisScope this_;
+
+ CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :