on c9f3911 help sign in
elk/src/Generate/JavaScript/Variable.hs
106 lines 2.9 kB history raw
1module Generate.JavaScript.Variable (fresh, canonical, define, safe) where
3import qualified Control.Monad.State as State
4import qualified Data.List as List
5import qualified Data.Set as Set
6import qualified Language.ECMAScript3.Syntax as JS
8import qualified AST.Helpers as Help
9import qualified AST.Module.Name as ModuleName
10import qualified AST.Variable as Var
11import qualified Elm.Package as Pkg
12import qualified Generate.JavaScript.Helpers as JS
15-- FRESH NAMES
17fresh :: State.State Int String
18fresh =
19 do n <- State.get
20 State.modify (+1)
21 return ("_v" ++ show n)
24-- DEF NAMES
26define :: String -> JS.Expression () -> JS.Statement ()
27define name body =
28 if Help.isOp name then
29 let
30 root =
31 JS.VarRef () (JS.Id () "_op")
33 lvalue =
34 JS.LBracket () root (JS.StringLit () name)
35 in
36 JS.ExprStmt () (JS.AssignExpr () JS.OpAssign lvalue body)
38 else
39 JS.VarDeclStmt () [ JS.VarDecl () (JS.Id () (safe name)) (Just body) ]
42-- INSTANTIATE VARIABLES
44canonical :: Var.Canonical -> JS.Expression ()
45canonical (Var.Canonical home name) =
46 if Help.isOp name then
47 JS.BracketRef () (addRoot home "_op") (JS.string name)
49 else
50 addRoot home (safe name)
53addRoot :: Var.Home -> String -> JS.Expression ()
54addRoot home name =
55 case home of
56 Var.Local ->
57 JS.ref name
59 Var.TopLevel _moduleName ->
60 JS.ref name
62 Var.BuiltIn ->
63 JS.ref name
65 Var.Module moduleName ->
66 JS.DotRef () (JS.ref (canonicalModuleName moduleName)) (JS.Id () name)
69canonicalModuleName :: ModuleName.Canonical -> String
70canonicalModuleName (ModuleName.Canonical (Pkg.Name _user _project) moduleName) =
71 '$' : List.intercalate "$" moduleName
74swap :: Char -> Char -> Char -> Char
75swap from to c =
76 if c == from then to else c
79-- SAFE NAMES
81safe :: String -> String
82safe name =
83 let saferName =
84 if Set.member name jsReserveds then '$' : name else name
85 in
86 map (swap '\'' '$') saferName
89jsReserveds :: Set.Set String
90jsReserveds =
91 Set.fromList
92 -- JS reserved words
93 [ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
94 , "arguments", "int", "byte", "char", "goto", "long", "final", "float"
95 , "short", "double", "native", "throws", "boolean", "abstract", "volatile"
96 , "transient", "synchronized", "function", "break", "case", "catch"
97 , "continue", "debugger", "default", "delete", "do", "else", "finally"
98 , "for", "function", "if", "in", "instanceof", "new", "return", "switch"
99 , "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
100 , "const", "enum", "export", "extends", "import", "super", "implements"
101 , "interface", "let", "package", "private", "protected", "public"
102 , "static", "yield"
103 -- reserved by the Elm runtime system
104 , "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
105 , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
106 ]