1{-# OPTIONS_GHC -Wall #-}
2module Generate.JavaScript.Variable
12import qualified Control.Monad.State as State
13import qualified Data.List as List
14import qualified Data.Set as Set
15import qualified Language.ECMAScript3.Syntax as JS
17import qualified AST.Helpers as Help
18import qualified AST.Module.Name as ModuleName
19import qualified AST.Variable as Var
20import qualified Elm.Package as Pkg
21import qualified Generate.JavaScript.Helpers as JS
28fresh :: State.State Int String
32 return ("_v" ++ show n)
39define :: Maybe ModuleName.Canonical -> String -> JS.Expression () -> [JS.Statement ()]
40define maybeHome name body =
41 if not (Help.isOp name) then
44 maybe unqualified qualified maybeHome name
46 [ JS.VarDeclStmt () [ JS.varDecl jsName body ] ]
51 error "can only define infix operators at the top level"
56 getOpsDictName (Var.TopLevel home)
59 JS.LBracket () (JS.ref opsDictName) (JS.StringLit () name)
61 [ JS.VarDeclStmt () [ JS.varDecl opsDictName (JS.refOrObject opsDictName) ]
62 , JS.ExprStmt () (JS.AssignExpr () JS.OpAssign lvalue body)
67-- INSTANTIATE VARIABLES
70canonical :: Var.Canonical -> JS.Expression ()
71canonical (Var.Canonical home name) =
72 if Help.isOp name then
73 JS.BracketRef () (JS.ref (getOpsDictName home)) (JS.StringLit () name)
78 JS.ref (unqualified name)
81 JS.ref (unqualified name)
83 Var.Module moduleName@(ModuleName.Canonical _ rawName) ->
84 if ModuleName.isNative rawName then
85 native moduleName name
88 JS.ref (qualified moduleName name)
90 Var.TopLevel moduleName ->
91 JS.ref (qualified moduleName name)
94unqualified :: String -> String
99qualified :: ModuleName.Canonical -> String -> String
100qualified moduleName name =
101 moduleToString moduleName ++ "$" ++ removePrimes name
104native :: ModuleName.Canonical -> String -> JS.Expression ()
105native moduleName name =
106 JS.obj [ moduleToString moduleName, name ]
109getOpsDictName :: Var.Home -> String
114 Var.Local -> error "infix operators should only be defined in top-level declarations"
115 Var.BuiltIn -> error "there should be no built-in infix operators"
116 Var.Module name -> name
117 Var.TopLevel name -> name
119 moduleToString moduleName ++ "_ops"
122moduleToString :: ModuleName.Canonical -> String
123moduleToString (ModuleName.Canonical (Pkg.Name user project) moduleName) =
126 map (swap '-' '_') user
129 map (swap '-' '_') project
132 List.intercalate "_" moduleName
134 '_' : safeUser ++ "$" ++ safeProject ++ "$" ++ safeModuleName
137swap :: Char -> Char -> Char -> Char
139 if c == from then to else c
146safe :: String -> String
149 if Set.member name jsReserveds then '$' : name else name
152removePrimes :: String -> String
154 map (swap '\'' '$') name
157jsReserveds :: Set.Set String
161 [ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
162 , "arguments", "int", "byte", "char", "goto", "long", "final", "float"
163 , "short", "double", "native", "throws", "boolean", "abstract", "volatile"
164 , "transient", "synchronized", "function", "break", "case", "catch"
165 , "continue", "debugger", "default", "delete", "do", "else", "finally"
166 , "for", "function", "if", "in", "instanceof", "new", "return", "switch"
167 , "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
168 , "const", "enum", "export", "extends", "import", "super", "implements"
169 , "interface", "let", "package", "private", "protected", "public"
171 -- reserved by the Elm runtime system
172 , "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
173 , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
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