@@ -1,4 +1,4 @@
1−module Parser (toDefs) where
1+module Parser (parseProgram) where
4import Control.Applicative ((<$>), (<*>))
4import Control.Applicative ((<$>), (<*>))
@@ -8,122 +8,31 @@ import Data.List (foldl')
8import Text.Parsec hiding (newline,spaces)
8import Text.Parsec hiding (newline,spaces)
10import ParseLib
10import ParseLib
11−import Patterns
11+import ParseExpr
13import ParseTypes
12import ParseTypes
16−import Types (Type (VarT))
18−-------- Basic Terms --------
20−numTerm :: (Monad m) => ParsecT [Char] u m Expr
21−numTerm = liftM (Number . read) (many1 digit) <?> "number"
23−strTerm :: (Monad m) => ParsecT [Char] u m Expr
24−strTerm = liftM Str . expecting "string" . betwixt '"' '"' . many $
25− backslashed <|> satisfy (/='"')
27−varTerm :: (Monad m) => ParsecT [Char] u m Expr
28−varTerm = toVar <$> var <?> "variable"
30−toVar v = case v of "True" -> Boolean True
31− "False" -> Boolean False
34−chrTerm :: (Monad m) => ParsecT [Char] u m Expr
35−chrTerm = Chr <$> betwixt '\'' '\'' (backslashed <|> satisfy (/='\''))
39−-------- Complex Terms --------
41−listTerm = braces $ choice
42− [ try $ do { lo <- expr; whitespace; string ".." ; whitespace
43− ; Range lo <$> expr }
44− , list <$> commaSep expr
47−parensTerm = parens $ choice
49− return . Lambda "x" . Lambda "y" $ Binop op (Var "x") (Var "y")
50− , do es <- commaSep expr
51− return $ case es of { [e] -> e; _ -> tuple es }
54−term = choice [ numTerm, strTerm, chrTerm
56− , listTerm, parensTerm ]
57− <?> "basic term (4, x, 'c', etc.)"
59−-------- Applications --------
62− tlist <- spaceSep1 term
63− return $ case tlist of
65− t:ts -> foldl' App t ts
67−-------- Normal Expressions --------
69−binaryExpr = binops appExpr anyOp
71−ifExpr = do reserved "if" ; whitespace ; e1 <- expr ; whitespace
72− reserved "then" ; whitespace ; e2 <- expr ; (whitespace <?> "an 'else' branch")
73− reserved "else" <?> "an 'else' branch" ; whitespace ; If e1 e2 <$> expr
75−lambdaExpr = do char '\\' <|> char '\x03BB' <?> "anonymous function"
77− args <- spaceSep1 patternTerm
78− whitespace ; arrow ; whitespace
80− return $ makeFunction args e
84− choice [ try $ do v <- PVar <$> lowVar
85− notFollowedBy (whitespace >> char ':')
86− (v:) <$> spacePrefix patternTerm
87− , (:[]) <$> patternExpr
88− ] <?> "the definition of a variable (x = ...)"
89− whitespace; string "="; whitespace; exp <- expr
90− flattenPatterns patterns exp
94− brace <- optionMaybe . try $ do
96− char '{' <?> "a set of definitions { x = ... ; y = ... }"
98− Nothing -> do whitespace; ds <- assignExpr
99− whitespace; reserved "in"; whitespace; Let ds <$> expr
100− Just '{' -> do whitespace ; dss <- semiSep1 assignExpr ; whitespace
101− string "}" <?> "closing bracket '}'"
102− whitespace; reserved "in"; whitespace; e <- expr
103− return $ Let (concat dss) e
106− reserved "case"; whitespace; e <- expr; whitespace; reserved "of"; whitespace
107− Case e <$> brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
108− where case_ = do p <- patternExpr; whitespace; arrow; whitespace
112−expr = choice [ ifExpr, letExpr, caseExpr, lambdaExpr, binaryExpr ] <?> "expression"
114−def = do (fs,es) <- unzip <$> assignExpr
115− return (fs, es, mapM (\_ -> liftM VarT guid) fs)
117−defs1 = do optional freshLine
118− d <- datatype <|> def
17+defs1 = do d <- datatype <|> def <?> "at least one definition"
119 (d:) <$> many (try (try freshLine >> (datatype <|> def)))
18 (d:) <$> many (try (try freshLine >> (datatype <|> def)))
122 (fss,ess,tss) <- unzip3 <$> defs1
21 (fss,ess,tss) <- unzip3 <$> defs1
123− let (fs,es,ts) = (concat fss, concat ess, concat `liftM` sequence tss)
22+ return (concat fss, concat ess, concat `liftM` sequence tss)
27+ (name,exports) <- option ("",[]) moduleDef
124 optional freshLine ; optional spaces ; eof
32 optional freshLine ; optional spaces ; eof
125− return (Let (zip fs es) (Var "main"), liftM (zip fs) ts)
33+ return (Module name exports is, ds)
127−toDefs source = case parse defs "" source of
36+ case parse program "" source of
128− Right result -> Right result
37+ Right result -> Right result
129− Left err -> Left $ "Parse error at " ++ show err
38+ Left err -> Left $ "Parse error at " ++ show err