Remade the algorithm myself. Still some bugs.

This commit is contained in:
sebastianselander 2023-02-18 23:08:27 +01:00
parent f188cffb8d
commit 8b5cd3cf9a
12 changed files with 584 additions and 257 deletions

View file

@ -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

View file

@ -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
View 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