Skip to content

Commit f8a0aea

Browse files
committed
wip: parse spread operator.
1 parent 1bc4033 commit f8a0aea

File tree

6 files changed

+16
-0
lines changed

6 files changed

+16
-0
lines changed

src/Language/JavaScript/Parser/AST.hs

+2
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ data JSExpression
108108
| JSObjectLiteral !JSAnnot !JSObjectPropertyList !JSAnnot -- ^lbrace contents rbrace
109109
| JSUnaryExpression !JSUnaryOp !JSExpression
110110
| JSVarInitExpression !JSExpression !JSVarInitializer -- ^identifier, initializer
111+
| JSSpreadExpression !JSAnnot !JSExpression
111112
deriving (Data, Eq, Show, Typeable)
112113

113114
data JSBinOp
@@ -311,6 +312,7 @@ instance ShowStripped JSExpression where
311312
ss (JSStringLiteral _ s) = "JSStringLiteral " ++ s
312313
ss (JSUnaryExpression op x) = "JSUnaryExpression (" ++ ss op ++ "," ++ ss x ++ ")"
313314
ss (JSVarInitExpression x1 x2) = "JSVarInitExpression (" ++ ss x1 ++ ") " ++ ss x2
315+
ss (JSSpreadExpression _ x1) = "JSSpreadExpression (" ++ ss x1 ++ ")"
314316

315317
instance ShowStripped JSTryCatch where
316318
ss (JSCatch _ _lb x1 _rb x3) = "JSCatch (" ++ ss x1 ++ "," ++ ss x3 ++ ")"

src/Language/JavaScript/Parser/Grammar7.y

+7
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import qualified Language.JavaScript.Parser.AST as AST
7171
'%' { ModToken {} }
7272
'!' { NotToken {} }
7373
'~' { BitwiseNotToken {} }
74+
'...' { SpreadToken {} }
7475
'.' { DotToken {} }
7576
'[' { LeftBracketToken {} }
7677
']' { RightBracketToken {} }
@@ -181,6 +182,9 @@ Colon : ':' { mkJSAnnot $1 }
181182
Semi :: { AST.JSAnnot }
182183
Semi : ';' { mkJSAnnot $1 }
183184

185+
Spread :: { AST.JSAnnot }
186+
Spread : '...' { mkJSAnnot $1 }
187+
184188
Dot :: { AST.JSAnnot }
185189
Dot : '.' { mkJSAnnot $1 }
186190

@@ -416,6 +420,7 @@ PrimaryExpression : 'this' { AST.JSLiteral (mkJSAnnot $1) "thi
416420
| Literal { $1 {- 'PrimaryExpression2' -} }
417421
| ArrayLiteral { $1 {- 'PrimaryExpression3' -} }
418422
| ObjectLiteral { $1 {- 'PrimaryExpression4' -} }
423+
| SpreadExpression { $1 }
419424
| LParen Expression RParen { AST.JSExpressionParen $1 $2 $3 }
420425

421426
-- Identifier :: See 7.6
@@ -468,6 +473,8 @@ IdentifierName : Identifier {$1}
468473
| 'future' { AST.JSIdentifier (mkJSAnnot $1) (tokenLiteral $1) }
469474

470475

476+
SpreadExpression :: { AST.JSExpression }
477+
SpreadExpression : Spread Expression { AST.JSSpreadExpression $1 $2 {- 'SpreadExpression' -} }
471478

472479
-- ArrayLiteral : See 11.1.4
473480
-- [ Elisionopt ]

src/Language/JavaScript/Parser/Lexer.x

+1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ tokens :-
320320
"%" { adapt (symbolToken ModToken) }
321321
"!" { adapt (symbolToken NotToken) }
322322
"~" { adapt (symbolToken BitwiseNotToken) }
323+
"..." { adapt (symbolToken SpreadToken) }
323324
"." { adapt (symbolToken DotToken) }
324325
"[" { adapt (symbolToken LeftBracketToken) }
325326
"]" { adapt (symbolToken RightBracketToken) }

src/Language/JavaScript/Parser/Token.hs

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ data Token
141141
| ModToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
142142
| NotToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
143143
| BitwiseNotToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
144+
| SpreadToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
144145
| DotToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
145146
| LeftBracketToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
146147
| RightBracketToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }

test/Test/Language/Javascript/ExpressionParser.hs

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ testExpressionParser = describe "Parse expressions:" $ do
6969
testExpr "!y" `shouldBe` "Right (JSAstExpression (JSUnaryExpression ('!',JSIdentifier 'y')))"
7070
testExpr "y++" `shouldBe` "Right (JSAstExpression (JSExpressionPostfix ('++',JSIdentifier 'y')))"
7171
testExpr "y--" `shouldBe` "Right (JSAstExpression (JSExpressionPostfix ('--',JSIdentifier 'y')))"
72+
testExpr "...y" `shouldBe` "Right (JSAstExpression (JSSpreadExpression (JSIdentifier 'y')))"
73+
7274

7375
it "new expression" $ do
7476
testExpr "new x()" `shouldBe` "Right (JSAstExpression (JSMemberNew (JSIdentifier 'x',JSArguments ())))"

test/Test/Language/Javascript/Lexer.hs

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ testLexer = describe "Lexer:" $ do
4949
testLex "'\"'" `shouldBe` "[StringToken '\"']"
5050
testLex "\"\\'\"" `shouldBe` "[StringToken \"\\'\"]"
5151

52+
it "spread token" $ do
53+
testLex "...a" `shouldBe` "[SpreadToken,IdentifierToken 'a']"
54+
5255
it "assignment" $ do
5356
testLex "x=1" `shouldBe` "[IdentifierToken 'x',SimpleAssignToken,DecimalToken 1]"
5457
testLex "x=1\ny=2" `shouldBe` "[IdentifierToken 'x',SimpleAssignToken,DecimalToken 1,WsToken,IdentifierToken 'y',SimpleAssignToken,DecimalToken 2]"

0 commit comments

Comments
 (0)