@@ -13,10 +13,12 @@ type Tag = Int
13type Arity = Int
13type Arity = Int
15data SCDef = SCDef { sc_args :: [(Name, CType)],
15data SCDef = SCDef { sc_args :: [(Name, CType)],
16 sc_def :: SCExp }
17 sc_def :: SCExp }
17 deriving Show
18 deriving Show
19data SCExp = SRef Name
20data SCExp = SRef Name
21+ | SLoc Int -- de Bruijn level
20 | SApp SCExp [SCExp]
22 | SApp SCExp [SCExp]
21 | SLazyApp Name [SCExp]
23 | SLazyApp Name [SCExp]
22 | SLet Name SCExp SCExp
24 | SLet Name SCExp SCExp
@@ -24,7 +26,7 @@ data SCExp = SRef Name
24 | SCon Tag [SCExp] -- constructor, assume saturated (forcing does this)
26 | SCon Tag [SCExp] -- constructor, assume saturated (forcing does this)
25 | SConst Const
27 | SConst Const
26 | SError String
28 | SError String
27− | SCase Name [SAlt]
29+ | SCase SCExp [SAlt]
28 | SPrimOp SPrim [SCExp]
30 | SPrimOp SPrim [SCExp]
29 deriving Show
31 deriving Show
@@ -71,14 +73,17 @@ toSC prims (n, d)
71 Nothing -> sclift (n, d)
73 Nothing -> sclift (n, d)
72 Just (args, rt, op) ->
74 Just (args, rt, op) ->
73 let anames = zipWith mkA args [0..] in
75 let anames = zipWith mkA args [0..] in
76+ [(n, SCDef anames (length anames)
74− [(n, SCDef anames (SPrimOp op (map (SRef . fst) anames)))]
77+ (SPrimOp op (map (SRef . fst) anames)))]
75 where mkA t i = (MN i "primArg", t)
78 where mkA t i = (MN i "primArg", t)
77sclift :: (Name, Def) -> [(Name, SCDef)]
80sclift :: (Name, Def) -> [(Name, SCDef)]
78sclift (n, d) = fst (execState (sc [] d) ([], n))
81sclift (n, d) = fst (execState (sc [] d) ([], n))
83+add (n, SCDef args _ def)
80−add x = do (xs, b) <- get
84+ = do (xs, b) <- get
81− put (x : xs, b)
85+ let (def', maxloc) = dbl (map fst args) def
86+ put ((n, SCDef args maxloc def') : xs, b)
83nextSC :: State SCState Name
88nextSC :: State SCState Name
84nextSC = do (xs, n) <- get
89nextSC = do (xs, n) <- get
@@ -99,15 +104,15 @@ class Lift s t | s -> t where
99instance Lift Def () where
104instance Lift Def () where
100 sc env (Function ty tm) = do n <- sname
105 sc env (Function ty tm) = do n <- sname
101 tm' <- sc env tm
106 tm' <- sc env tm
102− add (n, SCDef (zip env (repeat Nothing)) tm')
107+ add (n, SCDef (zip env (repeat Nothing)) 0 tm')
103 sc env (TyDecl _ _) = do n <- sname
108 sc env (TyDecl _ _) = do n <- sname
104− add (n, SCDef (zip env (repeat Nothing))
109+ add (n, SCDef (zip env (repeat Nothing)) 0
105 (SError $ "undefined " ++ show n))
110 (SError $ "undefined " ++ show n))
106 sc env (Operator _ _ _) = return ()
111 sc env (Operator _ _ _) = return ()
107 sc env (CaseOp _ _ _ _ _ args cases)
112 sc env (CaseOp _ _ _ _ _ args cases)
108 = do n <- sname
113 = do n <- sname
109 cases' <- sc (env ++ args) cases
114 cases' <- sc (env ++ args) cases
110− add (n, SCDef (zip (env ++ args) (repeat Nothing)) cases')
115+ add (n, SCDef (zip (env ++ args) (repeat Nothing)) 0 cases')
112instance Lift (TT Name) SCExp where
117instance Lift (TT Name) SCExp where
113 sc env (P _ n _) = return $ SRef n
118 sc env (P _ n _) = return $ SRef n
@@ -132,14 +137,14 @@ instance Lift (TT Name) SCExp where
132 scLam args (Bind n (Lam _) e) = scLam (n : args) e
137 scLam args (Bind n (Lam _) e) = scLam (n : args) e
133 scLam args x = do x' <- sc (args ++ env) x
138 scLam args x = do x' <- sc (args ++ env) x
134 fn <- nextSC
139 fn <- nextSC
135− add (fn, SCDef (zip (env ++ reverse args) (repeat Nothing)) x')
140+ add (fn, SCDef (zip (env ++ reverse args) (repeat Nothing)) 0 x')
136 return $ SApp (SRef fn) (map SRef env)
141 return $ SApp (SRef fn) (map SRef env)
137 sc _ _ = return $ SConst (I 42424242)
142 sc _ _ = return $ SConst (I 42424242)
140instance Lift SC SCExp where
145instance Lift SC SCExp where
141 sc env (Case n alts) = do alts' <- mapM (sc env) alts
146 sc env (Case n alts) = do alts' <- mapM (sc env) alts
142− return (SCase n alts')
147+ return (SCase (SRef n) alts')
143 sc env (STerm t) = do t' <- sc env t
148 sc env (STerm t) = do t' <- sc env t
144 return t'
149 return t'
145 sc env (UnmatchedCase s) = return (SError s)
150 sc env (UnmatchedCase s) = return (SError s)
@@ -160,7 +165,7 @@ sPrim env (P _ (UN "mkForeign") _) args = do x <- doForeign env args
160sPrim env (P _ (UN "lazy") _) [_, arg]
165sPrim env (P _ (UN "lazy") _) [_, arg]
161 = do arg' <- sc env arg
166 = do arg' <- sc env arg
162 fn <- nextSC
167 fn <- nextSC
163− add (fn, SCDef (zip env (repeat Nothing)) arg')
168+ add (fn, SCDef (zip env (repeat Nothing)) 0 arg')
164 return $ Just $ SLazyApp fn (map SRef env)
169 return $ Just $ SLazyApp fn (map SRef env)
165sPrim env (P _ (UN "prim__IO") _) [v] = do v' <- sc env v
170sPrim env (P _ (UN "prim__IO") _) [v] = do v' <- sc env v
166 return $ Just v'
171 return $ Just v'
@@ -195,3 +200,47 @@ mkEty "FString" = Just StrType
195mkEty "FPtr" = Just PtrType
200mkEty "FPtr" = Just PtrType
196mkEty "FUnit" = Just VoidType
201mkEty "FUnit" = Just VoidType
203+-- Convert local variable names to de Bruijn levels, return the biggest
205+dbl :: [Name] -> SCExp -> (SCExp, Int)
206+dbl ns exp = runState (db' (extends [] ns) exp) (length ns) where
207+ db' :: [(Name, Int)] -> SCExp -> State Int SCExp
208+ db' env (SRef n) = case lookup n env of
209+ Just i -> do ref i; return $ SLoc i
210+ Nothing -> return $ SRef n
211+ db' env (SApp f args) = do f' <- db' env f
212+ args' <- mapM (db' env) args
213+ return $ SApp f' args'
214+ db' env (SLazyApp n args) = do args' <- mapM (db' env) args
215+ return $ SLazyApp n args'
216+ db' env (SLet n v sc) = do v' <- db' env v
217+ sc' <- db' (extend env n) sc
218+ ref (length env + 1)
219+ return $ SLet n v' sc'
220+ db' env (SFCall n t args) = do args' <- mapM (\ (e,t) -> do e' <- db' env e
221+ return (e', t)) args
222+ return $ SFCall n t args'
223+ db' env (SCon t args) = do args' <- mapM (db' env) args
224+ return $ SCon t args'
225+ db' env (SCase n alts) = do n' <- db' env n
226+ alts' <- mapM (dbAlt env) alts
227+ return $ SCase n' alts'
228+ db' env (SPrimOp p args) = do args' <- mapM (db' env) args
229+ return $ SPrimOp p args'
230+ db' env x = return x
232+ dbAlt env (SConCase t ns exp) = do exp' <- db' (extends env ns) exp
233+ ref (length env + length ns)
234+ return $ SConCase t ns exp'
235+ dbAlt env (SConstCase c e) = do e' <- db' env e
236+ return $ SConstCase c e'
237+ dbAlt env (SDefaultCase e) = do e' <- db' env e
238+ return $ SDefaultCase e'
240+ extend env n = env ++ [(n, length env)]
241+ extends env [] = env
242+ extends env (n : ns) = extends (extend env n) ns
245+ when (i > s) $ put i