1{-# OPTIONS_GHC -Wall #-}
2module Generate.JavaScript.Variable
11import qualified Control.Monad.State as State
12import qualified Data.List as List
13import qualified Data.Set as Set
14import qualified Language.ECMAScript3.Syntax as JS
16import qualified AST.Helpers as Help
17import qualified AST.Module.Name as ModuleName
18import qualified AST.Variable as Var
19import qualified Elm.Package as Pkg
20import qualified Generate.JavaScript.Helpers as JS
27fresh :: State.State Int String
31 return ("_v" ++ show n)
38define :: Maybe ModuleName.Canonical -> String -> JS.Expression () -> [JS.Statement ()]
39define maybeHome name body =
40 if not (Help.isOp name) then
43 maybe unqualified qualified maybeHome name
45 [ JS.VarDeclStmt () [ JS.varDecl jsName body ] ]
50 error "can only define infix operators at the top level"
55 getOpsDictName (Var.TopLevel home)
58 JS.LBracket () (JS.ref opsDictName) (JS.StringLit () name)
60 [ JS.VarDeclStmt () [ JS.varDecl opsDictName (JS.refOrObject opsDictName) ]
61 , JS.ExprStmt () (JS.AssignExpr () JS.OpAssign lvalue body)
66-- INSTANTIATE VARIABLES
69canonical :: Var.Canonical -> JS.Expression ()
70canonical (Var.Canonical home name) =
71 if Help.isOp name then
72 JS.BracketRef () (JS.ref (getOpsDictName home)) (JS.StringLit () name)
77 JS.ref (unqualified name)
80 JS.ref (unqualified name)
82 Var.Module moduleName@(ModuleName.Canonical _ rawName) ->
83 if ModuleName.isNative rawName then
84 native moduleName name
87 JS.ref (qualified moduleName name)
89 Var.TopLevel moduleName ->
90 JS.ref (qualified moduleName name)
93unqualified :: String -> String
98qualified :: ModuleName.Canonical -> String -> String
99qualified moduleName name =
100 moduleToString moduleName ++ "$" ++ removePrimes name
103native :: ModuleName.Canonical -> String -> JS.Expression ()
104native moduleName name =
105 JS.obj [ moduleToString moduleName, name ]
108getOpsDictName :: Var.Home -> String
113 Var.Local -> error "infix operators should only be defined in top-level declarations"
114 Var.BuiltIn -> error "there should be no built-in infix operators"
115 Var.Module name -> name
116 Var.TopLevel name -> name
118 moduleToString moduleName ++ "_ops"
121moduleToString :: ModuleName.Canonical -> String
122moduleToString (ModuleName.Canonical (Pkg.Name user project) moduleName) =
125 map (swap '-' '_') user
128 map (swap '-' '_') project
131 List.intercalate "_" moduleName
133 '_' : safeUser ++ "$" ++ safeProject ++ "$" ++ safeModuleName
136swap :: Char -> Char -> Char -> Char
138 if c == from then to else c
145safe :: String -> String
148 if Set.member name jsReserveds then '$' : name else name
151removePrimes :: String -> String
153 map (swap '\'' '$') name
156jsReserveds :: Set.Set String
160 [ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
161 , "arguments", "int", "byte", "char", "goto", "long", "final", "float"
162 , "short", "double", "native", "throws", "boolean", "abstract", "volatile"
163 , "transient", "synchronized", "function", "break", "case", "catch"
164 , "continue", "debugger", "default", "delete", "do", "else", "finally"
165 , "for", "function", "if", "in", "instanceof", "new", "return", "switch"
166 , "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
167 , "const", "enum", "export", "extends", "import", "super", "implements"
168 , "interface", "let", "package", "private", "protected", "public"
170 -- reserved by the Elm runtime system
171 , "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
172 , "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