: "," { $$ = NULL; }
     ;
 /* }}} */
+
 /* JavaScript 1.7: Array Comprehensions {{{ */
 IfComprehension
     : "if" "(" Expression ")" { $$ = new(driver.pool_) CYIfComprehension($3); }
     : LetStatement
     ;
 *//* }}} */
+
 /* JavaScript FTW: Function Statements {{{ */
 Statement
     : LexSetRegExp FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $2; }
     ;
 /* }}} */
+/* JavaScript FTW: Optional Arguments {{{ */
+FormalParameterList
+    : Identifier "=" AssignmentExpression FormalParameterList_ { $$ = new(driver.pool_) CYOptionalFunctionParameter($1, $3, $4); }
+    ;
+/* }}} */
 
 %%
 
         out << ')';
 }
 
+void CYOptionalFunctionParameter::Output(CYOutput &out) const {
+    out << *name_ << '=' << *initializer_;
+    if (next_ != NULL)
+        out << ',' << ' ' << *next_;
+}
+
 void CYPostfix::Output(CYOutput &out, CYFlags flags) const {
     lhs_->Output(out, Precedence(), CYLeft(flags));
     out << Operator();
 
     {
     }
 
-    void Replace(CYContext &context);
+    virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
+    virtual void Output(CYOutput &out) const;
+};
+
+struct CYOptionalFunctionParameter :
+    CYFunctionParameter
+{
+    CYExpression *initializer_;
+
+    CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
+        CYFunctionParameter(name, next),
+        initializer_(initializer)
+    {
+    }
+
+    virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
     virtual void Output(CYOutput &out) const;
 };
 
 
     if (!outer && name_ != NULL)
         Inject(context);
 
-    parameters_->Replace(context);
+    parameters_ = parameters_->Replace(context, code_);
     code_.Replace(context);
 
     context.scope_ = scope.parent_;
     return this;
 }
 
-void CYFunctionParameter::Replace(CYContext &context) { $T()
+CYFunctionParameter *CYFunctionParameter::Replace(CYContext &context, CYBlock &code) {
     name_ = name_->Replace(context);
     context.scope_->Declare(context, name_, CYIdentifierArgument);
-    next_->Replace(context);
+    if (next_ != NULL)
+        next_ = next_->Replace(context, code);
+    return this;
 }
 
 CYStatement *CYFunctionStatement::Replace(CYContext &context) {
     return this;
 }
 
+CYFunctionParameter *CYOptionalFunctionParameter::Replace(CYContext &context, CYBlock &code) {
+    CYFunctionParameter *parameter($ CYFunctionParameter(name_, next_));
+    parameter = parameter->Replace(context, code);
+
+    CYVariable *name($ CYVariable(name_));
+    code.AddPrev($ CYIf($ CYIdentical($ CYTypeOf(name), $S("undefined")), $$->*
+        $E($ CYAssign(name, initializer_))
+    ));
+
+    return parameter;
+}
+
 CYExpression *CYPostfix::Replace(CYContext &context) {
     context.Replace(lhs_);
     return this;