@@ -1,37 +1,42 @@
1+{-# LANGUAGE PatternGuards #-}
1module IRTS.CodegenJava (codegenJava) where
2module IRTS.CodegenJava (codegenJava) where
3−import Core.TT
4+import Core.TT hiding (mkApp)
4import IRTS.BCImp
5import IRTS.BCImp
5import IRTS.CodegenCommon
6import IRTS.CodegenCommon
7+import IRTS.Java.ASTBuilding
8+import IRTS.Java.JTypes
9+import IRTS.Java.Mangling
6import IRTS.Lang
10import IRTS.Lang
7import IRTS.Simplified
11import IRTS.Simplified
8import Paths_idris
12import Paths_idris
9import Util.System
13import Util.System
11−import Control.Applicative
15+import Control.Applicative hiding (Const)
12import Control.Arrow
16import Control.Arrow
13import Control.Monad
17import Control.Monad
18+import Control.Monad.Error
14−import qualified Control.Monad.Trans as T
19+import qualified Control.Monad.Trans as T
15import Control.Monad.Trans.State
20import Control.Monad.Trans.State
17−import Data.Maybe (fromJust)
18−import Data.List (isPrefixOf, isSuffixOf, intercalate, foldl')
19import Data.Int
21import Data.Int
22+import Data.List (foldl', intercalate, isPrefixOf,
24+import Data.Maybe (fromJust)
20−import qualified Data.Text as T
25+import qualified Data.Text as T
21−import qualified Data.Text.IO as TIO
26+import qualified Data.Text.IO as TIO
27+import qualified Data.Vector.Unboxed as V
22import Language.Java.Parser
28import Language.Java.Parser
23import Language.Java.Pretty
29import Language.Java.Pretty
24−import Language.Java.Syntax hiding (Name)
30+import Language.Java.Syntax hiding (Name)
25−import qualified Language.Java.Syntax as J
31+import qualified Language.Java.Syntax as J
26import System.Directory
32import System.Directory
27import System.Exit
33import System.Exit
28import System.FilePath
34import System.FilePath
29import System.IO
35import System.IO
30import System.Process
36import System.Process
32−data CodeGenerationEnv = CodeGenerationEnv { globalVariablePositions :: [(Name, Integer)] }
38+-----------------------------------------------------------------------
34−type CodeGeneration = StateT (CodeGenerationEnv) (Either String)
36codegenJava :: [(Name, SExp)] -> -- initialization of globals
41codegenJava :: [(Name, SExp)] -> -- initialization of globals
37 [(Name, SDecl)] ->
42 [(Name, SDecl)] ->
@@ -44,12 +49,11 @@ codegenJava globalInit defs out hdrs libs exec = do
44 withTempdir (takeBaseName out) $ \ tmpDir -> do
49 withTempdir (takeBaseName out) $ \ tmpDir -> do
45 let srcdir = tmpDir </> "src" </> "main" </> "java"
50 let srcdir = tmpDir </> "src" </> "main" </> "java"
46 createDirectoryIfMissing True srcdir
51 createDirectoryIfMissing True srcdir
47− let (Ident clsName) =
48− either error id (evalStateT (mkClassName out) (mkCodeGenEnv globalInit))
52+ let (Ident clsName) = either error id (mkClassName out)
49 let outjava = srcdir </> clsName <.> "java"
53 let outjava = srcdir </> clsName <.> "java"
50 let jout = either error
54 let jout = either error
51− (flatIndent . prettyPrint)
55+ (prettyPrint)-- flatIndent . prettyPrint)
52− (evalStateT (mkCompilationUnit globalInit defs hdrs out) (mkCodeGenEnv globalInit))
56+ (evalStateT (mkCompilationUnit globalInit defs hdrs out) mkCodeGenEnv)
53 writeFile outjava jout
57 writeFile outjava jout
54 if (exec == Raw)
58 if (exec == Raw)
55 then copyFile outjava (takeDirectory out </> clsName <.> "java")
59 then copyFile outjava (takeDirectory out </> clsName <.> "java")
@@ -58,8 +62,8 @@ codegenJava globalInit defs out hdrs libs exec = do
58 execPomTemplate <- TIO.readFile execPom
62 execPomTemplate <- TIO.readFile execPom
59 let execPom = T.replace (T.pack "$MAIN-CLASS$")
63 let execPom = T.replace (T.pack "$MAIN-CLASS$")
60 (T.pack clsName)
64 (T.pack clsName)
61− (T.replace (T.pack "$ARTIFACT-NAME$")
65+ (T.replace (T.pack "$ARTIFACT-NAME$")
62− (T.pack $ takeBaseName out)
66+ (T.pack $ takeBaseName out)
63 (T.replace (T.pack "$DEPENDENCIES$")
67 (T.replace (T.pack "$DEPENDENCIES$")
64 (mkPomDependencies libs)
68 (mkPomDependencies libs)
65 execPomTemplate
69 execPomTemplate
@@ -72,11 +76,11 @@ codegenJava globalInit defs out hdrs libs exec = do
72 when (exit /= ExitSuccess) $ error ("FAILURE: " ++ mvnCmd ++ " compile\n" ++ err ++ mvout)
76 when (exit /= ExitSuccess) $ error ("FAILURE: " ++ mvnCmd ++ " compile\n" ++ err ++ mvout)
73 if (exec == Object)
77 if (exec == Object)
75− classFiles <-
79+ classFiles <-
76 map (\ clsFile -> tmpDir </> "target" </> "classes" </> clsFile)
80 map (\ clsFile -> tmpDir </> "target" </> "classes" </> clsFile)
77− . filter ((".class" ==) . takeExtension)
81+ . filter ((".class" ==) . takeExtension)
78 <$> getDirectoryContents (tmpDir </> "target" </> "classes")
82 <$> getDirectoryContents (tmpDir </> "target" </> "classes")
79− mapM_ (\ clsFile -> copyFile clsFile (takeDirectory out </> takeFileName clsFile))
83+ mapM_ (\ clsFile -> copyFile clsFile (takeDirectory out </> takeFileName clsFile))
80 classFiles
84 classFiles
82 (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ ["package"]) ""
86 (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ ["package"]) ""
@@ -94,8 +98,11 @@ codegenJava globalInit defs out hdrs libs exec = do
94 readProcess mvnCmd (args ++ ["clean"]) ""
98 readProcess mvnCmd (args ++ ["clean"]) ""
95 removeFile (tmpDir </> "pom.xml")
99 removeFile (tmpDir </> "pom.xml")
101+-----------------------------------------------------------------------
102+-- Jar and Pom infrastructure
97jarHeader :: String
104jarHeader :: String
98−jarHeader =
105+jarHeader =
99 "#!/bin/sh\n"
106 "#!/bin/sh\n"
100 ++ "MYSELF=`which \"$0\" 2>/dev/null`\n"
107 ++ "MYSELF=`which \"$0\" 2>/dev/null`\n"
101 ++ "[ $? -gt 0 -a -f \"$0\" ] && MYSELF=\"./$0\"\n"
108 ++ "[ $? -gt 0 -a -f \"$0\" ] && MYSELF=\"./$0\"\n"
@@ -110,7 +117,7 @@ mkPomDependencies :: [String] -> T.Text
110mkPomDependencies deps =
117mkPomDependencies deps =
111 T.concat $ map (T.concat . map (T.append (T.pack " ")) . mkDependency . T.pack) deps
118 T.concat $ map (T.concat . map (T.append (T.pack " ")) . mkDependency . T.pack) deps
113− mkDependency s =
120+ mkDependency s =
114 case T.splitOn (T.pack ":") s of
121 case T.splitOn (T.pack ":") s of
115 [g, a, v] ->
122 [g, a, v] ->
116 [ T.pack $ "<dependency>\n"
123 [ T.pack $ "<dependency>\n"
@@ -124,136 +131,236 @@ mkPomDependencies deps =
124 mkArtifactId a = T.append (T.pack $ "<artifactId>") (T.append a $ T.pack "</artifactId>\n")
131 mkArtifactId a = T.append (T.pack $ "<artifactId>") (T.append a $ T.pack "</artifactId>\n")
125 mkVersion v = T.append (T.pack $ "<version>") (T.append v $ T.pack "</version>\n")
132 mkVersion v = T.append (T.pack $ "<version>") (T.append v $ T.pack "</version>\n")
127−mkCodeGenEnv :: [(Name, SExp)] -> CodeGenerationEnv
134+-----------------------------------------------------------------------
135+-- Code generation environment
137+data CodeGenerationEnv
139+ { globalVariables :: [(Name, ArrayIndex)]
140+ , localVariables :: [[(Int, Ident)]]
141+ , localVarCounter :: Int
144+type CodeGeneration = StateT (CodeGenerationEnv) (Either String)
128−mkCodeGenEnv globalInit =
146+mkCodeGenEnv :: CodeGenerationEnv
129− CodeGenerationEnv $ zipWith (\ (name, _) pos -> (name, pos)) globalInit [0..]
147+mkCodeGenEnv = CodeGenerationEnv [] [] 0
149+varPos :: LVar -> CodeGeneration (Either ArrayIndex Ident)
151+ vars <- (concat . localVariables) <$> get
152+ case lookup i vars of
153+ (Just varName) -> return (Right varName)
154+ Nothing -> throwError $ "Invalid local variable id: " ++ show i
155+varPos (Glob name) = do
156+ vars <- globalVariables <$> get
157+ case lookup name vars of
158+ (Just varIdx) -> return (Left varIdx)
159+ Nothing -> throwError $ "Invalid global variable id: " ++ show name
161+pushScope :: CodeGeneration ()
163+ modify (\ env -> env { localVariables = []:(localVariables env) })
165+popScope :: CodeGeneration ()
168+ let lVars = tail $ localVariables env
169+ let vC = if null lVars then 0 else localVarCounter env
170+ put $ env { localVariables = tail (localVariables env)
171+ , localVarCounter = vC }
173+setVariable :: LVar -> CodeGeneration (Either ArrayIndex Ident)
174+setVariable (Loc i) = do
176+ let lVars = localVariables env
177+ let getter = localVar $ localVarCounter env
178+ let lVars' = ((i, getter) : head lVars) : tail lVars
179+ put $ env { localVariables = lVars'
180+ , localVarCounter = 1 + localVarCounter env}
181+ return (Right getter)
182+setVariable (Glob n) = do
184+ let gVars = globalVariables env
185+ let getter = globalContext @! length gVars
186+ let gVars' = (n, getter):gVars
187+ put (env { globalVariables = gVars' })
188+ return (Left getter)
190+pushParams :: [Ident] -> CodeGeneration ()
191+pushParams paramNames =
192+ let varMap = zipWith (flip (,)) paramNames [0..] in
193+ modify (\ env -> env { localVariables = varMap:(localVariables env)
194+ , localVarCounter = (length varMap) + (localVarCounter env) })
196+flatIndent :: String -> String
197+flatIndent (' ' : ' ' : xs) = flatIndent xs
198+flatIndent (x:xs) = x:flatIndent xs
201+-----------------------------------------------------------------------
202+-- Maintaining control structures over code blocks
204+data BlockPostprocessor
205+ = BlockPostprocessor
206+ { ppInnerBlock :: [BlockStmt] -> Exp -> CodeGeneration [BlockStmt]
207+ , ppOuterBlock :: [BlockStmt] -> CodeGeneration [BlockStmt]
210+ppExp :: BlockPostprocessor -> Exp -> CodeGeneration [BlockStmt]
211+ppExp pp exp = ((ppInnerBlock pp) [] exp) >>= ppOuterBlock pp
213+addReturn :: BlockPostprocessor
216+ { ppInnerBlock = (\ block exp -> return $ block ++ [jReturn exp])
217+ , ppOuterBlock = return
220+ignoreResult :: BlockPostprocessor
223+ { ppInnerBlock = (\ block exp -> return block)
224+ , ppOuterBlock = return
227+ignoreOuter :: BlockPostprocessor -> BlockPostprocessor
228+ignoreOuter pp = pp { ppOuterBlock = return }
230+throwRuntimeException :: BlockPostprocessor -> BlockPostprocessor
231+throwRuntimeException pp =
234+ (\ blk exp -> return $
235+ blk ++ [ BlockStmt $ Throw
238+ (toClassType runtimeExceptionType)
247+rethrowAsRuntimeException :: BlockPostprocessor -> BlockPostprocessor
248+rethrowAsRuntimeException pp =
252+ ex <- ppInnerBlock (throwRuntimeException pp) [] (ExpName $ J.Name [Ident "ex"])
256+ [Catch (FormalParam [] exceptionType False (VarId (Ident "ex"))) $
264+-----------------------------------------------------------------------
131mkCompilationUnit :: [(Name, SExp)] -> [(Name, SDecl)] -> [String] -> FilePath -> CodeGeneration CompilationUnit
267mkCompilationUnit :: [(Name, SExp)] -> [(Name, SDecl)] -> [String] -> FilePath -> CodeGeneration CompilationUnit
132−mkCompilationUnit globalInit defs hdrs out =
268+mkCompilationUnit globalInit defs hdrs out = do
269+ clsName <- mkClassName out
133 CompilationUnit Nothing ( [ ImportDecl False idrisRts True
270 CompilationUnit Nothing ( [ ImportDecl False idrisRts True
134 , ImportDecl True idrisForeign True
271 , ImportDecl True idrisForeign True
272+ , ImportDecl False idrisPrimFn False
135 , ImportDecl False bigInteger False
273 , ImportDecl False bigInteger False
136− , ImportDecl False stringBuffer False
137 , ImportDecl False runtimeException False
274 , ImportDecl False runtimeException False
138− , ImportDecl False scanner False
139− , ImportDecl False arrays False
140 ] ++ otherHdrs
275 ] ++ otherHdrs
142− <$> mkTypeDecl globalInit defs out
277+ <$> mkTypeDecl clsName globalInit defs
144 idrisRts = J.Name $ map Ident ["org", "idris", "rts"]
279 idrisRts = J.Name $ map Ident ["org", "idris", "rts"]
145 idrisForeign = J.Name $ map Ident ["org", "idris", "rts", "ForeignPrimitives"]
280 idrisForeign = J.Name $ map Ident ["org", "idris", "rts", "ForeignPrimitives"]
281+ idrisPrimFn = J.Name $ map Ident ["org", "idris", "rts", "PrimFn"]
146 bigInteger = J.Name $ map Ident ["java", "math", "BigInteger"]
282 bigInteger = J.Name $ map Ident ["java", "math", "BigInteger"]
147− stringBuffer = J.Name $ map Ident ["java", "lang", "StringBuffer"]
148 runtimeException = J.Name $ map Ident ["java", "lang", "RuntimeException"]
283 runtimeException = J.Name $ map Ident ["java", "lang", "RuntimeException"]
149− scanner = J.Name $ map Ident ["java", "util", "Scanner"]
150− arrays = J.Name $ map Ident ["java", "util", "Arrays"]
151 otherHdrs = map ( (\ name -> ImportDecl False name False)
284 otherHdrs = map ( (\ name -> ImportDecl False name False)
152− . J.Name
285+ . J.Name
153− . map (Ident . T.unpack)
286+ . map (Ident . T.unpack)
154− . T.splitOn (T.pack ".")
287+ . T.splitOn (T.pack ".")
155− . T.pack)
288+ . T.pack)
156 $ filter (not . isSuffixOf ".h") hdrs
289 $ filter (not . isSuffixOf ".h") hdrs
158−flatIndent :: String -> String
291+-----------------------------------------------------------------------
159−flatIndent (' ' : ' ' : xs) = flatIndent xs
292+-- Main class
160−flatIndent (x:xs) = x:flatIndent xs
293+
163−prefixCallNamespaces :: Ident -> SExp -> SExp
164−prefixCallNamespaces (Ident name) (SApp tail (NS n ns) args) = SApp tail (NS n (name:ns)) args
165−prefixCallNamespaces name (SLet var e1 e2) = SLet var (prefixCallNamespaces name e1) (prefixCallNamespaces name e2)
166−prefixCallNamespaces name (SUpdate var e) = SUpdate var (prefixCallNamespaces name e)
167−prefixCallNamespaces name (SCase var alts) = SCase var (map (prefixCallNamespacesCase name) alts)
168−prefixCallNamespaces name (SChkCase var alts) = SChkCase var (map (prefixCallNamespacesCase name) alts)
169−prefixCallNamespaces _ exp = exp
171−prefixCallNamespacesCase :: Ident -> SAlt -> SAlt
172−prefixCallNamespacesCase name (SConCase x y n ns e) = SConCase x y n ns (prefixCallNamespaces name e)
173−prefixCallNamespacesCase name (SConstCase c e) = SConstCase c (prefixCallNamespaces name e)
174−prefixCallNamespacesCase name (SDefaultCase e) = SDefaultCase (prefixCallNamespaces name e)
176−prefixCallNamespacesDecl :: Ident -> SDecl -> SDecl
177−prefixCallNamespacesDecl name (SFun fname args i e) = SFun fname args i (prefixCallNamespaces name e)
179−mkTypeDecl :: [(Name, SExp)] -> [(Name, SDecl)] -> FilePath -> CodeGeneration [TypeDecl]
294+mkTypeDecl :: Ident -> [(Name, SExp)] -> [(Name, SDecl)] -> CodeGeneration [TypeDecl]
180−mkTypeDecl globalInit defs out =
295+mkTypeDecl name globalInit defs =
181− (\ name body -> [ClassTypeDecl $ ClassDecl [ Public
296+ (\ body -> [ClassTypeDecl $ ClassDecl [ Public
182− , Annotation $ SingleElementAnnotation
297+ , Annotation $ SingleElementAnnotation
183− (J.Name [Ident "SuppressWarnings"])
298+ (jName "SuppressWarnings")
184− (EVVal . InitExp . Lit $ String "unchecked")
299+ (EVVal . InitExp $ jString "unchecked")
188− Nothing
303+ Nothing
192− <*> ( mkClassName out
193− >>= (\ ident -> mkClassBody globalInit (map (second (prefixCallNamespacesDecl ident)) defs))
306+ <$> mkClassBody globalInit (map (second (prefixCallNamespaces name)) defs)
196−mkClassName :: FilePath -> CodeGeneration Ident
198− T.lift $ left (\ err -> "Parser error in \"" ++ path ++ "\": " ++ (show err))
199− (parser ident . takeBaseName $ takeFileName path)
201mkClassBody :: [(Name, SExp)] -> [(Name, SDecl)] -> CodeGeneration ClassBody
308mkClassBody :: [(Name, SExp)] -> [(Name, SDecl)] -> CodeGeneration ClassBody
202−mkClassBody globalInit defs =
309+mkClassBody globalInit defs =
203 (\ globals defs -> ClassBody . (globals++) . addMainMethod . mergeInnerClasses $ defs)
310 (\ globals defs -> ClassBody . (globals++) . addMainMethod . mergeInnerClasses $ defs)
204 <$> mkGlobalContext globalInit
311 <$> mkGlobalContext globalInit
205 <*> mapM mkDecl defs
312 <*> mapM mkDecl defs
207mkGlobalContext :: [(Name, SExp)] -> CodeGeneration [Decl]
314mkGlobalContext :: [(Name, SExp)] -> CodeGeneration [Decl]
208mkGlobalContext [] = return []
315mkGlobalContext [] = return []
209−mkGlobalContext initExps =
316+mkGlobalContext initExps = do
319+ mapM (\ (name, exp) -> do
320+ pos <- setVariable (Glob name)
321+ mkUpdate ignoreResult (Glob name) exp
210− (\ exps -> [ MemberDecl $ FieldDecl [Private, Static, Final]
324+ return [ MemberDecl $ FieldDecl [Private, Static, Final]
211− objectArrayType
325+ (array objectType)
212− [VarDecl (VarId $ Ident "globalContext")
326+ [ VarDecl (VarId $ globalContextID). Just . InitExp
213− (Just . InitArray $ ArrayInit exps)
327+ $ ArrayCreate objectType [jInt $ length initExps] 0
215− ]
329+ , InitDecl True (Block $ concat varInit)
217− <$> mapM (\ (_, exp) -> InitExp <$> mkExp exp) initExps
221addMainMethod :: [Decl] -> [Decl]
332addMainMethod :: [Decl] -> [Decl]
222addMainMethod decls
333addMainMethod decls
223 | findMain decls = mkMainMethod : decls
334 | findMain decls = mkMainMethod : decls
224 | otherwise = decls
335 | otherwise = decls
226− findMain ((MemberDecl (MemberClassDecl (ClassDecl _ (Ident "Main") _ _ _ (ClassBody body)))):_) =
337+ findMain ((MemberDecl (MemberClassDecl (ClassDecl _ name _ _ _ (ClassBody body)))):_)
227− findMainMethod body
338+ | name == mangle' (UN "Main") = findMainMethod body
228 findMain (_:decls) = findMain decls
339 findMain (_:decls) = findMain decls
229 findMain [] = False
340 findMain [] = False
342+ innerMainMethod = (either error id $ mangle (UN "main"))
231− findMainMethod ((MemberDecl (MethodDecl _ _ _ (Ident "main") [] _ _)):_) = True
343+ findMainMethod ((MemberDecl (MethodDecl _ _ _ name [] _ _)):_)
344+ | name == mangle' (UN "main") = True
232 findMainMethod (_:decls) = findMainMethod decls
345 findMainMethod (_:decls) = findMainMethod decls
233 findMainMethod [] = False
346 findMainMethod [] = False
235mkMainMethod :: Decl
348mkMainMethod :: Decl
236−mkMainMethod =
349+mkMainMethod =
237− MemberDecl $ MethodDecl [Public, Static]
351+ [Public, Static]
239− Nothing
352+ Nothing
240− (Ident "main")
353+ "main"
241− [FormalParam [] stringArrayType False (VarId $ Ident "args")]
354+ [FormalParam [] (array stringType) False (VarId $ Ident "args")]
243− (MethodBody . Just $ Block [ BlockStmt . ExpStmt . MethodInv $
355+ $ Block [ BlockStmt . ExpStmt
244− MethodCall (J.Name [Ident "idris_initArgs"])
245− [ MethodInv $ TypeMethodCall
246− (J.Name [Ident "Thread"])
248− (Ident "currentThread")
356+ $ call "idris_initArgs" [ (threadType ~> "currentThread") []
249− []
357+ , jConst "args"
250− , ExpName $ J.Name [Ident "args"]
252− , BlockStmt . ExpStmt . MethodInv $
359+ , BlockStmt . ExpStmt $ call (mangle' (MN 0 "runMain")) []
253− MethodCall (J.Name [Ident "runMain_0"])
362+-----------------------------------------------------------------------
363+-- Inner classes (idris namespaces)
258mergeInnerClasses :: [Decl] -> [Decl]
365mergeInnerClasses :: [Decl] -> [Decl]
259mergeInnerClasses = foldl' mergeInner []
366mergeInnerClasses = foldl' mergeInner []
@@ -274,1308 +381,336 @@ mergeInnerClasses = foldl' mergeInner []
274 mergeInner [] decl' = [decl']
381 mergeInner [] decl' = [decl']
277−mkIdentifier :: Name -> CodeGeneration Ident
278−mkIdentifier (NS name _) = mkIdentifier name
279−mkIdentifier (MN i name) = (\ (Ident x) -> Ident $ x ++ ('_' : show i))
280− <$> mkIdentifier (UN name)
281−mkIdentifier (UN name) =
282− T.lift $ left (\ err -> "Parser error in \"" ++ name ++ "\": " ++ (show err))
287− $ cleanWs False name)
290− | isNumber x = '_' : (x:xs)
291− | otherwise = (x:xs)
293− cleanNonLetter (x:xs)
294− | x == '#' = "_Hash" ++ cleanNonLetter xs
295− | x == '@' = "_At" ++ cleanNonLetter xs
296− | x == '$' = "_Dollar" ++ cleanNonLetter xs
297− | x == '!' = "_Bang" ++ cleanNonLetter xs
298− | x == '.' = "_Dot" ++ cleanNonLetter xs
299− | x == '\'' = "_Prime" ++ cleanNonLetter xs
300− | x == '*' = "_Times" ++ cleanNonLetter xs
301− | x == '+' = "_Plus" ++ cleanNonLetter xs
302− | x == '/' = "_Divide" ++ cleanNonLetter xs
303− | x == '-' = "_Minus" ++ cleanNonLetter xs
304− | x == '%' = "_Mod" ++ cleanNonLetter xs
305− | x == '<' = "_LessThan" ++ cleanNonLetter xs
306− | x == '=' = "_Equals" ++ cleanNonLetter xs
307− | x == '>' = "_MoreThan" ++ cleanNonLetter xs
308− | x == '[' = "_LSBrace" ++ cleanNonLetter xs
309− | x == ']' = "_RSBrace" ++ cleanNonLetter xs
310− | x == '(' = "_LBrace" ++ cleanNonLetter xs
311− | x == ')' = "_RBrace" ++ cleanNonLetter xs
312− | x == '_' = "__" ++ cleanNonLetter xs
313− | not (isAlphaNum x) = "_" ++ (show $ ord x) ++ xs
314− | otherwise = x:cleanNonLetter xs
315− cleanNonLetter [] = []
316− cleanWs capitalize (x:xs)
317− | isSpace x = cleanWs True xs
318− | capitalize = (toUpper x) : (cleanWs False xs)
319− | otherwise = x : (cleanWs False xs)
323− cleanReserved "param" = "_param"
324− cleanReserved "globalContext" = "_globalContext"
325− cleanReserved "context" = "_context"
326− cleanReserved "newcontext" = "_newcontext"
328− cleanReserved "void" = "_void"
329− cleanReserved "null" = "_null"
330− cleanReserved "int" = "_int"
331− cleanReserved "long" = "_long"
332− cleanReserved "char" = "_char"
333− cleanReserved "byte" = "_byte"
334− cleanReserved "double" = "_double"
335− cleanReserved "float" = "_float"
336− cleanReserved "boolean" = "_boolean"
337− cleanReserved "Object" = "_Object"
338− cleanReserved "String" = "_String"
339− cleanReserved "StringBuilder" = "_StringBuilder"
340− cleanReserved "StringBuffer" = "_StringBuffer"
341− cleanReserved "Scanner" = "_Scanner"
342− cleanReserved "Integer" = "_Integer"
343− cleanReserved "Double" = "_Double"
344− cleanReserved "Byte" = "_Byte"
345− cleanReserved "Character" = "_Character"
346− cleanReserved "BigInteger" = "_BigInteger"
347− cleanReserved "Boolean" = "_Boolean"
348− cleanReserved "Closure" = "_Closure"
349− cleanReserved "IdrisObject" = "_IdrisObject"
350− cleanReserved "TailCallClosure" = "_TailCallClosure"
351− cleanReserved "System" = "_System"
352− cleanReserved "Math" = "_Math"
353− cleanReserved "Arrays" = "_Arrays"
354− cleanReserved "RuntimeException" = "_RuntimeException"
355− cleanReserved "Comparable" = "_Comparable"
357− cleanReserved "class" = "_class"
358− cleanReserved "enum" = "_enum"
359− cleanReserved "interface" = "_interface"
360− cleanReserved "extends" = "_extends"
361− cleanReserved "implements" = "_implements"
362− cleanReserved "public" = "_public"
363− cleanReserved "private" = "_private"
364− cleanReserved "protected" = "_protected"
365− cleanReserved "static" = "_static"
366− cleanReserved "final" = "_final"
367− cleanReserved "abstract" = "_abstract"
368− cleanReserved "strict" = "_strict"
369− cleanReserved "volatile" = "_volatile"
370− cleanReserved "transient" = "_transient"
371− cleanReserved "native" = "_native"
372− cleanReserved "const" = "_const"
374− cleanReserved "import" = "_import"
375− cleanReserved "package" = "_package"
377− cleanReserved "throw" = "_throw"
378− cleanReserved "throws" = "_throws"
379− cleanReserved "try" = "_try"
380− cleanReserved "catch" = "_catch"
382− cleanReserved "synchronized" = "_synchronized"
384− cleanReserved "if" = "_if"
385− cleanReserved "else" = "_else"
386− cleanReserved "switch" = "_switch"
387− cleanReserved "case" = "_case"
388− cleanReserved "default" = "_default"
390− cleanReserved "while" = "_while"
391− cleanReserved "for" = "_for"
392− cleanReserved "do" = "_do"
393− cleanReserved "break" = "_break"
394− cleanReserved "continue" = "_continue"
395− cleanReserved "goto" = "_goto"
397− cleanReserved "this" = "_this"
398− cleanReserved "super" = "_super"
399− cleanReserved "new" = "_new"
400− cleanReserved "return" = "_return"
402− cleanReserved "idris_initArgs" = "_idris_initArgs"
403− cleanReserved "idris_numArgs" = "_idris_numArgs"
404− cleanReserved "idris_getArg" = "_idris_getArg"
405− cleanReserved "getenv" = "_getenv"
406− cleanReserved "exit" = "_exit"
407− cleanReserved "usleep" = "_usleep"
408− cleanReserved "idris_sendMessage" = "_idris_sendMessage"
409− cleanReserved "idris_checkMessage" = "_idris_checkMessage"
410− cleanReserved "idris_recvMessage" = "_idris_recvMessage"
411− cleanReserved "putStr" = "_putStr"
412− cleanReserved "putchar" = "_putchar"
413− cleanReserved "getchar" = "_getchar"
414− cleanReserved "fileOpen" = "_fileOpen"
415− cleanReserved "fileClose" = "_fileClose"
416− cleanReserved "fputStr" = "_fputStr"
417− cleanReserved "fileEOF" = "_fileEOF"
418− cleanReserved "isNull" = "_isNull"
419− cleanReserved "idris_K" = "_idris_K"
420− cleanReserved "idris_flipK" = "_idris_flipK"
421− cleanReserved "idris_assignStack" = "_idris_assignStack"
422− cleanReserved "free" = "_free"
423− cleanReserved "malloc" = "_malloc"
424− cleanReserved "idris_memset" = "_idris_memset"
425− cleanReserved "idris_peek" = "_idris_peek"
426− cleanReserved "idris_poke" = "_idris_poke"
427− cleanReserved "idris_memmove" = "_idris_memmove"
431−mkName :: Name -> CodeGeneration J.Name
432−mkName (NS name nss) = (\ n ns -> J.Name (n:ns))
433− <$> mkIdentifier name
434− <*> mapM (mkIdentifier . UN) nss
435−mkName n = J.Name . (:[]) <$> mkIdentifier n
437−voidType :: ClassType
438−voidType = ClassType [(Ident "Void", [])]
440−objectType :: ClassType
441−objectType = ClassType [(Ident "Object", [])]
443−objectArrayType :: Language.Java.Syntax.Type
444−objectArrayType = RefType . ArrayType . RefType . ClassRefType $ objectType
446−idrisClosureType :: ClassType
447−idrisClosureType = ClassType [(Ident "Closure", [])]
449−idrisTailCallClosureType :: ClassType
450−idrisTailCallClosureType = ClassType [(Ident "TailCallClosure", [])]
452−idrisObjectType :: ClassType
453−idrisObjectType = ClassType [(Ident "IdrisObject", [])]
455−contextArray :: LVar -> Exp
456−contextArray (Loc _) = ExpName $ J.Name [Ident "context"]
457−contextArray (Glob _) = ExpName $ J.Name [Ident "globalContext"]
459−charType :: ClassType
460−charType = ClassType [(Ident "Character", [])]
462−byteType :: ClassType
463−byteType = ClassType [(Ident "Byte", [])]
465−shortType :: ClassType
466−shortType = ClassType [(Ident "Short", [])]
468−integerType :: ClassType
469−integerType = ClassType [(Ident "Integer", [])]
471−longType :: ClassType
472−longType = ClassType [(Ident "Long", [])]
474−nextIntTy :: IntTy -> IntTy
475−nextIntTy (ITFixed IT8) = (ITFixed IT16)
476−nextIntTy (ITFixed IT16) = (ITFixed IT32)
477−nextIntTy (ITFixed IT32) = (ITFixed IT64)
478−nextIntTy (ITFixed IT64) = (ITFixed IT64)
479−nextIntTy ITNative = (ITFixed IT64)
480−nextIntTy ITChar = (ITFixed IT64)
482−intTyToIdent :: IntTy -> Ident
483−intTyToIdent (ITFixed IT8) = Ident "Byte"
484−intTyToIdent (ITFixed IT16) = Ident "Short"
485−intTyToIdent (ITFixed IT32) = Ident "Integer"
486−intTyToIdent (ITFixed IT64) = Ident "Long"
487−intTyToIdent ITNative = Ident "Integer"
488−intTyToIdent ITBig = Ident "BigInteger"
489−intTyToIdent ITChar = Ident "Integer"
491−intTyToClass :: IntTy -> ClassType
492−intTyToClass ty = ClassType [(intTyToIdent ty, [])]
494−intTyToMethod :: IntTy -> String
495−intTyToMethod (ITFixed IT8) = "byteValue"
496−intTyToMethod (ITFixed IT16) = "shortValue"
497−intTyToMethod (ITFixed IT32) = "intValue"
498−intTyToMethod (ITFixed IT64) = "longValue"
499−intTyToMethod ITNative = "intValue"
500−intTyToMethod ITChar = "intValue"
502−intTyToPrimTy :: IntTy -> PrimType
503−intTyToPrimTy (ITFixed IT8) = ByteT
504−intTyToPrimTy (ITFixed IT16) = ShortT
505−intTyToPrimTy (ITFixed IT32) = IntT
506−intTyToPrimTy (ITFixed IT64) = LongT
507−intTyToPrimTy ITNative = IntT
508−intTyToPrimTy ITChar = IntT
510−bigIntegerType :: ClassType
511−bigIntegerType = ClassType [(Ident "BigInteger", [])]
513−doubleType :: ClassType
514−doubleType = ClassType [(Ident "Double", [])]
516−stringType :: ClassType
517−stringType = ClassType [(Ident "String", [])]
519−stringArrayType :: Language.Java.Syntax.Type
520−stringArrayType = RefType . ArrayType . RefType . ClassRefType $ stringType
522−exceptionType :: ClassType
523−exceptionType = ClassType [(Ident "Throwable", [])]
525−runtimeExceptionType :: ClassType
526−runtimeExceptionType = ClassType [(Ident "RuntimeException", [])]
528−comparableType :: ClassType
529−comparableType = ClassType [(Ident "Comparable", [])]
531mkDecl :: (Name, SDecl) -> CodeGeneration Decl
385mkDecl :: (Name, SDecl) -> CodeGeneration Decl
532mkDecl ((NS n (ns:nss)), decl) =
386mkDecl ((NS n (ns:nss)), decl) =
533− (\ name body -> MemberDecl $ MemberClassDecl $ ClassDecl [Public, Static] name [] Nothing [] body)
388+ MemberDecl $ MemberClassDecl $ ClassDecl [Public, Static] name [] Nothing [] body)
534− <$> mkIdentifier (UN ns)
389+ <$> mangle (UN ns)
535 <*> mkClassBody [] [(NS n nss, decl)]
390 <*> mkClassBody [] [(NS n nss, decl)]
536−mkDecl (_, SFun name params stackSize body) =
391+mkDecl (_, SFun name params stackSize body) = do
537− (\ name params paramNames methodBody ->
392+ (Ident methodName) <- mangle name
538− MemberDecl $ MethodDecl [Public, Static]
393+ methodParams <- mapM mkFormalParam params
539− []
394+ paramNames <- mapM mangle params
540− (Just . RefType $ ClassRefType objectType)
395+ pushParams paramNames
541− name
396+ methodBody <- mkExp addReturn body
544− (MethodBody . Just $ Block
399+ simpleMethod [Public, Static] (Just objectType) methodName methodParams
547− [ VarDecl (VarDeclArray . VarId $ Ident "context")
548− (Just . InitArray . ArrayInit $
550− ++ replicate stackSize (InitExp . Lit $ Null))
552− , BlockStmt . Return $ Just methodBody
400+ (Block methodBody)
556− <$> mkIdentifier name
557− <*> mapM mkFormalParam params
558− <*> mapM (\ p -> (InitExp . ExpName) <$> mkName p) params
562−mkClosure :: [Name] -> Int -> SExp -> CodeGeneration Exp
563−mkClosure params stackSize body =
564− (\ paramArray body ->
568− (Just $ ClassBody [body])
570− <$> mkStackInit params stackSize
571− <*> mkClosureCall body
573mkFormalParam :: Name -> CodeGeneration FormalParam
402mkFormalParam :: Name -> CodeGeneration FormalParam
574mkFormalParam name =
403mkFormalParam name =
575− (\ name -> FormalParam [Final] (RefType . ClassRefType $ objectType) False (VarId name))
404+ (\ name -> FormalParam [Final] objectType False (VarId name))
576− <$> mkIdentifier name
405+ <$> mangle name
578−mkClosureCall :: SExp -> CodeGeneration Decl
407+-----------------------------------------------------------------------
579−mkClosureCall body =
408+-- Expressions
580− (\ body -> MemberDecl $ MethodDecl [Public] [] (Just . RefType $ ClassRefType objectType) (Ident "call") [] [] body)
409+
581− <$> mkMethodBody body
410+-- | Compile a simple expression and use the given continuation to postprocess
582−
411+-- the resulting value.
583−mkMethodBody :: SExp -> CodeGeneration MethodBody
412+mkExp :: BlockPostprocessor -> SExp -> CodeGeneration [BlockStmt]
584−mkMethodBody exp =
413+-- Variables
585− (\ exp -> MethodBody . Just . Block $ [BlockStmt . Return . Just $ exp])
414+mkExp pp (SV var) =
586− <$> mkExp exp
415+ (Nothing <>@! var) >>= ppExp pp
588−mkStackInit :: [Name] -> Int -> CodeGeneration Exp
417+-- Applications
589−mkStackInit params stackSize =
418+mkExp pp (SApp pushTail name args) =
590− (\ localVars -> ArrayCreateInit objectArrayType 0 . ArrayInit $
419+ mkApp pushTail name args >>= ppExp pp
591− (map (InitExp . ExpName) localVars)
420+
592− ++ (replicate (stackSize) (InitExp $ Lit Null)))
421+-- Bindings
593− <$> mapM mkName params
422+mkExp pp (SLet var newExp inExp) =
594−
423+ mkLet pp var newExp inExp
595−mkK :: Exp -> Exp -> Exp
424+mkExp pp (SUpdate var newExp) =
596−mkK result drop =
425+ mkUpdate pp var newExp
597− MethodInv $ MethodCall (J.Name [Ident "idris_K"]) [ result, drop ]
426+
599−mkFlipK :: Exp -> Exp -> Exp
428+mkExp pp (SCon conId _ args) =
600−mkFlipK drop result =
429+ mkIdrisObject conId args >>= ppExp pp
601− MethodInv $ MethodCall (J.Name [Ident "idris_flipK"]) [ drop, result ]
430+
602−
431+-- Case expressions
603−mkLet :: LVar -> SExp -> SExp -> CodeGeneration Exp
432+mkExp pp (SCase var alts) = mkCase pp True var alts
604−mkLet (Loc pos) oldExp newExp =
433+mkExp pp (SChkCase var alts) = mkCase pp False var alts
605− (\ oldExp newExp ->
434+
606− mkFlipK ( Assign ( ArrayLhs $ ArrayIndex (ExpName $ J.Name [Ident "context"])
435+-- Projections
607− (Lit $ Int (toInteger pos)))
436+mkExp pp (SProj var i) =
608− EqualA
437+ mkProjection var i >>= ppExp pp
611− oldExp
440+mkExp pp (SConst c) =
612− )
441+ ppExp pp $ mkConstant c
613− <$> mkExp oldExp
442+
614− <*> mkExp newExp
443+-- Foreign function calls
615−mkLet (Glob _) _ _ = T.lift $ Left "Cannot let bind to global variable"
444+mkExp pp (SForeign lang resTy text params) =
616−
445+ mkForeign pp lang resTy text params
617−reverseNameSpace :: J.Name -> J.Name
446+
618−reverseNameSpace (J.Name ids) =
447+-- Primitive functions
619− J.Name ((tail ids) ++ [head ids])
448+mkExp pp (SOp LFork [arg]) =
620−
449+ (mkThread arg) >>= ppExp pp
621−mkCase :: Bool -> LVar -> [SAlt] -> CodeGeneration Exp
450+mkExp pp (SOp LPar [arg]) =
622−mkCase checked var ((SConCase parentStackPos consIndex _ params branchExpression):cases) =
451+ (Nothing <>@! arg) >>= ppExp pp
623− mkConsCase checked
452+mkExp pp (SOp LNoOp args) =
624− var
453+ (Nothing <>@! (last args)) >>= ppExp pp
625− parentStackPos
454+mkExp pp (SOp op args) =
626− consIndex
455+ (mkPrimitiveFunction op args) >>= ppExp pp
628− branchExpression
457+-- Empty expressions
629− (SCase var cases)
458+mkExp pp (SNothing) = ppExp pp $ Lit Null
630−mkCase checked var (c@(SConstCase constant branchExpression):cases) =
459+
631− (\ constant branchExpression alternative var->
460+-- Errors
632− Cond ( MethodInv $ PrimaryMethodCall (constant)
461+mkExp pp (SError err) = ppExp (throwRuntimeException pp) (jString err)
634− (Ident "equals")
463+-----------------------------------------------------------------------
635− [var]
464+-- Variable access
640− <$> mkExp (SConst constant)
641− <*> mkExp branchExpression
642− <*> mkCase checked var cases
643− <*> mkVarAccess Nothing var
644−mkCase checked var (SDefaultCase exp:cases) = mkExp exp
645−mkCase checked _ [] = mkExp (SError "Non-exhaustive pattern")
647−mkConsCase :: Bool -> LVar -> Int -> Int -> [Name] -> SExp -> SExp -> CodeGeneration Exp
466+(<>@!) :: Maybe J.Type -> LVar -> CodeGeneration Exp
648−mkConsCase checked
467+(<>@!) Nothing var =
649− toDeconstruct
468+ either ArrayAccess (\ n -> ExpName $ J.Name [n]) <$> varPos var
650− parentStackStart
469+(<>@!) (Just castTo) var =
651− consIndex
470+ (castTo <>) <$> (Nothing <>@! var)
653− branchExpression
472+-----------------------------------------------------------------------
654− alternative =
473+-- Application (wrap method calls in tail call closures)
655− (\ caseBinding alternative var varCasted->
474+
656− Cond (BinOp (InstanceOf (var)
657− (ClassRefType idrisObjectType)
661− ( MethodInv $ PrimaryMethodCall (varCasted)
663− (Ident "getConstructorId")
667− (Lit $ Int (toInteger consIndex))
673− <$> mkCaseBinding checked toDeconstruct parentStackStart params branchExpression
674− <*> mkExp alternative
675− <*> mkVarAccess (Nothing) toDeconstruct
676− <*> mkVarAccess (Just idrisObjectType) toDeconstruct
679−mkCaseBinding :: Bool -> LVar -> Int -> [Name] -> SExp -> CodeGeneration Exp
475+mkApp :: Bool -> Name -> [LVar] -> CodeGeneration Exp
680−mkCaseBinding True var parentStackStart params branchExpression =
476+mkApp False name args =
681− (\ branchExpression deconstruction ->
477+ (\ methodName params ->
682− mkFlipK (MethodInv $ MethodCall (J.Name [Ident "idris_assignStack"])
478+ (idrisClosureType ~> "unwrapTailCall") [call methodName params]
683− ( (ExpName $ J.Name [Ident "context"])
684− : (Lit $ Int (toInteger parentStackStart))
689− <$> mkExp branchExpression
480+ <$> mangleFull name
690− <*> mkCaseBindingDeconstruction var params
481+ <*> mapM (Nothing <>@!) args
691−mkCaseBinding False var parentStackStart params branchExpression =
482+mkApp True name args = mkMethodCallClosure name args
692− (\ bindingMethod deconstruction ->
483+
693− MethodInv $ PrimaryMethodCall
484+mkMethodCallClosure :: Name -> [LVar] -> CodeGeneration Exp
694− ( MethodInv $ PrimaryMethodCall (InstanceCreation []
485+mkMethodCallClosure name args =
695− (ClassType [(Ident "Object", [])])
486+ (\ name args -> closure (call name args))
696− []
487+ <$> mangleFull name
697− (Just $ ClassBody [MemberDecl $ bindingMethod])
488+ <*> mapM (Nothing <>@!) args
490+-----------------------------------------------------------------------
491+-- Updates (change context array) and Let bindings (Update, execute)
493+mkUpdate :: BlockPostprocessor -> LVar -> SExp -> CodeGeneration [BlockStmt]
494+mkUpdate pp var exp =
499+ pos <- setVariable var
500+ vExp <- Nothing <>@! var
501+ ppInnerBlock pp (blk ++ [pos @:= rhs]) vExp
700− (Ident "apply")
504+ ) exp
701− ( contextArray (Loc undefined) : deconstruction )
505+
702− )
506+mkLet :: BlockPostprocessor -> LVar -> SExp -> SExp -> CodeGeneration [BlockStmt]
703− []
507+mkLet pp var@(Loc pos) newExp inExp =
704− (Ident "call")
508+ mkUpdate (pp { ppInnerBlock =
705− []
509+ (\ blk _ -> do
510+ inBlk <- mkExp pp inExp
511+ return (blk ++ inBlk)
515+mkLet _ (Glob _) _ _ = T.lift $ Left "Cannot let bind to global variable"
517+-----------------------------------------------------------------------
520+mkIdrisObject :: Int -> [LVar] -> CodeGeneration Exp
521+mkIdrisObject conId args =
523+ InstanceCreation [] (toClassType idrisObjectType) ((jInt conId):args) Nothing
707− <$> mkCaseBindingMethod parentStackStart params branchExpression
525+ <$> mapM (Nothing <>@!) args
708− <*> mkCaseBindingDeconstruction var params
526+
709−
527+-----------------------------------------------------------------------
710−mkCaseBindingDeconstruction :: LVar -> [Name] -> CodeGeneration [Exp]
528+-- Case expressions
711−mkCaseBindingDeconstruction var members =
529+
712− mapM (mkProjection var) ([0..(length members - 1)])
530+mkCase :: BlockPostprocessor -> Bool -> LVar -> [SAlt] -> CodeGeneration [BlockStmt]
713−
531+mkCase pp checked var cases
714−mkCaseBindingMethod :: Int -> [Name] -> SExp -> CodeGeneration MemberDecl
532+ | isDefaultOnlyCase cases = mkDefaultMatch pp cases
715−mkCaseBindingMethod parentStackStart params branchExpression =
533+ | isConstCase cases = do
716− (\ formalParams caseBindingStack branchExpression ->
534+ ifte <- mkConstMatch (ignoreOuter pp) (\ pp -> mkDefaultMatch pp cases) var cases
717− MethodDecl [Final, Public]
535+ ppOuterBlock pp [BlockStmt ifte]
718− []
536+ | otherwise = do
719− (Just . RefType $ ClassRefType idrisClosureType)
537+ switchExp <- mkGetConstructorId checked var
720− (Ident "apply")
538+ matchBlocks <- mkConsMatch (ignoreOuter pp) (\ pp -> mkDefaultMatch pp cases) var cases
721− (mkContextParam:formalParams)
539+ ppOuterBlock pp [BlockStmt $ Switch switchExp matchBlocks]
723− (MethodBody . Just . Block $
541+isConstCase :: [SAlt] -> Bool
724− caseBindingStack ++
542+isConstCase ((SConstCase _ _):_) = True
725− [BlockStmt . Return $ Just branchExpression]))
543+isConstCase ((SDefaultCase _):cases) = isConstCase cases
726− <$> mapM mkFormalParam params
544+isConstCase _ = False
727− <*> mkBindingStack False parentStackStart params
545+
728− <*> mkBindingClosure branchExpression
546+isDefaultOnlyCase :: [SAlt] -> Bool
729−
547+isDefaultOnlyCase [SDefaultCase _] = True
730−mkContextParam :: FormalParam
548+isDefaultOnlyCase [] = True
731−mkContextParam =
549+isDefaultOnlyCase _ = False
732− FormalParam [Final] (objectArrayType) False (VarId (Ident "context"))
550+
733−
551+mkDefaultMatch :: BlockPostprocessor -> [SAlt] -> CodeGeneration [BlockStmt]
552+mkDefaultMatch pp (x@(SDefaultCase branchExpression):_) =
554+ stmt <- mkExp pp branchExpression
557+mkDefaultMatch pp (x:xs) = mkDefaultMatch pp xs
558+mkDefaultMatch pp [] =
559+ ppExp (throwRuntimeException pp) (jString "Non-exhaustive pattern")
561+mkMatchConstExp :: LVar -> Const -> CodeGeneration Exp
562+mkMatchConstExp var c
564+ (\ var -> (primFnType ~> opName (LEq undefined)) [var, jc] ~==~ jInt 1)
565+ <$> (Just cty <>@! var)
567+ (\ var -> (arraysType ~> "equals") [var, jc])
568+ <$> (Just cty <>@! var)
570+ (\ var -> ((primFnType ~> opName (LStrEq)) [var, jc] ~==~ jInt 1))
571+ <$> (Just cty <>@! var)
573+ (\ var -> (var ~> "equals") [jc])
574+ <$> (Just cty <>@! var)
579+mkConstMatch :: BlockPostprocessor ->
580+ (BlockPostprocessor -> CodeGeneration [BlockStmt]) ->
584+mkConstMatch pp getDefaultStmts var ((SConstCase constant branchExpression):cases) = do
585+ matchExp <- mkMatchConstExp var constant
587+ branchBlock <- mkExp pp branchExpression
589+ otherBranches <- mkConstMatch pp getDefaultStmts var cases
591+ $ IfThenElse matchExp (StmtBlock $ Block branchBlock) otherBranches
592+mkConstMatch pp getDefaultStmts var (c:cases) = mkConstMatch pp getDefaultStmts var cases
593+mkConstMatch pp getDefaultStmts _ [] = do
594+ defaultBlock <- getDefaultStmts pp
595+ return $ StmtBlock (Block defaultBlock)
734−mkBindingClosure :: SExp -> CodeGeneration Exp
597+mkGetConstructorId :: Bool -> LVar -> CodeGeneration Exp
735−mkBindingClosure oldExp =
598+mkGetConstructorId True var =
736− (\ oldCall ->
599+ (\ var -> ((idrisObjectType <> var) ~> "getConstructorId") [])
737− InstanceCreation []
600+ <$> (Nothing <>@! var)
738− idrisClosureType
601+mkGetConstructorId False var =
739− [ ExpName $ J.Name [Ident "new_context"] ]
602+ (\ var match ->
740− (Just $ ClassBody [oldCall])
603+ Cond (InstanceOf var (toRefType idrisObjectType)) match (jInt (-1))
742− <$> mkClosureCall oldExp
605+ <$> (Nothing <>@! var)
743−
606+ <*> mkGetConstructorId True var
745−mkBindingStack :: Bool -> Int -> [Name] -> CodeGeneration [BlockStmt]
608+mkConsMatch :: BlockPostprocessor ->
746−mkBindingStack checked parentStackStart params =
609+ (BlockPostprocessor -> CodeGeneration [BlockStmt]) ->
747− (\ paramNames ->
610+ LVar ->
748− ( LocalVars [Final]
611+ [SAlt] ->
749− objectArrayType
612+ CodeGeneration [SwitchBlock]
750− [ VarDecl (VarDeclArray . VarId $ Ident "new_context")
613+mkConsMatch pp getDefaultStmts var ((SConCase parentStackPos consIndex _ params branchExpression):cases) = do
751− (Just . InitExp $ mkContextCopy checked parentStackStart params)
614+ pushScope
752− ])
615+ caseBranch <- mkCaseBinding pp var parentStackPos params branchExpression
753− : ( map (\ (param, pos) ->
616+ popScope
754− BlockStmt . ExpStmt $
617+ otherBranches <- mkConsMatch pp getDefaultStmts var cases
755− Assign (ArrayLhs $ ArrayIndex (ExpName $ J.Name [Ident "new_context"])
618+ return $
756− (Lit $ Int (toInteger pos)))
619+ (SwitchBlock (SwitchCase $ jInt consIndex) caseBranch):otherBranches
757− EqualA
620+mkConsMatch pp getDefaultStmts var (c:cases) = mkConsMatch pp getDefaultStmts var cases
758− (ExpName param)) $ zip paramNames [parentStackStart..]
621+mkConsMatch pp getDefaultStmts _ [] = do
759− )
622+ defaultBlock <- getDefaultStmts pp
761− <$> mapM mkName params
624+ [SwitchBlock Default defaultBlock]
763−mkContextCopy :: Bool -> Int -> [Name] -> Exp
626+mkCaseBinding :: BlockPostprocessor -> LVar -> Int -> [Name] -> SExp -> CodeGeneration [BlockStmt]
764−mkContextCopy True parentStackStart params =
627+mkCaseBinding pp var stackStart params branchExpression =
765− MethodInv $ PrimaryMethodCall (ExpName $ J.Name [Ident "context"])
628+ mkExp pp (toLetIn var stackStart params branchExpression)
767− (Ident "clone")
630+ toLetIn :: LVar -> Int -> [Name] -> SExp -> SExp
768− []
631+ toLetIn var stackStart members start =
769−mkContextCopy False parentStackStart params =
632+ foldr
770− MethodInv $ TypeMethodCall (J.Name [Ident "Arrays"])
633+ (\ pos inExp -> SLet (Loc (stackStart + pos)) (SProj var pos) inExp)
772− (Ident "copyOf")
635+ [0.. (length members - 1)]
773− [ ExpName $ J.Name [Ident "context"]
636+
774− , MethodInv
637+-----------------------------------------------------------------------
775− $ TypeMethodCall (J.Name [Ident "Math"])
638+-- Projection (retrieve the n-th field of an object)
778− [ FieldAccess $ PrimaryFieldAccess (ExpName $ J.Name [Ident "context"])
780− , Lit . Int $ toInteger (parentStackStart + length params)
784mkProjection :: LVar -> Int -> CodeGeneration Exp
640mkProjection :: LVar -> Int -> CodeGeneration Exp
785mkProjection var memberNr =
641mkProjection var memberNr =
786− (\ var -> ArrayAccess $ ArrayIndex ( MethodInv $ PrimaryMethodCall
642+ (\ var -> ArrayAccess $ ((var ~> "getData") []) @! memberNr)
787− (var)
643+ <$> (Just idrisObjectType <>@! var)
789− (Ident "getData")
645+-----------------------------------------------------------------------
792− (Lit $ Int (toInteger memberNr))
648+mkConstantArray :: (V.Unbox a) => J.Type -> (a -> Const) -> V.Vector a -> Exp
793− )
649+mkConstantArray cty elemToConst elems =
794− <$> mkVarAccess (Just idrisObjectType) var
650+ ArrayCreateInit
796−type ClassName = String
652+ 0
797−
653+ (ArrayInit . map (InitExp . mkConstant . elemToConst) $ V.toList elems)
798−mkPrimitive :: ClassName -> Literal -> Exp
654+
799−mkPrimitive className value =
655+mkConstant :: Const -> Exp
800− MethodInv $ TypeMethodCall (J.Name [Ident className])
656+mkConstant c@(I x) = constType c <> (Lit . Word $ toInteger x)
801− []
657+mkConstant c@(BI x) = bigInteger (show x)
802− (Ident "valueOf")
658+mkConstant c@(Fl x) = constType c <> (Lit . Double $ x)
803− [Lit $ value]
659+mkConstant c@(Ch x) = constType c <> (Lit . Char $ x)
804−
660+mkConstant c@(Str x) = constType c <> (Lit . String $ x)
805−mkClass :: ClassType -> Exp
661+mkConstant c@(B8 x) = constType c <> (Lit . Word $ toInteger x)
806−mkClass classType =
662+mkConstant c@(B16 x) = constType c <> (Lit . Word $ toInteger x)
807− ClassLit . Just . RefType .ClassRefType $ classType
663+mkConstant c@(B32 x) = constType c <> (Lit . Word $ toInteger x)
808−
664+mkConstant c@(B64 x) = (bigInteger (show c) ~> "longValue") []
809−mkBinOpExp :: ClassType -> Op -> [LVar] -> CodeGeneration Exp
665+mkConstant c@(B8V x) = mkConstantArray (constType c) B8 x
810−mkBinOpExp castTo op (var:vars) = do
666+mkConstant c@(B16V x) = mkConstantArray (constType c) B16 x
811− start <- mkVarAccess (Just castTo) var
667+mkConstant c@(B32V x) = mkConstantArray (constType c) B32 x
812− foldM (\ exp var -> BinOp exp op <$> mkVarAccess (Just castTo) var) start vars
668+mkConstant c@(B64V x) = mkConstantArray (constType c) B64 x
813−
669+mkConstant c@(AType x) = ClassLit (Just $ box (constType c))
814−mkBinOpExpTrans :: (Exp -> Exp) -> (Exp -> Exp) -> ClassType -> Op -> [LVar] -> CodeGeneration Exp
670+mkConstant c@(StrType ) = ClassLit (Just $ stringType)
815−mkBinOpExpTrans opTransformation resultTransformation castTo op (var:vars) = do
671+mkConstant c@(PtrType ) = ClassLit (Just $ objectType)
816− start <- (mkVarAccess (Just castTo) var)
672+mkConstant c@(VoidType ) = ClassLit (Just $ voidType)
817− foldM (\ exp var -> resultTransformation
673+mkConstant c@(Forgot ) = ClassLit (Just $ objectType)
818− . BinOp (opTransformation exp) op
674+
819− . opTransformation
675+-----------------------------------------------------------------------
820− <$> mkVarAccess (Just castTo) var)
676+-- Foreign function calls
822− vars
678+mkForeign :: BlockPostprocessor -> FLang -> FType -> String -> [(FType, LVar)] -> CodeGeneration [BlockStmt]
823−
679+mkForeign pp (LANG_C) resTy text params = mkForeign pp (LANG_JAVA FStatic) resTy text params
824−mkBinOpExpConv :: String -> PrimType -> ClassType -> Op -> [LVar] -> CodeGeneration Exp
680+mkForeign pp (LANG_JAVA callType) resTy text params
825−mkBinOpExpConv fromMethodName toType fromType@(ClassType [(cls@(Ident _), [])]) op args =
681+ | callType <- FStatic = do
826− mkBinOpExpTrans (\ exp -> MethodInv $ TypeMethodCall (J.Name [cls])
682+ method <- liftParsed (parser name text)
827− []
683+ args <- foreignVarAccess params
828− (Ident fromMethodName)
684+ wrapReturn resTy (call method args)
829− [exp]
685+ | callType <- FObject = do
830− )
686+ method <- liftParsed (parser ident text)
831− (\ exp -> MethodInv $ TypeMethodCall (J.Name [cls])
687+ (tgt:args) <- foreignVarAccess params
832− []
688+ wrapReturn resTy ((tgt ~> (show $ pretty method)) args)
833− (Ident "valueOf")
689+ | callType <- FConstructor = do
834− [Cast (PrimType $ toType) exp]
690+ clsTy <- liftParsed (parser classType text)
835− )
691+ args <- foreignVarAccess params
836− fromType
692+ wrapReturn resTy (InstanceCreation [] clsTy args Nothing)
838− args
694+ foreignVarAccess args =
839−
695+ mapM (\ (fty, var) -> (foreignType fty <>@! var)) args
840−mkLogicalBinOpExp :: ClassType -> Op -> [LVar] -> CodeGeneration Exp
841−mkLogicalBinOpExp castTo op (var:vars) = do
842− start <- mkVarAccess (Just castTo) var
843− foldM (\ exp var -> mkBoolToNumber castTo . BinOp exp op <$> mkVarAccess (Just castTo) var)
847−mkMethodOpChain1 :: (Exp -> Exp) -> ClassType -> String -> [LVar] -> CodeGeneration Exp
848−mkMethodOpChain1 = mkMethodOpChain id
850−mkMethodOpChain :: (Exp -> Exp) -> (Exp -> Exp) -> ClassType -> String -> [LVar] -> CodeGeneration Exp
851−mkMethodOpChain initialTransformation resultTransformation castTo method (arg:args) = do
852− start <- initialTransformation <$> mkVarAccess (Just $ castTo) arg
853− foldM (\ exp arg' ->
854− resultTransformation
856− . PrimaryMethodCall exp [] (Ident method)
858− <$> mkVarAccess (Just $ castTo) arg'
863−mkBoolToNumber :: ClassType -> Exp -> Exp
864−mkBoolToNumber (ClassType [(Ident name, [])]) boolExp =
865− Cond boolExp (mkPrimitive name (Int 1)) (mkPrimitive name (Int 0))
867−mkZeroExt :: String -> Int -> ClassType -> ClassType -> LVar -> CodeGeneration Exp
868−mkZeroExt toMethod bits fromType toType@(ClassType [(toTypeName, [])]) var = do
870− MethodInv $ TypeMethodCall (J.Name [toTypeName])
873− [ Cond ( BinOp (var)
877− ( BinOp (Lit $ Int (2^bits))
884− <$> mkVarAccess (Just $ fromType) var
885− <*> mkSignedExt' toMethod fromType var
887−mkSignedExt :: String -> ClassType -> ClassType -> LVar -> CodeGeneration Exp
888−mkSignedExt toMethod fromType (ClassType [(toTypeName, [])]) var =
889− (\ sext -> MethodInv $ TypeMethodCall (J.Name [toTypeName])
894− <$> mkSignedExt' toMethod fromType var
896−mkSignedExt' :: String -> ClassType -> LVar -> CodeGeneration Exp
897−mkSignedExt' toMethod fromType var =
898− (\ var -> MethodInv $ PrimaryMethodCall (var)
903− <$> mkVarAccess (Just $ fromType) var
912−mkPartialOrder :: SPartialOrder -> Exp -> Exp
913−mkPartialOrder SLt x = (BinOp (Lit $ Int (-1)) Equal x)
914−mkPartialOrder SLe x =
915− BinOp (BinOp (Lit $ Int (-1)) Equal x)
917− (BinOp (Lit $ Int 0) Equal x)
918−mkPartialOrder SEq x = BinOp (Lit $ Int 0) Equal x
919−mkPartialOrder SGe x =
920− BinOp (BinOp (Lit $ Int 1) Equal x)
922− (BinOp (Lit $ Int 0) Equal x)
923−mkPartialOrder SGt x = (BinOp (Lit $ Int 1) Equal x)
925−varPos :: LVar -> CodeGeneration Integer
926−varPos (Loc i) = return (toInteger i)
927−varPos (Glob name) = do
928− positions <- globalVariablePositions <$> get
929− case lookup name positions of
930− (Just pos) -> return pos
931− Nothing -> T.lift . Left $ "Invalid global variable id: " ++ show name
933−mkVarAccess :: Maybe ClassType -> LVar -> CodeGeneration Exp
934−mkVarAccess Nothing var =
935− (\ pos -> ArrayAccess $ ArrayIndex (contextArray var) (Lit $ Int pos))
937−mkVarAccess (Just castTo) var =
938− Cast (RefType . ClassRefType $ castTo) <$> (mkVarAccess Nothing var)
940−mkPrimitiveCast :: ClassType -> ClassType -> LVar -> CodeGeneration Exp
941−mkPrimitiveCast fromType (ClassType [(toType, [])]) var =
943− MethodInv $ TypeMethodCall (J.Name [toType])
948− <$> mkVarAccess (Just fromType) var
950−mkToString :: ClassType -> LVar -> CodeGeneration Exp
951−mkToString castTo var =
952− (\ var -> MethodInv $ PrimaryMethodCall (var)
957− <$> mkVarAccess (Just castTo) var
958−data Std = In | Out | Err
960−instance Show Std where
965−mkSystemStd :: Std -> Exp
966−mkSystemStd std = FieldAccess $ PrimaryFieldAccess (ExpName $ J.Name [Ident "System"]) (Ident $ show std)
968−mkSystemOutPrint :: Exp -> Exp
969−mkSystemOutPrint value =
970− MethodInv $ PrimaryMethodCall (mkSystemStd Out)
975−mkMathFun :: String -> LVar -> CodeGeneration Exp
976−mkMathFun funName var =
977− (\ var -> MethodInv $ TypeMethodCall (J.Name [Ident "Double"])
980− [ MethodInv $ TypeMethodCall (J.Name [Ident "Math"])
986− <$> mkVarAccess (Just doubleType) var
988−mkStringAtIndex :: LVar -> Exp -> CodeGeneration Exp
989−mkStringAtIndex var indexExp =
990− (\ var -> MethodInv $ TypeMethodCall (J.Name [Ident "Integer"])
993− [ MethodInv $ PrimaryMethodCall (var)
999− <$> mkVarAccess (Just stringType) var
1001−mkForeignType :: FType -> Maybe ClassType
1002−mkForeignType (FArith (ATInt ity)) = return (intTyToClass ity)
1003−mkForeignType (FArith ATFloat) = return doubleType
1004−mkForeignType FString = return stringType
1005−mkForeignType FPtr = return objectType
1006−mkForeignType FAny = return objectType
1007−mkForeignType FUnit = Nothing
1009−mkForeignVarAccess :: FType -> LVar -> CodeGeneration Exp
1010−mkForeignVarAccess (FArith (ATInt ty)) var =
1011− (\ var -> MethodInv $ PrimaryMethodCall var
1013− (Ident (intTyToMethod ty))
1016− <$> mkVarAccess (Just $ intTyToClass ty) var
1017−-- mkForeignVarAccess (FArith (ATInt ITChar)) var = Cast (PrimType CharT) <$> mkForeignVarAccess (FArith (ATInt (ITFixed IT32))) var
1018−mkForeignVarAccess (FArith ATFloat) var =
1019− (\ var -> MethodInv $ PrimaryMethodCall (var)
1021− (Ident "doubleValue")
1024− <$> mkVarAccess (Just doubleType) var
1025−mkForeignVarAccess otherType var = mkVarAccess (mkForeignType otherType) var
1027−mkFromForeignType :: FType -> Exp -> Exp
1028−{-mkFromForeignType (FArith (ATInt ty)) from =
1029− MethodInv $ TypeMethodCall (J.Name [intTyToIdent ty])
1033−mkFromForeignType (FArith (ATInt ITChar)) from = mkFromForeignType (FArith (ATInt (ITFixed IT32))) from
1034−mkFromForeignType (FArith ATFloat) from =
1035− MethodInv $ TypeMethodCall (J.Name [Ident "Double"])
1039−mkFromForeignType _ from = from
1041−mkForeignInvoke :: FType -> String -> [(FType, LVar)] -> CodeGeneration Exp
1042−mkForeignInvoke fType method args =
1043− (\ foreignInvokeMeth ->
1044− MethodInv $ PrimaryMethodCall (InstanceCreation []
1047− (Just $ ClassBody [ MemberDecl $ foreignInvokeMeth ])
1050− (Ident "foreignInvoke")
1053− <$> mkForeignInvokeMethod fType method args
1056−mkForeignInvokeMethod :: FType -> String -> [(FType, LVar)] -> CodeGeneration MemberDecl
1057−mkForeignInvokeMethod fType method args =
1059− MethodDecl [Public, Final]
1061− (Just . RefType $ ClassRefType objectType)
1062− (Ident "foreignInvoke")
1065− (MethodBody . Just $ Block
1068− [ Catch (FormalParam []
1069− (RefType $ ClassRefType exceptionType)
1071− (VarId $ Ident "ex")
1075− $ InstanceCreation []
1076− runtimeExceptionType
1077− [ExpName $ J.Name [Ident "ex"]]
1086− <$> mkForeignInvokeTryBlock fType method args
697+ pp' = rethrowAsRuntimeException pp
1089−mkForeignInvokeTryBlock :: FType -> String -> [(FType, LVar)] -> CodeGeneration Block
699+ wrapReturn FUnit exp =
1090−mkForeignInvokeTryBlock FUnit method args =
700+ ((ppInnerBlock pp') [BlockStmt $ ExpStmt exp] (Lit Null)) >>= ppOuterBlock pp'
1091− (\ method args -> Block [ BlockStmt . ExpStmt . MethodInv $ MethodCall method args
701+ wrapReturn _ exp =
1092− , BlockStmt $ Return (Just $ Lit Null)
702+ ((ppInnerBlock pp') [] exp) >>= ppOuterBlock pp'
1094− )
704+-----------------------------------------------------------------------
1095− <$> ( T.lift $ left (\ err -> "Error parsing name \"" ++ method ++ "\" :" ++ (show err))
705+-- Primitive functions
1096− (parser name method)
706+
1097− )
707+mkPrimitiveFunction :: PrimFn -> [LVar] -> CodeGeneration Exp
1098− <*> mapM (uncurry mkForeignVarAccess) args
708+mkPrimitiveFunction op args =
1099−mkForeignInvokeTryBlock fType method args =
709+ (\ args -> (primFnType ~> opName op) args)
1100− (\ method args -> Block [ BlockStmt . Return
710+ <$> sequence (zipWith (\ a t -> (Just t) <>@! a) args (sourceTypes op))
1102− . mkFromForeignType fType
1104− $ MethodCall method args
1107− <$> ( T.lift $ left (\ err -> "Error parsing name \"" ++ method ++ "\" :" ++ (show err))
1108− (parser name method)
1110− <*> mapM (uncurry mkForeignVarAccess) args
1112−mkMethodClosure :: Name -> [LVar] -> CodeGeneration Exp
1113−mkMethodClosure name args =
1115− InstanceCreation []
1117− [ (ExpName $ J.Name [Ident "context"]) ]
1121− $ MethodDecl [Public, Final]
1123− (Just . RefType $ ClassRefType objectType)
1129− $ Block [ BlockStmt
1133− $ MethodCall (reverseNameSpace name)
1141− <*> mapM (mkExp . SV) args
1143mkThread :: LVar -> CodeGeneration Exp
712mkThread :: LVar -> CodeGeneration Exp
1144mkThread arg =
713mkThread arg =
1145− (\ eval ->
714+ (\ closure -> (closure ~> "fork") []) <$> mkMethodCallClosure (MN 0 "EVAL") [arg]
1147− $ PrimaryMethodCall (InstanceCreation []
1148− (ClassType [(Ident "Thread", [])])
1151− $ ClassBody [ MemberDecl
1152− $ MethodDecl [Public, Final]
1154− (Just . RefType $ ClassRefType objectType)
1160− $ Block [ BlockStmt
1163− $ MethodCall (J.Name [Ident "start"])
1178− <$> mkThreadBinding arg
1180−mkThreadBinding :: LVar -> CodeGeneration Exp
1181−mkThreadBinding var =
1182− (\ bindingMethod var ->
1183− MethodInv $ PrimaryMethodCall ( InstanceCreation []
1186− (Just $ ClassBody [MemberDecl $ bindingMethod])
1192− <$> mkThreadBindingMethod
1193− <*> mkVarAccess Nothing var
1196−mkThreadBindingMethod :: CodeGeneration MemberDecl
1197−mkThreadBindingMethod =
1199− MethodDecl [Final, Public]
1201− (Just . RefType $ ClassRefType idrisClosureType)
1203− [ FormalParam [Final] (RefType . ClassRefType $ objectType) False (VarId $ Ident "param") ]
1205− (MethodBody . Just $ Block
1206− [ mkThreadBindingStack
1207− , BlockStmt . Return $ Just compute
1211− <$> mkBindingClosure (SUpdate (Loc 0) (SApp False (MN 0 "EVAL") [Loc 0]))
1214−mkThreadBindingStack :: BlockStmt
1215−mkThreadBindingStack =
1218− [ VarDecl (VarDeclArray . VarId $ Ident "new_context")
1219− (Just . InitArray $ ArrayInit [InitExp . ExpName $ J.Name [Ident "param"]])
1223−mkExp :: SExp -> CodeGeneration Exp
1224−mkExp (SV var) = mkVarAccess Nothing var
1225−mkExp (SApp False name args) =
1227− MethodInv $ PrimaryMethodCall ( InstanceCreation []
1228− idrisTailCallClosureType
1236− <$> mkMethodClosure name args
1237−mkExp (SApp True name args) =
1239− ( InstanceCreation []
1240− idrisTailCallClosureType
1245− <$> mkMethodClosure name args
1246−mkExp (SLet var new old) =
1248−mkExp (SUpdate var exp) =
1249− (\ rhs varPos -> Assign (ArrayLhs $ ArrayIndex (contextArray var) (Lit $ Int varPos))
1255−mkExp (SCon conId name args) =
1256− (\ args -> InstanceCreation []
1258− ((Lit $ Int (toInteger conId)):args)
1260− <$> mapM (mkExp .SV) args
1261−mkExp (SCase var alts) = mkCase False var alts
1262−mkExp (SChkCase var alts) = mkCase True var alts
1263−mkExp (SProj var i) = mkProjection var i
1264−mkExp (SConst (I x)) =
1265− let x' :: Int32; x' = fromInteger (toInteger x) in
1266− return $ mkPrimitive "Integer" (Int (fromInteger (toInteger x')))
1267−mkExp (SConst (BI x)) =
1268− return $ InstanceCreation []
1269− (ClassType [(Ident "BigInteger", [])])
1270− [Lit $ String (show x)]
1272−mkExp (SConst (Fl x)) = return $ mkPrimitive "Double" (Double x)
1273−mkExp (SConst (Ch x)) = return $ mkPrimitive "Integer" (Char x)
1274−mkExp (SConst (Str x)) = return $ Lit $ String x
1275−mkExp (SConst (AType (ATInt ITNative))) = return $ mkClass integerType
1276−mkExp (SConst (AType (ATInt ITBig))) = return $ mkClass bigIntegerType
1277−mkExp (SConst (AType ATFloat)) = return $ mkClass doubleType
1278−mkExp (SConst (AType (ATInt ITChar))) = return $ mkClass charType
1279−mkExp (SConst StrType) = return $ mkClass stringType
1280−mkExp (SConst (B8 x)) = return $ mkPrimitive "Byte" (String (show x))
1281−mkExp (SConst (B16 x)) = return $ mkPrimitive "Short" (String (show x))
1282−mkExp (SConst (B32 x)) = return $ mkPrimitive "Integer" (Int (toInteger x))
1283−mkExp (SConst (B64 x)) = return $ mkPrimitive "Long" (String (show x))
1284−mkExp (SConst (AType (ATInt (ITFixed IT8)))) = return $ mkClass byteType
1285−mkExp (SConst (AType (ATInt (ITFixed IT16)))) = return $ mkClass shortType
1286−mkExp (SConst (AType (ATInt (ITFixed IT32)))) = return $ mkClass integerType
1287−mkExp (SConst (AType (ATInt (ITFixed IT64)))) = return $ mkClass longType
1288−mkExp (SConst (PtrType)) = return $ mkClass objectType
1289−mkExp (SConst (VoidType)) = return $ mkClass voidType
1290−mkExp (SConst (Forgot)) = return $ mkClass objectType
1291−mkExp (SForeign _ fType meth args) = mkForeignInvoke fType meth args
1292−mkExp (SOp (LPlus (ATInt ITNative)) args) = mkExp (SOp (LPlus (ATInt (ITFixed IT32))) args)
1293−mkExp (SOp (LMinus (ATInt ITNative)) args) = mkExp (SOp (LMinus (ATInt (ITFixed IT32))) args)
1294−mkExp (SOp (LTimes (ATInt ITNative)) args) = mkExp (SOp (LTimes (ATInt (ITFixed IT32))) args)
1295−mkExp (SOp (LSDiv (ATInt ITNative)) args) = mkExp (SOp (LSDiv (ATInt (ITFixed IT32))) args)
1296−mkExp (SOp (LSRem (ATInt ITNative)) args) = mkExp (SOp (LSRem (ATInt (ITFixed IT32))) args)
1297−mkExp (SOp (LAnd ITNative) args) = mkExp (SOp (LAnd (ITFixed IT32)) args)
1298−mkExp (SOp (LOr ITNative) args) = mkExp (SOp (LOr (ITFixed IT32)) args)
1299−mkExp (SOp (LXOr ITNative) args) = mkExp (SOp (LXOr (ITFixed IT32)) args)
1300−mkExp (SOp (LCompl ITNative) args) = mkExp (SOp (LCompl (ITFixed IT32)) args)
1301−mkExp (SOp (LSHL ITNative) args) = mkExp (SOp (LSHL (ITFixed IT32)) args)
1302−mkExp (SOp (LASHR ITNative) args) = mkExp (SOp (LASHR (ITFixed IT32)) args)
1303−mkExp (SOp (LEq (ATInt ITNative)) args) = mkExp (SOp (LEq (ATInt (ITFixed IT32))) args)
1304−mkExp (SOp (LLt (ATInt ITNative)) args) = mkExp (SOp (LLt (ATInt (ITFixed IT32))) args)
1305−mkExp (SOp (LLe (ATInt ITNative)) args) = mkExp (SOp (LLe (ATInt (ITFixed IT32))) args)
1306−mkExp (SOp (LGt (ATInt ITNative)) args) = mkExp (SOp (LGt (ATInt (ITFixed IT32))) args)
1307−mkExp (SOp (LGe (ATInt ITNative)) args) = mkExp (SOp (LGe (ATInt (ITFixed IT32))) args)
1308−mkExp (SOp (LPlus ATFloat) args) = mkBinOpExp doubleType Add args
1309−mkExp (SOp (LMinus ATFloat) args) = mkBinOpExp doubleType Sub args
1310−mkExp (SOp (LTimes ATFloat) args) = mkBinOpExp doubleType Mult args
1311−mkExp (SOp (LSDiv ATFloat) args) = mkBinOpExp doubleType Div args
1312−mkExp (SOp (LEq ATFloat) args) =
1313− mkMethodOpChain1 (mkBoolToNumber doubleType) doubleType "equals" args
1314−mkExp (SOp (LLt ATFloat) args) = mkLogicalBinOpExp integerType LThan args
1315−mkExp (SOp (LLe ATFloat) args) = mkLogicalBinOpExp integerType LThanE args
1316−mkExp (SOp (LGt ATFloat) args) = mkLogicalBinOpExp integerType GThan args
1317−mkExp (SOp (LGe ATFloat) args) = mkLogicalBinOpExp integerType GThanE args
1318−mkExp (SOp (LPlus (ATInt ITBig)) args) = mkMethodOpChain1 id bigIntegerType "add" args
1319−mkExp (SOp (LMinus (ATInt ITBig)) args) = mkMethodOpChain1 id bigIntegerType "subtract" args
1320−mkExp (SOp (LTimes (ATInt ITBig)) args) = mkMethodOpChain1 id bigIntegerType "multiply" args
1321−mkExp (SOp (LSDiv (ATInt ITBig)) args) = mkMethodOpChain1 id bigIntegerType "divide" args
1322−mkExp (SOp (LSRem (ATInt ITBig)) args) = mkMethodOpChain1 id bigIntegerType "mod" args
1323−mkExp (SOp (LEq (ATInt ITBig)) args) =
1324− mkMethodOpChain1 (mkBoolToNumber bigIntegerType) bigIntegerType "equals" args
1325−mkExp (SOp (LLt (ATInt ITBig)) args) =
1326− mkMethodOpChain1 ( mkBoolToNumber bigIntegerType
1327− . mkPartialOrder SLt
1332−mkExp (SOp (LLe (ATInt ITBig)) args) =
1333− mkMethodOpChain1 ( mkBoolToNumber bigIntegerType
1334− . mkPartialOrder SLe
1339−mkExp (SOp (LGt (ATInt ITBig)) args) =
1340− mkMethodOpChain1 ( mkBoolToNumber bigIntegerType
1341− . mkPartialOrder SGt
1346−mkExp (SOp (LGe (ATInt ITBig)) args) =
1347− mkMethodOpChain1 ( mkBoolToNumber bigIntegerType
1348− . mkPartialOrder SGe
1353−mkExp (SOp LStrConcat args) =
1354− mkMethodOpChain (\ exp -> InstanceCreation []
1355− (ClassType [(Ident "StringBuilder", [])])
1359− (\ exp -> MethodInv $ PrimaryMethodCall exp [] (Ident "toString") [])
1363−mkExp (SOp LStrLt args@[_, _]) =
1364− mkMethodOpChain1 ( mkBoolToNumber integerType
1365− . mkPartialOrder SLt
1370−mkExp (SOp LStrEq args@[_, _]) =
1371− mkMethodOpChain1 ( mkBoolToNumber integerType)
1375−mkExp (SOp LStrLen [arg]) =
1376− (\ var -> MethodInv $ PrimaryMethodCall var [] (Ident "length") [])
1377− <$> mkVarAccess (Just stringType) arg
1378−mkExp (SOp (LIntFloat ity) [arg]) =
1379− mkPrimitiveCast (intTyToClass ity) doubleType arg
1380−mkExp (SOp (LFloatInt ity) [arg]) =
1381− mkSignedExt (intTyToMethod ity) doubleType (intTyToClass ity) arg
1382−mkExp (SOp (LIntStr ity) [arg]) =
1383− mkToString (intTyToClass ity) arg
1384−mkExp (SOp (LStrInt ity) [arg]) =
1385− mkPrimitiveCast stringType (intTyToClass ity) arg
1386−mkExp (SOp LFloatStr [arg]) =
1387− mkToString doubleType arg
1388−mkExp (SOp LStrFloat [arg]) =
1389− mkPrimitiveCast doubleType stringType arg
1390−mkExp (SOp (LSExt ITNative ITBig) [arg]) =
1391− mkPrimitiveCast integerType bigIntegerType arg
1392−mkExp (SOp (LTrunc ITBig ITNative) [arg]) =
1393− mkPrimitiveCast bigIntegerType integerType arg
1394−mkExp (SOp (LChInt ITNative) [arg]) =
1395− mkVarAccess (Just integerType) arg
1396−mkExp (SOp (LIntCh ITNative) [arg]) =
1397− mkVarAccess (Just integerType) arg
1398−mkExp (SOp LPrintNum [arg]) =
1399− mkSystemOutPrint <$> (mkVarAccess Nothing arg)
1400−mkExp (SOp LPrintStr [arg]) =
1401− mkSystemOutPrint <$> (mkVarAccess (Just stringType) arg)
1402−mkExp (SOp LReadStr [arg]) = mkExp (SForeign LANG_C FString "idris_readStr" [(FPtr, arg)])
1403−mkExp (SOp (LLt (ATInt ty)) args) = mkLogicalBinOpExp (intTyToClass ty) LThan args
1404−mkExp (SOp (LLe (ATInt ty)) args) = mkLogicalBinOpExp (intTyToClass ty) LThanE args
1405−mkExp (SOp (LEq (ATInt ty)) args) =
1406− mkMethodOpChain1 (mkBoolToNumber (intTyToClass ty)) (intTyToClass ty) "equals" args
1407−mkExp (SOp (LGt (ATInt ty)) args) = mkLogicalBinOpExp (intTyToClass ty) GThan args
1408−mkExp (SOp (LGe (ATInt ty)) args) = mkLogicalBinOpExp (intTyToClass ty) GThanE args
1409−mkExp (SOp (LPlus (ATInt ty)) args) = mkBinOpExp (intTyToClass ty) Add args
1410−mkExp (SOp (LMinus (ATInt ty)) args) = mkBinOpExp (intTyToClass ty) Sub args
1411−mkExp (SOp (LTimes (ATInt ty)) args) = mkBinOpExp (intTyToClass ty) Mult args
1412−mkExp (SOp (LUDiv (ITFixed IT64)) (arg:args)) = do
1413− (arg:args) <- mapM (mkVarAccess (Just longType)) (arg:args)
1414− return $ foldl (\ exp arg ->
1415− MethodInv $ PrimaryMethodCall
1416− ( MethodInv $ PrimaryMethodCall
1417− ( MethodInv $ TypeMethodCall (J.Name [Ident "BigInteger"])
1424− [ MethodInv $ TypeMethodCall (J.Name [Ident "BigInteger"])
1431− (Ident "longValue")
1436−mkExp (SOp (LUDiv ty) args) =
1437− mkBinOpExpConv (intTyToMethod $ nextIntTy ty)
1438− (intTyToPrimTy $ nextIntTy ty)
1442−mkExp (SOp (LSDiv (ATInt ty)) args) = mkBinOpExp (intTyToClass ty) Div args
1443−mkExp (SOp (LURem (ITFixed IT64)) (arg:args)) = do
1444− (arg:args) <- mapM (mkVarAccess (Just longType)) (arg:args)
1445− return $ foldl (\ exp arg ->
1446− MethodInv $ PrimaryMethodCall
1447− ( MethodInv $ PrimaryMethodCall
1448− ( MethodInv $ TypeMethodCall (J.Name [Ident "BigInteger"])
1454− (Ident "remainder")
1455− [ MethodInv $ TypeMethodCall (J.Name [Ident "BigInteger"])
1462− (Ident "longValue")
1467−mkExp (SOp (LURem ty) args) =
1468− mkBinOpExpConv (intTyToMethod $ nextIntTy ty)
1469− (intTyToPrimTy $ nextIntTy ty)
1473−mkExp (SOp (LSRem (ATInt ty)) args) = mkBinOpExp (intTyToClass ty) Rem args
1474−mkExp (SOp (LSHL ty) args) = mkBinOpExp (intTyToClass ty) LShift args
1475−mkExp (SOp (LLSHR ty) args) = mkBinOpExp (intTyToClass ty) RRShift args
1476−mkExp (SOp (LASHR ty) args) = mkBinOpExp (intTyToClass ty) RShift args
1477−mkExp (SOp (LAnd ty) args) = mkBinOpExp (intTyToClass ty) And args
1478−mkExp (SOp (LOr ty) args) = mkBinOpExp (intTyToClass ty) Or args
1479−mkExp (SOp (LXOr ty) args) = mkBinOpExp (intTyToClass ty) Xor args
1480−mkExp (SOp (LCompl ty) [var]) = PreBitCompl <$> mkVarAccess (Just $ intTyToClass ty) var
1481−mkExp (SOp (LZExt from to) [var])
1482− | intTyWidth from < intTyWidth to
1483− = mkZeroExt (intTyToMethod to) (intTyWidth from) (intTyToClass from) (intTyToClass to) var
1484−mkExp (SOp (LSExt from to) [var])
1485− | intTyWidth from < intTyWidth to
1486− = mkSignedExt (intTyToMethod to) (intTyToClass from) (intTyToClass to) var
1487−mkExp (SOp (LTrunc from to) [var])
1488− | intTyWidth from > intTyWidth to
1489− = mkSignedExt (intTyToMethod to) (intTyToClass from) (intTyToClass to) var
1490−mkExp (SOp LFExp [arg]) = mkMathFun "exp" arg
1491−mkExp (SOp LFLog [arg]) = mkMathFun "log" arg
1492−mkExp (SOp LFSin [arg]) = mkMathFun "sin" arg
1493−mkExp (SOp LFCos [arg]) = mkMathFun "cos" arg
1494−mkExp (SOp LFTan [arg]) = mkMathFun "tan" arg
1495−mkExp (SOp LFASin [arg]) = mkMathFun "asin" arg
1496−mkExp (SOp LFACos [arg]) = mkMathFun "acos" arg
1497−mkExp (SOp LFATan [arg]) = mkMathFun "atan" arg
1498−mkExp (SOp LFSqrt [arg]) = mkMathFun "sqrt" arg
1499−mkExp (SOp LFFloor [arg]) = mkMathFun "floor" arg
1500−mkExp (SOp LFCeil [arg]) = mkMathFun "ceil" arg
1501−mkExp (SOp LStrHead [arg]) = mkStringAtIndex arg (Lit $ Int 0)
1502−mkExp (SOp LStrTail [arg]) =
1503− (\ var -> MethodInv $ PrimaryMethodCall (var)
1505− (Ident "substring")
1508− <$> mkVarAccess (Just stringType) arg
1509−mkExp (SOp LStrCons [c, cs]) =
1510− (\ cVar csVar -> MethodInv $
1511− PrimaryMethodCall ( MethodInv $ PrimaryMethodCall (InstanceCreation []
1512− (ClassType [(Ident "StringBuilder", [])])
1519− Cast (PrimType CharT)
1520− (MethodInv $ PrimaryMethodCall
1532− <$> mkVarAccess (Just integerType) c
1533− <*> mkVarAccess (Just stringType) cs
1534−mkExp (SOp LStrIndex [str, i]) = mkVarAccess (Just integerType) i >>= mkStringAtIndex str
1535−mkExp (SOp LStrRev [str]) =
1536− (\ var -> MethodInv $
1537− PrimaryMethodCall ( MethodInv $ PrimaryMethodCall (InstanceCreation []
1538− (ClassType [(Ident "StringBuffer", [])])
1550− <$> mkVarAccess (Just stringType) str
1551−mkExp (SOp LStdIn []) = return $ mkSystemStd In
1552−mkExp (SOp LStdOut []) = return $ mkSystemStd Out
1553−mkExp (SOp LStdErr []) = return $ mkSystemStd Err
1554−mkExp (SOp LFork [arg]) = mkThread arg
1555−mkExp (SOp LPar [arg]) = mkExp (SV arg)
1556−mkExp (SOp LVMPtr []) =
1557− return $ MethodInv $ TypeMethodCall (J.Name [Ident "Thread"]) [] (Ident "currentThread") []
1558−mkExp (SOp LNoOp args) = mkExp . SV $ last args
1559−mkExp (SNothing) = return $ Lit Null
1560−mkExp (SError err) =
1561− return . MethodInv $
1562− PrimaryMethodCall (InstanceCreation []
1563− runtimeExceptionType
1566− [ MemberDecl $ MethodDecl [Public, Final]
1568− (Just . RefType $ ClassRefType objectType)
1569− (Ident "throwSelf")
1572− ( MethodBody . Just $
1573− Block [ BlockStmt (Throw This) ]
1579− (Ident "throwSelf")
1581−mkExp other = error (show other)