1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Generate.JavaScript.Variable
17import qualified Control.Monad.State.Strict as State
18import qualified Data.ByteString as BS
19import Data.Monoid ((<>))
20import qualified Data.Map as Map
21import qualified Data.Set as Set
22import Data.Text (Text)
23import qualified Data.Text as Text
24import qualified Data.Text.Encoding as Text (encodeUtf8)
25import Data.Word (Word8)
27import qualified AST.Helpers as Help
28import qualified AST.Module.Name as ModuleName
29import qualified AST.Variable as Var
30import qualified Elm.Package as Pkg
31import qualified Generate.JavaScript.Builder as JS
32import qualified Generate.JavaScript.Helpers as JS
39type Generator = State.State Int
42run :: Generator a -> a
44 State.evalState generator 0
51fresh :: Generator Text
55 return ("_v" <> Text.pack (show uid))
62local :: Text -> JS.Expr
69 if Set.member name reservedNames then
79reservedNames :: Set.Set Text
81 Set.union jsReservedWords elmReservedWords
84jsReservedWords :: Set.Set Text
88 , "NaN", "int", "for", "new", "try", "var", "let"
89 , "null", "true", "eval", "byte", "char", "goto", "long", "case", "else", "this", "void", "with", "enum"
90 , "false", "final", "float", "short", "break", "catch", "throw", "while", "class", "const", "super", "yield"
91 , "double", "native", "throws", "delete", "return", "switch", "typeof", "export", "import", "public", "static"
92 , "boolean", "default", "finally", "extends", "package", "private"
93 , "Infinity", "abstract", "volatile", "function", "continue", "debugger", "function"
94 , "undefined", "arguments", "transient", "interface", "protected"
95 , "instanceof", "implements"
100elmReservedWords :: Set.Set Text
103 [ "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
104 , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
112global :: Var.Global -> Generator JS.Expr
114 JS.ref <$> globalName var
117globalName :: Var.Global -> Generator Text
118globalName (Var.Global home name) =
119 return (globalToName home name)
122globalToName :: ModuleName.Canonical -> Text -> Text
123globalToName (ModuleName.Canonical (Pkg.Name user project) moduleName) name =
124 if ModuleName.isKernel moduleName then
125 "_" <> ModuleName.getKernel moduleName <> "_" <> name
130 if Help.isOp name then
131 "_op_" <> Help.desymbol name
135 Text.replace "-" "_" user
136 <> "$" <> Text.replace "-" "_" project
137 <> "$" <> Text.replace "." "_" moduleName
138 <> "$" <> revisedName
145intToAscii :: Int -> BS.ByteString
147 if n < 53 then -- skip $ as a standalone name
148 BS.singleton (toByte n)
151 intToAsciiHelp (numStartBytes * numInnerBytes) allBadFields (n - 53)
154intToAsciiHelp :: Int -> [BadFields] -> Int -> BS.ByteString
155intToAsciiHelp blockSize badFields n =
158 if n < blockSize then
161 intToAsciiHelp (blockSize * numInnerBytes) [] (n - blockSize)
163 BadFields renamings : biggerBadFields ->
164 if n < blockSize - Map.size renamings then
165 let name = unsafeIntToAscii n in
166 Map.findWithDefault name name renamings
168 intToAsciiHelp (blockSize * numInnerBytes) biggerBadFields (n - blockSize)
172-- UNSAFE INT TO ASCII
175unsafeIntToAscii :: Int -> BS.ByteString
178 (quotient, remainder) =
179 quotRem n numStartBytes
181 BS.pack $ toByte remainder : unsafeIntToAsciiHelp quotient
184unsafeIntToAsciiHelp :: Int -> [Word8]
185unsafeIntToAsciiHelp n =
189 let (quotient, remainder) = quotRem n numInnerBytes in
190 toByte remainder : unsafeIntToAsciiHelp quotient
207toByte :: Int -> Word8
209 | n < 26 = fromIntegral (97 + n ) {- lower -}
210 | n < 52 = fromIntegral (65 + n - 26) {- upper -}
211 | n == 53 = 95 {- _ -}
212 | n == 54 = 36 {- $ -}
213 | n < 64 = fromIntegral (48 + n - 54) {- digit -}
214 | True = error $ "cannot convert int " ++ show n ++ " to ASCII"
222 BadFields { _renamings :: Renamings }
226 Map.Map BS.ByteString BS.ByteString
229allBadFields :: [BadFields]
233 Map.alter (Just . addRenaming keyword) (Text.length keyword) dict
235 Map.elems $ Set.foldr add Map.empty jsReservedWords
238addRenaming :: Text -> Maybe BadFields -> BadFields
239addRenaming keyword maybeBadFields =
242 numStartBytes * numInnerBytes ^ (Text.length keyword - 1) - 1
244 case maybeBadFields of
246 BadFields $ Map.singleton (Text.encodeUtf8 keyword) (unsafeIntToAscii maxName)
248 Just (BadFields renamings) ->
249 BadFields $ Map.insert (Text.encodeUtf8 keyword) (unsafeIntToAscii (maxName - Map.size renamings)) renamings
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list