2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
4 \section{Generate Java}
7 module JavaGen( javaGen ) where
11 import Literal ( Literal(..) )
12 import Id ( Id, isDataConId_maybe, isId, idName, isDeadBinder )
13 import Name ( NamedThing(..), getOccString, isGlobalName )
14 import DataCon ( DataCon, dataConRepArity, dataConId )
15 import qualified CoreSyn
16 import CoreSyn ( CoreBind, CoreExpr, CoreAlt, CoreBndr,
17 Bind(..), Alt, AltCon(..), collectBinders, isValArg
19 import CoreUtils( exprIsValue, exprIsTrivial )
20 import Module ( Module, moduleString )
21 import TyCon ( TyCon, isDataTyCon, tyConDataCons )
24 #include "HsVersions.h"
30 javaGen :: Module -> [Module] -> [TyCon] -> [CoreBind] -> CompilationUnit
32 javaGen mod import_mods tycons binds
33 = Package [moduleString mod] decls
35 decls = [Import [moduleString mod] | mod <- import_mods] ++
36 concat (map javaTyCon (filter isDataTyCon tycons)) ++
37 concat (map javaTopBind binds)
41 %************************************************************************
43 \subsection{Type declarations}
45 %************************************************************************
48 javaTyCon :: TyCon -> [Decl]
49 -- public class List {}
51 -- public class $wCons extends List {
52 -- Object f1; Object f2
54 -- public class $wNil extends List {}
57 = tycon_jclass : map constr_class constrs
59 constrs = tyConDataCons tycon
60 tycon_jclass_jname = javaName tycon
61 tycon_jclass = Class [Public] tycon_jclass_jname [] [] []
64 = Class [Public] constr_jname [tycon_jclass_jname] [] field_decls
66 constr_jname = javaConstrWkrName data_con
67 enter_meth = Method [Public] objectType enterName [] stmts
68 n_val_args = dataConRepArity data_con
69 field_names = map fieldName [1..n_val_args]
70 field_decls = [Field [Public] objectType f Nothing | f <- field_names]
71 stmts = vmCOLLECT n_val_args (Var thisName) ++
72 [var [Final] objectType f vmPOP | f <- field_names] ++
73 [Return (New constr_jname (map Var field_names) Nothing)]
76 %************************************************************************
80 %************************************************************************
83 javaTopBind :: CoreBind -> [Decl]
84 javaTopBind (NonRec bndr rhs) = [java_top_bind bndr rhs]
85 javaTopBind (Rec prs) = [java_top_bind bndr rhs | (bndr,rhs) <- prs]
87 java_top_bind :: Id -> CoreExpr -> Decl
88 -- public class f implements Code {
89 -- public Object ENTER() { ...translation of rhs... }
91 java_top_bind bndr rhs
92 = Class [Public] (javaName bndr) [] [codeName] [enter_meth]
94 enter_meth = Method [Public] objectType enterName [] (javaExpr rhs)
98 %************************************************************************
100 \subsection{Expressions}
102 %************************************************************************
105 javaVar :: Id -> Expr
106 javaVar v | isGlobalName (idName v) = New (javaName v) [] Nothing
107 | otherwise = Var (javaName v)
110 javaLit :: Literal.Literal -> Lit
111 javaLit (MachInt i) = UIntLit (fromInteger i)
112 javaLit (MachChar c) = UCharLit c
113 javaLit other = pprPanic "javaLit" (ppr other)
115 javaExpr :: CoreExpr -> [Statement]
116 -- Generate code to apply the value of
117 -- the expression to the arguments aleady on the stack
118 javaExpr (CoreSyn.Var v) = [Return (javaVar v)]
119 javaExpr (CoreSyn.Lit l) = [Return (Literal (javaLit l))]
120 javaExpr (CoreSyn.App f a) = javaApp f [a]
121 javaExpr e@(CoreSyn.Lam _ _) = javaLam (collectBinders e)
122 javaExpr (CoreSyn.Case e x alts) = javaCase e x alts
123 javaExpr (CoreSyn.Let bind body) = javaBind bind ++ javaExpr body
124 javaExpr (CoreSyn.Note _ e) = javaExpr e
126 javaCase :: CoreExpr -> Id -> [CoreAlt] -> [Statement]
127 -- case e of x { Nil -> r1
130 -- final Object x = VM.WHNF(...code for e...)
131 -- else if x instance_of Nil {
132 -- ...translation of r1...
133 -- } else if x instance_of Cons {
134 -- final Object p = ((Cons) x).f1
135 -- final Object q = ((Cons) x).f2
136 -- ...translation of r2...
137 -- } else return null
140 = [var [Final] objectType (javaName x) (vmWHNF (javaArg e)),
141 IfThenElse (map mk_alt alts) Nothing]
143 mk_alt (DEFAULT, [], rhs) = (true, Block (javaExpr rhs))
144 mk_alt (DataAlt d, bs, rhs) = (instanceOf x d, Block (bind_args d bs ++ javaExpr rhs))
145 mk_alt alt@(LitAlt _, _, _) = pprPanic "mk_alt" (ppr alt)
147 bind_args d bs = [var [Final] objectType (javaName b)
148 (Access (Cast (Type (javaConstrWkrName d)) (javaVar x)) f)
149 | (b, f) <- filter isId bs `zip` map fieldName [1..],
153 javaBind (NonRec x rhs)
157 final Object x = new Thunk( new Code() { ...code for rhs_x... } )
159 = [var [Final] objectType (javaName x) (javaArg rhs)]
162 {- rec { x = ...rhs_x...; y = ...rhs_y... }
164 class x implements Code {
166 public Object ENTER() { ...code for rhs_x...}
170 final x x_inst = new x();
173 final Thunk x = new Thunk( x_inst );
180 = (map mk_class prs) ++ (map mk_inst prs) ++
181 (map mk_thunk prs) ++ concat (map mk_knot prs)
183 mk_class (b,r) = Declaration (Class [] (javaName b) [] [codeName] stmts)
185 stmts = [Field [] codeType (javaName b) Nothing | (b,_) <- prs] ++
186 [Method [Public] objectType enterName [] (javaExpr r)]
188 mk_inst (b,r) = var [Final] (Type (javaName b)) (javaInstName b)
189 (New (javaName b) [] Nothing)
191 mk_thunk (b,r) = var [Final] thunkType (javaName b)
192 (New thunkName [Var (javaInstName b)] Nothing)
194 mk_knot (b,_) = [ExprStatement (Assign lhs rhs)
196 let lhs = Access (Var (javaInstName b)) (javaName b'),
197 let rhs = Var (javaName b')
200 javaLam :: ([CoreBndr], CoreExpr) -> [Statement]
201 javaLam (bndrs, body)
202 | null val_bndrs = javaExpr body
204 = vmCOLLECT (length val_bndrs) (Var thisName)
205 ++ [var [Final] objectType (javaName n) vmPOP | n <- val_bndrs]
208 val_bndrs = filter isId bndrs
210 javaApp :: CoreExpr -> [CoreExpr] -> [Statement]
211 javaApp (CoreSyn.App f a) as = javaApp f (a:as)
212 javaApp (CoreSyn.Var f) as
213 = case isDataConId_maybe f of {
214 Just dc | length as == dataConRepArity dc
215 -> -- Saturated constructors
216 [Return (New (javaName f) (javaArgs as) Nothing)]
218 ; other -> -- Not a saturated constructor
219 java_apply (CoreSyn.Var f) as
222 javaApp f as = java_apply f as
224 java_apply :: CoreExpr -> [CoreExpr] -> [Statement]
225 java_apply f as = [ExprStatement (vmPUSH arg) | arg <- javaArgs as] ++ javaExpr f
227 javaArgs :: [CoreExpr] -> [Expr]
228 javaArgs args = [javaArg a | a <- args, isValArg a]
230 javaArg :: CoreExpr -> Expr
231 javaArg (CoreSyn.Type t) = pprPanic "javaArg" (ppr t)
232 javaArg e | exprIsValue e || exprIsTrivial e = newCode (javaExpr e)
233 | otherwise = newThunk (newCode (javaExpr e))
236 %************************************************************************
238 \subsection{Helper functions}
240 %************************************************************************
248 vmCOLLECT :: Int -> Expr -> [Statement]
250 vmCOLLECT n e = [ExprStatement (Call (Var vmName) ["COLLECT"] [Literal (IntLit n), e])]
253 vmPOP = Call (Var vmName) ["POP"] []
255 vmPUSH :: Expr -> Expr
256 vmPUSH e = Call (Var vmName) ["PUSH"] [e]
258 var :: [Modifier] -> Type -> Name -> Expr -> Statement
259 var ms ty field_name value = Declaration (Field ms ty field_name (Just value))
261 vmWHNF :: Expr -> Expr
262 vmWHNF e = Call (Var vmName) ["WHNF"] [e]
264 instanceOf :: Id -> DataCon -> Expr
265 instanceOf x data_con
266 = InstanceOf (Var (javaName x)) (Type (javaConstrWkrName data_con))
268 newCode :: [Statement] -> Expr
269 newCode [Return e] = e
270 newCode stmts = New codeName [] (Just [Method [Public] objectType enterName [] stmts])
272 newThunk :: Expr -> Expr
273 newThunk e = New thunkName [e] Nothing
276 %************************************************************************
278 \subsection{Name mangling}
280 %************************************************************************
283 codeName, enterName, vmName :: Name
285 thunkName = ["Thunk"]
286 enterName = ["ENTER"]
290 fieldName :: Int -> Name -- Names for fields of a constructor
291 fieldName n = ["f" ++ show n]
293 javaName :: NamedThing a => a -> Name
294 javaName n = [getOccString n]
296 javaConstrWkrName :: DataCon -> Name
297 -- The function that makes the constructor
298 javaConstrWkrName con = [getOccString (dataConId con)]
300 javaInstName :: NamedThing a => a -> Name
301 -- Makes x_inst for Rec decls
302 javaInstName n = [getOccString n ++ "_inst"]
305 %************************************************************************
307 \subsection{Type mangling}
309 %************************************************************************
312 codeType, thunkType, objectType :: Type
313 objectType = Type ["Object"]
314 codeType = Type codeName
315 thunkType = Type thunkName