}
 
 _finline CYFlags CYRight(CYFlags flags) {
-    return flags & (CYNoIn | CYNoTrailer);
+    return flags & (CYNoIn | CYNoTrailer | CYNoTerminator);
 }
 
 bool CYFalse::Value() const {
 }
 
 void CYAssignment::Output(CYOutput &out, CYFlags flags) const {
-    lhs_->Output(out, Precedence() - 1, CYLeft(flags));
+    lhs_->Output(out, Precedence() - 1, CYLeft(flags) | CYNoRightHand);
     out << Operator();
     rhs_->Output(out, Precedence(), CYRight(flags));
 }
 
-void CYBlock::Output(CYOutput &out) const {
-    for (CYStatement *statement(statements_); statement != NULL; statement = statement->next_)
-        statement->Output(out);
+void CYBlock::Output(CYOutput &out, CYFlags flags) const {
+    statements_->Single(out, flags);
 }
 
 void CYBoolean::Output(CYOutput &out, CYFlags flags) const {
         out << ' ';
 }
 
-void CYBreak::Output(CYOutput &out) const {
+void CYBreak::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "break";
     if (label_ != NULL)
         out << ' ' << *label_;
-    out << ';';
+    if ((flags & CYNoTerminator) == 0)
+        out << ';';
+    else if ((flags & CYNoTrailer) != 0)
+        out << ' ';
 }
 
 void CYCall::Output(CYOutput &out, CYFlags flags) const {
-    function_->Output(out, Precedence(), CYLeft(flags));
+    bool protect((flags & CYNoCall) != 0);
+    if (protect)
+        out << '(';
+    function_->Output(out, Precedence(), protect ? CYNoFlags : flags);
     out << '(';
     if (arguments_ != NULL)
         arguments_->Output(out);
     out << ')';
+    if (protect)
+        out << ')';
 }
 
 void CYCatch::Output(CYOutput &out) const {
     out << "catch(" << *name_ << "){";
     if (code_ != NULL)
-        code_->Show(out);
+        code_->Multiple(out);
     out << "}";
 }
 
-void CYCategory::Output(CYOutput &out) const {
+void CYCategory::Output(CYOutput &out, CYFlags flags) const {
     out << "(function($cys,$cyp,$cyc,$cyn,$cyt){";
     out << "$cyp=object_getClass($cys);";
     out << "$cyc=$cys;";
         messages_->Output(out, true);
     out << "})(";
     name_->ClassName(out, true);
-    out << ");";
-}
-
-void CYClass::Output(CYOutput &out) const {
-    Output(out, CYNoBF);
-    out << ";";
+    out << ')';
+    if ((flags & CYNoTerminator) == 0)
+        out << ';';
 }
 
 void CYClass::Output(CYOutput &out, CYFlags flags) const {
     out << "))";
 }
 
+void CYClassExpression::Output(CYOutput &out, CYFlags flags) const {
+    CYClass::Output(out, flags);
+}
+
+void CYClassStatement::Output(CYOutput &out, CYFlags flags) const {
+    CYClass::Output(out, flags);
+}
+
 void CYCompound::Output(CYOutput &out, CYFlags flags) const {
     if (CYExpression *expression = expressions_)
         if (CYExpression *next = expression->next_) {
     false_->Output(out, CYPA, CYRight(flags));
 }
 
-void CYContinue::Output(CYOutput &out) const {
+void CYContinue::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "continue";
     if (label_ != NULL)
         out << ' ' << *label_;
-    out << ';';
+    if ((flags & CYNoTerminator) == 0)
+        out << ';';
+    else if ((flags & CYNoTrailer) != 0)
+        out << ' ';
 }
 
 void CYClause::Output(CYOutput &out) const {
         out << "default";
     out << ':';
     if (code_ != NULL)
-        code_->Output(out, false);
+        code_->Multiple(out, next_ == NULL ? CYNoFlags : CYNoTrailer);
     if (next_ != NULL)
         out << *next_;
 }
 void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const {
     if ((flags & CYNoLeader) != 0)
         out << ' ';
-    out << "var ";
-    Output(out, CYRight(flags));
+    out << "var";
+    Output(out, CYRight(flags) | CYNoLeader);
 }
 
 void CYDeclaration::ForEachIn(CYOutput &out) const {
 }
 
 void CYDeclaration::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << *identifier_;
     if (initialiser_ != NULL) {
         out << '=';
 }
 
 void CYDeclarations::For(CYOutput &out) const {
-    out << "var ";
-    Output(out, CYNoIn);
+    out << "var";
+    Output(out, CYNoIn | CYNoLeader);
 }
 
 void CYDeclarations::Output(CYOutput &out, CYFlags flags) const {
     const CYDeclarations *declaration(this);
+    bool first(true);
   output:
     CYDeclarations *next(declaration->next_);
-    CYFlags right(next == NULL ? CYRight(flags) : CYCenter(flags));
-    declaration->declaration_->Output(out, right);
+    CYFlags jacks(first ? CYLeft(flags) : next == NULL ? CYRight(flags) : CYCenter(flags));
+    first = false;
+    declaration->declaration_->Output(out, jacks);
 
     if (next != NULL) {
         out << ',';
     }
 }
 
-void CYDoWhile::Output(CYOutput &out) const {
-    // XXX: extra space character!
-    out << "do ";
-    code_->Output(out, false);
+void CYDoWhile::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
+    out << "do";
+    code_->Single(out, CYNoLeader | CYNoTrailer);
     out << "while(";
     test_->Output(out, CYNoFlags);
     out << ')';
         next_->Output(out);
 }
 
-void CYEmpty::Output(CYOutput &out) const {
+void CYEmpty::Output(CYOutput &out, CYFlags flags) const {
     out << ';';
 }
 
-void CYEmpty::Output(CYOutput &out, bool block) const {
-    if (next_ != NULL)
-        CYStatement::Output(out, block);
-    else
-        out << "{}";
-}
-
-void CYExpress::Output(CYOutput &out) const {
-    expression_->Output(out, CYNoBF);
-    out << ';';
+void CYExpress::Output(CYOutput &out, CYFlags flags) const {
+    bool terminator((flags & CYNoTerminator) == 0);
+    expression_->Output(out, (terminator ? CYLeft(flags) : flags) | CYNoBF);
+    if (terminator)
+        out << ';';
 }
 
 void CYExpression::ClassName(CYOutput &out, bool object) const {
 }
 
 void CYExpression::ForEachIn(CYOutput &out) const {
-    // XXX: this should handle LeftHandSideExpression
-    Output(out, CYPA, CYNoFlags);
+    Output(out, CYPA, CYNoRightHand);
 }
 
 void CYExpression::ForIn(CYOutput &out, CYFlags flags) const {
-    // XXX: this should handle LeftHandSideExpression
-    Output(out, flags);
+    Output(out, flags | CYNoRightHand);
 }
 
 void CYExpression::Output(CYOutput &out, unsigned precedence, CYFlags flags) const {
-    if (precedence < Precedence()) {
+    if (precedence < Precedence() || (flags & CYNoRightHand) != 0 && RightHand()) {
         out << '(';
         Output(out, CYNoFlags);
         out << ')';
 void CYFinally::Output(CYOutput &out) const {
     out << "finally{";
     if (code_ != NULL)
-        code_->Show(out);
+        code_->Multiple(out);
     out << "}";
 }
 
-void CYFor::Output(CYOutput &out) const {
+void CYFor::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "for(";
     if (initialiser_ != NULL)
         initialiser_->For(out);
     if (increment_ != NULL)
         increment_->Output(out, CYNoFlags);
     out << ')';
-    code_->Output(out, false);
+    code_->Single(out, CYNoFlags);
 }
 
-void CYForEachIn::Output(CYOutput &out) const {
+void CYForEachIn::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
+
     out << "with({$cys:0,$cyt:0}){";
 
     out << "$cys=";
     initialiser_->ForEachIn(out);
     out << "=$cys[$cyt];";
 
-    code_->Show(out);
+    code_->Multiple(out);
 
     out << '}';
 
     out << "}}());";
 }
 
-void CYForIn::Output(CYOutput &out) const {
+void CYForIn::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "for(";
     initialiser_->ForIn(out, CYNoIn | CYNoTrailer);
     out << "in";
     set_->Output(out, CYNoLeader);
     out << ')';
-    code_->Output(out, false);
+    code_->Single(out, CYRight(flags));
 }
 
 void CYForInComprehension::Begin_(CYOutput &out) const {
     out << ')';
 }
 
-void CYFunction::Output(CYOutput &out) const {
-    CYLambda::Output(out, CYNoFlags);
+void CYFunction::Output(CYOutput &out, CYFlags flags) const {
+    bool protect((flags & CYNoFunction) != 0);
+    if (protect)
+        out << '(';
+    else if ((flags & CYNoLeader) != 0)
+        out << ' ';
+    out << "function";
+    if (name_ != NULL)
+        out << ' ' << *name_;
+    out << '(';
+    if (parameters_ != NULL)
+        out << *parameters_;
+    out << "){";
+    if (body_ != NULL)
+        body_->Multiple(out);
+    out << '}';
+    if (protect)
+        out << ')';
+}
+
+void CYFunctionExpression::Output(CYOutput &out, CYFlags flags) const {
+    CYFunction::Output(out, flags);
+}
+
+void CYFunctionStatement::Output(CYOutput &out, CYFlags flags) const {
+    CYFunction::Output(out, flags);
 }
 
 void CYFunctionParameter::Output(CYOutput &out) const {
     }
 }
 
-void CYIf::Output(CYOutput &out) const {
+void CYIf::Output(CYOutput &out, CYFlags flags) const {
+    bool protect(false);
+    if (false_ == NULL && (flags & CYNoDangle) != 0) {
+        protect = true;
+        out << '{';
+    } else if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "if(";
     test_->Output(out, CYNoFlags);
     out << ')';
-    true_->Output(out, true);
+    CYFlags right(protect ? CYNoFlags : CYRight(flags));
+    CYFlags jacks(CYNoDangle);
+    jacks |= false_ == NULL ? right : CYNoTrailer;
+    true_->Single(out, jacks);
     if (false_ != NULL) {
-        out << "else ";
-        false_->Output(out, false);
+        out << "else";
+        if (protect)
+            right |= CYNoTerminator;
+        false_->Single(out, CYNoLeader | right);
     }
+    if (protect)
+        out << '}';
 }
 
 void CYIfComprehension::Begin_(CYOutput &out) const {
 void CYIndirect::Output(CYOutput &out, CYFlags flags) const {
     rhs_->Output(out, 1, CYLeft(flags));
     out << ".$cyi";
+    if ((flags & CYNoTrailer) != 0)
+        out << ' ';
 }
 
 void CYIndirectMember::Output(CYOutput &out, CYFlags flags) const {
         out << ')';
 }
 
-void CYLambda::Output(CYOutput &out, CYFlags flags) const {
-    bool protect((flags & CYNoFunction) != 0);
-    if (protect)
-        out << '(';
-    else if ((flags & CYNoLeader) != 0)
+void CYLet::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
         out << ' ';
-    out << "function";
-    if (name_ != NULL)
-        out << ' ' << *name_;
-    out << '(';
-    if (parameters_ != NULL)
-        out << *parameters_;
-    out << "){";
-    if (body_ != NULL)
-        body_->Show(out);
-    out << '}';
-    if (protect)
-        out << ')';
-}
-
-void CYLet::Output(CYOutput &out) const {
     out << "let(";
     declarations_->Output(out, CYNoFlags);
     out << "){";
     if (statements_ != NULL)
-        statements_->Show(out);
+        statements_->Multiple(out);
     out << "}";
 }
 
             out << ',' << *parameter->name_;
     out << "){return function(){";
     if (body_ != NULL)
-        body_->Show(out);
+        body_->Multiple(out);
     out << "}.call(self);},$cyt),$cyt);";
 }
 
     if ((flags & CYNoLeader) != 0)
         out << ' ';
     out << "new";
-    constructor_->Output(out, Precedence(), CYCenter(flags) | CYNoLeader);
-    out << '(';
-    if (arguments_ != NULL)
+    constructor_->Output(out, Precedence(), CYCenter(flags) | CYNoLeader | CYNoCall);
+    if (arguments_ != NULL) {
+        out << '(';
         arguments_->Output(out);
-    out << ')';
+        out << ')';
+    }
 }
 
 void CYNull::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYNumber::PropertyName(CYOutput &out) const {
-    Output(out);
+    Output(out, CYNoFlags);
 }
 
 void CYObject::Output(CYOutput &out, CYFlags flags) const {
         out << ' ';
 }
 
-void CYReturn::Output(CYOutput &out) const {
+void CYReturn::Output(CYOutput &out, CYFlags flags) const {
+    bool terminator((flags & CYNoTerminator) == 0);
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "return";
     if (value_ != NULL)
-        value_->Output(out, CYNoLeader);
-    out << ';';
+        value_->Output(out, (terminator ? CYCenter(flags) : flags) | CYNoLeader);
+    if (terminator)
+        out << ';';
 }
 
 void CYSelector::Output(CYOutput &out, CYFlags flags) const {
     out << ')';
 }
 
-void CYStatement::Show(CYOutput &out) const {
-    for (const CYStatement *next(this); next != NULL; next = next->next_)
-        next->Output_(out);
+void CYStatement::Multiple(CYOutput &out, CYFlags flags) const {
+    bool first(true);
+    for (const CYStatement *next(this); next != NULL; next = next->next_) {
+        bool last(next->next_ == NULL);
+        CYFlags jacks(first ? last ? flags : CYLeft(flags) : last ? CYCenter(flags) : CYRight(flags));
+        if (last)
+            jacks |= CYNoTerminator;
+        first = false;
+        next->Output(out, jacks);
+    }
 }
 
-void CYStatement::Output(CYOutput &out, bool block) const {
-    if (!block && !IsBlock())
-        Output(out);
-    else {
+void CYStatement::Single(CYOutput &out, CYFlags flags) const {
+    if (next_ != NULL) {
         out << '{';
-        Show(out);
+        Multiple(out);
         out << '}';
+    } else {
+        bool protect(false);
+        if (labels_ != NULL && (flags & CYNoLeader) != 0)
+            protect = true;
+        if (protect)
+            out << ' ';
+        for (CYLabel *label(labels_); label != NULL; label = label->next_)
+            out << *label->name_ << ':';
+        Output(out, protect ? CYRight(flags) : flags);
     }
 }
 
-void CYStatement::Output_(CYOutput &out) const {
-    for (CYLabel *label(labels_); label != NULL; label = label->next_)
-        out << *label->name_ << ':';
-    Output(out);
-}
-
 void CYString::Output(CYOutput &out, CYFlags flags) const {
     unsigned quot(0), apos(0);
     for (const char *value(value_), *end(value_ + size_); value != end; ++value)
     if (const char *word = Word())
         out << word;
     else
-        Output(out);
+        Output(out, CYNoFlags);
 }
 
-void CYSwitch::Output(CYOutput &out) const {
+void CYSwitch::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "switch(";
     value_->Output(out, CYNoFlags);
     out << "){";
         out << ' ';
 }
 
-void CYThrow::Output(CYOutput &out) const {
+void CYThrow::Output(CYOutput &out, CYFlags flags) const {
+    bool terminator((flags & CYNoTerminator) == 0);
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "throw";
     if (value_ != NULL)
-        value_->Output(out, CYNoLeader);
-    out << ';';
+        value_->Output(out, (terminator ? CYCenter(flags) : flags) | CYNoLeader);
+    if (terminator)
+        out << ';';
 }
 
-void CYTry::Output(CYOutput &out) const {
+void CYTry::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "try{";
     if (code_ != NULL)
-        code_->Show(out);
+        code_->Multiple(out);
     out << "}";
     if (catch_ != NULL)
         catch_->Output(out);
         finally_->Output(out);
 }
 
-void CYVar::Output(CYOutput &out) const {
-    out << "var ";
-    declarations_->Output(out, CYNoFlags);
-    out << ';';
+void CYVar::Output(CYOutput &out, CYFlags flags) const {
+    bool terminator((flags & CYNoTerminator) == 0);
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
+    out << "var";
+    declarations_->Output(out, (terminator ? CYCenter(flags) : flags) | CYNoLeader);
+    if (terminator)
+        out << ';';
 }
 
 void CYVariable::Output(CYOutput &out, CYFlags flags) const {
         out << ' ';
 }
 
-void CYWhile::Output(CYOutput &out) const {
+void CYWhile::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "while(";
     test_->Output(out, CYNoFlags);
     out << ')';
-    code_->Output(out, false);
+    code_->Single(out, CYRight(flags));
 }
 
-void CYWith::Output(CYOutput &out) const {
+void CYWith::Output(CYOutput &out, CYFlags flags) const {
+    if ((flags & CYNoLeader) != 0)
+        out << ' ';
     out << "with(";
     scope_->Output(out, CYNoFlags);
     out << ')';
-    code_->Output(out, false);
+    code_->Single(out, CYRight(flags));
 }
 
 void CYWord::ClassName(CYOutput &out, bool object) const {
 
     }
 };
 
+enum CYNeeded {
+    CYNever     = -1,
+    CYSometimes =  0,
+    CYAlways    =  1,
+};
+
+enum CYFlags {
+    CYNoFlags =      0,
+    CYNoBrace =      (1 << 0),
+    CYNoFunction =   (1 << 1),
+    CYNoLeader =     (1 << 2),
+    CYNoTrailer =    (1 << 3),
+    CYNoIn =         (1 << 4),
+    CYNoHyphen =     (1 << 5),
+    CYNoCall =       (1 << 6),
+    CYNoRightHand =  (1 << 7),
+    CYNoDangle =     (1 << 8),
+    CYNoTerminator = (1 << 9),
+    CYNoBF =         (CYNoBrace | CYNoFunction),
+};
+
 struct CYStatement :
     CYNext<CYStatement>
 {
         return next_ != NULL;
     }
 
-    virtual void Show(CYOutput &out) const;
-    virtual void Output(CYOutput &out) const = 0;
-    virtual void Output(CYOutput &out, bool block) const;
-    virtual void Output_(CYOutput &out) const;
+    virtual void Single(CYOutput &out, CYFlags flags) const;
+    virtual void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
+
+  private:
+    virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 };
 
 struct CYBlock :
         return true;
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 enum CYState {
     void Warning(const cy::location &location, const char *message);
 };
 
-enum CYFlags {
-    CYNoFlags =    0,
-    CYNoBrace =    (1 << 0),
-    CYNoFunction = (1 << 1),
-    CYNoLeader =   (1 << 2),
-    CYNoTrailer =  (1 << 3),
-    CYNoIn =       (1 << 4),
-    CYNoHyphen =   (1 << 5),
-    CYNoBF =       (CYNoBrace | CYNoFunction),
-};
-
 struct CYForInitialiser {
     virtual void For(CYOutput &out) const = 0;
 };
 {
     virtual unsigned Precedence() const = 0;
 
+    virtual bool RightHand() const {
+        return true;
+    }
+
     virtual void For(CYOutput &out) const;
     virtual void ForIn(CYOutput &out, CYFlags flags) const;
 
         return value; \
     }
 
+#define CYRightHand(value) \
+    virtual bool RightHand() const { \
+        return value; \
+    }
+
 struct CYCompound :
     CYExpression
 {
     CYExpression
 {
     CYPrecedence(0)
+    CYRightHand(false)
 };
 
 struct CYMagic :
     CYExpression
 {
     CYPrecedence(0)
+    CYRightHand(false)
 };
 
 struct CYSelectorPart :
         return Value();
     }
 
-    virtual void Output(CYOutput &out) const {
-        return Output(out, CYNoFlags);
-    }
-
     virtual void Output(CYOutput &out, CYFlags flags) const;
     virtual void PropertyName(CYOutput &out) const;
 };
         return value_;
     }
 
-    virtual void Output(CYOutput &out) const {
-        return Output(out, CYNoFlags);
-    }
-
     virtual void Output(CYOutput &out, CYFlags flags) const;
     virtual void PropertyName(CYOutput &out) const;
 };
     }
 
     CYPrecedence(0)
+    CYRightHand(false)
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYLet :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYField :
     virtual void Output(CYOutput &out, bool replace) const;
 };
 
-struct CYClass :
-    CYExpression,
-    CYStatement
-{
+struct CYClass {
     CYClassName *name_;
     CYExpression *super_;
     CYField *fields_;
     {
     }
 
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYClassExpression :
+    CYClass,
+    CYExpression
+{
+    CYClassExpression(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) :
+        CYClass(name, super, fields, messages)
+    {
+    }
+
     CYPrecedence(0)
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYClassStatement :
+    CYClass,
+    CYStatement
+{
+    CYClassStatement(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) :
+        CYClass(name, super, fields, messages)
+    {
+    }
+
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYFunctionParameter :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYForIn :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYForEachIn :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYProperty :
     }
 
     CYPrecedence(1)
+    CYRightHand(false)
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
     }
 
     CYPrecedence(1)
+    CYRightHand(false)
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
     {
     }
 
-    CYPrecedence(1)
+    virtual unsigned Precedence() const {
+        return arguments_ == NULL ? 2 : 1;
+    }
+
+    CYRightHand(false)
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
     {
     }
 
-    CYPrecedence(2)
+    CYPrecedence(1)
+    CYRightHand(false)
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYDoWhile :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYWhile :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
-struct CYLambda :
-    CYExpression
-{
+struct CYFunction {
     CYIdentifier *name_;
     CYFunctionParameter *parameters_;
     CYStatement *body_;
 
-    CYLambda(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) :
+    CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) :
         name_(name),
         parameters_(parameters),
         body_(body)
     {
     }
 
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYFunctionExpression :
+    CYFunction,
+    CYExpression
+{
+    CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) :
+        CYFunction(name, parameters, body)
+    {
+    }
+
     CYPrecedence(0)
+    CYRightHand(false)
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
-struct CYFunction :
-    CYLambda,
+struct CYFunctionStatement :
+    CYFunction,
     CYStatement
 {
-    CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) :
-        CYLambda(name, parameters, body)
+    CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) :
+        CYFunction(name, parameters, body)
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYExpress :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYContinue :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYBreak :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYReturn :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYEmpty :
     CYStatement
 {
-    virtual void Output(CYOutput &out) const;
-    virtual void Output(CYOutput &out, bool block) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYFinally {
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYThrow :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYWith :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYSwitch :
     {
     }
 
-    virtual void Output(CYOutput &out) const;
+    virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
 struct CYCondition :