module Generate.JavaScript.Variable where
import qualified AST.Helpers as Help
import qualified AST.Module as Module
import qualified AST.Variable as Var
import qualified Data.List as List
import qualified Data.Set as Set
import qualified Generate.JavaScript.Helpers as JS
import qualified Language.ECMAScript3.Syntax as JS
swap :: Char -> Char -> Char -> Char
swap from to c =
if c == from then to else c
canonical :: Var.Canonical -> JS.Expression ()
canonical (Var.Canonical home name) =
case Help.isOp name of
True -> JS.BracketRef () (JS.obj (home' ++ ["_op"])) (JS.string name)
False -> JS.obj (home' ++ [ varName name ])
where
home' =
case home of
Var.Local -> []
Var.BuiltIn -> []
Var.Module path -> [ moduleName path ]
moduleName :: Module.Name -> String
moduleName name =
'$' : List.intercalate "$" name
varName :: String -> String
varName name =
let saferName =
if Set.member name jsReserveds then '$' : name else name
in
map (swap '\'' '$') saferName
value :: Module.Name -> String -> JS.Expression ()
value home name =
canonical (Var.Canonical (Var.Module home) name)
jsReserveds :: Set.Set String
jsReserveds = Set.fromList
[ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
, "arguments", "int", "byte", "char", "goto", "long", "final", "float"
, "short", "double", "native", "throws", "boolean", "abstract", "volatile"
, "transient", "synchronized", "function", "break", "case", "catch"
, "continue", "debugger", "default", "delete", "do", "else", "finally"
, "for", "function", "if", "in", "instanceof", "new", "return", "switch"
, "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
, "const", "enum", "export", "extends", "import", "super", "implements"
, "interface", "let", "package", "private", "protected", "public"
, "static", "yield"
, "Elm"
, "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
, "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
]