Unreachable branhces are removed, fixed a nasty bug in monomorphizer 😸
This commit is contained in:
parent
46a4d3d252
commit
3729278041
4 changed files with 68 additions and 16 deletions
11
sample-programs/bubble-sort.chrf
Normal file
11
sample-programs/bubble-sort.chrf
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
data List (a) where
|
||||||
|
Cons : a -> List (a) -> List (a)
|
||||||
|
Nil : List (a)
|
||||||
|
|
||||||
|
bubblesort : List (a) -> List (a)
|
||||||
|
bubblesort xs = case xs of
|
||||||
|
Nil => Nil
|
||||||
|
Cons x => case x of
|
||||||
|
Nil => Cons x Nil
|
||||||
|
Cons y =>
|
||||||
|
|
||||||
23
sample-programs/insertion-sort.chrf
Normal file
23
sample-programs/insertion-sort.chrf
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
data List (a) where
|
||||||
|
Nil : List (a)
|
||||||
|
Cons : a -> List (a) -> List (a)
|
||||||
|
|
||||||
|
insert : Int -> List (Int) -> List (Int)
|
||||||
|
insert x xs = case xs of
|
||||||
|
Cons z zs => case (lt x z) of
|
||||||
|
True => Cons x (Cons z zs)
|
||||||
|
False => Cons z (insert x zs)
|
||||||
|
Nil => Cons x Nil
|
||||||
|
|
||||||
|
insertionSort : List (Int) -> List (Int)
|
||||||
|
insertionSort xs = case xs of
|
||||||
|
Cons y ys => case ys of
|
||||||
|
_ => insert y (insertionSort ys)
|
||||||
|
Nil => xs
|
||||||
|
Nil => Nil
|
||||||
|
|
||||||
|
main = head (insertionSort (Cons 5 (Cons 4 (Cons 3 (Cons 2 (Cons 1 Nil))))))
|
||||||
|
|
||||||
|
head xs = case xs of
|
||||||
|
Cons x _ => x
|
||||||
|
|
||||||
|
|
@ -5,6 +5,9 @@ data Either(a b) where
|
||||||
unwrapLeft x = case x of
|
unwrapLeft x = case x of
|
||||||
Left y => y
|
Left y => y
|
||||||
|
|
||||||
|
unwrapRight x = case x of
|
||||||
|
Right y => y
|
||||||
|
|
||||||
wow = Left 5
|
wow = Left 5
|
||||||
|
|
||||||
main = unwrapLeft wow
|
main = unwrapLeft wow
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ import Control.Monad.State (
|
||||||
)
|
)
|
||||||
import Data.Coerce (coerce)
|
import Data.Coerce (coerce)
|
||||||
import Data.Map qualified as Map
|
import Data.Map qualified as Map
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromJust, catMaybes)
|
||||||
import Data.Set qualified as Set
|
import Data.Set qualified as Set
|
||||||
import Debug.Trace
|
import Debug.Trace
|
||||||
import Grammar.Print (printTree)
|
import Grammar.Print (printTree)
|
||||||
|
|
@ -102,6 +102,10 @@ markBind ident = modify (Map.insert ident Marked)
|
||||||
isBindMarked :: Ident -> EnvM Bool
|
isBindMarked :: Ident -> EnvM Bool
|
||||||
isBindMarked ident = gets (Map.member ident)
|
isBindMarked ident = gets (Map.member ident)
|
||||||
|
|
||||||
|
-- | Checks if constructor is outputted.
|
||||||
|
isConsMarked :: Ident -> EnvM Bool
|
||||||
|
isConsMarked ident = gets (Map.member ident)
|
||||||
|
|
||||||
-- | Finds main bind.
|
-- | Finds main bind.
|
||||||
getMain :: EnvM T.Bind
|
getMain :: EnvM T.Bind
|
||||||
getMain = asks (\env -> case Map.lookup (T.Ident "main") (input env) of
|
getMain = asks (\env -> case Map.lookup (T.Ident "main") (input env) of
|
||||||
|
|
@ -228,7 +232,7 @@ morphExp expectedType exp = case exp of
|
||||||
t' <- getMonoFromPoly t
|
t' <- getMonoFromPoly t
|
||||||
bs' <- mapM morphBranch bs
|
bs' <- mapM morphBranch bs
|
||||||
exp' <- morphExp t' exp
|
exp' <- morphExp t' exp
|
||||||
return $ M.ECase (exp', t') bs'
|
return $ M.ECase (exp', t') (catMaybes bs')
|
||||||
T.EVar ident -> do
|
T.EVar ident -> do
|
||||||
isLocal <- localExists ident
|
isLocal <- localExists ident
|
||||||
if isLocal
|
if isLocal
|
||||||
|
|
@ -248,28 +252,39 @@ morphExp expectedType exp = case exp of
|
||||||
T.ELet (T.Bind{}) _ -> error "lets not possible yet"
|
T.ELet (T.Bind{}) _ -> error "lets not possible yet"
|
||||||
|
|
||||||
-- | Monomorphizes case-of branches.
|
-- | Monomorphizes case-of branches.
|
||||||
morphBranch :: T.Branch -> EnvM M.Branch
|
morphBranch :: T.Branch -> EnvM (Maybe M.Branch)
|
||||||
morphBranch (T.Branch (p, pt) (e, et)) = do
|
morphBranch (T.Branch (p, pt) (e, et)) = do
|
||||||
pt' <- getMonoFromPoly pt
|
pt' <- getMonoFromPoly pt
|
||||||
et' <- getMonoFromPoly et
|
et' <- getMonoFromPoly et
|
||||||
env <- ask
|
env <- ask
|
||||||
(p', newLocals) <- morphPattern p pt'
|
maybeMorphedPattern <- morphPattern p pt'
|
||||||
|
case maybeMorphedPattern of
|
||||||
|
Nothing -> return Nothing
|
||||||
|
Just (p', newLocals) ->
|
||||||
local (const env { locals = Set.union (locals env) newLocals }) $ do
|
local (const env { locals = Set.union (locals env) newLocals }) $ do
|
||||||
e' <- morphExp et' e
|
e' <- morphExp et' e
|
||||||
return $ M.Branch (p', pt') (e', et')
|
return $ Just (M.Branch (p', pt') (e', et'))
|
||||||
|
|
||||||
morphPattern :: T.Pattern -> M.Type -> EnvM (M.Pattern, Set.Set Ident)
|
morphPattern :: T.Pattern -> M.Type -> EnvM (Maybe (M.Pattern, Set.Set Ident))
|
||||||
morphPattern p expectedType = case p of
|
morphPattern p expectedType = case p of
|
||||||
T.PVar ident -> return (M.PVar (ident, expectedType), Set.singleton ident)
|
T.PVar ident -> return $ Just (M.PVar (ident, expectedType), Set.singleton ident)
|
||||||
T.PLit lit -> return (M.PLit (convertLit lit, expectedType), Set.empty)
|
T.PLit lit -> return $ Just (M.PLit (convertLit lit, expectedType), Set.empty)
|
||||||
T.PCatch -> return (M.PCatch, Set.empty)
|
T.PCatch -> return $ Just (M.PCatch, Set.empty)
|
||||||
T.PEnum ident -> do --morphCons expectedType ident
|
T.PEnum ident -> do --morphCons expectedType ident
|
||||||
return (M.PEnum ident, Set.empty)
|
return $ Just (M.PEnum ident, Set.empty)
|
||||||
T.PInj ident pts -> do --morphCons expectedType ident
|
T.PInj ident pts -> do --morphCons expectedType ident
|
||||||
|
isMarked <- isConsMarked ident
|
||||||
|
if isMarked
|
||||||
|
then do
|
||||||
ts' <- mapM (getMonoFromPoly . snd) pts
|
ts' <- mapM (getMonoFromPoly . snd) pts
|
||||||
let pts' = zip (map fst pts) ts'
|
let pts' = zip (map fst pts) ts'
|
||||||
psSets <- mapM (uncurry morphPattern) pts'
|
psSets <- mapM (uncurry morphPattern) pts'
|
||||||
return (M.PInj ident (map fst psSets), Set.unions $ map snd psSets)
|
let maybePsSets = sequence psSets
|
||||||
|
case maybePsSets of
|
||||||
|
Nothing -> return Nothing
|
||||||
|
Just psSets' -> return $ Just
|
||||||
|
(M.PInj ident (map fst psSets'), Set.unions $ map snd psSets')
|
||||||
|
else return Nothing
|
||||||
|
|
||||||
-- | Creates a new identifier for a function with an assigned type.
|
-- | Creates a new identifier for a function with an assigned type.
|
||||||
newFuncName :: M.Type -> T.Bind -> Ident
|
newFuncName :: M.Type -> T.Bind -> Ident
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue