: "," { $$ = 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;