on master help sign in
Merge branch 'master' of https://github.com/evancz/Elm
commit61b6c88ad31f701a2d425580ae5c026882266e9b authorevancz <info@elm-lang.org> dateFri 27 Apr 2012, 17:33 (15 years ago) parentfea475112976d3
5 files changed+82−58
README.md+1−1 src/ExtractNoscript.hs+3−3 src/FreeVar.hs+5−5 src/Parse/Binop.hs+3−3 src/Rename.hs+70−46
README.md+1−1
@@ -20,7 +20,7 @@ Assuming everything goes correctly (potential problems are discussed later), thi
2020
2121* elm-server :: This is both a compiler and server, allowing you to develop without designing and setting up a server yourself. Running the "elm-server" program starts a server in the current directory. It will compile and serve any .elm files in the current directory and its sub-directories. This is how I prefer to develop Elm programs.
2222
23−To use these executables you may need to add a new directory to your PATH. For me, the executables were placed in /home/evan/.cabal/bin which I appended to the end of my PATH variable in my .bashrc file. Cabal should tell you where your executables are located, so you can make a similar addition.
23+To use these executables you need to add a new directory to your PATH. For me, the executables were placed in /home/evan/.cabal/bin which I appended to the end of my PATH variable in my .bashrc file. Cabal should tell you where your executables are located, so you can make a similar addition (see this tutorial if you are new to changing your PATH in [Unix/Linux](http://www.cyberciti.biz/faq/unix-linux-adding-path/)).
2424
2525That is almost everything. Create a new directory and navigate into it. Download the [elm-mini.js](https://raw.github.com/evancz/Elm/master/elm-mini.js) file which is the Elm runtime system. It is separate from the compiler for now. You can use the command
2626
src/ExtractNoscript.hs+3−3
@@ -2,7 +2,7 @@
22module ExtractNoscript (extract) where
33
44import Ast
5−import List (isPrefixOf)
5+import Data.List (isPrefixOf)
66
77extract = extract'
88
@@ -35,9 +35,9 @@ toString _ = []
3535makeLinks (a:b:[]) = linkify a b
3636makeLinks xs = xs
3737
38−linkish s = not (isPrefixOf "<a" s) && all (/=' ') s && any (=='/') s
38+linkish s = not ("<a" `isPrefixOf` s) && notElem ' ' s && elem '/' s
3939
4040linkify a b
4141 | linkish a = [ "<a href=\"" ++ a ++ "\">" ++ b ++ "</a>" ]
4242 | linkish b = [ "<a href=\"" ++ b ++ "\">" ++ a ++ "</a>" ]
43− | otherwise = [a,b]
43+ | otherwise = [a,b]
src/FreeVar.hs+5−5
@@ -8,10 +8,10 @@ x `freeIn` expr = member x $ freeVars expr
88freeVars expr =
99 let f = freeVars in
1010 case expr of
11− Range e1 e2 -> union (f e1) (f e2)
12− Binop op e1 e2 -> union (f e1) (f e2)
11+ Range e1 e2 -> f e1 `union` f e2
12+ Binop op e1 e2 -> f e1 `union` f e2
1313 Lambda x e -> delete x (f e)
14− App e1 e2 -> union (f e1) (f e2)
14+ App e1 e2 -> f e1 `union` f e2
1515 If e1 e2 e3 -> unions $ map f [e1,e2,e3]
1616 Lift e es -> unions $ map f es
1717 Fold e1 e2 e3 -> unions $ map f [e1,e2,e3]
@@ -20,11 +20,11 @@ freeVars expr =
2020 where (vs,es) = unzip defs
2121 Var x -> singleton x
2222 Data name es -> unions (map f es)
23− Case e cases -> union (f e) (unions $ map caseFreeVars cases)
23+ Case e cases -> f e `union` unions (map caseFreeVars cases)
2424 _ -> empty
2525
2626caseFreeVars (p,e) = difference (freeVars e) (pvars p)
2727 where pvars p = case p of
2828 PAnything -> empty
2929 PVar x -> singleton x
30− PData _ ps -> unions (map pvars ps)
30+ PData _ ps -> unions (map pvars ps)
src/Parse/Binop.hs+3−3
@@ -5,7 +5,7 @@ import Combinators
55import Control.Monad (liftM,guard)
66import Control.Monad.Error
77import Data.List (foldl',splitAt,elemIndices,group,groupBy,sortBy,find)
8−import Data.Map as Map
8+import qualified Data.Map as Map
99import Data.Maybe (mapMaybe)
1010
1111data Assoc = L | Non | R deriving (Eq,Show)
@@ -45,14 +45,14 @@ binopOf seen (tbl@((lvl, L, op):rest)) ops es =
4545 case elemIndices op ops of
4646 [] -> binopOf seen rest ops es
4747 is -> case Map.lookup lvl seen of
48− Nothing -> binopSplit (insert lvl (L,op) seen) tbl (last is) ops es
48+ Nothing -> binopSplit (Map.insert lvl (L,op) seen) tbl (last is) ops es
4949 Just (L,_) -> binopSplit seen tbl (last is) ops es
5050 Just (assoc,op') -> Left $ errorMessage lvl op L op' assoc
5151binopOf seen (tbl@((lvl, assoc, op):rest)) ops es =
5252 case elemIndices op ops of
5353 [] -> binopOf seen rest ops es
5454 i:_ -> case Map.lookup lvl seen of
55− Nothing -> binopSplit (insert lvl (R,op) seen) tbl i ops es
55+ Nothing -> binopSplit (Map.insert lvl (R,op) seen) tbl i ops es
5656 Just (assoc',op') ->
5757 if assoc == assoc' && assoc /= Non then
5858 binopSplit seen tbl i ops es
src/Rename.hs+70−46
@@ -1,73 +1,97 @@
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
12module Rename (rename) where
23
34import Ast
45import Control.Arrow (first)
5−import Control.Monad.State
6+import Control.Monad (ap, liftM, foldM, mapM, Monad)
7+import Control.Monad.State (evalState, State, get, put)
68import Data.Char (isLower)
7−import Data.List (mapAccumL)
8−import Data.Functor.Identity
99
10−rename expr = evalState (rename' id expr) 0
10+-- Wrapper around State monad.
11+newtype GuidCounter a = GC { runGC :: State Int a }
12+ deriving (Monad)
1113
12−guid :: State Int Int
13−guid = do n <- get
14− put (n+1)
15− return n
14+-- Get the next GUID, incrementing the counter.
15+guid :: GuidCounter Int
16+guid = GC $ do n <- get
17+ put (n + 1)
18+ return n
1619
20+rename :: Expr -> Expr
21+rename expr = evalState (runGC $ rename' id expr) 0
22+
23+rename' :: (String -> String) -> Expr -> GuidCounter Expr
1724rename' env expr =
1825 case expr of
19− Range e1 e2 -> do
20− re1 <- rename' env e1; re2 <- rename' env e2
21− return $ Range re1 re2
22− Access e x -> do
23− re <- rename' env e
24− return $ Access re x
25− Binop op e1 e2 ->
26− do let rop = if isLower (head op) || '_' == head op then env op else op
27− re1 <- rename' env e1; re2 <- rename' env e2
28− return $ Binop rop re1 re2
29− Lambda x e -> do (rx, env') <- extend env x
30− rename' env' e >>= return . Lambda rx
31− App e1 e2 -> do
32− re1 <- rename' env e1; re2 <- rename' env e2
33− return $ App re1 re2
34− If e1 e2 e3 -> do
35− re1 <- rename' env e1; re2 <- rename' env e2; re3 <- rename' env e3
36− return $ If re1 re2 re3
37− Lift e es -> do
38− re <- rename' env e
39− mapM (rename' env) es >>= return . Lift re
40− Fold e1 e2 e3 -> do
41− re1 <- rename' env e1; re2 <- rename' env e2; re3 <- rename' env e3
42− return $ Fold re1 re2 re3
43− Async e -> rename' env e >>= return . Async
26+
27+ Range e1 e2 -> Range `liftM` rnm e1
28+ `ap` rnm e2
29+
30+ Access e x -> Access `liftM` rnm e
31+ `ap` return x
32+
33+ Binop op@(h:_) e1 e2 ->
34+ let rop = if isLower h || '_' == h
35+ then env op
36+ else op
37+ in Binop rop `liftM` rnm e1
38+ `ap` rnm e2
39+
40+ Lambda x e -> do
41+ (rx, env') <- extend env x
42+ Lambda rx `liftM` rename' env' e
43+
44+ App e1 e2 -> App `liftM` rnm e1
45+ `ap` rnm e2
46+
47+ If e1 e2 e3 -> If `liftM` rnm e1
48+ `ap` rnm e2
49+ `ap` rnm e3
50+
51+ Lift e es -> Lift `liftM` rnm e
52+ `ap` mapM rnm es
53+
54+ Fold e1 e2 e3 -> Fold `liftM` rnm e1
55+ `ap` rnm e2
56+ `ap` rnm e3
57+
58+ Async e -> Async `liftM` rnm e
59+
4460 Let defs e -> do
4561 let (vs,es) = unzip defs
46− env' <- foldM (\acc x -> extend acc x >>= return . snd) env vs
62+ env' <- foldM (\acc x -> snd `liftM` extend acc x) env vs
4763 es' <- mapM (rename' env') es; re <- rename' env' e
4864 return $ Let (zip (map env' vs) es') re
65+
4966 Var x -> return . Var $ env x
50− Data name es -> mapM (rename' env) es >>= return . Data name
51− Case e cases -> do
52− re <- rename' env e
53− mapM (pattern_rename env) cases >>= return . (Case re)
67+
68+ Data name es -> Data name `liftM` mapM rnm es
69+
70+ Case e cases -> Case `liftM` rnm e
71+ `ap` mapM (patternRename env) cases
72+
5473 _ -> return expr
5574
75+ where rnm = rename' env
76+
77+extend :: (String -> String) -> String -> GuidCounter (String, String -> String)
5678extend env x = do
5779 n <- guid
5880 let rx = x ++ "_" ++ show n
59− return (rx, (\y -> if y == x then rx else env y))
81+ return (rx, \y -> if y == x then rx else env y)
6082
61−pattern_extend pattern env =
83+patternExtend :: Pattern -> (String -> String) -> GuidCounter (Pattern, String -> String)
84+patternExtend pattern env =
6285 case pattern of
6386 PAnything -> return (PAnything, env)
64− PVar x -> extend env x >>= return . first PVar
87+ PVar x -> first PVar `liftM` extend env x
6588 PData name ps ->
66− foldM f ([],env) ps >>= return . first (PData name . reverse)
67− where f (rps,env') p = do (rp,env'') <- pattern_extend p env'
89+ first (PData name . reverse) `liftM` foldM f ([], env) ps
90+ where f (rps,env') p = do (rp,env'') <- patternExtend p env'
6891 return (rp:rps, env'')
6992
70−pattern_rename env (p,e) = do
71− (rp,env') <- pattern_extend p env
93+patternRename :: (String -> String) -> (Pattern, Expr) -> GuidCounter (Pattern, Expr)
94+patternRename env (p,e) = do
95+ (rp,env') <- patternExtend p env
7296 re <- rename' env' e
73− return (rp,re)
97+ return (rp,re)