1{-# LANGUAGE PatternGuards #-}
3module Idris.Compiler where
11import Control.Monad.State
13import Epic.Epic hiding (Term, Type, Name, fn, compile)
14import qualified Epic.Epic as E
16primDefs = [UN ["mkForeign"]]
18compile :: FilePath -> Idris ()
19compile f = do ds <- mkDecls
20 lift $ compileWith [Debug] (mkProgram ds) f
22mkDecls :: Idris [EpicDecl]
23mkDecls = do i <- getIState
24 decls <- mapM build (toAlist (tt_ctxt i))
25 return $ basic_defs ++ EpicFn (name "main") epicMain : decls
27ename x = name ("idris_" ++ show x)
28aname x = name ("a_" ++ show x)
30epicMain = ref (ename (UN ["main"]))
33 epic :: a -> Idris E.Term
35build :: (Name, Def) -> Idris EpicDecl
36build (n, d) = do i <- getIState
37 case lookup n (idris_prims i) of
38 Just opDef -> return $ EpicFn (ename n) opDef
40 return $ EpicFn (ename n) def
42impossible = int 42424242
44instance ToEpic Def where
45 epic (Function (Fun _ _ tm _)) = epic tm
46 epic (CaseOp _ pats args sc) = epic (args, sc) -- TODO: redo case comp after optimising
47 epic _ = return impossible
49instance ToEpic (TT Name) where
50 epic tm = epic' [] tm where
51 epic' env tm@(App f a)
52 | (P _ (UN ["mkForeign"]) _, args) <- unApply tm
54 | (P _ (UN ["lazy"]) _, [_, arg]) <- unApply tm
55 = do arg' <- epic' env arg
57 epic' env (P (DCon t a) n _) = return $ con_ t
58 epic' env (P (TCon t a) n _) = return $ con_ t
59 epic' env (P _ n _) = return $ ref (ename n)
60 epic' env (V i) = return $ ref (env!!i)
61 epic' env (Bind n (Lam _) sc)
62 = do sc' <- epic' (aname n : env) sc
63 return $ term ([aname n], sc')
64 epic' env (Bind n (Let _ v) sc)
65 = do sc' <- epic' (aname n : env) sc
67 return $ let_ v' (aname n, sc')
68 epic' env (Bind _ _ _) = return impossible
69 epic' env (App f a) = do f' <- epic' env f
71 logLvl 3 $ "Compiled " ++ show f ++ " @@ " ++ show a
73 epic' env (Constant c) = epic c
74 epic' env (Set _) = return impossible
76doForeign :: [TT Name] -> Idris E.Term
77doForeign (_ : fgn : args)
78 | (_, (Constant (Str fgnName) : fgnArgTys : P _ (UN [ret]) _ : [])) <- unApply fgn
79 = let tys = getFTypes fgnArgTys
81 do args' <- mapM epic args
82 -- wrap it in a prim__IO
83 return $ con_ 0 @@ impossible @@ foreign_ rty fgnName (zip args' tys)
84 | otherwise = fail "Badly formed foreign function call"
86getFTypes :: TT Name -> [E.Type]
87getFTypes tm = case unApply tm of
89 (cons, [a, (P _ (UN [ty]) _), xs]) ->
90 let rest = getFTypes xs in
94mkEty "FFloat" = tyFloat
96mkEty "FString" = tyString
100instance ToEpic Const where
101 epic (I i) = return (int i)
102 epic (Fl f) = return (float f)
103 epic (Str s) = return (str s)
104 epic (Ch c) = return (char c)
105 epic IType = return $ con_ 1
106 epic FlType = return $ con_ 2
107 epic ChType = return $ con_ 3
108 epic StrType = return $ con_ 4
109 epic PtrType = return $ con_ 5
111instance ToEpic ([Name], SC) where
112 epic (args, tree) = do logLvl 3 $ "Compiling " ++ show args ++ "\n" ++ show tree
114 return $ term (map ename args, tree')
116instance ToEpic SC where
117 epic (STerm t) = epic t
118 epic (UnmatchedCase str) = return $ error_ str
119 epic (Case n alts) = do alts' <- mapM mkEpicAlt alts
120 return $ case_ (ref (ename n)) alts'
122 mkEpicAlt (ConCase n t args rhs) = do rhs' <- epic rhs
123 return $ con t (map ename args, rhs')
124 mkEpicAlt (ConstCase (I i) rhs) = do rhs' <- epic rhs
125 return $ constcase i rhs'
126 mkEpicAlt (ConstCase IType rhs) = do rhs' <- epic rhs
127 return $ defaultcase rhs'
128 mkEpicAlt (ConstCase c rhs)
129 = fail $ "Can only pattern match on integer constants (" ++ show c ++ ")"
130 mkEpicAlt (DefaultCase rhs) = do rhs' <- epic rhs
131 return $ defaultcase rhs'
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