]> git.saurik.com Git - cycript.git/commitdiff
Parse (but ignore) ECMAScript 6 "spread elements".
authorJay Freeman (saurik) <saurik@saurik.com>
Mon, 30 Nov 2015 21:20:35 +0000 (13:20 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Mon, 30 Nov 2015 21:20:35 +0000 (13:20 -0800)
Complete.cpp
Cycript.yy.in
Output.cpp
Parser.hpp
Replace.cpp

index 13590bba7a2cbeafd8bc73714b4e004b4a12ed33..3d14193817461c6948b27fc9c34c5c735a1dc72d 100644 (file)
@@ -137,8 +137,12 @@ _visible char **CYComplete(const char *word, const std::string &line, CYUTF8Stri
     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;
index 1215d39207be49bc6b8076c509ed15f01212a6b7..908d4ca077a43645eb933026233b79eba0b2be00 100644 (file)
@@ -377,6 +377,7 @@ _finline int yylex(cy::parser::semantic_type *semantic, CYLocation *location, vo
 %type <expression_> ArrowFunction
 %type <functionParameter_> ArrowParameters
 %type <expression_> AssignmentExpression
+%type <expression_> AssignmentExpressionOpt
 %type <identifier_> Binding
 %type <identifier_> BindingIdentifier
 %type <expression_> BitwiseANDExpression
@@ -408,8 +409,6 @@ _finline int yylex(cy::parser::semantic_type *semantic, CYLocation *location, vo
 %type <statement_> Declaration_
 %type <statement_> Declaration
 %type <clause_> DefaultClause
-%type <expression_> Element
-%type <expression_> ElementOpt
 %type <element_> ElementList
 %type <element_> ElementListOpt
 %type <statement_> ElseStatementOpt
@@ -829,18 +828,10 @@ ArrayLiteral
     : "[" 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
@@ -1086,6 +1077,11 @@ AssignmentExpression
     | LeftHandSideExpression "^=" AssignmentExpression { $$ = CYNew CYBitwiseXOrAssign($1, $3); }
     | LeftHandSideExpression "|=" AssignmentExpression { $$ = CYNew CYBitwiseOrAssign($1, $3); }
     ;
+
+AssignmentExpressionOpt
+    : AssignmentExpression { $$ = $1; }
+    | LexSetRegExp { $$ = NULL; }
+    ;
 /* }}} */
 /* 12.15 Comma Operator ( , ) {{{ */
 Expression
index 9ec05c2044e100057f8c43489dbf7545add0ccaa..2ff5ad784c299bd1b894ea8cb4f017bf8032ae9f 100644 (file)
@@ -291,12 +291,16 @@ void CYDoWhile::Output(CYOutput &out, CYFlags flags) const {
     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)
index 93d44cb93727b3cc7078afdc86794699e96e3413..7602a6394eacf31a92ae4a2abf8c838928cde937 100644 (file)
@@ -797,7 +797,7 @@ struct CYString :
     virtual void PropertyName(CYOutput &out) const;
 };
 
-struct CYElement;
+struct CYElementValue;
 
 struct CYSpan :
     CYNext<CYSpan>
@@ -812,7 +812,7 @@ struct CYSpan :
     {
     }
 
-    CYElement *Replace(CYContext &context);
+    CYElementValue *Replace(CYContext &context);
 };
 
 struct CYTemplate :
@@ -1069,19 +1069,49 @@ struct CYClause :
 };
 
 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 :
index 79e18d4546a21eef8cfd4d0033c3a52360e0b896..06b6359fcc2c3ec7a8f42a0095f78d4e692c38aa 100644 (file)
@@ -80,7 +80,8 @@ CYArgument *CYArgument::Replace(CYContext &context) { $T(NULL)
 }
 
 CYExpression *CYArray::Replace(CYContext &context) {
-    elements_->Replace(context);
+    if (elements_ != NULL)
+        elements_->Replace(context);
     return this;
 }
 
@@ -298,9 +299,14 @@ CYStatement *CYDoWhile::Replace(CYContext &context) {
     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) {
@@ -853,8 +859,8 @@ void CYScope::Close(CYContext &context, CYStatement *&statements) {
         }
 }
 
-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() {
@@ -886,7 +892,7 @@ CYStatement *CYSwitch::Replace(CYContext &context) {
 }
 
 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) {