@@ -1,15 +1,19 @@
1−module Parser where
1+module Parser (toDefs) where
4import Control.Applicative ((<$>), (<*>))
4import Control.Applicative ((<$>), (<*>))
5import Control.Monad
5import Control.Monad
6import Data.Char (isSymbol, isDigit)
6import Data.Char (isSymbol, isDigit)
7import Data.List (foldl')
7import Data.List (foldl')
8−import Text.Parsec
8+import Text.Parsec hiding (newline,spaces)
10import ParseLib
10import ParseLib
11import Patterns
11import Patterns
12−import Binop
12+import Binops
16+import Types (Type (VarT))
14-------- Basic Terms --------
18-------- Basic Terms --------
@@ -17,7 +21,8 @@ numTerm :: (Monad m) => ParsecT [Char] u m Expr
17numTerm = liftM (Number . read) (many1 digit) <?> "number"
21numTerm = liftM (Number . read) (many1 digit) <?> "number"
19strTerm :: (Monad m) => ParsecT [Char] u m Expr
23strTerm :: (Monad m) => ParsecT [Char] u m Expr
20−strTerm = expecting "string" . liftM Str . betwixt '"' '"' . many $ noneOf "\""
24+strTerm = liftM Str . expecting "string" . betwixt '"' '"' . many $
25+ backslashed <|> satisfy (/='"')
22varTerm :: (Monad m) => ParsecT [Char] u m Expr
27varTerm :: (Monad m) => ParsecT [Char] u m Expr
23varTerm = toVar <$> var <?> "variable"
28varTerm = toVar <$> var <?> "variable"
@@ -27,20 +32,20 @@ toVar v = case v of "True" -> Boolean True
27 _ -> Var v
32 _ -> Var v
29chrTerm :: (Monad m) => ParsecT [Char] u m Expr
34chrTerm :: (Monad m) => ParsecT [Char] u m Expr
30−chrTerm = Chr <$> betwixt '\'' '\'' anyChar <?> "character"
35+chrTerm = Chr <$> betwixt '\'' '\'' (backslashed <|> satisfy (/='\'')) <?> "character"
33-------- Complex Terms --------
38-------- Complex Terms --------
35listTerm = expecting "list" . betwixtSpcs '[' ']' $ choice
40listTerm = expecting "list" . betwixtSpcs '[' ']' $ choice
36− [ try $ do { lo <- expr; string ".." ; Range lo <$> expr }
41+ [ try $ do { lo <- expr; symbol ".." ; Range lo <$> expr }
37− , list <$> expr `sepBy` lexeme (char ',')
42+ , list <$> commaSep expr
40parensTerm = expecting "parenthesized expression" . betwixtSpcs '(' ')' $ choice
45parensTerm = expecting "parenthesized expression" . betwixtSpcs '(' ')' $ choice
41 [ do op <- anyOp
46 [ do op <- anyOp
42 return . Lambda "x" . Lambda "y" $ Binop op (Var "x") (Var "y")
47 return . Lambda "x" . Lambda "y" $ Binop op (Var "x") (Var "y")
43− , do es <- expr `sepBy` lexeme (char ',')
48+ , do es <- commaSep expr
44 return $ case es of { [e] -> e; _ -> tuple es }
49 return $ case es of { [e] -> e; _ -> tuple es }
@@ -74,7 +79,7 @@ lambdaExpr = do lexeme $ oneOf "\\\x03BB"
74 return $ makeFunction args e
79 return $ makeFunction args e
76assignExpr = do
81assignExpr = do
77− patterns <- patternTerm `endBy1` whitespace; symbol "="; exp <- expr
82+ patterns <- (patternTerm <?> "definition") `endBy1` whitespace; symbol "="; exp <- expr
78 case patterns of
83 case patterns of
79 PVar f : args -> return (f, makeFunction args exp)
84 PVar f : args -> return (f, makeFunction args exp)
80 [PData x ps] -> if "Tuple" == take 5 x && all isDigit (drop 5 x) then
85 [PData x ps] -> if "Tuple" == take 5 x && all isDigit (drop 5 x) then
@@ -100,21 +105,21 @@ caseExpr = do
101expr = choice [ ifExpr, letExpr, caseExpr, lambdaExpr, binaryExpr ]
106expr = choice [ ifExpr, letExpr, caseExpr, lambdaExpr, binaryExpr ]
103−aoeu = parse (between whitespace eof expr) ""
105−symbol = lexeme . try . string
106−arrow = symbol "->" <|> symbol "\8594"
108def = do (f,e) <- assignExpr
108def = do (f,e) <- assignExpr
109 return ([f], [e], guid >>= \x -> return [VarT x])
109 return ([f], [e], guid >>= \x -> return [VarT x])
111−{--
111+manyDefs = try (do { d <- anyDef ; ds <- many freshDef ; return (d:ds) })
112+ <|> try (many1 freshDef)
113+ where freshDef = try $ many1 freshLine >> anyDef
114+ anyDef = def <|> datatype
113− (fss,ess,tss) <- unzip3 `liftM` plus (whitespace >> plus (sat (==NEWLINE)) >> def +|+ datatype)
117+ ds <- manyDefs
118+ let (fss,ess,tss) = unzip3 ds
114 let (fs,es,ts) = (concat fss, concat ess, concat `liftM` sequence tss)
119 let (fs,es,ts) = (concat fss, concat ess, concat `liftM` sequence tss)
115− star $ sat (==NEWLINE) +|+ sat (==SPACES)
120+ optional freshLine ; optional whitespace ; eof
116 return (Let (zip fs es) (Var "main"), liftM (zip fs) ts)
121 return (Let (zip fs es) (Var "main"), liftM (zip fs) ts)
118−err = "Parse Error: Better error messages to come!"
119−toDefs = parse defs . ('\n':)
123+toDefs source = case parse defs "Elm code" source of
120−--}
124+ Right result -> Right result
125+ Left err -> Left $ show err