@@ -0,0 +1,71 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Scope
4+-- Copyright : (c) Phil Freeman 2013
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+--
13+-----------------------------------------------------------------------------
14+
15+module Language.PureScript.Scope (
16+ usedNames,
17+ unusedNames,
18+ firstUnusedName
19+) where
20+
21+import Data.Data
22+import Data.List ((\\), nub)
23+import Data.Generics (extQ, mkQ, everything)
24+
25+import Language.PureScript.Values
26+import Language.PureScript.Names
27+import Language.PureScript.CodeGen.JS.AST
28+import Data.Maybe (mapMaybe)
29+import Text.Read (readMaybe)
30+
31+usedNames :: (Data d) => d -> [Ident]
32+usedNames val = nub $ everything (++) (mkQ [] namesV `extQ` namesS `extQ` namesB `extQ` namesJS) val
33+ where
34+ namesV :: Value -> [Ident]
35+ namesV (Abs args _) = args
36+ namesV (Var (Qualified (ModulePath []) name)) = [name]
37+ namesV _ = []
38+ namesS :: Statement -> [Ident]
39+ namesS (VariableIntroduction name _) = [name]
40+ namesS (For name _ _ _) = [name]
41+ namesS _ = []
42+ namesB :: Binder -> [Ident]
43+ namesB (VarBinder name) = [name]
44+ namesB _ = []
45+ namesJS :: JS -> [Ident]
46+ namesJS (JSVar name) = [name]
47+ namesJS (JSFunction (Just name) args _) = name : args
48+ namesJS (JSFunction Nothing args _) = args
49+ namesJS (JSVariableIntroduction name _) = [name]
50+ namesJS (JSFor name _ _ _) = [name]
51+ namesJS _ = []
52+
53+unusedNames :: (Data d) => d -> [Ident]
54+unusedNames val =
55+ let
56+ allNames = usedNames val
57+ varNames = map (Ident . ('_' :) . show) ([1..] :: [Int])
58+ in
59+ varNames \\ allNames
60+
61+firstUnusedName :: (Data d) => d -> Int
62+firstUnusedName val =
63+ let
64+ allNames = usedNames val
65+ varNames = mapMaybe toUnknown allNames
66+ in
67+ 1 + maximum (0 : varNames)
68+ where
69+ toUnknown :: Ident -> Maybe Int
70+ toUnknown (Ident ('_' : s)) = readMaybe s
71+ toUnknown _ = Nothing