on master help sign in
Add support for unary negation with the '-' symbol. Makes the use of

'-' whitespace sensitive, as in the unary negation proposal in elm-discuss. f -1 == f (0-1) x - 1 == (x-1) x-1 == (x-1)

commit343dcf22500071ff5bac577419394cb28408f734 authorEvan Czaplicki <evan@Evans-MacBook-Air.local> dateSun 14 Jul 2013, 17:55 (13 years ago) parent08ff939
3 files changed+42−20
compiler/Parse/Expression.hs+15−5 compiler/Parse/Helpers.hs+26−14 compiler/Parse/Parser.hs+1−1
compiler/Parse/Expression.hs+15−5
@@ -39,6 +39,14 @@ accessor = do
3939 let loc e = Location.add ("." ++ lbl) (Location.at start end e)
4040 return (Lambda (PVar "_") (loc $ Access (loc $ Var "_") lbl))
4141
42+negative :: IParser (Expr t v)
43+negative = do
44+ start <- getPosition
45+ nTerm <- try (char '-' >> notFollowedBy (char '.' <|> char '-')) >> term
46+ end <- getPosition
47+ let loc e = Location.at start end e
48+ return (Binop "-" (loc $ Literal (Literal.IntNum 0)) nTerm)
49+
4250
4351-------- Complex Terms --------
4452
@@ -113,7 +121,7 @@ recordTerm = brackets $ choice [ misc, addLocation record ]
113121
114122
115123term :: IParser (LExpr t v)
116−term = addLocation (choice [ Literal <$> literal, listTerm, accessor ])
124+term = addLocation (choice [ Literal <$> literal, listTerm, accessor, negative ])
117125 <|> accessible (addLocation varTerm <|> parensTerm <|> recordTerm)
118126 <?> "basic term (4, x, 'c', etc.)"
119127
@@ -121,10 +129,12 @@ term = addLocation (choice [ Literal <$> literal, listTerm, accessor ])
121129
122130appExpr :: IParser (LExpr t v)
123131appExpr = do
124− tlist <- spaceSep1 term
125− return $ case tlist of
126− t:[] -> t
127− t:ts -> foldl' (\f x -> Location.merge f x $ App f x) t ts
132+ t <- term
133+ ts <- constrainedSpacePrefix term $ \str ->
134+ if null str then notFollowedBy (char '-') else return ()
135+ return $ case ts of
136+ [] -> t
137+ _ -> foldl' (\f x -> Location.merge f x $ App f x) t ts
128138
129139-------- Normal Expressions --------
130140
compiler/Parse/Helpers.hs+26−14
@@ -103,7 +103,14 @@ dotSep1 p = (:) <$> p <*> many (try (char '.') >> p)
103103spaceSep1 :: IParser a -> IParser [a]
104104spaceSep1 p = (:) <$> p <*> spacePrefix p
105105
106−spacePrefix p = many (try (whitespace >> indented >> p))
106+spacePrefix p = constrainedSpacePrefix p (\_ -> return ())
107+
108+constrainedSpacePrefix p constraint =
109+ many . try $ do
110+ n <- whitespace
111+ constraint n
112+ indented
113+ p
107114
108115followedBy a b = do x <- a ; b ; return x
109116
@@ -150,38 +157,43 @@ accessible expr = do
150157
151158
152159spaces :: IParser String
153−spaces = many1 ((multiComment <|> string " " <?> "") >> return ' ') <?> "spaces"
160+spaces = concat <$> many1 (multiComment <|> string " ") <?> "spaces"
154161
155−forcedWS :: IParser [String]
156−forcedWS = try (do { spaces; many nl_space }) <|> try (many1 nl_space)
157− where nl_space = try $ many1 newline >> spaces
162+forcedWS :: IParser String
163+forcedWS = choice [ try $ (++) <$> spaces <*> (concat <$> many nl_space)
164+ , try $ concat <$> many1 nl_space ]
165+ where nl_space = try ((++) <$> (concat <$> many1 newline) <*> spaces)
158166
159167-- Just eats whitespace until the next meaningful character.
160−dumbWhitespace :: IParser ()
161−dumbWhitespace = many (spaces <|> newline) >> return ()
168+dumbWhitespace :: IParser String
169+dumbWhitespace = concat <$> many (spaces <|> newline)
162170
163−whitespace :: IParser ()
164−whitespace = optional forcedWS <?> ""
171+whitespace :: IParser String
172+whitespace = option "" forcedWS <?> "whitespace"
165173
166174freshLine :: IParser [[String]]
167175freshLine = try (many1 newline >> many space_nl) <|> try (many1 space_nl) <?> ""
168176 where space_nl = try $ spaces >> many1 newline
169177
170178newline :: IParser String
171−newline = simpleNewline <|> lineComment <?> ""
179+newline = simpleNewline <|> lineComment <?> "newline"
172180
173181simpleNewline :: IParser String
174182simpleNewline = try (string "\r\n") <|> string "\n"
175183
176184lineComment :: IParser String
177−lineComment = do try (string "--")
178− manyTill anyChar $ simpleNewline <|> (eof >> return "\n")
185+lineComment = do
186+ try (string "--")
187+ comment <- manyTill anyChar $ simpleNewline <|> (eof >> return "\n")
188+ return ("--" ++ comment)
179189
180190multiComment :: IParser String
181191multiComment = do { try (string "{-"); closeComment }
182192
183193closeComment :: IParser String
184−closeComment = manyTill anyChar . choice $
194+closeComment = do
195+ comment <- manyTill anyChar . choice $
185196 [ try (string "-}") <?> "close comment"
186197 , do { try $ string "{-"; closeComment; closeComment }
187− ]
198+ ]
199+ return ("{-" ++ comment ++ "-}")
compiler/Parse/Parser.hs+1−1
@@ -46,7 +46,7 @@ parseDependencies =
4646
4747parseInfix :: String -> Either String OpTable
4848parseInfix = setupParser . many $ do
49− manyTill (whitespace <|> (anyChar >> return ())) freshLine
49+ manyTill ((whitespace >> return ' ') <|> anyChar) freshLine
5050 infixStmt
5151
5252setupParser p source =