From fc8fc33d0c3a25e23e354fed740ff500fab218d9 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Mon, 30 Nov 2015 13:20:35 -0800 Subject: [PATCH] Parse (but ignore) ECMAScript 6 "spread elements". --- Complete.cpp | 8 ++++++-- Cycript.yy.in | 22 +++++++++------------- Output.cpp | 8 ++++++-- Parser.hpp | 42 ++++++++++++++++++++++++++++++++++++------ Replace.cpp | 18 ++++++++++++------ 5 files changed, 69 insertions(+), 29 deletions(-) diff --git a/Complete.cpp b/Complete.cpp index 13590bb..3d14193 100644 --- a/Complete.cpp +++ b/Complete.cpp @@ -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(element->value_)); + for (CYElement *element(array->elements_); element != NULL; ) { + CYElementValue *value(dynamic_cast(element)); + _assert(value != NULL); + element = value->next_; + + CYString *string(dynamic_cast(value->value_)); _assert(string != NULL); std::string completion; diff --git a/Cycript.yy.in b/Cycript.yy.in index 1215d39..908d4ca 100644 --- a/Cycript.yy.in +++ b/Cycript.yy.in @@ -377,6 +377,7 @@ _finline int yylex(cy::parser::semantic_type *semantic, CYLocation *location, vo %type ArrowFunction %type ArrowParameters %type AssignmentExpression +%type AssignmentExpressionOpt %type Binding %type BindingIdentifier %type BitwiseANDExpression @@ -408,8 +409,6 @@ _finline int yylex(cy::parser::semantic_type *semantic, CYLocation *location, vo %type Declaration_ %type Declaration %type DefaultClause -%type Element -%type ElementOpt %type ElementList %type ElementListOpt %type 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 diff --git a/Output.cpp b/Output.cpp index 9ec05c2..2ff5ad7 100644 --- a/Output.cpp +++ b/Output.cpp @@ -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) diff --git a/Parser.hpp b/Parser.hpp index 93d44cb..7602a63 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -797,7 +797,7 @@ struct CYString : virtual void PropertyName(CYOutput &out) const; }; -struct CYElement; +struct CYElementValue; struct CYSpan : CYNext @@ -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, CYThing +{ + virtual bool Elision() const = 0; + + virtual void Replace(CYContext &context) = 0; +}; + +struct CYElementValue : + CYNext, + CYElement { CYExpression *value_; - CYElement(CYExpression *value, CYElement *next) : + CYElementValue(CYExpression *value, CYElement *next) : CYNext(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 : diff --git a/Replace.cpp b/Replace.cpp index 79e18d4..06b6359 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -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) { -- 2.45.2