Remade the algorithm myself. Still some bugs.
This commit is contained in:
parent
f188cffb8d
commit
8b5cd3cf9a
12 changed files with 584 additions and 257 deletions
|
|
@ -38,7 +38,7 @@ renamePrg (Old.Program xs) = do
|
|||
return $ RProgram xs'
|
||||
|
||||
renameBind :: Old.Bind -> Rename RBind
|
||||
renameBind (Old.Bind i args e) = do
|
||||
renameBind (Old.Bind n t i args e) = do
|
||||
insertSig i
|
||||
e' <- renameExp (makeLambda (reverse args) e)
|
||||
return $ RBind i e'
|
||||
|
|
@ -53,12 +53,12 @@ renameExp = \case
|
|||
Old.EId i -> do
|
||||
st <- get
|
||||
case M.lookup i st.env of
|
||||
Just n -> return $ RBound n i
|
||||
Just n -> return $ RId i
|
||||
Nothing -> case S.member i st.sig of
|
||||
True -> return $ RFree i
|
||||
True -> return $ RId i
|
||||
False -> throwError $ UnboundVar (show i)
|
||||
|
||||
Old.EConst c -> return $ RConst c
|
||||
Old.EInt c -> return $ RInt c
|
||||
|
||||
Old.EAnn e t -> flip RAnn t <$> renameExp e
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,12 @@ module Renamer.RenamerIr (
|
|||
RExp (..),
|
||||
RBind (..),
|
||||
RProgram (..),
|
||||
Const (..),
|
||||
Ident (..),
|
||||
Type (..),
|
||||
) where
|
||||
|
||||
import Grammar.Abs (
|
||||
Bind (..),
|
||||
Const (..),
|
||||
Ident (..),
|
||||
Program (..),
|
||||
Type (..),
|
||||
|
|
@ -26,35 +24,9 @@ data RBind = RBind Ident RExp
|
|||
|
||||
data RExp
|
||||
= RAnn RExp Type
|
||||
| RBound Integer Ident
|
||||
| RFree Ident
|
||||
| RConst Const
|
||||
| RId Ident
|
||||
| RInt Integer
|
||||
| RApp RExp RExp
|
||||
| RAdd RExp RExp
|
||||
| RAbs Integer Ident RExp
|
||||
deriving (Eq, Ord, Show, Read)
|
||||
|
||||
instance Print RProgram where
|
||||
prt i = \case
|
||||
RProgram defs -> prPrec i 0 (concatD [prt 0 defs])
|
||||
|
||||
instance Print RBind where
|
||||
prt i = \case
|
||||
RBind x e ->
|
||||
prPrec i 0 $
|
||||
concatD
|
||||
[ prt 0 x
|
||||
, doc (showString "=")
|
||||
, prt 0 e
|
||||
, doc (showString "\n")
|
||||
]
|
||||
|
||||
instance Print RExp where
|
||||
prt i = \case
|
||||
RAnn e t -> prPrec i 2 (concatD [prt 0 e, doc (showString ":"), prt 1 t])
|
||||
RBound n _ -> prPrec i 3 (concatD [prt 0 n])
|
||||
RFree id -> prPrec i 3 (concatD [prt 0 id])
|
||||
RConst n -> prPrec i 3 (concatD [prt 0 n])
|
||||
RApp e e1 -> prPrec i 2 (concatD [prt 2 e, prt 3 e1])
|
||||
RAdd e e1 -> prPrec i 1 (concatD [prt 1 e, doc (showString "+"), prt 2 e1])
|
||||
RAbs u _ e -> prPrec i 0 (concatD [doc (showString "λ"), prt 0 u, doc (showString "."), prt 0 e])
|
||||
|
|
|
|||
83
src/Renamer/RenamerM.hs
Normal file
83
src/Renamer/RenamerM.hs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
{-# LANGUAGE LambdaCase #-}
|
||||
|
||||
module Renamer.RenamerM where
|
||||
|
||||
import Auxiliary (mapAccumM)
|
||||
import Control.Monad.State (MonadState, State, evalState, gets,
|
||||
modify)
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Tuple.Extra (dupe)
|
||||
import Grammar.Abs
|
||||
|
||||
|
||||
-- | Rename all variables and local binds
|
||||
rename :: Program -> Program
|
||||
rename (Program bs) = Program $ evalState (runRn $ mapM (renameSc initNames) bs) 0
|
||||
where
|
||||
initNames = Map.fromList $ map (\(Bind name _ _ _ _) -> dupe name) bs
|
||||
renameSc :: Names -> Bind -> Rn Bind
|
||||
renameSc old_names (Bind name t _ parms rhs) = do
|
||||
(new_names, parms') <- newNames old_names parms
|
||||
rhs' <- snd <$> renameExp new_names rhs
|
||||
pure $ Bind name t name parms' rhs'
|
||||
|
||||
|
||||
-- | Rename monad. State holds the number of renamed names.
|
||||
newtype Rn a = Rn { runRn :: State Int a }
|
||||
deriving (Functor, Applicative, Monad, MonadState Int)
|
||||
|
||||
-- | Maps old to new name
|
||||
type Names = Map Ident Ident
|
||||
|
||||
renameLocalBind :: Names -> Bind -> Rn (Names, Bind)
|
||||
renameLocalBind old_names (Bind name t _ parms rhs) = do
|
||||
(new_names, name') <- newName old_names name
|
||||
(new_names', parms') <- newNames new_names parms
|
||||
(new_names'', rhs') <- renameExp new_names' rhs
|
||||
pure (new_names'', Bind name' t name' parms' rhs')
|
||||
|
||||
renameExp :: Names -> Exp -> Rn (Names, Exp)
|
||||
renameExp old_names = \case
|
||||
EId n -> pure (old_names, EId . fromMaybe n $ Map.lookup n old_names)
|
||||
|
||||
EInt i1 -> pure (old_names, EInt i1)
|
||||
|
||||
EApp e1 e2 -> do
|
||||
(env1, e1') <- renameExp old_names e1
|
||||
(env2, e2') <- renameExp old_names e2
|
||||
pure (Map.union env1 env2, EApp e1' e2')
|
||||
|
||||
EAdd e1 e2 -> do
|
||||
(env1, e1') <- renameExp old_names e1
|
||||
(env2, e2') <- renameExp old_names e2
|
||||
pure (Map.union env1 env2, EAdd e1' e2')
|
||||
|
||||
ELet i e1 e2 -> do
|
||||
(new_names, e1') <- renameExp old_names e1
|
||||
(new_names', e2') <- renameExp new_names e2
|
||||
pure (new_names', ELet i e1' e2')
|
||||
|
||||
EAbs par e -> do
|
||||
(new_names, par') <- newName old_names par
|
||||
(new_names', e') <- renameExp new_names e
|
||||
pure (new_names', EAbs par' e')
|
||||
|
||||
EAnn e t -> do
|
||||
(new_names, e') <- renameExp old_names e
|
||||
pure (new_names, EAnn e' t)
|
||||
|
||||
-- | Create a new name and add it to name environment.
|
||||
newName :: Names -> Ident -> Rn (Names, Ident)
|
||||
newName env old_name = do
|
||||
new_name <- makeName old_name
|
||||
pure (Map.insert old_name new_name env, new_name)
|
||||
|
||||
-- | Create multiple names and add them to the name environment
|
||||
newNames :: Names -> [Ident] -> Rn (Names, [Ident])
|
||||
newNames = mapAccumM newName
|
||||
|
||||
-- | Annotate name with number and increment the number @prefix ⇒ prefix_number@.
|
||||
makeName :: Ident -> Rn Ident
|
||||
makeName (Ident prefix) = gets (\i -> Ident $ prefix ++ "_" ++ show i) <* modify succ
|
||||
Loading…
Add table
Add a link
Reference in a new issue