on master help sign in
Add guarded definitions. Add whitespace sensitivity for let- and case-expressions.
commit2eeac2fd0f386788538607444a8702fba0c63873 authorevancz <info@elm-lang.org> dateSat 24 Nov 2012, 20:49 (14 years ago) parent69ffd8e
15 files changed+143−77
core-js/Prelude.js+1 elm/Elm.cabal+4−2 elm/src/Ast.hs+2−1 elm/src/FreeVar.hs+2 elm/src/Gen/CompileToJS.hs+8 elm/src/Parse/Expr.hs+38−18 elm/src/Parse/Library.hs+41−30 elm/src/Parse/Modules.hs+7−7 elm/src/Parse/Parser.hs+1−1 elm/src/Parse/Patterns.hs+9−7 elm/src/Parse/Types.hs+10−9 elm/src/Rename.hs+4 elm/src/Replace.hs+3 elm/src/Substitute.hs+2−1 elm/src/Types/Constrain.hs+11−1
core-js/Prelude.js+1
@@ -75,6 +75,7 @@ Elm.Prelude = function() {
7575 snd : function(p) { return p[2]; },
7676 rem : function(x) { return function(y) { return x % y; }; },
7777 div : function(x) { return function(y) { return ~~(x / y); }; },
78+ otherwise : true,
7879 compare : function(x) { return function (y) {
7980 x = (typeof x === "object") ? toText(x) : x;
8081 y = (typeof y === "object") ? toText(y) : y;
elm/Elm.cabal+4−2
@@ -71,7 +71,8 @@ Library
7171 shakespeare >= 1,
7272 pandoc <= 1.9.4.2,
7373 bytestring,
74− hjsmin
74+ hjsmin,
75+ indents
7576
7677Executable elm
7778 Main-is: Compiler.hs
@@ -112,4 +113,5 @@ Executable elm
112113 cmdargs,
113114 pandoc <= 1.9.4.2,
114115 bytestring,
115− hjsmin
116+ hjsmin,
117+ indents
elm/src/Ast.hs+2−1
@@ -4,7 +4,6 @@ module Ast where
44import Data.Char (isDigit)
55import Data.List (intercalate)
66import Types.Types
7−import Guid
87import qualified Text.Pandoc as Pandoc
98
109data Module = Module [String] Exports Imports [Statement]
@@ -30,6 +29,7 @@ data Expr = IntNum Int
3029 | Lambda String Expr
3130 | App Expr Expr
3231 | If Expr Expr Expr
32+ | Guard [(Expr,Expr)]
3333 | Lift Expr [Expr]
3434 | Fold Expr Expr Expr
3535 | Async Expr
@@ -92,6 +92,7 @@ instance Show Expr where
9292 concat [ "\\", intercalate " " xs, " -> ", show e' ]
9393 show (App e1 e2) = show' e1 ++ " " ++ show' e2
9494 show (If e1 e2 e3) = concat [ "if ", show e1, " then ", show e2, " else ", show e3 ]
95+ show (Guard ps) = concatMap (\(b,e) -> concat ["\n | ",show b," = ",show e]) ps
9596 show (Let defs e) = "let { " ++ intercalate " ; " (map show defs) ++ " } in " ++ show e
9697 show (Var x) = x
9798 show (Case e pats) = "case " ++ show e ++ " of { " ++ intercalate " ; " (map (\(p,e) -> show p ++ " -> " ++ show e) pats) ++ " }"
elm/src/FreeVar.hs+2
@@ -1,6 +1,7 @@
11module FreeVar (freeIn,freeVars) where
22
33import Ast
4+import Control.Arrow ((***))
45import Data.Set (union, unions, delete, singleton, empty, difference, member)
56
67x `freeIn` expr = member x $ freeVars expr
@@ -13,6 +14,7 @@ freeVars expr =
1314 Lambda x e -> delete x (f e)
1415 App e1 e2 -> f e1 `union` f e2
1516 If e1 e2 e3 -> unions $ map f [e1,e2,e3]
17+ Guard ps -> map (f *** f) ps
1618 Lift e es -> unions $ map f es
1719 Fold e1 e2 e3 -> unions $ map f [e1,e2,e3]
1820 Async e -> f e
elm/src/Gen/CompileToJS.hs+8
@@ -173,6 +173,7 @@ instance ToJS Expr where
173173 Access e lbl -> (\s -> s ++ "." ++ lbl) `liftM` toJS e
174174 Binop op e1 e2 -> binop op `liftM` toJS e1 `ap` toJS e2
175175 If eb et ef -> parens `liftM` (iff `liftM` toJS eb `ap` toJS et `ap` toJS ef)
176+ Guard ps -> guardToJS ps
176177 Lambda v e -> liftM (jsFunc v . ret) (toJS e)
177178 App (Var "toText") (Str s) -> return $ "toText" ++ parens (show s)
178179 App (Var "link") (Str s) -> return $ "link(" ++ show s ++ ")"
@@ -191,6 +192,13 @@ formatMarkdown = concatMap f
191192 f '"' = "\""
192193 f c = [c]
193194
195+guardToJS ps = format `liftM` mapM f ps
196+ where format cs = foldr (\c e -> parens $ c ++ " : " ++ e) err cs
197+ err = "(function(){throw \"Non-exhaustive guard expression\";}())"
198+ f (b,e) = do b' <- toJS b
199+ e' <- toJS e
200+ return (b' ++ " ? " ++ e')
201+
194202jsLet defs e' = do
195203 body <- (++) `liftM` jsDefs defs `ap` (ret `liftM` toJS e')
196204 return $ jsFunc "" body ++ "()"
elm/src/Parse/Expr.hs+38−18
@@ -1,4 +1,4 @@
1−module Parse.Expr (def,term) where
1+module Parse.Expr {-(def,term)-} where
22
33import Ast
44import Control.Applicative ((<$>), (<*>))
@@ -6,6 +6,7 @@ import Control.Monad
66import Data.Char (isSymbol, isDigit)
77import Data.List (foldl')
88import Text.Parsec hiding (newline,spaces)
9+import Text.Parsec.Indent
910import qualified Text.Pandoc as Pan
1011
1112import Parse.Library
@@ -20,7 +21,7 @@ import System.IO.Unsafe
2021
2122-------- Basic Terms --------
2223
23−numTerm :: (Monad m) => ParsecT [Char] u m Expr
24+numTerm :: IParser Expr
2425numTerm = toExpr <$> (preNum <?> "number")
2526 where toExpr n | '.' `elem` n = FloatNum (read n)
2627 | otherwise = IntNum (read n)
@@ -29,24 +30,25 @@ numTerm = toExpr <$> (preNum <?> "number")
2930 string "."
3031 ('.':) <$> many1 digit
3132
32−strTerm :: (Monad m) => ParsecT [Char] u m Expr
33+strTerm :: IParser Expr
3334strTerm = liftM Str . expecting "string" . betwixt '"' '"' . many $
3435 backslashed <|> satisfy (/='"')
3536
36−varTerm :: (Monad m) => ParsecT [Char] u m Expr
37+varTerm :: IParser Expr
3738varTerm = toVar <$> var <?> "variable"
3839
3940toVar v = case v of "True" -> Boolean True
4041 "False" -> Boolean False
4142 _ -> Var v
4243
43−chrTerm :: (Monad m) => ParsecT [Char] u m Expr
44+chrTerm :: IParser Expr
4445chrTerm = Chr <$> betwixt '\'' '\'' (backslashed <|> satisfy (/='\''))
4546 <?> "character"
4647
4748
4849-------- Complex Terms --------
4950
51+listTerm :: IParser Expr
5052listTerm = (do { try $ string "[markdown|"
5153 ; md <- filter (/='\r') <$> manyTill anyChar (try $ string "|]")
5254 ; return . Markdown $ Pan.readMarkdown Pan.defaultParserState md })
@@ -55,6 +57,7 @@ listTerm = (do { try $ string "[markdown|"
5557 ; Range lo <$> expr }
5658 , list <$> commaSep expr ])
5759
60+parensTerm :: IParser Expr
5861parensTerm = parens $ choice
5962 [ do op <- anyOp
6063 return . Lambda "x" . Lambda "y" $ Binop op (Var "x") (Var "y")
@@ -66,6 +69,7 @@ parensTerm = parens $ choice
6669 return $ case es of { [e] -> e; _ -> tuple es }
6770 ]
6871
72+term :: IParser Expr
6973term = choice [ numTerm, strTerm, chrTerm
7074 , accessible varTerm
7175 , listTerm, parensTerm ]
@@ -73,6 +77,7 @@ term = choice [ numTerm, strTerm, chrTerm
7377
7478-------- Applications --------
7579
80+appExpr :: IParser Expr
7681appExpr = do
7782 tlist <- spaceSep1 term
7883 return $ case tlist of
@@ -81,12 +86,15 @@ appExpr = do
8186
8287-------- Normal Expressions --------
8388
89+binaryExpr :: IParser Expr
8490binaryExpr = binops appExpr anyOp
8591
92+ifExpr :: IParser Expr
8693ifExpr = do reserved "if" ; whitespace ; e1 <- expr ; whitespace
8794 reserved "then" ; whitespace ; e2 <- expr ; (whitespace <?> "an 'else' branch")
8895 reserved "else" <?> "an 'else' branch" ; whitespace ; If e1 e2 <$> expr
8996
97+lambdaExpr :: IParser Expr
9098lambdaExpr = do char '\\' <|> char '\x03BB' <?> "anonymous function"
9199 whitespace
92100 pats <- spaceSep1 patternTerm
@@ -94,32 +102,40 @@ lambdaExpr = do char '\\' <|> char '\x03BB' <?> "anonymous function"
94102 e <- expr
95103 return $ makeLambda pats e
96104
105+defSet :: IParser [Def]
97106defSet = do
98107 brace <- optionMaybe $ do
99− char '{' <?> "a set of definitions { x = ... ; y = ... }"
100− whitespace
108+ string "{" <?> "a set of definitions { x = ... ; y = ... }"
109+ whitespace >> return "{"
101110 case brace of
102− Nothing -> assignExpr
103− Just '{' -> do dss <- semiSep1 assignExpr
111+ Nothing -> concat <$> block (do d <- assignExpr ; whitespace ; return d)
112+ Just "{" -> do dss <- semiSep1 assignExpr
104113 whitespace
105114 string "}" <?> "closing bracket '}'"
106115 return (concat dss)
116+
117+letExpr :: IParser Expr
107118letExpr = do
108119 reserved "let" ; whitespace
109120 defs <- defSet
110121 whitespace ; reserved "in" ; whitespace
111122 Let defs <$> expr
112123
124+caseExpr :: IParser Expr
113125caseExpr = do
114126 reserved "case"; whitespace; e <- expr; whitespace; reserved "of"; whitespace
115− Case e <$> brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
127+ Case e <$> (with <|> without)
116128 where case_ = do p <- patternExpr; whitespace; arrow; whitespace
117129 (,) p <$> expr
130+ with = brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
131+ without = block (do c <- case_ ; whitespace ; return c)
118132
119133expr = choice [ ifExpr, letExpr, caseExpr
120134 , lambdaExpr, binaryExpr ] <?> "an expression"
121135
122−funcDef = do p1 <- try patternTerm ; infics p1 <|> func p1
136+funcDef = try (do p1 <- try patternTerm ; infics p1 <|> func p1)
137+ <|> ((:[]) <$> patternExpr)
138+ <?> "the definition of a variable (x = ...)"
123139 where func p@(PVar v) = (p:) <$> spacePrefix patternTerm
124140 func p = do try (lookAhead (whitespace >> string "="))
125141 return [p]
@@ -129,18 +145,22 @@ funcDef = do p1 <- try patternTerm ; infics p1 <|> func p1
129145 return $ if o == '`' then [ PVar $ takeWhile (/='`') p, p1, p2 ]
130146 else [ PVar (o:p), p1, p2 ]
131147
132−assignExpr = do
133− fDefs <- try funcDef
134− <|> ((:[]) <$> patternExpr)
135− <?> "the definition of a variable (x = ...)"
136− whitespace; string "="; whitespace
137− e <- expr
148+assignExpr :: IParser [Def]
149+assignExpr = withPos $ do
150+ fDefs <- funcDef
151+ whitespace
152+ e <- (string "=" >> whitespace >> expr) <|> guardExpr
138153 flattenPatterns fDefs e
139154
155+guardExpr = (Guard <$> spaceSep1 gExpr)
156+ where gExpr = do string "|" ; whitespace
157+ b <- expr ; whitespace ; string "=" ; whitespace
158+ (,) b <$> expr
159+
140160def = map Definition <$> assignExpr
141161
142162
143163parseDef str =
144− case parse def "" str of
164+ case iParse def "" str of
145165 Right result -> Right result
146166 Left err -> Left $ "Parse error at " ++ show err
elm/src/Parse/Library.hs+41−30
@@ -4,8 +4,10 @@ module Parse.Library where
44import Ast
55import Control.Applicative ((<$>),(<*>))
66import Control.Monad
7+import Control.Monad.State
78import Data.Char (isSymbol)
8−import Text.Parsec hiding (newline,spaces)
9+import Text.Parsec hiding (newline,spaces,State)
10+import Text.Parsec.Indent
911
1012reserveds = [ "if", "then", "else"
1113 , "case", "of", "data"
@@ -16,74 +18,82 @@ reserveds = [ "if", "then", "else"
1618
1719expecting = flip (<?>)
1820
19−backslashed :: (Monad m) => ParsecT [Char] u m Char
21+type IParser a = ParsecT String () (State SourcePos) a
22+
23+iParse :: IParser a -> SourceName -> String -> Either ParseError a
24+iParse aParser source_name input =
25+ runIndent source_name $ runParserT aParser () source_name input
26+
27+backslashed :: IParser Char
2028backslashed = do { char '\\'; c <- anyChar
2129 ; return . read $ ['\'','\\',c,'\''] }
2230
23−var :: (Monad m) => ParsecT [Char] u m String
31+var :: IParser String
2432var = makeVar (letter <|> char '_' <?> "variable")
2533
26−lowVar :: (Monad m) => ParsecT [Char] u m String
34+lowVar :: IParser String
2735lowVar = makeVar (lower <?> "lower case variable")
28−capVar :: (Monad m) => ParsecT [Char] u m String
36+capVar :: IParser String
2937capVar = makeVar (upper <?> "upper case variable")
3038
31−innerVarChar :: (Monad m) => ParsecT [Char] u m Char
39+innerVarChar :: IParser Char
3240innerVarChar = alphaNum <|> char '_' <|> char '\'' <?> ""
3341
42+makeVar :: IParser Char -> IParser String
3443makeVar p = do v <- (:) <$> p <*> many innerVarChar
3544 guard (v `notElem` reserveds)
3645 return v
3746
47+reserved :: String -> IParser String
3848reserved word =
3949 try (string word >> notFollowedBy innerVarChar) >> return word
4050 <?> "reserved word '" ++ word ++ "'"
4151
42−anyOp :: (Monad m) => ParsecT [Char] u m String
52+anyOp :: IParser String
4353anyOp = betwixt '`' '`' var <|> symOp <?> "infix operator (e.g. +, *, ||)"
4454
4555isOp c = isSymbol c || elem c "+-/*=.$<>:&|^?%#@~!"
4656
47−symOp :: (Monad m) => ParsecT [Char] u m String
57+symOp :: IParser String
4858symOp = do op <- many1 (satisfy isOp)
4959 guard (op `notElem` [ "=", "..", "->", "--", "|", "\8594" ])
5060 return op
5161
52−arrow :: (Monad m) => ParsecT [Char] u m String
62+arrow :: IParser String
5363arrow = string "->" <|> string "\8594" <?> "arrow (->)"
5464
5565
5666commitIf check p = commit <|> try p
5767 where commit = do (try $ lookAhead check) >> p
5868
59−spaceySepBy1 :: (Monad m) => ParsecT [Char] u m b -> ParsecT [Char] u m a -> ParsecT [Char] u m [a]
69+spaceySepBy1 :: IParser b -> IParser a -> IParser [a]
6070spaceySepBy1 sep p = do
6171 a <- p
6272 (a:) <$> many (commitIf (whitespace >> sep) (whitespace >> sep >> whitespace >> p))
6373
6474
65−commaSep1 :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m [a]
75+commaSep1 :: IParser a -> IParser [a]
6676commaSep1 = spaceySepBy1 (char ',' <?> "comma ','")
6777
68−commaSep :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m [a]
78+commaSep :: IParser a -> IParser [a]
6979commaSep = option [] . commaSep1
7080
71−semiSep1 :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m [a]
81+semiSep1 :: IParser a -> IParser [a]
7282semiSep1 = spaceySepBy1 (char ';' <?> "semicolon ';'")
7383
74−pipeSep1 :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m [a]
84+pipeSep1 :: IParser a -> IParser [a]
7585pipeSep1 = spaceySepBy1 (char '|' <?> "type divider '|'")
7686
77−consSep1 :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m [a]
87+consSep1 :: IParser a -> IParser [a]
7888consSep1 = spaceySepBy1 (char ':' <?> "cons operator ':'")
7989
80−dotSep1 :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m [a]
90+dotSep1 :: IParser a -> IParser [a]
8191dotSep1 p = (:) <$> p <*> many (try (char '.') >> p)
8292
83−spaceSep1 :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m [a]
93+spaceSep1 :: IParser a -> IParser [a]
8494spaceSep1 p = (:) <$> p <*> spacePrefix p
8595
86−spacePrefix p = many (commitIf (whitespace >> (char '[' <|> char '(')) (whitespace >> p))
96+spacePrefix p = many (try (whitespace >> indented >> p))
8797
8898followedBy a b = do x <- a ; b ; return x
8999
@@ -95,15 +105,16 @@ surround a z name p = do
95105 char z <?> unwords ["closing", name, show z]
96106 return v
97107
98−braces :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m a
108+braces :: IParser a -> IParser a
99109braces = surround '[' ']' "brace"
100110
101−parens :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m a
111+parens :: IParser a -> IParser a
102112parens = surround '(' ')' "paren"
103113
104−brackets :: (Monad m) => ParsecT [Char] u m a -> ParsecT [Char] u m a
114+brackets :: IParser a -> IParser a
105115brackets = surround '{' '}' "bracket"
106116
117+accessible :: IParser Expr -> IParser Expr
107118accessible expr = do
108119 e <- expr
109120 access <- optionMaybe . try $
@@ -113,34 +124,34 @@ accessible expr = do
113124 Nothing -> return e
114125
115126
116−spaces :: (Monad m) => ParsecT [Char] u m String
127+spaces :: IParser String
117128spaces = many1 ((multiComment <|> string " " <?> "") >> return ' ') <?> "spaces"
118129
119−forcedWS :: (Monad m) => ParsecT [Char] u m [String]
130+forcedWS :: IParser [String]
120131forcedWS = try (do { spaces; many nl_space }) <|> try (many1 nl_space)
121132 where nl_space = try $ many1 newline >> spaces
122133
123−whitespace :: (Monad m) => ParsecT [Char] u m ()
134+whitespace :: IParser ()
124135whitespace = optional forcedWS <?> ""
125136
126−freshLine :: (Monad m) => ParsecT [Char] u m [[String]]
137+freshLine :: IParser [[String]]
127138freshLine = try (do { many1 newline; many space_nl }) <|> try (many1 space_nl) <?> ""
128139 where space_nl = try $ spaces >> many1 newline
129140
130−newline :: (Monad m) => ParsecT [Char] u m String
141+newline :: IParser String
131142newline = simpleNewline <|> lineComment <?> ""
132143
133−simpleNewline :: (Monad m) => ParsecT [Char] u m String
144+simpleNewline :: IParser String
134145simpleNewline = try (string "\r\n") <|> string "\n"
135146
136−lineComment :: (Monad m) => ParsecT [Char] u m String
147+lineComment :: IParser String
137148lineComment = do try (string "--")
138149 manyTill anyChar $ simpleNewline <|> (eof >> return "\n")
139150
140−multiComment :: (Monad m) => ParsecT [Char] u m String
151+multiComment :: IParser String
141152multiComment = do { try (string "{-"); closeComment }
142153
143−closeComment :: (Monad m) => ParsecT [Char] u m String
154+closeComment :: IParser String
144155closeComment = manyTill anyChar . choice $
145156 [ try (string "-}") <?> "close comment"
146157 , do { try $ string "{-"; closeComment; closeComment }
elm/src/Parse/Modules.hs+7−7
@@ -8,10 +8,10 @@ import Text.Parsec hiding (newline,spaces)
88import Ast
99import Parse.Library
1010
11−varList :: (Monad m) => ParsecT [Char] u m [String]
11+varList :: IParser [String]
1212varList = parens $ commaSep1 (var <|> parens symOp)
1313
14−moduleDef :: (Monad m) => ParsecT [Char] u m ([String], [String])
14+moduleDef :: IParser ([String], [String])
1515moduleDef = do
1616 try (reserved "module")
1717 whitespace
@@ -22,11 +22,11 @@ moduleDef = do
2222 reserved "where"
2323 return (names, exports)
2424
25−imports :: (Monad m) => ParsecT [Char] u m Imports
25+imports :: IParser Imports
2626imports = option [] ((:) <$> import' <*> many (try (freshLine >> import')))
2727
2828
29−import' :: (Monad m) => ParsecT [Char] u m (String, ImportMethod)
29+import' :: IParser (String, ImportMethod)
3030import' = do
3131 reserved "import"
3232 whitespace
@@ -36,12 +36,12 @@ import' = do
3636 return (name, method)
3737
3838
39−as' :: (Monad m) => ParsecT [Char] u m ImportMethod
39+as' :: IParser ImportMethod
4040as' = reserved "as" >> whitespace >> As <$> capVar <?> "alias for module"
4141
42−hiding' :: (Monad m) => ParsecT [Char] u m ImportMethod
42+hiding' :: IParser ImportMethod
4343hiding' = reserved "hiding" >> whitespace >>
4444 Hiding <$> varList <?> "listing of hidden values"
4545
46−importing' :: (Monad m) => ParsecT [Char] u m ImportMethod
46+importing' :: IParser ImportMethod
4747importing' = Importing <$> varList <?> "listing of imported values (x,y,z)"
elm/src/Parse/Parser.hs+1−1
@@ -36,6 +36,6 @@ program = do
3636 return $ Module names exports is statements
3737
3838parseProgram source =
39− case parse program "" source of
39+ case iParse program "" source of
4040 Right result -> Right result
4141 Left err -> Left $ "Parse error at " ++ show err
elm/src/Parse/Patterns.hs+9−7
@@ -4,30 +4,32 @@ import Ast
44import Data.Char (isUpper)
55import Control.Applicative ((<$>),(<*>))
66import Control.Monad
7−import Text.Parsec
7+import Control.Monad.State
8+import Text.Parsec hiding (newline,spaces,State)
9+import Text.Parsec.Indent
810import Parse.Library
911
10−patternBasic :: Monad m => ParsecT [Char] u m Pattern
12+patternBasic :: IParser Pattern
1113patternBasic =
1214 choice [ char '_' >> return PAnything
1315 , do x@(c:_) <- var
1416 return $ if isUpper c then PData x [] else PVar x
1517 ]
1618
17−patternTuple :: Monad m => ParsecT [Char] u m Pattern
19+patternTuple :: IParser Pattern
1820patternTuple = do ps <- parens (commaSep patternExpr)
1921 return $ case ps of { [p] -> p; _ -> ptuple ps }
2022
21−patternList :: Monad m => ParsecT [Char] u m Pattern
23+patternList :: IParser Pattern
2224patternList = plist <$> braces (commaSep patternExpr)
2325
24−patternTerm :: Monad m => ParsecT [Char] u m Pattern
26+patternTerm :: IParser Pattern
2527patternTerm = patternTuple <|> patternList <|> patternBasic <?> "pattern"
2628
27−patternConstructor :: Monad m => ParsecT [Char] u m Pattern
29+patternConstructor :: IParser Pattern
2830patternConstructor = PData <$> capVar <*> spacePrefix patternTerm
2931
30−patternExpr :: Monad m => ParsecT [Char] u m Pattern
32+patternExpr :: IParser Pattern
3133patternExpr = foldr1 pcons <$> consSep1 (patternConstructor <|> patternTerm) <?> "pattern"
3234
3335
elm/src/Parse/Types.hs+10−9
@@ -7,6 +7,7 @@ import Data.Char (isUpper,isLower)
77import Data.Maybe (fromMaybe)
88import Data.List (lookup)
99import Text.Parsec
10+import Text.Parsec.Indent
1011
1112import Parse.Library
1213import Types.Types hiding (string,parens)
@@ -19,43 +20,43 @@ data ParseType = VarPT String
1920listPT t = ADTPT "List" [t]
2021tuplePT ts = ADTPT ("Tuple" ++ show (length ts)) ts
2122
22−typeVar :: (Monad m) => ParsecT [Char] u m ParseType
23+typeVar :: IParser ParseType
2324typeVar = VarPT <$> lowVar <?> "type variable"
2425
25−typeList :: (Monad m) => ParsecT [Char] u m ParseType
26+typeList :: IParser ParseType
2627typeList = listPT <$> braces typeExpr
2728
28−typeTuple :: (Monad m) => ParsecT [Char] u m ParseType
29+typeTuple :: IParser ParseType
2930typeTuple = do ts <- parens (commaSep typeExpr)
3031 return $ case ts of { [t] -> t ; _ -> tuplePT ts }
3132
32−typeUnambiguous :: (Monad m) => ParsecT [Char] u m ParseType
33+typeUnambiguous :: IParser ParseType
3334typeUnambiguous = typeList <|> typeTuple
3435
35−typeSimple :: (Monad m) => ParsecT [Char] u m ParseType
36+typeSimple :: IParser ParseType
3637typeSimple = dealias <$> var
3738 where dealias "String" = listPT (VarPT "Char")
3839 dealias v = VarPT v
3940
40−typeApp :: (Monad m) => ParsecT [Char] u m ParseType
41+typeApp :: IParser ParseType
4142typeApp = do name <- capVar <?> "type constructor"
4243 args <- spacePrefix (typeUnambiguous <|> typeSimple)
4344 return $ case args of
4445 [] -> VarPT name
4546 _ -> ADTPT name args
4647
47−typeExpr :: (Monad m) => ParsecT [Char] u m ParseType
48+typeExpr :: IParser ParseType
4849typeExpr = do
4950 t1 <- typeVar <|> typeApp <|> typeUnambiguous
5051 whitespace ; arr <- optionMaybe arrow ; whitespace
5152 case arr of Just _ -> LambdaPT t1 <$> typeExpr
5253 Nothing -> return t1
5354
54−typeConstructor :: (Monad m) => ParsecT [Char] u m (String, [ParseType])
55+typeConstructor :: IParser (String, [ParseType])
5556typeConstructor = (,) <$> (capVar <?> "another type constructor")
5657 <*> spacePrefix (typeSimple <|> typeUnambiguous)
5758
58−datatype :: (Monad m) => ParsecT [Char] u m Statement
59+datatype :: IParser Statement
5960datatype = do
6061 reserved "data" <?> "datatype definition (data T = A | B | ...)"
6162 forcedWS ; name <- capVar <?> "name of data-type" ; args <- spacePrefix lowVar
elm/src/Rename.hs+4
@@ -77,6 +77,10 @@ instance Rename Expr where
7777 `ap` rnm e2
7878 `ap` rnm e3
7979
80+ Guard ps -> Guard `liftM` mapM grnm ps
81+ where grnm (b,e) = (,) `liftM` rnm b
82+ `ap` rnm e
83+
8084 Lift e es -> Lift `liftM` rnm e
8185 `ap` mapM rnm es
8286
elm/src/Replace.hs+3
@@ -1,6 +1,7 @@
11module Replace (replace, depth) where
22
33import Ast
4+import Control.Arrow ((***))
45import Data.Set (singleton,empty,unions,member, Set)
56
67replace :: String -> Expr -> Expr -> Expr
@@ -12,6 +13,7 @@ replace y v expr =
1213 Binop op e1 e2 -> Binop op (f e1) (f e2)
1314 App e1 e2 -> App (f e1) (f e2)
1415 If e1 e2 e3 -> If (f e1) (f e2) (f e3)
16+ Guard ps -> map (f *** f) ps
1517 Lift e es -> Lift (f e) (map f es)
1618 Fold e1 e2 e3 -> Fold (f e1) (f e2) (f e3)
1719 Async e -> Async (f e)
@@ -44,6 +46,7 @@ depth' d expr =
4446 Lambda x e -> f e
4547 App e1 e2 -> max (f e1) (f e2)
4648 If e1 e2 e3 -> maximum [f e1, f e2, f e3]
49+ Guard ps -> maximum (map (uncurry max . f *** f) ps)
4750 Lift e es -> maximum $ f e : map f es
4851 Fold e1 e2 e3 -> maximum [f e1, f e2, f e3]
4952 Async e -> f e
elm/src/Substitute.hs+2−1
@@ -1,6 +1,6 @@
11module Substitute (subst) where
22
3−import Control.Arrow (second)
3+import Control.Arrow (second, (***))
44
55import Ast
66
@@ -14,6 +14,7 @@ subst old new expr =
1414 Lambda x e -> if x == old then expr else Lambda x (f e)
1515 App e1 e2 -> App (f e1) (f e2)
1616 If e1 e2 e3 -> If (f e1) (f e2) (f e3)
17+ Guard ps -> Guard (map (f *** f) ps)
1718 Lift e es -> Lift (f e) (map f es)
1819 Fold e1 e2 e3 -> Fold (f e1) (f e2) (f e3)
1920 Async e -> Async (f e)
elm/src/Types/Constrain.hs+11−1
@@ -122,6 +122,16 @@ gen (Range e1 e2) =
122122 , ctx e2 (t2 :=: int) ] ]
123123 , listOf int )
124124
125+gen e@(Guard ps) = do (ass,css,t:ts) <- unzip3 `liftM` mapM genPair ps
126+ let cs = Set.fromList (map (ctx e . (t :=:)) ts)
127+ return (unionsA ass, Set.unions (cs:css), t)
128+ where genPair (b,e) = do
129+ (a1,c1,t1) <- gen b
130+ (a2,c2,t2) <- gen e
131+ return ( unionsA [a1,a2]
132+ , Set.unions [ c1, c2, Set.singleton (ctx b (t1 :=: bool)) ]
133+ , t2 )
134+
125135gen other =
126136 case other of
127137 IntNum _ -> do t <- beta
@@ -131,7 +141,7 @@ gen other =
131141 Str _ -> primitive string
132142 Boolean _ -> primitive bool
133143 Markdown _ -> primitive element
134− _ -> beta >>= primitive
144+ -- _ -> beta >>= primitive
135145
136146primitive t = return (Map.empty, Set.empty, t)
137147