on master help sign in
Convert intermediate expressions to let bound variables
commitece92fe82ad7672b63b5f5711302c2797dcd6cd5 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateTue 7 Aug 2012, 15:49 (14 years ago) parent9b1587b
5 files changed+200−83
idris.cabal+1−1 src/IRTS/Bytecode.hs+62−14 src/IRTS/LParser.hs+7−6 src/IRTS/Lang.hs+1−62 src/IRTS/Simplified.hs+129
idris.cabal+1−1
@@ -70,7 +70,7 @@ Executable idris
7070 Util.Pretty,
7171
7272 RTS.Bytecode, RTS.SC, RTS.PreC, RTS.CodegenC,
73− IRTS.Lang, IRTS.LParser, IRTS.Bytecode,
73+ IRTS.Lang, IRTS.LParser, IRTS.Bytecode, IRTS.Simplified,
7474
7575 Paths_idris
7676
src/IRTS/Bytecode.hs+62−14
@@ -1,21 +1,69 @@
11module IRTS.Bytecode where
22
33import IRTS.Lang
4+import IRTS.Simplified
45import Core.TT
6+import Data.Maybe
57
6−data BC = PUSH Int
7− | PUSHCONST Const
8− | MKCON Int Int
9− | CASE [(Int, [BC])] (Maybe [BC])
10− | CONSTCASE [(Const, [BC])] (Maybe [BC])
11− | PRINTNUM
12− | PRINTSTR
13− | INTOP PrimFn
14− deriving Show
8+-- data Reg = RVal | CaseVar | L Int
159
16−toBC :: (Name, LDecl) -> Maybe (Name, [BC])
17−toBC (n, LConstructor _ _ _) = Nothing
18−toBC (n, LFun n' args exp) = Just (n, bc exp)
10+-- data BC = ASSIGN Reg Reg
11+-- | ASSIGNCONST Reg Const
12+-- | MKCON Reg Int Int
13+-- | CASE [(Int, [BC])] (Maybe [BC])
14+-- | GETARGS Int -- discards afterwards
15+-- | CONSTCASE [(Const, [BC])] (Maybe [BC])
16+-- | CALL Name
17+-- | TAILCALL Name
18+-- | PRINTNUM
19+-- | PRINTSTR
20+-- | GROWSTACK Int
21+-- | DROPSTACK Int
22+-- | SLIDE Int Int -- number to drop, number to keep
23+-- | OP PrimFn
24+-- deriving Show
1925
20−bc :: LExp -> [BC]
21−bc x = []
26+-- toBC :: (Name, LDecl) -> Maybe (Name, [BC])
27+-- toBC (n, LConstructor _ _ _) = Nothing
28+-- toBC (n, LFun n' args exp) = let cleanup = [SLIDE (length args) 1] in
29+-- Just (n, bc (length args - 1) exp cleanup)
30+--
31+-- bc :: Int -> LExp -> [BC] -> [BC]
32+-- bc top (LV (Glob n)) c = [CALL n] ++ c
33+-- bc top (LV (Loc i)) c = [PUSH (top-i)] ++ c
34+-- bc top (LApp tc fn args) c
35+-- = bcArgs top args ++
36+-- if tc then [SLIDE top (length args), TAILCALL fn]
37+-- else [CALL fn] ++ c
38+-- bc top (LCon tag _ args) c
39+-- = bcArgs top args ++ [MKCON tag (length args)] ++ c
40+-- bc top (LConst i) c = [PUSHCONST i] ++ c
41+-- bc top (LCase e alts) c = bc top e [] ++
42+-- if constCase alts then bcCaseConst top alts
43+-- else bcCase top alts
44+-- ++ c
45+-- bc top (LLet _ v e) c = bc top v [] ++ bc (top + 1) e [] ++ c
46+-- bc top (LOp prim args) c = bcArgs top args ++ [OP prim] ++ c
47+--
48+-- bcArgs top [] = []
49+-- bcArgs top (x : xs) = bc top x [] ++ bcArgs (top + 1) xs
50+--
51+-- constCase (LConstCase _ _ : _) = True
52+-- constCase (LConCase _ _ _ _ : _) = False
53+-- constCase (_ : xs) = constCase xs
54+-- constCase _ = False
55+--
56+-- bcCase top xs = [CASE (mapMaybe (conClause top) xs) (defaultCase top xs)]
57+-- bcCaseConst top xs = [CONSTCASE (mapMaybe (constClause top) xs) (defaultCase top xs)]
58+--
59+-- conClause top (LConCase tag _ args e) = Just (tag, GETARGS (length args) :
60+-- bc (top + length args) e []
61+-- ++ [SLIDE (length args) 1])
62+-- conClause top _ = Nothing
63+--
64+-- constClause top (LConstCase c e) = Just (c, bc top e [])
65+-- constClause top _ = Nothing
66+--
67+-- defaultCase top [] = Nothing
68+-- defaultCase top (LDefaultCase e : xs) = Just (bc top e [])
69+-- defaultCase top (_ : xs) = defaultCase top xs
src/IRTS/LParser.hs+7−6
@@ -3,7 +3,7 @@ module IRTS.LParser where
33import Core.CoreParser
44import Core.TT
55import IRTS.Lang
6−import IRTS.Bytecode
6+import IRTS.Simplified
77
88import Text.ParserCombinators.Parsec
99import Text.ParserCombinators.Parsec.Error
@@ -47,9 +47,9 @@ fovm f = do defs <- parseFOVM f
4747 let ctxtIn = addAlist tagged emptyContext
4848 let checked = checkDefs ctxtIn tagged
4949 print checked
50− case checked of
51− OK c -> do let bc = mapMaybe toBC c
52− print bc
50+-- case checked of
51+-- OK c -> do let bc = mapMaybe toBC c
52+-- print bc
5353
5454parseFOVM :: FilePath -> IO [(Name, LDecl)]
5555parseFOVM fname = do putStrLn $ "Reading " ++ fname
@@ -92,11 +92,12 @@ pLExp' = try (do reserved "printNum"; e <- pLExp
9292 return (LOp LPrintNum [e]))
9393 <|> try (do reserved "print"; e <- pLExp
9494 return (LOp LPrintStr [e]))
95− <|> try (do x <- iName [];
95+ <|> try (do tc <- option False (do lchar '%'; reserved "tc"; return True)
96+ x <- iName [];
9697 lchar '('
9798 args <- sepBy pLExp (lchar ',')
9899 lchar ')'
99− if null args then return (LV (Glob x)) else return (LApp x args))
100+ if null args then return (LV (Glob x)) else return (LApp tc x args))
100101 <|> do lchar '('; e <- pLExp; lchar ')'; return e
101102 <|> pLConst
102103 <|> do reserved "let"; x <- iName []; lchar '='; v <- pLExp
src/IRTS/Lang.hs+1−62
@@ -6,7 +6,7 @@ data LVar = Loc Int | Glob Name
66 deriving Show
77
88data LExp = LV LVar
9− | LApp Name [LExp]
9+ | LApp Bool Name [LExp] -- True = tail call
1010 | LLet Name LExp LExp -- name just for pretty printing
1111 | LCon Int Name [LExp]
1212 | LCase LExp [LAlt]
@@ -29,8 +29,6 @@ data LDecl = LFun Name [Name] LExp -- name, arg names, definition
2929
3030type LDefs = Ctxt LDecl
3131
32−-- TODO: scope and arity checker.
33−
3432addTags :: [(Name, LDecl)] -> [(Name, LDecl)]
3533addTags ds = tag 0 ds
3634 where tag i ((n, LConstructor n' t a) : as)
@@ -38,62 +36,3 @@ addTags ds = tag 0 ds
3836 tag i (x : as) = x : tag i as
3937 tag i [] = []
4038
41−checkDefs :: LDefs -> [(Name, LDecl)] -> TC [(Name, LDecl)]
42−checkDefs ctxt [] = return []
43−checkDefs ctxt (con@(n, LConstructor _ _ _) : xs) = do xs' <- checkDefs ctxt xs
44− return (con : xs')
45−checkDefs ctxt ((n, LFun n' args exp) : xs)
46− = do exp' <- scopecheck ctxt (zip args [0..]) exp
47− xs' <- checkDefs ctxt xs
48− return ((n, LFun n' args exp') : xs')
49−
50−scopecheck :: LDefs -> [(Name, Int)] -> LExp -> TC LExp
51−scopecheck ctxt env tm = sc env tm where
52− sc env (LV (Glob n))
53− = case lookup n (reverse env) of -- most recent first
54− Just i -> return (LV (Loc i))
55− Nothing -> case lookupCtxt Nothing n ctxt of
56− [LConstructor _ i ar] ->
57− if ar == 0 then return (LCon i n [])
58− else fail $ "Codegen error: Constructor " ++ show n ++
59− " has arity " ++ show ar
60− [_] -> return (LV (Glob n))
61− [] -> fail $ "Codegen error: No such variable " ++ show n
62− sc env (LApp f args)
63− = do args' <- mapM (sc env) args
64− case lookupCtxt Nothing f ctxt of
65− [LConstructor n tag ar] ->
66− if (ar == length args)
67− then return $ LCon tag n args'
68− else fail $ "Codegen error: Constructor " ++ show f ++
69− " has arity " ++ show ar
70− [_] -> return $ LApp f args'
71− [] -> fail $ "Codegen error: No such variable " ++ show f
72− sc env (LCase e alts)
73− = do e' <- sc env e
74− alts' <- mapM (scalt env) alts
75− return (LCase e' alts')
76− sc env (LLet n v e)
77− = do v' <- sc env v
78− e' <- sc (env ++ [(n, length env)]) e
79− return (LLet n v' e')
80− sc env (LOp prim args)
81− = do args' <- mapM (sc env) args
82− return (LOp prim args')
83− sc env x = return x
84−
85− scalt env (LConCase i n args e)
86− = do let env' = env ++ zip args [length env..]
87− tag <- case lookupCtxt Nothing n ctxt of
88− [LConstructor _ i ar] ->
89− if (length args == ar) then return i
90− else fail $ "Codegen error: Constructor " ++ show n ++
91− " has arity " ++ show ar
92− _ -> fail $ "Codegen error: No constructor " ++ show n
93− e' <- sc env' e
94− return (LConCase tag n args e')
95− scalt env (LConstCase c e) = do e' <- sc env e
96− return (LConstCase c e')
97− scalt env (LDefaultCase e) = do e' <- sc env e
98− return (LDefaultCase e')
99−
src/IRTS/Simplified.hsnew file+129
@@ -0,0 +1,129 @@
1+module IRTS.Simplified where
2+
3+import IRTS.Lang
4+import Core.TT
5+import Data.Maybe
6+import Control.Monad.State
7+
8+-- Simplified expressions, where functions/constructors can only be applied
9+-- to variables
10+
11+data SExp = SV LVar
12+ | SApp Bool Name [LVar]
13+ | SLet Name SExp SExp
14+ | SCon Int Name [LVar]
15+ | SCase LVar [SAlt]
16+ | SConst Const
17+ | SOp PrimFn [LVar]
18+ deriving Show
19+
20+data SAlt = SConCase Int Name [Name] SExp
21+ | SConstCase Const SExp
22+ | SDefaultCase SExp
23+ deriving Show
24+
25+data SDecl = SFun Name [Name] SExp
26+ deriving Show
27+
28+hvar :: State Int Int
29+hvar = do h <- get
30+ put (h + 1)
31+ return h
32+
33+simplify :: LExp -> State Int SExp
34+simplify (LV (Loc i)) = return (SV (Loc i))
35+simplify (LV x) = return (SV x)
36+simplify (LApp tc n args) = do args' <- mapM sVar args
37+ mkapp (SApp tc n) args'
38+simplify (LLet n v e) = do v' <- simplify v
39+ e' <- simplify e
40+ return (SLet n v' e')
41+simplify (LCon i n args) = do args' <- mapM sVar args
42+ mkapp (SCon i n) args'
43+simplify (LCase e alts) = do v <- sVar e
44+ alts' <- mapM sAlt alts
45+ case v of
46+ (x, Nothing) -> return (SCase x alts')
47+ (Glob x, Just e) ->
48+ return (SLet x e (SCase (Glob x) alts'))
49+simplify (LConst c) = return (SConst c)
50+simplify (LOp p args) = do args' <- mapM sVar args
51+ mkapp (SOp p) args'
52+
53+sVar (LV x) = return (x, Nothing)
54+sVar e = do e' <- simplify e
55+ i <- hvar
56+ return (Glob (MN i "R"), Just e')
57+
58+mkapp f args = mkapp' f args [] where
59+ mkapp' f [] args = return $ f (reverse args)
60+ mkapp' f ((x, Nothing) : xs) args = mkapp' f xs (x : args)
61+ mkapp' f ((Glob x, Just e) : xs) args
62+ = do sc <- mkapp' f xs (Glob x : args)
63+ return (SLet x e sc)
64+
65+sAlt (LConCase i n args e) = do e' <- simplify e
66+ return (SConCase i n args e')
67+sAlt (LConstCase c e) = do e' <- simplify e
68+ return (SConstCase c e')
69+sAlt (LDefaultCase e) = do e' <- simplify e
70+ return (SDefaultCase e')
71+
72+checkDefs :: LDefs -> [(Name, LDecl)] -> TC [(Name, SDecl)]
73+checkDefs ctxt [] = return []
74+checkDefs ctxt (con@(n, LConstructor _ _ _) : xs)
75+ = do xs' <- checkDefs ctxt xs
76+ return xs'
77+checkDefs ctxt ((n, LFun n' args exp) : xs)
78+ = do let sexp = evalState (simplify exp) 0
79+ exp' <- scopecheck ctxt (zip args [0..]) sexp
80+ xs' <- checkDefs ctxt xs
81+ return ((n, SFun n' args exp') : xs')
82+
83+scopecheck :: LDefs -> [(Name, Int)] -> SExp -> TC SExp
84+scopecheck ctxt env tm = sc env tm where
85+ sc env (SV (Glob n))
86+ = case lookup n (reverse env) of -- most recent first
87+ Just i -> return (SV (Loc i))
88+ Nothing -> case lookupCtxt Nothing n ctxt of
89+ [LConstructor _ i ar] ->
90+ if ar == 0 then return (SCon i n [])
91+ else fail $ "Codegen error: Constructor " ++ show n ++
92+ " has arity " ++ show ar
93+ [_] -> return (SV (Glob n))
94+ [] -> fail $ "Codegen error: No such variable " ++ show n
95+ sc env (SApp tc f args)
96+ = do case lookupCtxt Nothing f ctxt of
97+ [LConstructor n tag ar] ->
98+ if (ar == length args)
99+ then return $ SCon tag n args
100+ else fail $ "Codegen error: Constructor " ++ show f ++
101+ " has arity " ++ show ar
102+ [_] -> return $ SApp tc f args
103+ [] -> fail $ "Codegen error: No such variable " ++ show f
104+ sc env (SCase e alts)
105+ = do alts' <- mapM (scalt env) alts
106+ return (SCase e alts')
107+ sc env (SLet n v e)
108+ = do v' <- sc env v
109+ e' <- sc (env ++ [(n, length env)]) e
110+ return (SLet n v' e')
111+ sc env (SOp prim args)
112+ = do return (SOp prim args)
113+ sc env x = return x
114+
115+ scalt env (SConCase i n args e)
116+ = do let env' = env ++ zip args [length env..]
117+ tag <- case lookupCtxt Nothing n ctxt of
118+ [LConstructor _ i ar] ->
119+ if (length args == ar) then return i
120+ else fail $ "Codegen error: Constructor " ++ show n ++
121+ " has arity " ++ show ar
122+ _ -> fail $ "Codegen error: No constructor " ++ show n
123+ e' <- sc env' e
124+ return (SConCase tag n args e')
125+ scalt env (SConstCase c e) = do e' <- sc env e
126+ return (SConstCase c e')
127+ scalt env (SDefaultCase e) = do e' <- sc env e
128+ return (SDefaultCase e')
129+