module IRTS.Java.ASTBuilding where import IRTS.Java.JTypes import Language.Java.Syntax hiding (Name) import qualified Language.Java.Syntax as J toClassType :: J.Type -> ClassType toClassType (RefType (ClassRefType ct)) = ct toClassType t = error $ "Not a class type: " ++ (show t) toRefType :: J.Type -> RefType toRefType (RefType rt) = rt toRefType t = error $ "Not a ref type: " ++ (show t) class InvocationTarget a where (~>) :: a -> String -> [Argument] -> Exp instance InvocationTarget ClassType where (~>) (ClassType ts) method args = MethodInv $ TypeMethodCall (J.Name $ map fst ts) (concatMap (map fromActType . snd) ts) (Ident method) args where fromActType (ActualType refType) = refType instance InvocationTarget Exp where (~>) exp method args = MethodInv $ PrimaryMethodCall exp [] (Ident method) args instance InvocationTarget J.Type where (~>) t method args = ((toClassType t) ~> method) args class Callable a where call :: a -> [Argument] -> Exp instance Callable String where call method args = MethodInv $ MethodCall (J.Name [Ident method]) args instance Callable Ident where call method args = MethodInv $ MethodCall (J.Name [method]) args instance Callable J.Name where call method args = MethodInv $ MethodCall method args (<>) :: Type -> Exp -> Exp (<>) = Cast localVar :: Int -> Ident localVar i = Ident $ "loc" ++ show i (@!) :: Exp -> Int -> ArrayIndex (@!) target pos = ArrayIndex target (Lit $ Int (toInteger pos)) (@:=) :: Either ArrayIndex Ident -> Exp -> BlockStmt (@:=) (Right lhs) rhs = LocalVars [Final] objectType [VarDecl (VarId lhs) (Just $ InitExp rhs)] (@:=) (Left lhs) rhs = BlockStmt . ExpStmt $ Assign (ArrayLhs lhs) EqualA rhs (~&&~) :: Exp -> Exp -> Exp (~&&~) e1 e2 = BinOp e1 CAnd e2 (~==~) :: Exp -> Exp -> Exp (~==~) e1 e2 = BinOp e1 Equal e2 addToBlock :: [BlockStmt] -> Exp -> [BlockStmt] addToBlock blk exp = blk ++ [BlockStmt $ ExpStmt exp] jName :: String -> J.Name jName n = J.Name [Ident n] jConst :: String -> Exp jConst = ExpName . jName jReturn :: Exp -> BlockStmt jReturn = BlockStmt . Return . Just jInt :: Int -> Exp jInt = Lit . Int . toInteger jString :: String -> Exp jString = Lit . String simpleMethod :: [Modifier] -> Maybe J.Type -> String -> [FormalParam] -> Block -> Decl simpleMethod mods t name params body = MemberDecl $ MethodDecl mods [] t (Ident $ name) params [] (MethodBody . Just $ body) declareFinalObjectArray :: Ident -> Maybe VarInit -> BlockStmt declareFinalObjectArray name init = LocalVars [Final] (array objectType) [ VarDecl (VarDeclArray . VarId $ name) init ] arrayInitExps :: [Exp] -> VarInit arrayInitExps = InitArray . ArrayInit . map (InitExp) extendWithNull :: [Exp] -> Int -> [Exp] extendWithNull exps additionalZeros = exps ++ (replicate additionalZeros (Lit $ Null)) closure :: Exp -> Exp closure body = InstanceCreation [] (toClassType idrisClosureType) [] (Just $ ClassBody [ simpleMethod [Public, Final] (Just objectType) "call" [] (Block [jReturn body]) ] ) bigInteger :: String -> Exp bigInteger s = InstanceCreation [] (toClassType bigIntegerType) [Lit $ String s] Nothing