on 572f3c2 help sign in
elk/src/Generate/JavaScript/Variable.hs
122 lines 2.8 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Generate.JavaScript.Variable
4 ( Generator
5 , run
6 , fresh
7 , local
8 , safe
9 , global
10 , globalName
11 , globalToName
12 )
13 where
16import qualified Control.Monad.State.Strict as State
17import Data.Monoid ((<>))
18import qualified Data.Set as Set
19import qualified Data.Text as Text
20import Data.Text (Text)
22import qualified AST.Helpers as Help
23import qualified AST.Module.Name as ModuleName
24import qualified AST.Variable as Var
25import qualified Elm.Package as Pkg
26import qualified Generate.JavaScript.Builder as JS
27import qualified Generate.JavaScript.Helpers as JS
31-- GENERATOR
34type Generator = State.State Int
37run :: Generator a -> a
38run generator =
39 State.evalState generator 0
43-- FRESH NAMES
46fresh :: Generator Text
47fresh =
48 do uid <- State.get
49 State.put (uid + 1)
50 return ("_v" <> Text.pack (show uid))
54-- LOCAL NAMES
57local :: Text -> JS.Expr
58local name =
59 JS.ref (safe name)
62safe :: Text -> Text
63safe name =
64 if Set.member name reservedWords then
65 "_" <> name
66 else
67 name
70reservedWords :: Set.Set Text
71reservedWords =
72 Set.fromList
73 -- reserved by JavaScript
74 [ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
75 , "arguments", "int", "byte", "char", "goto", "long", "final", "float"
76 , "short", "double", "native", "throws", "boolean", "abstract", "volatile"
77 , "transient", "synchronized", "function", "break", "case", "catch"
78 , "continue", "debugger", "default", "delete", "do", "else", "finally"
79 , "for", "function", "if", "in", "instanceof", "new", "return", "switch"
80 , "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
81 , "const", "enum", "export", "extends", "import", "super", "implements"
82 , "interface", "let", "package", "private", "protected", "public"
83 , "static", "yield"
84 -- reserved by Elm
85 , "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
86 , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
87 , "ctor"
88 ]
92-- GLOBAL NAMES
95global :: Var.Global -> Generator JS.Expr
96global var =
97 JS.ref <$> globalName var
100globalName :: Var.Global -> Generator Text
101globalName (Var.Global home name) =
102 return (globalToName home name)
105globalToName :: ModuleName.Canonical -> Text -> Text
106globalToName (ModuleName.Canonical (Pkg.Name user project) moduleName) name =
107 if ModuleName.isKernel moduleName then
108 "_" <> ModuleName.getKernel moduleName <> "_" <> name
110 else
111 let
112 revisedName =
113 if Help.isOp name then
114 "_op_" <> Help.desymbol name
115 else
116 name
117 in
118 Text.replace "-" "_" user
119 <> "$" <> Text.replace "-" "_" project
120 <> "$" <> Text.replace "." "_" moduleName
121 <> "$" <> revisedName