1{-# LANGUAGE PatternGuards #-}
3module IRTS.CodegenJavaScript (codegenJavaScript) where
9import IRTS.CodegenCommon
19type NamespaceName = String
21idrNamespace :: NamespaceName
22idrNamespace = "__IDR__"
29codegenJavaScript definitions filename outputType = do
30 let def = map (first translateNamespace) definitions
31 let output = idrRuntime ++ concatMap (translateModule Nothing) def ++ "\nMain.main()"
32 writeFile filename output
36 createModule Nothing idrNamespace $ concat
37 [ "__IDR__.IntType = { type: 'IntType' };"
38 , "__IDR__.Con = function(i,name,vars)"
39 , "{this.i = i;this.name = name;this.vars = vars;};"
42createModule :: Maybe String -> NamespaceName -> String -> String
43createModule toplevel modname body =
44 concat [header modname, body, footer modname]
46 header :: NamespaceName -> String
49 [ "\nvar " ++ modname ++ ";"
50 , "(function(" ++ modname ++ "){"
53 footer :: NamespaceName -> String
55 let m = maybe "" (++ ".") toplevel ++ modname in
63translateModule :: Maybe String -> ([String], SDecl) -> String
64translateModule toplevel ([modname], decl) =
65 let body = translateDeclaration modname decl in
66 createModule toplevel modname body
67translateModule toplevel (n:ns, decl) =
68 createModule toplevel n $ translateModule (Just n) (ns, decl)
70translateIdentifier :: String -> String
72 concatMap replaceBadChars
73 where replaceBadChars :: Char -> String
74 replaceBadChars ' ' = "_"
75 replaceBadChars '@' = "__at__"
76 replaceBadChars '[' = "__OSB__"
77 replaceBadChars ']' = "__CSB__"
78 replaceBadChars '{' = "__OB__"
79 replaceBadChars '}' = "__CB__"
80 replaceBadChars '!' = "__bang__"
81 replaceBadChars '#' = "__hash__"
82 replaceBadChars '.' = "__dot__"
83 replaceBadChars ':' = "__colon__"
84 replaceBadChars '+' = "__plus__"
85 replaceBadChars '-' = "__minus__"
86 replaceBadChars '<' = "__lt__"
87 replaceBadChars '>' = "__gt__"
88 replaceBadChars '=' = "__eq__"
89 replaceBadChars '|' = "__pipe__"
90 replaceBadChars '\'' = "__apo__"
92 | isDigit c = "__" ++ [c] ++ "__"
95translateNamespace :: Name -> [String]
96translateNamespace (UN _) = [idrNamespace]
97translateNamespace (NS _ ns) = map translateIdentifier ns
98translateNamespace (MN _ _) = [idrNamespace]
100translateName :: Name -> String
101translateName (UN name) = translateIdentifier name
102translateName (NS name _) = translateName name
103translateName (MN i name) = translateIdentifier name ++ show i
105translateQualifiedName :: Name -> String
106translateQualifiedName name =
107 intercalate "." (translateNamespace name) ++ "." ++ translateName name
109translateConstant :: Const -> String
110translateConstant (I i) = show i
111translateConstant (BI i) = show i
112translateConstant (Fl f) = show f
113translateConstant (Ch c) = show c
114translateConstant (Str s) = show s
115translateConstant IType = "__IDR__.IntType"
117 "(function(){throw 'Unimplemented Const: " ++ show c ++ "';})()"
119translateParameterlist =
120 map (\(MN i name) -> name ++ show i)
122translateDeclaration :: NamespaceName -> SDecl -> String
123translateDeclaration modname (SFun name params stackSize body) =
126 ++ translateName name
130 ++ concatMap assignVar (zip [0..] p)
131 ++ concatMap allocVar [numP..(numP+stackSize-1)]
133 ++ translateExpression modname body
139 allocVar :: Int -> String
140 allocVar n = "var __var_" ++ show n ++ ";\n"
142 assignVar :: (Int, String) -> String
143 assignVar (n, s) = "var __var_" ++ show n ++ " = " ++ s ++ ";\n"
146 p = translateParameterlist params
148translateVariableName :: LVar -> String
149translateVariableName (Loc i) =
152translateExpression :: NamespaceName -> SExp -> String
153translateExpression modname (SLet name value body) =
155 ++ translateVariableName name
157 ++ translateExpression modname body
159 ++ translateExpression modname value
162translateExpression _ (SConst cst) =
163 translateConstant cst
165translateExpression _ (SV var) =
166 translateVariableName var
168translateExpression modname (SApp tc name vars) =
169 concat (intersperse "." $ translateNamespace name)
171 ++ translateName name
173 ++ intercalate "," (map translateVariableName vars)
176translateExpression _ (SOp op vars)
178 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
180 , (lhs:rhs:_) <- vars = translateBinaryOp "-" lhs rhs
182 , (lhs:rhs:_) <- vars = translateBinaryOp "*" lhs rhs
184 , (lhs:rhs:_) <- vars = translateBinaryOp "/" lhs rhs
186 , (lhs:rhs:_) <- vars = translateBinaryOp "%" lhs rhs
188 , (lhs:rhs:_) <- vars = translateBinaryOp "===" lhs rhs
190 , (lhs:rhs:_) <- vars = translateBinaryOp "<" lhs rhs
192 , (lhs:rhs:_) <- vars = translateBinaryOp "<=" lhs rhs
194 , (lhs:rhs:_) <- vars = translateBinaryOp ">" lhs rhs
196 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
199 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
201 , (lhs:rhs:_) <- vars = translateBinaryOp "-" lhs rhs
203 , (lhs:rhs:_) <- vars = translateBinaryOp "*" lhs rhs
205 , (lhs:rhs:_) <- vars = translateBinaryOp "/" lhs rhs
207 , (lhs:rhs:_) <- vars = translateBinaryOp "===" lhs rhs
209 , (lhs:rhs:_) <- vars = translateBinaryOp "<" lhs rhs
211 , (lhs:rhs:_) <- vars = translateBinaryOp "<=" lhs rhs
213 , (lhs:rhs:_) <- vars = translateBinaryOp ">" lhs rhs
215 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
218 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
220 , (lhs:rhs:_) <- vars = translateBinaryOp "-" lhs rhs
222 , (lhs:rhs:_) <- vars = translateBinaryOp "*" lhs rhs
224 , (lhs:rhs:_) <- vars = translateBinaryOp "/" lhs rhs
226 , (lhs:rhs:_) <- vars = translateBinaryOp "%" lhs rhs
228 , (lhs:rhs:_) <- vars = translateBinaryOp "===" lhs rhs
230 , (lhs:rhs:_) <- vars = translateBinaryOp "<" lhs rhs
232 , (lhs:rhs:_) <- vars = translateBinaryOp "<=" lhs rhs
234 , (lhs:rhs:_) <- vars = translateBinaryOp ">" lhs rhs
236 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
239 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
242 , (arg:_) <- vars = "String(" ++ translateVariableName arg ++ ");"
245 translateBinaryOp :: String -> LVar -> LVar -> String
246 translateBinaryOp f lhs rhs =
247 translateVariableName lhs
249 ++ translateVariableName rhs
251translateExpression _ (SError msg) =
252 "(function(){throw \'" ++ msg ++ "\';})();"
254translateExpression _ (SForeign _ _ "putStr" [(FString, var)]) =
255 "console.log(" ++ translateVariableName var ++ ");"
257translateExpression _ (SForeign _ _ fun args) =
260 ++ intercalate "," (map (translateVariableName . snd) args)
263translateExpression modname (SChkCase var cases) =
265 ++ intercalate " else " (map (translateCase modname "e") cases)
267 ++ translateVariableName var
270translateExpression modname (SCase var cases) =
272 ++ intercalate " else " (map (translateCase modname "e") cases)
274 ++ translateVariableName var
277translateExpression _ (SCon i name vars) =
278 concat [ "new __IDR__.Con("
281 , '\'' : translateQualifiedName name ++ "\',["
282 , intercalate "," $ map translateVariableName vars
286translateExpression modname (SUpdate var e) =
287 "(function(){\nreturn ("
288 ++ translateVariableName var
289 ++ " = " ++ translateExpression modname e
292translateExpression modname (SProj var i) =
293 "(function(){\nreturn "
294 ++ translateVariableName var ++ ".vars[" ++ show i ++"];\n})()"
296translateExpression _ SNothing = "null"
298translateExpression _ e =
299 "(function(){throw 'Not yet implemented: "
300 ++ filter (/= '\'') (show e)
303translateCase :: String -> String -> SAlt -> String
304translateCase modname _ (SDefaultCase e) =
305 createIfBlock "true" (translateExpression modname e)
307translateCase modname var (SConstCase cst e) =
308 let cond = var ++ " === " ++ translateConstant cst in
309 createIfBlock cond (translateExpression modname e)
311translateCase modname var (SConCase a i name vars e) =
312 let isCon = var ++ " instanceof __IDR__.Con"
313 isI = show i ++ " === " ++ var ++ ".i"
314 params = intercalate "," $ map (("__var_" ++) . show) [a..(a+length vars)]
315 args = ".apply(this," ++ var ++ ".vars)"
319 ++ "){\nreturn " ++ b ++ "\n})" ++ args
320 cond = intercalate " && " [isCon, isI] in
321 createIfBlock cond $ f (translateExpression modname e)
323createIfBlock cond e =
324 "if (" ++ cond ++") {\n"
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