on master help sign in
Be more aggressive with parsing reserved words
bf46a33Evan Czaplicki
src/Parse/Declaration.hs+33−23
@@ -21,29 +21,32 @@ definition = D.Definition <$> Expr.def
21
21
22typeDecl :: IParser D.SourceDecl
22typeDecl :: IParser D.SourceDecl
23typeDecl =
23typeDecl =
24− do reserved "type" <?> "type declaration"
24+ do try (reserved "type") <?> "type declaration"
25− forcedWS
25+ forcedWS
26− isAlias <- optionMaybe (string "alias" >> forcedWS)
26+ isAlias <- optionMaybe (string "alias" >> forcedWS)
27
27
28− name <- capVar
28+ name <- capVar
29− args <- spacePrefix lowVar
29+ args <- spacePrefix lowVar
30− padded equals
30+ padded equals
31
31
32− case isAlias of
32+ case isAlias of
33− Just _ ->
33+ Just _ ->
34− do tipe <- Type.expr <?> "a type"
34+ do tipe <- Type.expr <?> "a type"
35− return (D.TypeAlias name args tipe)
35+ return (D.TypeAlias name args tipe)
36
36
37− Nothing ->
37+ Nothing ->
38− do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
38+ do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
39− return $ D.Datatype name args tcs
39+ return $ D.Datatype name args tcs
40
40
41
41
42infixDecl :: IParser D.SourceDecl
42infixDecl :: IParser D.SourceDecl
43infixDecl = do
43infixDecl = do
44+ assoc <-
45+ choice
44− assoc <- choice [ reserved "infixl" >> return D.L
46+ [ try (reserved "infixl") >> return D.L
45− , reserved "infix" >> return D.N
46− , reserved "infixr" >> return D.R ]
47+ , try (reserved "infixr") >> return D.R
48+ , try (reserved "infix") >> return D.N
49+ ]
47 forcedWS
50 forcedWS
48 n <- digit
51 n <- digit
49 forcedWS
52 forcedWS
@@ -52,10 +55,17 @@ infixDecl = do
52
55
53port :: IParser D.SourceDecl
56port :: IParser D.SourceDecl
54port =
57port =
55− do try (reserved "port")
58+ do try (reserved "port")
56− whitespace
59+ whitespace
57− name <- lowVar
60+ name <- lowVar
58− whitespace
61+ whitespace
59− let port' op ctor expr = do { try op ; whitespace ; ctor name <$> expr }
62+ let port' op ctor expr =
63+ do try op
64+ whitespace
65+ ctor name <$> expr
66+
67+ D.Port <$>
68+ choice
60− D.Port <$> choice [ port' hasType D.PPAnnotation Type.expr
69+ [ port' hasType D.PPAnnotation Type.expr
61− , port' equals D.PPDef Expr.expr ]
70+ , port' equals D.PPDef Expr.expr
71+ ]
src/Parse/Expression.hs+72−40
@@ -139,56 +139,87 @@ appExpr = do
139-------- Normal Expressions --------
139-------- Normal Expressions --------
140
140
141binaryExpr :: IParser Source.Expr
141binaryExpr :: IParser Source.Expr
142+binaryExpr =
142−binaryExpr = Binop.binops appExpr lastExpr anyOp
143+ Binop.binops appExpr lastExpr anyOp
144+ where
143− where lastExpr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
145+ lastExpr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
144− <|> lambdaExpr
146+ <|> lambdaExpr
147+
145
148
146ifExpr :: IParser Source.Expr'
149ifExpr :: IParser Source.Expr'
150+ifExpr =
151+ do try (reserved "if")
152+ whitespace
147−ifExpr = reserved "if" >> whitespace >> (normal <|> multiIf)
153+ normal <|> multiIf
148− where
154+ where
149− normal = do
155+ normal = do
150− bool <- expr
156+ bool <- expr
151− padded (reserved "then")
157+ padded (reserved "then")
152− thenBranch <- expr
158+ thenBranch <- expr
159+ whitespace <?> "an 'else' branch"
153− whitespace <?> "an 'else' branch" ; reserved "else" <?> "an 'else' branch" ; whitespace
160+ reserved "else" <?> "an 'else' branch"
161+ whitespace
154− elseBranch <- expr
162+ elseBranch <- expr
155− return $ E.MultiIf
163+ return $ E.MultiIf
156− [ (bool, thenBranch)
164+ [ (bool, thenBranch)
157− , (Annotation.sameAs elseBranch (E.Literal . L.Boolean $ True), elseBranch)
165+ , (Annotation.sameAs elseBranch (E.Literal . L.Boolean $ True), elseBranch)
158− ]
166+ ]
159−
167+
168+ multiIf =
160− multiIf = E.MultiIf <$> spaceSep1 iff
169+ E.MultiIf <$> spaceSep1 iff
170+ where
171+ iff =
161− where iff = do string "|" ; whitespace
172+ do string "|" ; whitespace
162− b <- expr ; padded arrow
173+ b <- expr ; padded arrow
163− (,) b <$> expr
174+ (,) b <$> expr
175+
164
176
165lambdaExpr :: IParser Source.Expr
177lambdaExpr :: IParser Source.Expr
178+lambdaExpr =
166−lambdaExpr = do char '\\' <|> char '\x03BB' <?> "anonymous function"
179+ do char '\\' <|> char '\x03BB' <?> "anonymous function"
167− whitespace
180+ whitespace
168− args <- spaceSep1 Pattern.term
181+ args <- spaceSep1 Pattern.term
169− padded arrow
182+ padded arrow
170− body <- expr
183+ body <- expr
171− return (makeFunction args body)
184+ return (makeFunction args body)
185+
172
186
173defSet :: IParser [Source.Def]
187defSet :: IParser [Source.Def]
188+defSet =
189+ block $
190+ do d <- def
174−defSet = block (do d <- def ; whitespace ; return d)
191+ whitespace
192+ return d
193+
175
194
176letExpr :: IParser Source.Expr'
195letExpr :: IParser Source.Expr'
177−letExpr = do
196+letExpr =
197+ do try (reserved "let")
178− reserved "let" ; whitespace
198+ whitespace
179− defs <- defSet
199+ defs <- defSet
180− padded (reserved "in")
200+ padded (reserved "in")
181− E.Let defs <$> expr
201+ E.Let defs <$> expr
202+
182
203
183caseExpr :: IParser Source.Expr'
204caseExpr :: IParser Source.Expr'
184−caseExpr = do
205+caseExpr =
185− reserved "case"; e <- padded expr; reserved "of"; whitespace
206+ do try (reserved "case")
207+ e <- padded expr
208+ reserved "of"
209+ whitespace
186− E.Case e <$> (with <|> without)
210+ E.Case e <$> (with <|> without)
211+ where
212+ case_ =
187− where case_ = do p <- Pattern.expr
213+ do p <- Pattern.expr
188− padded arrow
214+ padded arrow
189− (,) p <$> expr
215+ (,) p <$> expr
216+
217+ with =
190− with = brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
218+ brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
219+
220+ without =
191− without = block (do c <- case_ ; whitespace ; return c)
221+ block (do c <- case_ ; whitespace ; return c)
222+
192
223
193expr :: IParser Source.Expr
224expr :: IParser Source.Expr
194expr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
225expr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
@@ -196,6 +227,7 @@ expr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
196 <|> binaryExpr
227 <|> binaryExpr
197 <?> "an expression"
228 <?> "an expression"
198
229
230+
199defStart :: IParser [P.RawPattern]
231defStart :: IParser [P.RawPattern]
200defStart =
232defStart =
201 choice [ do p1 <- try Pattern.term
233 choice [ do p1 <- try Pattern.term
src/Parse/Helpers.hs+4−2
@@ -95,8 +95,10 @@ makeVar p =
95
95
96reserved :: String -> IParser String
96reserved :: String -> IParser String
97reserved word =
97reserved word =
98+ expecting ("reserved word '" ++ word ++ "'") $
99+ do string word
98− (try (string word >> notFollowedBy innerVarChar) >> return word)
100+ notFollowedBy innerVarChar
99− <?> "reserved word '" ++ word ++ "'"
101+ return word
100
102
101
103
102-- INFIX OPERATORS
104-- INFIX OPERATORS
src/Parse/Module.hs+3−7
@@ -26,12 +26,8 @@ headerAndImports =
26 do optional freshLine
26 do optional freshLine
27 (names, exports) <-
27 (names, exports) <-
28 option (["Main"], Var.openListing) (header `followedBy` freshLine)
28 option (["Main"], Var.openListing) (header `followedBy` freshLine)
29− imports' <- commitToImports <|> return []
29+ imports' <- imports
30 return $ Module.HeaderAndImports names exports imports'
30 return $ Module.HeaderAndImports names exports imports'
31− where
32− commitToImports =
33− do try (lookAhead $ reserved "import")
34− imports `followedBy` freshLine
35
31
36
32
37header :: IParser ([String], Var.Listing Var.Value)
33header :: IParser ([String], Var.Listing Var.Value)
@@ -48,12 +44,12 @@ header =
48
44
49imports :: IParser [(Module.Name, Module.ImportMethod)]
45imports :: IParser [(Module.Name, Module.ImportMethod)]
50imports =
46imports =
51− option [] ((:) <$> import' <*> many (try (freshLine >> import')))
47+ many (import' `followedBy` freshLine)
52
48
53
49
54import' :: IParser (Module.Name, Module.ImportMethod)
50import' :: IParser (Module.Name, Module.ImportMethod)
55import' =
51import' =
56− do reserved "import"
52+ do try (reserved "import")
57 whitespace
53 whitespace
58 names <- dotSep1 capVar
54 names <- dotSep1 capVar
59 (,) names <$> option (Module.As (intercalate "." names)) method
55 (,) names <$> option (Module.As (intercalate "." names)) method
src/Parse/Pattern.hs+10−5
@@ -25,12 +25,17 @@ basic = choice
25 c:_ | isUpper c -> P.Data (Var.Raw v) []
25 c:_ | isUpper c -> P.Data (Var.Raw v) []
26 _ -> P.Var v
26 _ -> P.Var v
27
27
28+
28asPattern :: P.RawPattern -> IParser P.RawPattern
29asPattern :: P.RawPattern -> IParser P.RawPattern
29−asPattern pattern = do
30+asPattern pattern =
30− var <- optionMaybe (try (whitespace >> reserved "as" >> whitespace >> lowVar))
31+ do var <- optionMaybe (try (whitespace >> reserved "as") >> whitespace >> lowVar)
31− return $ case var of
32+ case var of
33+ Just v ->
32− Just v -> P.Alias v pattern
34+ return (P.Alias v pattern)
35+
33− Nothing -> pattern
36+ Nothing ->
37+ return pattern
38+
34
39
35record :: IParser P.RawPattern
40record :: IParser P.RawPattern
36record = P.Record <$> brackets (commaSep1 lowVar)
41record = P.Record <$> brackets (commaSep1 lowVar)