Skip to content

Commit 98935c7

Browse files
committed
parse arrow functions.
1 parent 6ec951c commit 98935c7

File tree

5 files changed

+20
-2
lines changed

5 files changed

+20
-2
lines changed

src/Language/JavaScript/Parser/AST.hs

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ data JSExpression
9999
| JSExpressionParen !JSAnnot !JSExpression !JSAnnot -- ^lb,expression,rb
100100
| JSExpressionPostfix !JSExpression !JSUnaryOp -- ^expression, operator
101101
| JSExpressionTernary !JSExpression !JSAnnot !JSExpression !JSAnnot !JSExpression -- ^cond, ?, trueval, :, falseval
102+
| JSArrowExpression !JSAnnot !(JSCommaList JSIdent) !JSAnnot !JSAnnot !(Either JSExpression JSBlock) -- ^parameter list,arrow,block`
102103
| JSFunctionExpression !JSAnnot !JSIdent !JSAnnot !(JSCommaList JSIdent) !JSAnnot !JSBlock -- ^fn,name,lb, parameter list,rb,block`
103104
| JSMemberDot !JSExpression !JSAnnot !JSExpression -- ^firstpart, dot, name
104105
| JSMemberExpression !JSExpression !JSAnnot !(JSCommaList JSExpression) !JSAnnot -- expr, lb, args, rb
@@ -296,6 +297,8 @@ instance ShowStripped JSExpression where
296297
ss (JSExpressionParen _lp x _rp) = "JSExpressionParen (" ++ ss x ++ ")"
297298
ss (JSExpressionPostfix xs op) = "JSExpressionPostfix (" ++ ss op ++ "," ++ ss xs ++ ")"
298299
ss (JSExpressionTernary x1 _q x2 _c x3) = "JSExpressionTernary (" ++ ss x1 ++ "," ++ ss x2 ++ "," ++ ss x3 ++ ")"
300+
ss (JSArrowExpression _ n _ _ (Right bd)) = "JSArrowExpression (" ++ ss n ++ ") => " ++ ss bd
301+
ss (JSArrowExpression _ n _ _ (Left bd)) = "JSArrowExpression (" ++ ss n ++ ") => " ++ ss bd
299302
ss (JSFunctionExpression _ n _lb pl _rb x3) = "JSFunctionExpression " ++ ssid n ++ " " ++ ss pl ++ " (" ++ ss x3 ++ "))"
300303
ss (JSHexInteger _ s) = "JSHexInteger " ++ singleQuote s
301304
ss (JSOctal _ s) = "JSOctal " ++ singleQuote s

src/Language/JavaScript/Parser/Grammar7.y

+13-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import qualified Language.JavaScript.Parser.AST as AST
3939
'|' { BitwiseOrToken {} }
4040
'^' { BitwiseXorToken {} }
4141
'&' { BitwiseAndToken {} }
42+
'=>' { ArrowToken {} }
4243
'===' { StrictEqToken {} }
4344
'==' { EqToken {} }
4445
'*=' { TimesAssignToken {} }
@@ -182,6 +183,9 @@ Colon : ':' { mkJSAnnot $1 }
182183
Semi :: { AST.JSAnnot }
183184
Semi : ';' { mkJSAnnot $1 }
184185

186+
Arrow :: { AST.JSAnnot }
187+
Arrow : '=>' { mkJSAnnot $1 }
188+
185189
Spread :: { AST.JSAnnot }
186190
Spread : '...' { mkJSAnnot $1 }
187191

@@ -1106,8 +1110,15 @@ FunctionDeclaration : NamedFunctionExpression MaybeSemi { expressionToStatemen
11061110
-- FunctionExpression : See clause 13
11071111
-- function Identifieropt ( FormalParameterListopt ) { FunctionBody }
11081112
FunctionExpression :: { AST.JSExpression }
1109-
FunctionExpression : LambdaExpression { $1 {- 'FunctionExpression1' -} }
1110-
| NamedFunctionExpression { $1 {- 'FunctionExpression2' -} }
1113+
FunctionExpression : ArrowFunctionExpression { $1 {- 'ArrowFunctionExpression' -} }
1114+
| LambdaExpression { $1 {- 'FunctionExpression1' -} }
1115+
| NamedFunctionExpression { $1 {- 'FunctionExpression2' -} }
1116+
1117+
ArrowFunctionExpression :: { AST.JSExpression }
1118+
ArrowFunctionExpression : LParen FormalParameterList RParen Arrow Expression
1119+
{ AST.JSArrowExpression $1 $2 $3 $4 (Left $5) }
1120+
| LParen FormalParameterList RParen Arrow FunctionBody
1121+
{ AST.JSArrowExpression $1 $2 $3 $4 (Right $5) }
11111122
11121123
NamedFunctionExpression :: { AST.JSExpression }
11131124
NamedFunctionExpression : Function Identifier LParen RParen FunctionBody

src/Language/JavaScript/Parser/Lexer.x

+1
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ tokens :-
290290
"|" { adapt (symbolToken BitwiseOrToken) }
291291
"^" { adapt (symbolToken BitwiseXorToken) }
292292
"&" { adapt (symbolToken BitwiseAndToken) }
293+
"=>" { adapt (symbolToken ArrowToken) }
293294
"===" { adapt (symbolToken StrictEqToken) }
294295
"==" { adapt (symbolToken EqToken) }
295296
"*=" { adapt (symbolToken TimesAssignToken) }

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+
| ArrowToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
144145
| SpreadToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
145146
| DotToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }
146147
| LeftBracketToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] }

test/Test/Language/Javascript/ExpressionParser.hs

+2
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ testExpressionParser = describe "Parse expressions:" $ do
123123
testExpr "function(){}" `shouldBe` "Right (JSAstExpression (JSFunctionExpression '' () (JSBlock []))))"
124124
testExpr "function(a){}" `shouldBe` "Right (JSAstExpression (JSFunctionExpression '' (JSIdentifier 'a') (JSBlock []))))"
125125
testExpr "function(a,b){}" `shouldBe` "Right (JSAstExpression (JSFunctionExpression '' (JSIdentifier 'a',JSIdentifier 'b') (JSBlock []))))"
126+
testExpr "(a,b) => {}" `shouldBe` "Right (JSAstExpression (JSArrowExpression ((JSIdentifier 'a',JSIdentifier 'b')) => JSBlock []))"
127+
testExpr "(a,b) => a + b" `shouldBe` "Right (JSAstExpression (JSArrowExpression ((JSIdentifier 'a',JSIdentifier 'b')) => JSExpressionBinary ('+',JSIdentifier 'a',JSIdentifier 'b')))"
126128

127129
it "member expression" $ do
128130
testExpr "x[y]" `shouldBe` "Right (JSAstExpression (JSMemberSquare (JSIdentifier 'x',JSIdentifier 'y')))"

0 commit comments

Comments
 (0)