on master help sign in
Latest updates. Needs to be debugged.
commit42b364d623bce8e18475be9180944d9a8a0e65da authorevancz <info@elm-lang.org> dateSat 9 Jun 2012, 11:13 (14 years ago) parentd4c86ff
9 files changed+137−94
elm/Elm.cabal+2−2 elm/src/CompileToJS.hs+4−1 elm/src/Compiler.hs+1−1 elm/src/Initialize.hs+3−10 elm/src/Parse/Binop.hs → elm/src/Parse/Binops.hs+1−1 elm/src/Parse/ParseLib.hs+66−9 elm/src/Parse/ParsePatterns.hs−31 elm/src/Parse/ParseTypes.hs+35−19 elm/src/Parse/Parser.hs+25−20
elm/Elm.cabal+2−2
@@ -39,7 +39,7 @@ Library
3939 Guid,
4040 Initialize,
4141 Rename,
42− Binop,
42+ Binops,
4343 Patterns,
4444 Parser,
4545 ParseLib,
@@ -72,7 +72,7 @@ Executable elm
7272 Guid,
7373 Initialize,
7474 Rename,
75− Binop,
75+ Binops,
7676 Patterns,
7777 Parser,
7878 ParseLib,
elm/src/CompileToJS.hs+4−1
@@ -9,9 +9,12 @@ import Data.Map (toList)
99
1010import Initialize
1111
12+showErr :: String -> String
13+showErr err = "text(monospace(" ++ msg ++ "))"
14+ where msg = show . concatMap (++"<br>") . lines $ err
1215
1316compile = (return . addMain . toJS) <=< initialize
14−compileToJS = addMain . either (\err -> "text('"++err++"')") toJS
17+compileToJS = addMain . either showErr toJS
1518addMain body = "function main(){return " ++ body ++ ";}"
1619
1720parens = ("("++) . (++")")
elm/src/Compiler.hs+1−1
@@ -11,7 +11,7 @@ main = getArgs >>= parse
1111
1212parse :: [String] -> IO ()
1313parse ("--help":_) = putStrLn usage
14−parse ("--version":_) = putStrLn "The Elm Compiler 0.1.2.1"
14+parse ("--version":_) = putStrLn "The Elm Compiler 0.2"
1515parse [loc,file]
1616 | "--runtime-location=" `isPrefixOf` loc =
1717 produceHtml (tail $ dropWhile (/='=') loc) file
elm/src/Initialize.hs+3−10
@@ -6,23 +6,16 @@ import Control.Monad
66import Data.Char (isAlpha)
77import Data.Maybe (mapMaybe)
88import Data.Either (rights)
9−import Lexer
10−import Parser (toExpr,toDefs)
9+
10+import Parser (toDefs)
1111import Rename (rename)
1212
1313import Unify
1414import Hints
1515
16−{--
17−initialize str = do
18− (expr, hints') <- toDefs =<< tokenize str
19− let expr' = rename expr
20− subs <- unify (liftM2 (++) hints hints') expr'
21− return (seq subs expr')
22−--}
2316
2417initialize str = do
25− (expr, hints') <- toDefs =<< tokenize str
18+ (expr, hints') <- toDefs str
2619 let expr' = rename expr
2720 subs <- unify (liftM2 (++) hints hints') expr'
2821 let init = simp_loop expr'
elm/src/Parse/Binop.hs → elm/src/Parse/Binops.hsrenamed+1−1
@@ -1,4 +1,4 @@
1−module Binop (binops) where
1+module Binops (binops) where
22
33import Ast
44import Control.Monad (liftM,guard)
elm/src/Parse/ParseLib.hs+66−9
@@ -4,7 +4,7 @@ module ParseLib where
44import Ast
55import Control.Monad
66import Data.Char (isSymbol)
7−import Text.Parsec
7+import Text.Parsec hiding (newline,spaces)
88
99reserved = [ "if", "then", "else"
1010 , "case", "of", "data"
@@ -12,23 +12,46 @@ reserved = [ "if", "then", "else"
1212
1313expecting = flip (<?>)
1414
15+backslashed :: (Monad m) => ParsecT [Char] u m Char
16+backslashed = do { char '\\'; c <- anyChar
17+ ; return . read $ ['\'','\\',c,'\''] }
18+
1519var :: (Monad m) => ParsecT [Char] u m String
16−var = do
17− c <- letter {-lower-} <|> char '_'
20+var = makeVar $ letter <|> char '_'
21+
22+lowVar :: (Monad m) => ParsecT [Char] u m String
23+lowVar = makeVar (lower <?> "lower case variable")
24+capVar :: (Monad m) => ParsecT [Char] u m String
25+capVar = makeVar (upper <?> "upper case variable")
26+
27+makeVar p = do
28+ c <- p
1829 cs <- many $ alphaNum <|> char '_' <|> char '\''
1930 guard $ c:cs `notElem` reserved
2031 return $ c:cs
2132
33+
2234anyOp :: (Monad m) => ParsecT [Char] u m String
23−anyOp = many1 (satisfy isSymbol <|> oneOf "+-/*=.$<>:&|^?%#@~!")
35+anyOp = betwixt '`' '`' var <|>
36+ (do op <- many1 (satisfy isSymbol <|> oneOf "+-/*=.$<>:&|^?%#@~!")
37+ guard (op `notElem` [ "=", "..", "->" ])
38+ return op) <?> "infix operator"
2439
25−lexeme p = do e <- p ; whitespace ; return e
40+lexeme p = do whitespace ; p
2641
27−whitespace :: (Monad m) => ParsecT [Char] u m String
28−whitespace = try $ many (char ' ')
42+symbol :: (Monad m) => String -> ParsecT [Char] u m String
43+symbol s = whitespace >> string s
2944
30−betwixt a b = between (char a) (char b <?> "closing '" ++ [b] ++ "'")
31−betwixtSpcs a b = between (lexeme $ char a) (char b <?> "closing '" ++ [b] ++ "'")
45+arrow :: (Monad m) => ParsecT [Char] u m String
46+arrow = symbol "->" <|> symbol "\8594"
47+
48+commaSep p = p `sepBy` lexeme (char ',')
49+
50+
51+betwixt a b c = do char a ; out <- c
52+ char b <?> "closing '" ++ [b] ++ "'" ; return out
53+betwixtSpcs a b c = do char a ; whitespace ; out <- c ; whitespace
54+ char b <?> "closing '" ++ [b] ++ "'" ; return out
3255
3356listOf p = betwixtSpcs '[' ']' $ p `sepBy` lexeme (char ',')
3457
@@ -38,3 +61,37 @@ accessible expr = do
3861 case access of
3962 Just '.' -> accessible (Access e `liftM` var)
4063 Nothing -> return e
64+
65+
66+spaces :: (Monad m) => ParsecT [Char] u m String
67+spaces = many1 ((multiComment <|> string " ") >> return ' ') <?> "spaces"
68+
69+forcedWS :: (Monad m) => ParsecT [Char] u m [String]
70+forcedWS = try (do { spaces; many nl_space }) <|> try (many1 nl_space)
71+ where nl_space = try $ many1 newline >> spaces
72+
73+whitespace :: (Monad m) => ParsecT [Char] u m ()
74+whitespace = optional forcedWS <?> "whitespace"
75+
76+freshLine :: (Monad m) => ParsecT [Char] u m [[String]]
77+freshLine = try (do { many1 newline; many space_nl }) <|> try (many1 space_nl) <?> "fresh line"
78+ where space_nl = try $ spaces >> many1 newline
79+
80+newline :: (Monad m) => ParsecT [Char] u m String
81+newline = simpleNewline <|> lineComment <?> "newline"
82+
83+simpleNewline :: (Monad m) => ParsecT [Char] u m String
84+simpleNewline = try (string "\r\n") <|> string "\n"
85+
86+lineComment :: (Monad m) => ParsecT [Char] u m String
87+lineComment = do try $ string "--"
88+ manyTill anyChar $ simpleNewline <|> (eof >> return "\n")
89+
90+multiComment :: (Monad m) => ParsecT [Char] u m String
91+multiComment = do { try $ string "{-"; closeComment }
92+
93+closeComment :: (Monad m) => ParsecT [Char] u m String
94+closeComment = manyTill anyChar . choice $
95+ [ try $ string "-}"
96+ , do { try $ string "{-"; closeComment; closeComment }
97+ ]
elm/src/Parse/ParsePatterns.hsdeleted−31
@@ -1,31 +0,0 @@
1−module ParsePatterns (patternTerm, patternExpr) where
2−
3−import Ast
4−import Combinators
5−import Data.Char (isUpper)
6−import ParserLib
7−import Tokens
8−import Control.Monad (liftM)
9−
10−patternBasic =
11− (t UNDERSCORE >> return PAnything) +|+
12− (do { x@(c:_) <- var ;
13− if isUpper c then PData x `liftM` star patternTerm
14− else return $ PVar x })
15−
16−patternTuple = do
17− t LPAREN; ps <- sepBy1 (t COMMA) patternExpr; t RPAREN
18− return $ case ps of { [p] -> p; _ -> ptuple ps }
19−
20−patternCons = do
21− p <- patternTerm
22− colon <- optional $ opParser (==":")
23− case colon of
24− Just ":" -> pcons p `liftM` patternExpr
25− Nothing -> return p
26−
27−patternList = do
28− t LBRACKET; ps <- sepBy (t COMMA) patternExpr; t RBRACKET; return (plist ps)
29−
30−patternTerm = patternTuple +|+ patternList +|+ patternBasic
31−patternExpr = patternTuple +|+ patternList +|+ patternCons
elm/src/Parse/ParseTypes.hs+35−19
@@ -1,15 +1,16 @@
11module ParseTypes where
22
33import Ast
4−import Combinators
4+import Control.Applicative ((<$>))
5+import Control.Monad (liftM)
56import Data.Char (isUpper,isLower)
67import Data.Maybe (fromMaybe)
78import Data.List (lookup)
8−import ParserLib
9−import Tokens
9+import Text.Parsec
10+
11+import ParseLib
1012import Types
1113import Guid
12−import Control.Monad (liftM)
1314
1415data ParseType = VarPT String
1516 | LambdaPT ParseType ParseType
@@ -18,35 +19,50 @@ data ParseType = VarPT String
1819listPT t = ADTPT "List" [t]
1920tuplePT ts = ADTPT ("Tuple" ++ show (length ts)) ts
2021
21−typeVar = liftM VarPT lowVar
22−typeList = do t LBRACKET; te <- typeExpr; t RBRACKET; return $ listPT te
23−typeTuple = do { t LPAREN; ts <- sepBy (t COMMA) typeExpr; t RPAREN
24− ; return $ case ts of { [t] -> t ; _ -> tuplePT ts } }
25−typeUnambiguous = typeList +|+ typeTuple
22+typeVar :: (Monad m) => ParsecT [Char] u m ParseType
23+typeVar = VarPT <$> lowVar <?> "type variable"
24+
25+typeList :: (Monad m) => ParsecT [Char] u m ParseType
26+typeList = listPT <$> betwixtSpcs '[' ']' typeExpr
2627
27−typeSimple = liftM VarPT var
28+typeTuple :: (Monad m) => ParsecT [Char] u m ParseType
29+typeTuple = do ts <- betwixtSpcs '(' ')' (commaSep typeExpr)
30+ return $ case ts of { [t] -> t ; _ -> tuplePT ts }
31+
32+typeUnambiguous :: (Monad m) => ParsecT [Char] u m ParseType
33+typeUnambiguous = typeList <|> typeTuple
34+
35+typeSimple :: (Monad m) => ParsecT [Char] u m ParseType
36+typeSimple = VarPT <$> var
37+
38+typeApp :: (Monad m) => ParsecT [Char] u m ParseType
2839typeApp = do name <- capVar
29− args <- star (typeSimple +|+ typeUnambiguous)
40+ args <- many (typeSimple <|> typeUnambiguous)
3041 return $ case args of
3142 [] -> VarPT name
3243 _ -> ADTPT name args
33−
44+
45+typeExpr :: (Monad m) => ParsecT [Char] u m ParseType
3446typeExpr = do
35− t1 <- typeVar +|+ typeApp +|+ typeUnambiguous
36− arrow <- optional $ t ARROW
37− case arrow of Just ARROW -> LambdaPT t1 `liftM` typeExpr
47+ whitespace
48+ t1 <- typeVar <|> typeApp <|> typeUnambiguous
49+ arrow <- optionMaybe arrow
50+ case arrow of Just _ -> LambdaPT t1 <$> typeExpr
3851 Nothing -> return t1
3952
53+typeConstructor :: (Monad m) => ParsecT [Char] u m (String, [ParseType])
4054typeConstructor = do name <- capVar
41− args <- star (typeSimple +|+ typeUnambiguous)
55+ args <- many (typeSimple <|> typeUnambiguous)
4256 return $ (,) name args
4357
58+datatype :: (Monad m) => ParsecT [Char] u m ([String], [Expr], GuidCounter [Type])
4459datatype = do
45− t DATA ; name <- capVar ; args <- star lowVar ; assign
46− tcs <- sepBy1 (opParser (=="|")) typeConstructor
60+ symbol "data" <?> "datatype definition"
61+ name <- capVar ; args <- many lowVar ; symbol "="
62+ tcs <- typeConstructor `sepBy1` symbol "|"
4763 return $ (map fst tcs , map toFunc tcs , toTypes name args tcs)
4864
49−beta = VarT `liftM` guid
65+beta = liftM VarT guid
5066
5167toFunc (name,args) = foldr Lambda (Data name $ map Var argNames) argNames
5268 where argNames = map (("a"++) . show) [1..length args]
elm/src/Parse/Parser.hs+25−20
@@ -1,15 +1,19 @@
1−module Parser where
1+module Parser (toDefs) where
22
33import Ast
44import Control.Applicative ((<$>), (<*>))
55import Control.Monad
66import Data.Char (isSymbol, isDigit)
77import Data.List (foldl')
8−import Text.Parsec
8+import Text.Parsec hiding (newline,spaces)
99
1010import ParseLib
1111import Patterns
12−import Binop
12+import Binops
13+import ParseTypes
14+
15+import Guid
16+import Types (Type (VarT))
1317
1418-------- Basic Terms --------
1519
@@ -17,7 +21,8 @@ numTerm :: (Monad m) => ParsecT [Char] u m Expr
1721numTerm = liftM (Number . read) (many1 digit) <?> "number"
1822
1923strTerm :: (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 (/='"')
2126
2227varTerm :: (Monad m) => ParsecT [Char] u m Expr
2328varTerm = toVar <$> var <?> "variable"
@@ -27,20 +32,20 @@ toVar v = case v of "True" -> Boolean True
2732 _ -> Var v
2833
2934chrTerm :: (Monad m) => ParsecT [Char] u m Expr
30−chrTerm = Chr <$> betwixt '\'' '\'' anyChar <?> "character"
35+chrTerm = Chr <$> betwixt '\'' '\'' (backslashed <|> satisfy (/='\'')) <?> "character"
3136
3237
3338-------- Complex Terms --------
3439
3540listTerm = expecting "list" . betwixtSpcs '[' ']' $ choice
36− [ try $ do { lo <- expr; string ".." ; Range lo <$> expr }
37− , list <$> expr `sepBy` lexeme (char ',')
41+ [ try $ do { lo <- expr; symbol ".." ; Range lo <$> expr }
42+ , list <$> commaSep expr
3843 ]
3944
4045parensTerm = expecting "parenthesized expression" . betwixtSpcs '(' ')' $ choice
4146 [ do op <- anyOp
4247 return . Lambda "x" . Lambda "y" $ Binop op (Var "x") (Var "y")
43− , do es <- expr `sepBy` lexeme (char ',')
48+ , do es <- commaSep expr
4449 return $ case es of { [e] -> e; _ -> tuple es }
4550 ]
4651
@@ -74,7 +79,7 @@ lambdaExpr = do lexeme $ oneOf "\\\x03BB"
7479 return $ makeFunction args e
7580
7681assignExpr = do
77− patterns <- patternTerm `endBy1` whitespace; symbol "="; exp <- expr
82+ patterns <- (patternTerm <?> "definition") `endBy1` whitespace; symbol "="; exp <- expr
7883 case patterns of
7984 PVar f : args -> return (f, makeFunction args exp)
8085 [PData x ps] -> if "Tuple" == take 5 x && all isDigit (drop 5 x) then
@@ -100,21 +105,21 @@ caseExpr = do
100105
101106expr = choice [ ifExpr, letExpr, caseExpr, lambdaExpr, binaryExpr ]
102107
103−aoeu = parse (between whitespace eof expr) ""
104−
105−symbol = lexeme . try . string
106−arrow = symbol "->" <|> symbol "\8594"
107−
108108def = do (f,e) <- assignExpr
109109 return ([f], [e], guid >>= \x -> return [VarT x])
110110
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
115+
112116defs = do
113− (fss,ess,tss) <- unzip3 `liftM` plus (whitespace >> plus (sat (==NEWLINE)) >> def +|+ datatype)
117+ ds <- manyDefs
118+ let (fss,ess,tss) = unzip3 ds
114119 let (fs,es,ts) = (concat fss, concat ess, concat `liftM` sequence tss)
115− star $ sat (==NEWLINE) +|+ sat (==SPACES)
120+ optional freshLine ; optional whitespace ; eof
116121 return (Let (zip fs es) (Var "main"), liftM (zip fs) ts)
117122
118−err = "Parse Error: Better error messages to come!"
119−toDefs = parse defs . ('\n':)
120−--}
123+toDefs source = case parse defs "Elm code" source of
124+ Right result -> Right result
125+ Left err -> Left $ show err