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