std::string common;
bool rest(false);
- CYForEach (element, array->elements_) {
- CYString *string(dynamic_cast<CYString *>(element->value_));
+ for (CYElement *element(array->elements_); element != NULL; ) {
+ CYElementValue *value(dynamic_cast<CYElementValue *>(element));
+ _assert(value != NULL);
+ element = value->next_;
+
+ CYString *string(dynamic_cast<CYString *>(value->value_));
_assert(string != NULL);
std::string completion;
%type <expression_> ArrowFunction
%type <functionParameter_> ArrowParameters
%type <expression_> AssignmentExpression
+%type <expression_> AssignmentExpressionOpt
%type <identifier_> Binding
%type <identifier_> BindingIdentifier
%type <expression_> BitwiseANDExpression
%type <statement_> Declaration_
%type <statement_> Declaration
%type <clause_> DefaultClause
-%type <expression_> Element
-%type <expression_> ElementOpt
%type <element_> ElementList
%type <element_> ElementListOpt
%type <statement_> ElseStatementOpt
: "[" LexPushInOff ElementListOpt "]" LexPopIn { $$ = CYNew CYArray($3); }
;
-Element
- : AssignmentExpression { $$ = $1; }
- ;
-
-ElementOpt
- : Element { $$ = $1; }
- | LexSetRegExp { $$ = NULL; }
- ;
-
ElementList
- : ElementOpt "," ElementListOpt { $$ = CYNew CYElement($1, $3); }
- | Element { $$ = CYNew CYElement($1, NULL); }
+ : AssignmentExpressionOpt "," ElementListOpt { $$ = CYNew CYElementValue($1, $3); }
+ | LexSetRegExp "..." AssignmentExpression { $$ = CYNew CYElementSpread($3); }
+ | AssignmentExpression { $$ = CYNew CYElementValue($1, NULL); }
;
ElementListOpt
| LeftHandSideExpression "^=" AssignmentExpression { $$ = CYNew CYBitwiseXOrAssign($1, $3); }
| LeftHandSideExpression "|=" AssignmentExpression { $$ = CYNew CYBitwiseOrAssign($1, $3); }
;
+
+AssignmentExpressionOpt
+ : AssignmentExpression { $$ = $1; }
+ | LexSetRegExp { $$ = NULL; }
+ ;
/* }}} */
/* 12.15 Comma Operator ( , ) {{{ */
Expression
out << "while" << ' ' << '(' << *test_ << ')';
}
-void CYElement::Output(CYOutput &out) const {
+void CYElementSpread::Output(CYOutput &out) const {
+ out << "..." << value_;
+}
+
+void CYElementValue::Output(CYOutput &out) const {
if (value_ != NULL)
value_->Output(out, CYAssign::Precedence_, CYNoFlags);
if (next_ != NULL || value_ == NULL) {
out << ',';
- if (next_ != NULL && next_->value_ != NULL)
+ if (next_ != NULL && !next_->Elision())
out << ' ';
}
if (next_ != NULL)
virtual void PropertyName(CYOutput &out) const;
};
-struct CYElement;
+struct CYElementValue;
struct CYSpan :
CYNext<CYSpan>
{
}
- CYElement *Replace(CYContext &context);
+ CYElementValue *Replace(CYContext &context);
};
struct CYTemplate :
};
struct CYElement :
- CYNext<CYElement>,
CYThing
+{
+ virtual bool Elision() const = 0;
+
+ virtual void Replace(CYContext &context) = 0;
+};
+
+struct CYElementValue :
+ CYNext<CYElement>,
+ CYElement
{
CYExpression *value_;
- CYElement(CYExpression *value, CYElement *next) :
+ CYElementValue(CYExpression *value, CYElement *next) :
CYNext<CYElement>(next),
value_(value)
{
}
- void Replace(CYContext &context);
- void Output(CYOutput &out) const;
+ virtual bool Elision() const {
+ return value_ == NULL;
+ }
+
+ virtual void Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYElementSpread :
+ CYElement
+{
+ CYExpression *value_;
+
+ CYElementSpread(CYExpression *value) :
+ value_(value)
+ {
+ }
+
+ virtual bool Elision() const {
+ return false;
+ }
+
+ virtual void Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
};
struct CYArray :
}
CYExpression *CYArray::Replace(CYContext &context) {
- elements_->Replace(context);
+ if (elements_ != NULL)
+ elements_->Replace(context);
return this;
}
return this;
}
-void CYElement::Replace(CYContext &context) { $T()
+void CYElementSpread::Replace(CYContext &context) {
context.Replace(value_);
- next_->Replace(context);
+}
+
+void CYElementValue::Replace(CYContext &context) {
+ context.Replace(value_);
+ if (next_ != NULL)
+ next_->Replace(context);
}
CYStatement *CYEmpty::Replace(CYContext &context) {
}
}
-CYElement *CYSpan::Replace(CYContext &context) { $T(NULL)
- return $ CYElement(expression_, $ CYElement(string_, next_->Replace(context)));
+CYElementValue *CYSpan::Replace(CYContext &context) { $T(NULL)
+ return $ CYElementValue(expression_, $ CYElementValue(string_, next_->Replace(context)));
}
CYStatement *CYStatement::Return() {
}
CYExpression *CYTemplate::Replace(CYContext &context) {
- return $C2($M($M($M($V("String"), $S("prototype")), $S("concat")), $S("apply")), $S(""), $ CYArray($ CYElement(string_, spans_->Replace(context))));
+ return $C2($M($M($M($V("String"), $S("prototype")), $S("concat")), $S("apply")), $S(""), $ CYArray($ CYElementValue(string_, spans_->Replace(context))));
}
CYExpression *CYThis::Replace(CYContext &context) {