@@ -1,115 +1,114 @@
1module Parser where
1module Parser where
4−import Binop (binops)
4+import Control.Applicative ((<$>), (<*>))
6−import Control.Monad (liftM)
5+import Control.Monad
6+import Data.Char (isSymbol, isDigit)
7import Data.List (foldl')
7import Data.List (foldl')
8−import Guid
8+import Text.Parsec
10−import ParserLib
10+import ParseLib
11−import ParseTypes (datatype)
13−import Tokens
11+import Patterns
14−import Types (Type (VarT))
12+import Binop
16-------- Basic Terms --------
14-------- Basic Terms --------
18−numTerm = do { whitespace; t <- item
16+numTerm :: (Monad m) => ParsecT [Char] u m Expr
19− ; case t of { NUMBER n -> return $ Number n; _ -> zero } }
17+numTerm = liftM (Number . read) (many1 digit) <?> "number"
20−strTerm = do { whitespace; t <- item
18+
21− ; case t of { STRING cs -> return $ Str cs
19+strTerm :: (Monad m) => ParsecT [Char] u m Expr
22− ; _ -> zero } }
20+strTerm = expecting "string" . liftM Str . betwixt '"' '"' . many $ noneOf "\""
24−varTerm = Var `liftM` var
22+varTerm :: (Monad m) => ParsecT [Char] u m Expr
25−chrTerm = Chr `liftM` chr
23+varTerm = toVar <$> var <?> "variable"
27−trueTerm = do { t TRUE; return $ Boolean True }
25+toVar v = case v of "True" -> Boolean True
28−falseTerm = do { t FALSE; return $ Boolean False }
26+ "False" -> Boolean False
29+chrTerm :: (Monad m) => ParsecT [Char] u m Expr
30+chrTerm = Chr <$> betwixt '\'' '\'' anyChar <?> "character"
31-------- Complex Terms --------
33-------- Complex Terms --------
33−listTerm = (do { t LBRACKET; start <- expr; t DOT2; end <- expr; t RBRACKET
35+listTerm = expecting "list" . betwixtSpcs '[' ']' $ choice
34− ; return $ Range start end }) +|+
36+ [ try $ do { lo <- expr; string ".." ; Range lo <$> expr }
35− (do { t LBRACKET; es <- sepBy (t COMMA) expr; t RBRACKET
37+ , list <$> expr `sepBy` lexeme (char ',')
36− ; return $ list es })
38+ ]
38−parensTerm = (do { t LPAREN; op <- anyOp; t RPAREN
40+parensTerm = expecting "parenthesized expression" . betwixtSpcs '(' ')' $ choice
39− ; return . Lambda "x" . Lambda "y" $
42+ return . Lambda "x" . Lambda "y" $ Binop op (Var "x") (Var "y")
40− Binop op (Var "x") (Var "y") }) +|+
43+ , do es <- expr `sepBy` lexeme (char ',')
41− (do { t LPAREN; es <- sepBy (t COMMA) expr; t RPAREN
42− ; return $ case es of { [e] -> e; _ -> tuple es } })
44+ return $ case es of { [e] -> e; _ -> tuple es }
44−term = select [ numTerm
47+term = lexeme (choice [ numTerm, strTerm, chrTerm
45− , strTerm
48+ , accessible varTerm
50− , listTerm
49+ , listTerm, parensTerm ])
51− , accessible parensTerm
50+ <?> "basic term (number, variable, etc.)"
54-------- Applications --------
52-------- Applications --------
56appExpr = do
54appExpr = do
57− tlist <- plus term
55+ tlist <- many1 (try term)
58 return $ case tlist of
56 return $ case tlist of
60 t:ts -> foldl' App t ts
58 t:ts -> foldl' App t ts
63−-------- Expressions with infix operators --------
60+-------- Normal Expressions --------
65binaryExpr = binops appExpr anyOp
62binaryExpr = binops appExpr anyOp
64+ifExpr = expecting "if expression" $
65+ do symbol "if" ; e1 <- expr
66+ symbol "then" ; e2 <- expr
67+ expecting "else branch" $ do
68+ symbol "else" ; If e1 e2 <$> expr
70+lambdaExpr = do lexeme $ oneOf "\\\x03BB"
71+ args <- patternTerm `endBy1` whitespace
74+ return $ makeFunction args e
77+ patterns <- patternTerm `endBy1` whitespace; symbol "="; exp <- expr
79+ PVar f : args -> return (f, makeFunction args exp)
80+ [PData x ps] -> if "Tuple" == take 5 x && all isDigit (drop 5 x) then
81+ fail "matching tuples is not yet supported in this context"
82+ else fail $ "Only tuples can be matched in this context, " ++
83+ "not other abstract data types such as lists."
84+ _ -> fail $ "Variables in assign statement are not acceptable: " ++
85+ "only named variables, named functions, and tuples are okay."
68−-------- Normal Expressions --------
87+letExpr = do
88+ symbol "let"; brace <- optionMaybe . lexeme $ char '{'
90+ Nothing -> do f <- assignExpr; symbol "in"; e <- expr; return (Let [f] e)
91+ Just '{' -> do fs <- assignExpr `sepBy1` symbol ";"
92+ symbol "}" ; symbol "in"; e <- expr
70−ifExpr = do { t IF; e1 <- expr; t THEN; e2 <- expr; t ELSE; e3 <- expr
95+caseExpr = do
71− ; return $ If e1 e2 e3 }
96+ symbol "case"; e <- expr; symbol "of"
97+ betwixtSpcs '{' '}' $ Case e <$> case_ `sepBy1` symbol ";"
98+ where case_ = do p <- patternExpr; whitespace; arrow; e <- expr; return (p,e)
73−lambdaExpr = do { t LAMBDA; vs <- plus var; t ARROW; e <- expr
74− ; return $ foldr Lambda e vs }
76−assignExpr = whitespace >> assignExprNospace
101+expr = choice [ ifExpr, letExpr, caseExpr, lambdaExpr, binaryExpr ]
77−assignExprNospace = do
78− p:ps <- plus patternTerm; assign; e <- expr
80− PVar x : _ -> return (x, foldr func e ps)
81− where func PAnything e' = Lambda "_" e'
82− func (PVar x) e' = Lambda x e'
83− func p' e' = Lambda "_temp" (Case (Var "_temp") [(p', e')])
84−-- _ : [] -> return $ \hole -> Case e [(p,hole)]
87−letExpr = do
103+aoeu = parse (between whitespace eof expr) ""
88− t LET; brace <- optional $ t LBRACE
90− Nothing -> do f <- assignExpr; t IN; e <- expr; return (Let [f] e)
91− Just LBRACE -> do fs <- sepBy1 (t SEMI) assignExpr; t RBRACE; t IN;
92− e <- expr; return (Let fs e)
94−caseExpr = do
105+symbol = lexeme . try . string
95− t CASE; e <- expr; t OF; t LBRACE
106+arrow = symbol "->" <|> symbol "\8594"
96− cases <- sepBy1 (t SEMI)
107+
97− (do { p <- patternExpr; t ARROW; e <- expr; return (p,e) })
108+def = do (f,e) <- assignExpr
99− return $ Case e cases
101−-------- All Expressions --------
103−expr = select [ letExpr
110−def = do (f,e) <- assignExprNospace
111 return ([f], [e], guid >>= \x -> return [VarT x])
109 return ([f], [e], guid >>= \x -> return [VarT x])
114 (fss,ess,tss) <- unzip3 `liftM` plus (whitespace >> plus (sat (==NEWLINE)) >> def +|+ datatype)
113 (fss,ess,tss) <- unzip3 `liftM` plus (whitespace >> plus (sat (==NEWLINE)) >> def +|+ datatype)
115 let (fs,es,ts) = (concat fss, concat ess, concat `liftM` sequence tss)
114 let (fs,es,ts) = (concat fss, concat ess, concat `liftM` sequence tss)
@@ -117,5 +116,5 @@ defs = do
117 return (Let (zip fs es) (Var "main"), liftM (zip fs) ts)
116 return (Let (zip fs es) (Var "main"), liftM (zip fs) ts)
119err = "Parse Error: Better error messages to come!"
118err = "Parse Error: Better error messages to come!"
120−toExpr = extractResult err . parse expr
121−toDefs = extractResult err . parse defs . (NEWLINE:)
119+toDefs = parse defs . ('\n':)