on master help sign in
Output C file (not finished...)
commit0887715583e2428a5f1b2797b19742741e286df4 authorEdwin Brady <eb@cs.st-andrews.ac.uk> dateWed 23 May 2012, 12:01 (14 years ago) parentfa0ecde
8 files changed+93−14
src/Idris/AbsSyntax.hs+3 src/Idris/Compiler.hs−2 src/Idris/ElabDecls.hs−1 src/Idris/REPL.hs+6 src/Idris/REPLParser.hs+1 src/RTS/Bytecode.hs+3−2 src/RTS/CodegenC.hs+61−1 src/RTS/PreC.hs+19−8
src/Idris/AbsSyntax.hs+3
@@ -81,6 +81,8 @@ data IState = IState { tt_ctxt :: Context,
8181 ibc_write :: [IBCWrite],
8282 compiled_so :: Maybe String
8383 }
84+
85+primDefs = [UN "unsafePerformIO", UN "mkLazyForeign", UN "mkForeign", UN "FalseElim"]
8486
8587-- information that needs writing for the current module's .ibc file
8688data IBCWrite = IBCFix FixDecl
@@ -395,6 +397,7 @@ setTypeCase t = do i <- get
395397data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
396398 | Reload | Edit
397399 | Compile String | Execute | ExecVal PTerm
400+ | NewCompile String
398401 | Metavars | Prove Name | AddProof | Universes
399402 | TTShell
400403 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name
src/Idris/Compiler.hs−2
@@ -21,8 +21,6 @@ import Paths_idris
2121import Epic.Epic hiding (Term, Type, Name, fn, compile)
2222import qualified Epic.Epic as E
2323
24−primDefs = [UN "unsafePerformIO", UN "mkLazyForeign", UN "mkForeign", UN "FalseElim"]
25−
2624compile :: FilePath -> Term -> Idris ()
2725compile f tm
2826 = do checkMVs
src/Idris/ElabDecls.hs−1
@@ -25,7 +25,6 @@ import Data.List
2525import Data.Maybe
2626import Debug.Trace
2727
28−
2928recheckC fc env t
3029 = do -- t' <- applyOpts (forget t) (doesn't work, or speed things up...)
3130 ctxt <- getContext
src/Idris/REPL.hs+6
@@ -256,6 +256,12 @@ process fn (Compile f) = do (m, _) <- elabVal toplevel False
256256 [pexp $ PRef fc (NS (UN "main") ["main"])])
257257 compile f m
258258 where fc = FC "main" 0
259+process fn (NewCompile f)
260+ = do (m, _) <- elabVal toplevel False
261+ (PApp fc (PRef fc (UN "run__IO"))
262+ [pexp $ PRef fc (NS (UN "main") ["main"])])
263+ compileC f m
264+ where fc = FC "main" 0
259265process fn (LogLvl i) = setLogLevel i
260266process fn Metavars
261267 = do ist <- get
src/Idris/REPLParser.hs+1
@@ -27,6 +27,7 @@ pCmd = try (do cmd ["q", "quit"]; eof; return Quit)
2727 <|> try (do cmd ["exec", "execute"]; eof; return Execute)
2828 <|> try (do cmd ["ttshell"]; eof; return TTShell)
2929 <|> try (do cmd ["c", "compile"]; f <- identifier; eof; return (Compile f))
30+ <|> try (do cmd ["nc", "newcompile"]; f <- identifier; eof; return (NewCompile f))
3031 <|> try (do cmd ["m", "metavars"]; eof; return Metavars)
3132 <|> try (do cmd ["p", "prove"]; n <- pName; eof; return (Prove n))
3233 <|> try (do cmd ["a", "addproof"]; eof; return AddProof)
src/RTS/Bytecode.hs+3−2
@@ -37,10 +37,11 @@ data BAlt = BConCase Tag [Name] Int Bytecode
3737 | BDefaultCase Bytecode
3838 deriving Show
3939
40−bcdefs :: [(Name, SCDef)] -> [(Name, Bytecode)]
40+bcdefs :: [(Name, SCDef)] -> [(Name, (Int, Bytecode))]
4141bcdefs = map (\ (n, s) -> (n, bc s))
4242
43−bc (SCDef args max c) = BGetArgs (map fst args) (bcExp max (length args) c)
43+bc (SCDef args max c) = (length args,
44+ BGetArgs (map fst args) (bcExp max (length args) c))
4445
4546bcExp v arity x
4647 = let (code, max) = runState (bc' True arity x) v
src/RTS/CodegenC.hs+61−1
@@ -1,10 +1,68 @@
11module RTS.CodegenC where
22
33import Core.TT
4+import Core.Evaluate
5+import Core.CaseTree
6+
47import RTS.PreC
58import RTS.SC
9+import RTS.Bytecode
10+
11+import Idris.AbsSyntax
612
713import Data.Char
14+import Data.List
15+import Control.Monad.State
16+import System.Process
17+import System.IO
18+import System.Directory
19+import System.Environment
20+
21+import Paths_idris
22+
23+compileC :: FilePath -> Term -> Idris ()
24+compileC f tm
25+ = do checkMVs
26+ let tmnames = namesUsed (STerm tm)
27+ used <- mapM (allNames []) tmnames
28+ i <- get
29+ let entry = mainFn (idris_scprims i) tm
30+ scs' <- mkDecls tm (concat used)
31+ let scs = scs' ++ entry
32+ objs <- getObjectFiles
33+ libs <- getLibs
34+ hdrs <- getHdrs
35+ ddir <- liftIO $ getDataDir
36+ -- if any includes exist in the data directory, use that
37+ hdrs' <- liftIO $ mapM (inDir ddir) hdrs
38+ let bcs = bcdefs scs
39+ let pcs = preCdefs bcs
40+ let code = cdefs pcs
41+ liftIO $ writeFile (f ++ ".c") code
42+ where checkMVs = do i <- get
43+ case idris_metavars i \\ primDefs of
44+ [] -> return ()
45+ ms -> fail $ "There are undefined metavariables: " ++ show ms
46+ inDir d h = do let f = d ++ "/" ++ h
47+ ex <- doesFileExist f
48+ if ex then return f else return h
49+
50+
51+mainFn ps tm = toSC ps (MN 0 "_main", Function undefined tm)
52+
53+allNames :: [Name] -> Name -> Idris [Name]
54+allNames ns n | n `elem` ns = return []
55+allNames ns n = do i <- get
56+ case lookupCtxt Nothing n (idris_callgraph i) of
57+ [ns'] -> do more <- mapM (allNames (n:ns)) ns'
58+ return (nub (n : concat more))
59+ _ -> return [n]
60+
61+mkDecls :: Term -> [Name] -> Idris [(Name, SCDef)]
62+mkDecls t used
63+ = do i <- getIState
64+ let ds = filter (\ (n, d) -> n `elem` used) $ ctxtAlist (tt_ctxt i)
65+ return $ concatMap (toSC (idris_scprims i)) ds
866
967cdefs :: [(Name, (Int, PreC))] -> String
1068cdefs xs = concatMap (\ (n, (i, c)) -> proto n) xs ++ "\n" ++
@@ -12,7 +70,8 @@ cdefs xs = concatMap (\ (n, (i, c)) -> proto n) xs ++ "\n" ++
1270
1371codegenC :: Name -> Int -> PreC -> String
1472codegenC n args prec
15− = "void " ++ cname n ++ "(VM* vm) {\n" ++
73+ = "/* " ++ show prec ++ " */\n\n" ++
74+ "void " ++ cname n ++ "(VM* vm) {\n" ++
1675 concatMap (cg 1) prec ++ "}\n\n"
1776
1877indent i = take (i * 4) (repeat ' ')
@@ -23,6 +82,7 @@ reg (LVar v) = "*(vm->stack-" ++ show v ++ ")"
2382catom :: CAtom -> String
2483catom (CL l) = reg (LVar l)
2584catom (CC (I i)) = "MKINT(" ++ show i ++ ")"
85+catom (CC v) = "const(" ++ show v ++ ")"
2686catom (CP n) = cname n
2787
2888assignCon i r tag args
src/RTS/PreC.hs+19−8
@@ -15,7 +15,6 @@ data CAtom = CP Name | CL Local | CC Const
1515data CExp = CAtom CAtom
1616 | CApp CAtom [CAtom]
1717 | CExactApp CAtom [CAtom]
18− | CTailApp CAtom [CAtom]
1918 | CLazy CAtom [CAtom]
2019 | CFCall String CType [(CAtom, CType)]
2120 | CPrimOp SPrim [CAtom]
@@ -39,22 +38,34 @@ data CInst = ASSIGN Reg CExp
3938 | ERROR String
4039 | TAILCALL Int -- number of stack items to clear
4140 CAtom [CAtom]
41+ | TAILCALLEXACT Int CAtom [CAtom]
4242 deriving Show
4343
4444type PreC = [CInst]
4545
46−preCdefs :: [(Name, Bytecode)] -> [(Name, (Int, PreC))]
47−preCdefs = map (\ (n, b) -> (n, preC b))
46+preCdefs :: [(Name, (Int, Bytecode))] -> [(Name, (Int, PreC))]
47+preCdefs xs = map (\ (n, (i, b)) -> (n, preC xs b)) xs
4848
4949atom res (BP n) = CP n
5050atom res (BL n) = CL (res - n)
5151atom res (BC c) = CC c
5252
53−preC :: Bytecode -> (Int, PreC)
54−preC (BGetArgs ns bc) = (length ns, pc RVal (length ns) bc)
55− where pc loc d (BAtom b) = [ASSIGN loc (CAtom (atom d b))]
56− pc loc d (BApp f as) = [ASSIGN loc (CApp (atom d f) (map (atom d) as))]
57− pc loc d (BTailApp f as) = [TAILCALL d (atom d f) (map (atom d) as)]
53+preC :: [(Name, (Int, Bytecode))] -> Bytecode -> (Int, PreC)
54+preC all (BGetArgs ns bc) = (length ns, pc RVal (length ns) bc)
55+ where arity n = do (i, b) <- lookup n all
56+ return i
57+ exact (BP n) as = case arity n of
58+ Just i -> i == length as
59+ Nothing -> False
60+ exact _ as = False
61+
62+ pc loc d (BAtom b) = [ASSIGN loc (CAtom (atom d b))]
63+ pc loc d (BApp f as)
64+ | exact f as = [ASSIGN loc (CExactApp (atom d f) (map (atom d) as))]
65+ | otherwise = [ASSIGN loc (CApp (atom d f) (map (atom d) as))]
66+ pc loc d (BTailApp f as)
67+ | exact f as = [TAILCALLEXACT d (atom d f) (map (atom d) as)]
68+ | otherwise = [TAILCALL d (atom d f) (map (atom d) as)]
5869 pc loc d (BLazy f as) = [ASSIGN loc (CLazy (atom d f) (map (atom d) as))]
5970 pc loc d (BLet x val sc) = pc (LVar (d - x)) d val ++ pc loc d sc
6071 pc loc d (BFCall c t args)