1
1
mirror of https://github.com/anoma/juvix.git synced 2025-01-04 21:51:35 +03:00

Remove type arguments and type abstractions from Nodes (#1655)

This commit is contained in:
Łukasz Czajka 2022-12-12 14:58:25 +01:00 committed by GitHub
parent 503f5279ba
commit d9b020ec27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 382 additions and 227 deletions

View File

@ -14,14 +14,21 @@ runCommand opts = do
(tab, mnode) <- getRight (mapLeft JuvixError (Core.runParser f Core.emptyInfoTable s'))
let tab' = Core.applyTransformations (project opts ^. coreReadTransformations) tab
embed (Scoper.scopeTrace tab')
unless (project opts ^. coreReadNoPrint) (renderStdOut (Core.ppOut opts tab'))
unless (project opts ^. coreReadNoPrint) $ do
renderStdOut (Core.ppOut opts tab')
whenJust mnode $ doEval tab'
where
doEval :: Core.InfoTable -> Core.Node -> Sem r ()
doEval tab' node = when (project opts ^. coreReadEval) $ do
embed (putStrLn "--------------------------------")
embed (putStrLn "| Eval |")
embed (putStrLn "--------------------------------")
Eval.evalAndPrint opts tab' node
doEval tab' node =
if
| project opts ^. coreReadEval -> do
embed (putStrLn "--------------------------------")
embed (putStrLn "| Eval |")
embed (putStrLn "--------------------------------")
Eval.evalAndPrint opts tab' node
| otherwise -> do
embed (putStrLn "-- Node")
renderStdOut (Core.ppOut opts node)
embed (putStrLn "")
f :: FilePath
f = project opts ^. coreReadInputFile . pathPath

View File

@ -41,7 +41,6 @@ data IdentifierInfo = IdentifierInfo
_identifierLocation :: Maybe Location,
_identifierSymbol :: Symbol,
_identifierType :: Type,
-- _identifierArgsNum will be used often enough to justify avoiding recomputation
_identifierArgsNum :: Int,
_identifierArgsInfo :: [ArgumentInfo],
_identifierIsExported :: Bool

View File

@ -5,5 +5,6 @@ import Juvix.Prelude
data TransformationId
= LambdaLifting
| TopEtaExpand
| RemoveTypeArgs
| Identity
deriving stock (Data)

View File

@ -44,6 +44,7 @@ pcompletions = do
LambdaLifting -> strLifting
TopEtaExpand -> strTopEtaExpand
Identity -> strIdentity
RemoveTypeArgs -> strRemoveTypeArgs
lexeme :: MonadParsec e Text m => m a -> m a
lexeme = L.lexeme L.hspace
@ -59,12 +60,14 @@ transformation =
symbol strLifting $> LambdaLifting
<|> symbol strIdentity $> Identity
<|> symbol strTopEtaExpand $> TopEtaExpand
<|> symbol strRemoveTypeArgs $> RemoveTypeArgs
allStrings :: [Text]
allStrings =
[ strLifting,
strTopEtaExpand,
strIdentity
strIdentity,
strRemoveTypeArgs
]
strLifting :: Text
@ -75,3 +78,6 @@ strTopEtaExpand = "top-eta-expand"
strIdentity :: Text
strIdentity = "identity"
strRemoveTypeArgs :: Text
strRemoveTypeArgs = "remove-type-args"

View File

@ -182,6 +182,11 @@ isDynamic = \case
NDyn {} -> True
_ -> False
isTypeConstr :: Type -> Bool
isTypeConstr ty = case typeTarget ty of
NUniv {} -> True
_ -> False
-- | `expandType argtys ty` expands the dynamic target of `ty` to match the
-- number of arguments with types specified by `argstys`. For example,
-- `expandType [int, string] (int -> any) = int -> string -> any`.

View File

@ -32,3 +32,13 @@ binderNumCollector' ini = Collector ini (\(k, _) c -> c + k)
binderNumCollector :: Collector (Int, [Binder]) Index
binderNumCollector = binderNumCollector' 0
pairCollector :: Collector a b -> Collector a c -> Collector a (b, c)
pairCollector coll1 coll2 =
Collector
{ _cEmpty = (coll1 ^. cEmpty, coll2 ^. cEmpty),
_cCollect = \a (b, c) -> ((coll1 ^. cCollect) a b, (coll2 ^. cCollect) a c)
}
identityCollector :: c -> Collector a c
identityCollector ini = Collector ini (const id)

View File

@ -9,10 +9,10 @@ import Juvix.Compiler.Core.Extra.Base
import Juvix.Compiler.Core.Extra.Recursors.Base
import Juvix.Compiler.Core.Extra.Recursors.Parameters
type DirTy :: Direction -> GHC.Type
type family DirTy d = res | res -> d where
DirTy 'TopDown = Recur
DirTy 'BottomUp = Node -- For bottom up maps we never recur on the children
type DirTy :: Direction -> GHC.Type -> GHC.Type
type family DirTy d c = res | res -> d where
DirTy 'TopDown c = Recur' c
DirTy 'BottomUp _ = Node -- For bottom up maps we never recur on the children
-- | `umapG` maps the nodes bottom-up, i.e., when invoking the mapper function the
-- recursive subnodes have already been mapped
@ -36,7 +36,7 @@ dmapG ::
forall c m.
Monad m =>
Collector (Int, [Binder]) c ->
(c -> Node -> m Recur) ->
(c -> Node -> m (Recur' c)) ->
Node ->
m Node
dmapG coll f = go (coll ^. cEmpty)
@ -45,170 +45,80 @@ dmapG coll f = go (coll ^. cEmpty)
go c n = do
r <- f c n
case r of
End n' -> return n'
Recur n' ->
End' n' -> return n'
Recur' (c', n') ->
let ni = destruct n'
in reassembleDetails ni <$> mapM goChild (ni ^. nodeChildren)
where
goChild :: NodeChild -> m Node
goChild ch = go ((coll ^. cCollect) (ch ^. childBindersNum, ch ^. childBinders) c) (ch ^. childNode)
where
goChild :: NodeChild -> m Node
goChild ch = go ((coll ^. cCollect) (ch ^. childBindersNum, ch ^. childBinders) c') (ch ^. childNode)
type CtxTy :: Ctx -> GHC.Type
type family CtxTy x = res | res -> x where
CtxTy 'CtxBinderList = BinderList Binder
CtxTy 'CtxBinderNum = Index
CtxTy 'CtxNone = ()
type RetTy :: (GHC.Type -> GHC.Type) -> Direction -> Monadic -> Ret -> GHC.Type
type family RetTy m dir mon r = res | res -> mon r where
RetTy m 'TopDown 'Monadic 'RetRecur = m Recur
RetTy m 'TopDown 'Monadic 'RetSimple = m Node
RetTy _ 'TopDown 'NonMonadic 'RetRecur = Recur
RetTy _ 'TopDown 'NonMonadic 'RetSimple = Node
RetTy m 'BottomUp 'Monadic 'RetSimple = m Node
RetTy _ 'BottomUp 'NonMonadic 'RetSimple = Node
type BodyTy :: (GHC.Type -> GHC.Type) -> Direction -> Monadic -> Ctx -> Ret -> GHC.Type
type family BodyTy m dir mon x r = res | res -> x r where
BodyTy m dir 'Monadic 'CtxBinderList r = BinderList Binder -> Node -> RetTy m dir 'Monadic r
BodyTy m dir 'Monadic 'CtxBinderNum r = Int -> Node -> RetTy m dir 'Monadic r
BodyTy m dir 'Monadic 'CtxNone r = Node -> RetTy m dir 'Monadic r
BodyTy _ dir 'NonMonadic 'CtxBinderList r = BinderList Binder -> Node -> RetTy Identity dir 'NonMonadic r
BodyTy _ dir 'NonMonadic 'CtxBinderNum r = Int -> Node -> RetTy Identity dir 'NonMonadic r
BodyTy _ dir 'NonMonadic 'CtxNone r = Node -> RetTy Identity dir 'NonMonadic r
type NodeMapArg :: (GHC.Type -> GHC.Type) -> Direction -> Monadic -> CollectorIni -> Ctx -> Ret -> GHC.Type
type family NodeMapArg m dir mon i x r = res | res -> i x r where
NodeMapArg m dir mon 'Ini x r = (CtxTy x, BodyTy m dir mon x r)
NodeMapArg m dir mon 'NoIni 'CtxBinderList r = BinderList Binder -> Node -> RetTy m dir mon r
NodeMapArg m dir mon 'NoIni 'CtxBinderNum r = Int -> Node -> RetTy m dir mon r
NodeMapArg m dir mon 'NoIni 'CtxNone r = Node -> RetTy m dir mon r
type NodeMapRet :: (GHC.Type -> GHC.Type) -> Monadic -> GHC.Type
type family NodeMapRet m mon = res | res -> mon m where
NodeMapRet m 'Monadic = m Node
NodeMapRet Identity 'NonMonadic = Node
type OverIdentity' :: GHC.Type -> GHC.Type
type family OverIdentity' t = res where
OverIdentity' (a -> b) = a -> OverIdentity' b
OverIdentity' leaf = Identity leaf
type OverIdentity :: GHC.Type -> GHC.Type
type family OverIdentity t = res where
OverIdentity (a -> b) = a -> OverIdentity b
OverIdentity ((), b) = ((), OverIdentity b)
OverIdentity (BinderList Binder, b) = (BinderList Binder, OverIdentity b)
OverIdentity (Index, b) = (Index, OverIdentity b)
OverIdentity leaf = Identity leaf
OverIdentity ((), b) = ((), OverIdentity' b)
OverIdentity (BinderList Binder, b) = (BinderList Binder, OverIdentity' b)
OverIdentity (Index, b) = (Index, OverIdentity' b)
OverIdentity leaf = OverIdentity' leaf
class EmbedIdentity a where
embedIden :: a -> OverIdentity a
instance EmbedIdentity b => EmbedIdentity (a -> b) where
embedIden f = embedIden . f
class EmbedIdentity' a where
embedIden' :: a -> OverIdentity' a
instance EmbedIdentity b => EmbedIdentity ((), b) where
embedIden (a, b) = (a, embedIden b)
instance EmbedIdentity' b => EmbedIdentity' (a -> b) where
embedIden' f = embedIden' . f
instance EmbedIdentity b => EmbedIdentity (Index, b) where
embedIden (a, b) = (a, embedIden b)
instance EmbedIdentity' b => EmbedIdentity ((), b) where
embedIden (a, b) = (a, embedIden' b)
instance EmbedIdentity b => EmbedIdentity (BinderList Binder, b) where
embedIden (a, b) = (a, embedIden b)
instance EmbedIdentity' b => EmbedIdentity (Index, b) where
embedIden (a, b) = (a, embedIden' b)
instance EmbedIdentity Node where
embedIden = Identity
instance EmbedIdentity' b => EmbedIdentity (BinderList Binder, b) where
embedIden (a, b) = (a, embedIden' b)
instance EmbedIdentity Recur where
embedIden = Identity
instance EmbedIdentity' b => EmbedIdentity (a -> b) where
embedIden a = embedIden' a
type KDefaultIdentity :: Monadic -> (GHC.Type -> GHC.Type) -> GHC.Constraint
type family KDefaultIdentity mon m = res | res -> m where
KDefaultIdentity 'Monadic m = m ~ m
KDefaultIdentity 'NonMonadic m = Identity ~ m
instance EmbedIdentity' (c, Node) where
embedIden' = Identity
type KCompatibleDir :: Direction -> Ret -> GHC.Constraint
type family KCompatibleDir dir r = res where
KCompatibleDir 'TopDown r = r ~ r
KCompatibleDir 'BottomUp r = r ~ 'RetSimple
instance EmbedIdentity' Node where
embedIden' = Identity
nodeMapE ::
forall (dir :: Direction) (mon :: Monadic) (i :: CollectorIni) (x :: Ctx) (r :: Ret) m.
( Monad m,
KDefaultIdentity mon m,
KCompatibleDir dir r
) =>
instance EmbedIdentity' Recur where
embedIden' = Identity
instance EmbedIdentity' (Recur' c) where
embedIden' = Identity
fromSimple :: Functor g => c -> g Node -> g (Recur' c)
fromSimple c = fmap (\x -> Recur' (c, x))
fromRecur :: Functor g => c -> g Recur -> g (Recur' c)
fromRecur c =
fmap
( \case
End x -> End' x
Recur x -> Recur' (c, x)
)
fromPair :: Functor g => d -> g (c, Node) -> g (Recur' (c, d))
fromPair d = fmap (\(c, x) -> Recur' ((c, d), x))
nodeMapG' ::
Monad m =>
Sing dir ->
Sing mon ->
Sing i ->
Sing x ->
Sing r ->
NodeMapArg m dir mon i x r ->
Collector (Int, [Binder]) c ->
(c -> Node -> m (DirTy dir c)) ->
Node ->
NodeMapRet m mon
nodeMapE sdir smon sini sctx sret f = case smon :: SMonadic mon of
SMonadic ->
case (sdir, sini, sctx, sret) of
(STopDown, SNoIni, SCtxBinderList, SRetSimple) -> nodeMapG' binderInfoCollector (\bi -> fromSimple . f bi)
(STopDown, SNoIni, SCtxBinderList, SRetRecur) -> nodeMapG' binderInfoCollector f
(STopDown, SNoIni, SCtxBinderNum, SRetSimple) -> nodeMapG' binderNumCollector (\bi -> fromSimple . f bi)
(STopDown, SNoIni, SCtxBinderNum, SRetRecur) -> nodeMapG' binderNumCollector f
(STopDown, SNoIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const (fromSimple . f))
(STopDown, SNoIni, SCtxNone, SRetRecur) -> nodeMapG' binderInfoCollector (const f)
(STopDown, SIni, SCtxBinderList, SRetSimple) -> nodeMapG' (binderInfoCollector' (fst f)) (\bi -> fromSimple . snd f bi)
(STopDown, SIni, SCtxBinderList, SRetRecur) -> nodeMapG' (binderInfoCollector' (fst f)) (snd f)
(STopDown, SIni, SCtxBinderNum, SRetSimple) -> nodeMapG' (binderNumCollector' (fst f)) (\bi -> fromSimple . snd f bi)
(STopDown, SIni, SCtxBinderNum, SRetRecur) -> nodeMapG' (binderNumCollector' (fst f)) (snd f)
(STopDown, SIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const (fromSimple . snd f))
(STopDown, SIni, SCtxNone, SRetRecur) -> nodeMapG' binderInfoCollector (const (snd f))
(SBottomUp, SNoIni, SCtxBinderList, SRetSimple) -> nodeMapG' binderInfoCollector f
(SBottomUp, SNoIni, SCtxBinderNum, SRetSimple) -> nodeMapG' binderNumCollector f
(SBottomUp, SNoIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const f)
(SBottomUp, SIni, SCtxBinderList, SRetSimple) -> nodeMapG' (binderInfoCollector' (fst f)) (snd f)
(SBottomUp, SIni, SCtxBinderNum, SRetSimple) -> nodeMapG' (binderNumCollector' (fst f)) (snd f)
(SBottomUp, SIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const (snd f))
SNonMonadic ->
runIdentity
. case (sdir, sini, sctx, sret) of
(STopDown, SNoIni, SCtxBinderList, SRetSimple) -> nodeMapG' binderInfoCollector (\bi -> fromSimple . embedIden f bi)
(STopDown, SNoIni, SCtxBinderList, SRetRecur) -> nodeMapG' binderInfoCollector (embedIden f)
(STopDown, SNoIni, SCtxBinderNum, SRetSimple) -> nodeMapG' binderNumCollector (\bi -> fromSimple . embedIden f bi)
(STopDown, SNoIni, SCtxBinderNum, SRetRecur) -> nodeMapG' binderNumCollector (embedIden f)
(STopDown, SNoIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const (fromSimple . embedIden f))
(STopDown, SNoIni, SCtxNone, SRetRecur) -> nodeMapG' binderInfoCollector (const (embedIden f))
(STopDown, SIni, SCtxBinderList, SRetSimple) -> nodeMapG' (binderInfoCollector' (fst f)) (\bi -> fromSimple . snd (embedIden f) bi)
(STopDown, SIni, SCtxBinderList, SRetRecur) -> nodeMapG' (binderInfoCollector' (fst f)) (snd (embedIden f))
(STopDown, SIni, SCtxBinderNum, SRetSimple) -> nodeMapG' (binderNumCollector' (fst f)) (\bi -> fromSimple . snd (embedIden f) bi)
(STopDown, SIni, SCtxBinderNum, SRetRecur) -> nodeMapG' (binderNumCollector' (fst f)) (snd (embedIden f))
(STopDown, SIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const (fromSimple . snd (embedIden f)))
(STopDown, SIni, SCtxNone, SRetRecur) -> nodeMapG' binderInfoCollector (const (snd (embedIden f)))
(SBottomUp, SNoIni, SCtxBinderList, SRetSimple) -> nodeMapG' binderInfoCollector (embedIden f)
(SBottomUp, SNoIni, SCtxBinderNum, SRetSimple) -> nodeMapG' binderNumCollector (embedIden f)
(SBottomUp, SNoIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const (embedIden f))
(SBottomUp, SIni, SCtxBinderList, SRetSimple) -> nodeMapG' (binderInfoCollector' (fst f)) (snd (embedIden f))
(SBottomUp, SIni, SCtxBinderNum, SRetSimple) -> nodeMapG' (binderNumCollector' (fst f)) (snd (embedIden f))
(SBottomUp, SIni, SCtxNone, SRetSimple) -> nodeMapG' binderInfoCollector (const (snd (embedIden f)))
where
fromSimple :: forall g. Functor g => g Node -> g Recur
fromSimple = fmap Recur
nodeMapG' ::
Collector (Int, [Binder]) c ->
(c -> Node -> m (DirTy dir)) ->
Node ->
m Node
nodeMapG' = case sdir of
STopDown -> dmapG
SBottomUp -> umapG
-- | Implicit version of dmapE
nodeMapI ::
forall (dir :: Direction) (mon :: Monadic) (i :: CollectorIni) (x :: Ctx) (r :: Ret) m.
( SingI mon,
SingI i,
SingI x,
SingI r,
Monad m,
KDefaultIdentity mon m,
KCompatibleDir dir r
) =>
Sing dir ->
NodeMapArg m dir mon i x r ->
Node ->
NodeMapRet m mon
nodeMapI dir = nodeMapE dir sing sing sing sing
m Node
nodeMapG' sdir = case sdir of
STopDown -> dmapG
SBottomUp -> umapG

View File

@ -1,95 +1,114 @@
module Juvix.Compiler.Core.Extra.Recursors.Map.Named where
import Data.Functor.Identity
import Juvix.Compiler.Core.Extra.Recursors.Base
import Juvix.Compiler.Core.Extra.Recursors.Map
import Juvix.Compiler.Core.Extra.Recursors.Parameters
dmapLRM :: Monad m => (BinderList Binder -> Node -> m Recur) -> Node -> m Node
dmapLRM = nodeMapI STopDown
dmapLRM f = nodeMapG' STopDown binderInfoCollector (\bi -> fromRecur bi . f bi)
dmapLM :: Monad m => (BinderList Binder -> Node -> m Node) -> Node -> m Node
dmapLM = nodeMapI STopDown
dmapLM f = nodeMapG' STopDown binderInfoCollector (\bi -> fromSimple bi . f bi)
umapLM :: Monad m => (BinderList Binder -> Node -> m Node) -> Node -> m Node
umapLM = nodeMapI SBottomUp
umapLM f = nodeMapG' SBottomUp binderInfoCollector f
dmapNRM :: Monad m => (Index -> Node -> m Recur) -> Node -> m Node
dmapNRM = nodeMapI STopDown
dmapNRM f = nodeMapG' STopDown binderNumCollector (\bi -> fromRecur bi . f bi)
dmapNM :: Monad m => (Index -> Node -> m Node) -> Node -> m Node
dmapNM = nodeMapI STopDown
dmapNM f = nodeMapG' STopDown binderNumCollector (\bi -> fromSimple bi . f bi)
umapNM :: Monad m => (Index -> Node -> m Node) -> Node -> m Node
umapNM = nodeMapI STopDown
umapNM f = nodeMapG' SBottomUp binderNumCollector f
dmapRM :: Monad m => (Node -> m Recur) -> Node -> m Node
dmapRM = nodeMapI STopDown
dmapRM f = nodeMapG' STopDown unitCollector (const (fromRecur mempty . f))
dmapM :: Monad m => (Node -> m Node) -> Node -> m Node
dmapM = nodeMapI STopDown
dmapM f = nodeMapG' STopDown unitCollector (const (fromSimple mempty . f))
umapM :: Monad m => (Node -> m Node) -> Node -> m Node
umapM = nodeMapI SBottomUp
umapM f = nodeMapG' SBottomUp unitCollector (const f)
dmapLRM' :: Monad m => (BinderList Binder, BinderList Binder -> Node -> m Recur) -> Node -> m Node
dmapLRM' = nodeMapI STopDown
dmapLRM' f = nodeMapG' STopDown (binderInfoCollector' (fst f)) (\bi -> fromRecur bi . snd f bi)
dmapLM' :: Monad m => (BinderList Binder, BinderList Binder -> Node -> m Node) -> Node -> m Node
dmapLM' = nodeMapI STopDown
dmapLM' f = nodeMapG' STopDown (binderInfoCollector' (fst f)) (\bi -> fromSimple bi . snd f bi)
umapLM' :: Monad m => (BinderList Binder, BinderList Binder -> Node -> m Node) -> Node -> m Node
umapLM' = nodeMapI SBottomUp
umapLM' f = nodeMapG' SBottomUp (binderInfoCollector' (fst f)) (snd f)
dmapNRM' :: Monad m => (Index, Index -> Node -> m Recur) -> Node -> m Node
dmapNRM' = nodeMapI STopDown
dmapNRM' f = nodeMapG' STopDown (binderNumCollector' (fst f)) (\bi -> fromRecur bi . snd f bi)
dmapNM' :: Monad m => (Index, Index -> Node -> m Node) -> Node -> m Node
dmapNM' = nodeMapI STopDown
dmapNM' f = nodeMapG' STopDown (binderNumCollector' (fst f)) (\bi -> fromSimple bi . snd f bi)
umapNM' :: Monad m => (Index, Index -> Node -> m Node) -> Node -> m Node
umapNM' = nodeMapI SBottomUp
umapNM' f = nodeMapG' SBottomUp (binderNumCollector' (fst f)) (snd f)
dmapLR :: (BinderList Binder -> Node -> Recur) -> Node -> Node
dmapLR = nodeMapI STopDown
dmapLR f = runIdentity . dmapLRM (embedIden f)
dmapL :: (BinderList Binder -> Node -> Node) -> Node -> Node
dmapL = nodeMapI STopDown
dmapL f = runIdentity . dmapLM (embedIden f)
umapL :: (BinderList Binder -> Node -> Node) -> Node -> Node
umapL = nodeMapI SBottomUp
umapL f = runIdentity . umapLM (embedIden f)
dmapNR :: (Index -> Node -> Recur) -> Node -> Node
dmapNR = nodeMapI STopDown
dmapNR f = runIdentity . dmapNRM (embedIden f)
dmapN :: (Index -> Node -> Node) -> Node -> Node
dmapN = nodeMapI STopDown
dmapN f = runIdentity . dmapNM (embedIden f)
umapN :: (Index -> Node -> Node) -> Node -> Node
umapN = nodeMapI SBottomUp
umapN f = runIdentity . umapNM (embedIden f)
dmapR :: (Node -> Recur) -> Node -> Node
dmapR = nodeMapI STopDown
dmapR f = runIdentity . dmapRM (embedIden f)
dmap :: (Node -> Node) -> Node -> Node
dmap = nodeMapI STopDown
dmap f = runIdentity . dmapM (embedIden f)
umap :: (Node -> Node) -> Node -> Node
umap = nodeMapI SBottomUp
umap f = runIdentity . umapM (embedIden f)
dmapLR' :: (BinderList Binder, BinderList Binder -> Node -> Recur) -> Node -> Node
dmapLR' = nodeMapI STopDown
dmapLR' f = runIdentity . dmapLRM' (embedIden f)
dmapL' :: (BinderList Binder, BinderList Binder -> Node -> Node) -> Node -> Node
dmapL' = nodeMapI STopDown
dmapL' f = runIdentity . dmapLM' (embedIden f)
umapL' :: (BinderList Binder, BinderList Binder -> Node -> Node) -> Node -> Node
umapL' = nodeMapI SBottomUp
umapL' f = runIdentity . umapLM' (embedIden f)
dmapNR' :: (Index, Index -> Node -> Recur) -> Node -> Node
dmapNR' = nodeMapI STopDown
dmapNR' f = runIdentity . dmapNRM' (embedIden f)
dmapN' :: (Index, Index -> Node -> Node) -> Node -> Node
dmapN' = nodeMapI STopDown
dmapN' f = runIdentity . dmapNM' (embedIden f)
umapN' :: (Index, Index -> Node -> Node) -> Node -> Node
umapN' = nodeMapI SBottomUp
umapN' f = runIdentity . umapNM' (embedIden f)
dmapCLM :: Monad m => (c -> BinderList Binder -> Node -> m (c, Node)) -> c -> Node -> m Node
dmapCLM f ini = nodeMapG' STopDown (pairCollector (identityCollector ini) binderInfoCollector) (\(c, bi) -> fromPair bi . f c bi)
dmapCNM :: Monad m => (c -> Index -> Node -> m (c, Node)) -> c -> Node -> m Node
dmapCNM f ini = nodeMapG' STopDown (pairCollector (identityCollector ini) binderNumCollector) (\(c, bi) -> fromPair bi . f c bi)
dmapCM :: Monad m => (c -> Node -> m (c, Node)) -> c -> Node -> m Node
dmapCM f ini = nodeMapG' STopDown (identityCollector ini) (\c -> fmap Recur' . f c)
dmapCL :: (c -> BinderList Binder -> Node -> (c, Node)) -> c -> Node -> Node
dmapCL f ini = runIdentity . dmapCLM (embedIden f) ini
dmapCN :: (c -> Index -> Node -> (c, Node)) -> c -> Node -> Node
dmapCN f ini = runIdentity . dmapCNM (embedIden f) ini
dmapC :: (c -> Node -> (c, Node)) -> c -> Node -> Node
dmapC f ini = runIdentity . dmapCM (embedIden f) ini

View File

@ -2,11 +2,10 @@ module Juvix.Compiler.Core.Extra.Recursors.Recur where
import Juvix.Compiler.Core.Language
data Recur' c
= End' Node
| Recur' (c, Node)
data Recur
= End Node
| Recur Node
recurNode :: Lens' Recur Node
recurNode f = \case
End n -> End <$> f n
Recur n -> Recur <$> f n

View File

@ -1,20 +0,0 @@
module Juvix.Compiler.Core.Info.TypeInfo where
import Juvix.Compiler.Core.Extra.Base
import Juvix.Compiler.Core.Info qualified as Info
import Juvix.Compiler.Core.Language
newtype TypeInfo = TypeInfo {_infoType :: Type}
instance IsInfo TypeInfo
kTypeInfo :: Key TypeInfo
kTypeInfo = Proxy
makeLenses ''TypeInfo
getInfoType :: Info -> Type
getInfoType i = maybe mkDynamic' (^. infoType) (Info.lookup kTypeInfo i)
setInfoType :: Type -> Info -> Info
setInfoType = Info.insert . TypeInfo

View File

@ -271,7 +271,7 @@ instance HasAtomicity (Pattern' i a) where
PatConstr x -> atomicity x
instance HasAtomicity (Pi' i a) where
atomicity _ = Aggregate lambdaFixity
atomicity _ = Aggregate funFixity
instance HasAtomicity (Univ' i) where
atomicity _ = Atom

View File

@ -338,11 +338,19 @@ instance PrettyCode Stripped.Node where
branchTagNames = map (^. (caseBranchInfo . Stripped.caseBranchInfoConstrName)) _caseBranches
in ppCodeCase' branchBinderNames branchTagNames x
instance PrettyCode ConstructorInfo where
ppCode :: Member (Reader Options) r => ConstructorInfo -> Sem r (Doc Ann)
ppCode ci = do
name <- ppName KNameConstructor (ci ^. constructorName)
ty <- ppCode (ci ^. constructorType)
return $ name <+> colon <+> ty
instance PrettyCode InfoTable where
ppCode :: forall r. Member (Reader Options) r => InfoTable -> Sem r (Doc Ann)
ppCode tbl = do
tys <- ppInductives (toList (tbl ^. infoInductives))
ctx' <- ppContext (tbl ^. identContext)
return ("-- IdentContext" <> line <> ctx' <> line)
return ("-- Types" <> line <> tys <> line <> "-- Identifiers" <> line <> ctx' <> line)
where
ppContext :: IdentContext -> Sem r (Doc Ann)
ppContext ctx = do
@ -356,7 +364,21 @@ instance PrettyCode InfoTable where
mname' = (\nm -> nm <> "!" <> prettyText s) mname
sym' <- ppName KNameLocal mname'
body' <- ppCode n
return (kwDef <+> sym' <+> kwAssign <+> nest 2 body')
let ii = fromJust $ HashMap.lookup s (tbl ^. infoIdentifiers)
ty = ii ^. identifierType
ty' <- ppCode ty
let tydoc = if isDynamic ty then mempty else space <> colon <+> ty'
return (kwDef <+> sym' <> tydoc <+> kwAssign <+> nest 2 body')
ppInductives :: [InductiveInfo] -> Sem r (Doc Ann)
ppInductives inds = do
inds' <- mapM ppInductive inds
return (vsep inds')
where
ppInductive :: InductiveInfo -> Sem r (Doc Ann)
ppInductive ii = do
name <- ppName KNameInductive (ii ^. inductiveName)
ctrs <- mapM (fmap (<> semi) . ppCode) (ii ^. inductiveConstructors)
return (kwInductive <+> name <+> braces (line <> indent' (vsep ctrs) <> line))
instance PrettyCode Stripped.InfoTable where
ppCode :: forall r. Member (Reader Options) r => Stripped.InfoTable -> Sem r (Doc Ann)

View File

@ -13,6 +13,7 @@ import Juvix.Compiler.Core.Transformation.Base
import Juvix.Compiler.Core.Transformation.Eta
import Juvix.Compiler.Core.Transformation.Identity
import Juvix.Compiler.Core.Transformation.LambdaLifting
import Juvix.Compiler.Core.Transformation.RemoveTypeArgs
import Juvix.Compiler.Core.Transformation.TopEtaExpand
applyTransformations :: [TransformationId] -> InfoTable -> InfoTable
@ -23,3 +24,4 @@ applyTransformations ts tbl = foldl' (flip appTrans) tbl ts
LambdaLifting -> lambdaLifting
Identity -> identity
TopEtaExpand -> topEtaExpand
RemoveTypeArgs -> removeTypeArgs

View File

@ -10,7 +10,17 @@ import Juvix.Compiler.Core.Data.InfoTable
import Juvix.Compiler.Core.Data.InfoTableBuilder
import Juvix.Compiler.Core.Language
type Transformation = InfoTable -> InfoTable
mapIdents :: (IdentifierInfo -> IdentifierInfo) -> InfoTable -> InfoTable
mapIdents = over infoIdentifiers . fmap
mapInductives :: (InductiveInfo -> InductiveInfo) -> InfoTable -> InfoTable
mapInductives = over infoInductives . fmap
mapConstructors :: (ConstructorInfo -> ConstructorInfo) -> InfoTable -> InfoTable
mapConstructors = over infoConstructors . fmap
mapAxioms :: (AxiomInfo -> AxiomInfo) -> InfoTable -> InfoTable
mapAxioms = over infoAxioms . fmap
mapT :: (Symbol -> Node -> Node) -> InfoTable -> InfoTable
mapT f tab = tab {_identContext = HashMap.mapWithKey f (tab ^. identContext)}

View File

@ -74,5 +74,5 @@ etaExpandApps tab =
Just ci -> length (ci ^. inductiveParams)
Nothing -> 0
etaExpansionApps :: Transformation
etaExpansionApps :: InfoTable -> InfoTable
etaExpansionApps tab = mapT (const (etaExpandApps tab)) tab

View File

@ -0,0 +1,126 @@
module Juvix.Compiler.Core.Transformation.RemoveTypeArgs
( removeTypeArgs,
module Juvix.Compiler.Core.Transformation.Base,
)
where
import Data.HashMap.Strict qualified as HashMap
import Juvix.Compiler.Core.Data.BinderList qualified as BL
import Juvix.Compiler.Core.Extra
import Juvix.Compiler.Core.Transformation.Base
convertNode :: InfoTable -> Node -> Node
convertNode tab = convert mempty
where
unsupported :: forall a. a
unsupported = error "remove type arguments: unsupported node"
convert :: BinderList Binder -> Node -> Node
convert vars = dmapLR' (vars, go)
go :: BinderList Binder -> Node -> Recur
go vars node = case node of
NVar v@(Var {..}) ->
let ty = BL.lookup _varIndex vars ^. binderType
in if
| isTypeConstr ty -> End (mkDynamic _varInfo)
| otherwise -> End (NVar (shiftVar (-k) v))
where
k = length (filter (isTypeConstr . (^. binderType)) (take _varIndex (toList vars)))
NApp (App {}) ->
let (h, args) = unfoldApps node
ty =
case h of
NVar (Var {..}) ->
BL.lookup _varIndex vars ^. binderType
NIdt (Ident {..}) ->
let fi = fromJust $ HashMap.lookup _identSymbol (tab ^. infoIdentifiers)
in fi ^. identifierType
_ -> unsupported
args' = filterArgs ty args
in if
| null args' ->
End (convert vars h)
| otherwise ->
End (mkApps (convert vars h) (map (second (convert vars)) args'))
NCtr (Constr {..}) ->
let ci = fromJust $ HashMap.lookup _constrTag (tab ^. infoConstructors)
ty = ci ^. constructorType
args' = filterArgs ty _constrArgs
in End (mkConstr _constrInfo _constrTag (map (convert vars) args'))
NCase (Case {..}) ->
End (mkCase _caseInfo (convert vars _caseValue) (map convertBranch _caseBranches) (fmap (convert vars) _caseDefault))
where
convertBranch :: CaseBranch -> CaseBranch
convertBranch br@CaseBranch {..} =
let binders' = filterBinders vars _caseBranchBinders
body' =
convert
(BL.prependRev _caseBranchBinders vars)
_caseBranchBody
in br
{ _caseBranchBinders = binders',
_caseBranchBindersNum = length binders',
_caseBranchBody = body'
}
filterBinders :: BinderList Binder -> [Binder] -> [Binder]
filterBinders _ [] = []
filterBinders vars' (b : bs)
| isTypeConstr (b ^. binderType) =
filterBinders (BL.cons b vars') bs
filterBinders vars' (b : bs) =
over binderType (convert vars') b : filterBinders (BL.cons b vars') bs
NLam (Lambda {..})
| isTypeConstr (_lambdaBinder ^. binderType) ->
End (convert (BL.cons _lambdaBinder vars) _lambdaBody)
NPi (Pi {..})
| isTypeConstr (_piBinder ^. binderType) && not (isTypeConstr _piBody) ->
End (convert (BL.cons _piBinder vars) _piBody)
_ -> Recur node
where
filterArgs :: Type -> [a] -> [a]
filterArgs ty args =
map fst $
filter (not . isTypeConstr . snd) (zip args (typeArgs ty ++ repeat mkDynamic'))
convertIdent :: InfoTable -> IdentifierInfo -> IdentifierInfo
convertIdent tab ii =
ii
{ _identifierType = ty',
_identifierArgsInfo = map (over argumentType (convertNode tab) . fst) $ filter (not . isTypeConstr . snd) (zipExact (ii ^. identifierArgsInfo) tyargs),
_identifierArgsNum = length (typeArgs ty')
}
where
tyargs = typeArgs (ii ^. identifierType)
ty' = convertNode tab (ii ^. identifierType)
convertConstructor :: InfoTable -> ConstructorInfo -> ConstructorInfo
convertConstructor tab ci =
ci
{ _constructorType = ty',
_constructorArgsNum = length (typeArgs ty')
}
where
ty' = convertNode tab (ci ^. constructorType)
convertInductive :: InfoTable -> InductiveInfo -> InductiveInfo
convertInductive tab ii =
ii
{ _inductiveKind = ty',
_inductiveParams = map (over paramKind (convertNode tab) . fst) $ filter (not . isTypeConstr . snd) (zipExact (ii ^. inductiveParams) tyargs),
_inductiveConstructors = map (convertConstructor tab) (ii ^. inductiveConstructors)
}
where
tyargs = typeArgs (ii ^. inductiveKind)
ty' = convertNode tab (ii ^. inductiveKind)
convertAxiom :: InfoTable -> AxiomInfo -> AxiomInfo
convertAxiom tab = over axiomType (convertNode tab)
removeTypeArgs :: InfoTable -> InfoTable
removeTypeArgs tab =
mapAxioms (convertAxiom tab) $
mapInductives (convertInductive tab) $
mapConstructors (convertConstructor tab) $
mapIdents (convertIdent tab) $
mapT (const (convertNode tab)) tab

View File

@ -801,7 +801,7 @@ caseMatchingBranch varsNum vars = do
ns
br <- bracedExpr (varsNum + bindersNum) vars'
let info = setInfoName (ci ^. constructorName) mempty
binders = [Binder name (Just loc) mkDynamic' | (name, loc) <- ns]
binders = zipWith (\(name, loc) -> Binder name (Just loc)) ns (typeArgs (ci ^. constructorType) ++ repeat mkDynamic')
return $ CaseBranch info tag binders bindersNum br
Nothing ->
parseFailure off ("undeclared identifier: " ++ fromText txt)

View File

@ -249,5 +249,10 @@ tests =
"Eta-expansion"
"."
"test044.jvc"
"out/test044.out"
"out/test044.out",
PosTest
"Type application and abstraction"
"."
"test045.jvc"
"out/test045.out"
]

View File

@ -3,6 +3,7 @@ module Core.Transformation where
import Base
import Core.Transformation.Identity qualified as Identity
import Core.Transformation.Lifting qualified as Lifting
import Core.Transformation.RemoveTypeArgs qualified as RemoveTypeArgs
import Core.Transformation.TopEtaExpand qualified as TopEtaExpand
allTests :: TestTree
@ -11,5 +12,6 @@ allTests =
"JuvixCore transformations"
[ Identity.allTests,
TopEtaExpand.allTests,
Lifting.allTests
Lifting.allTests,
RemoveTypeArgs.allTests
]

View File

@ -0,0 +1,21 @@
module Core.Transformation.RemoveTypeArgs (allTests) where
import Base
import Core.Eval.Positive qualified as Eval
import Core.Transformation.Base
import Juvix.Compiler.Core.Transformation
allTests :: TestTree
allTests = testGroup "Remove type arguments" (map liftTest Eval.tests)
pipe :: [TransformationId]
pipe = [LambdaLifting, RemoveTypeArgs]
liftTest :: Eval.PosTest -> TestTree
liftTest _testEval =
fromTest
Test
{ _testTransformations = pipe,
_testAssertion = const (return ()),
_testEval
}

View File

@ -0,0 +1 @@
15

View File

@ -7,8 +7,10 @@ inductive list : Π A : Type, Type {
def id : Π A : Type, A → A := λ(A : Type) λ(x : A) x;
def hd : Π A : Type, list A → A := λA λl case l of { cons _ x _ := x };
def hd : Π A : Type, list A → A := λ(A : Type) λl case l of { cons _ x _ := x };
def tl : Π A : Type, list A → list A := λA λl case l of { cons _ _ y := y };
def tl : Π A : Type, list A → list A := λ(A : Type) λl case l of { cons _ _ y := y };
hd int (tl int (id (list int) (cons int 1 (cons int 2 (nil int)))))
def main := hd int (tl int (id (list int) (cons int 1 (cons int 2 (nil int)))));
main

View File

@ -7,4 +7,6 @@ def fun' := λ(T : Type → Type) λ(A : Type) λ(B : T A) λ(x : B)
let h := λ(b : B) λ(a : A) a * b - b in
f (λ(y : B) h y x);
fun int 2 + fun' (λA A) int int 3
def main := fun int 2 + fun' (λA A) int int 3;
main

View File

@ -0,0 +1,26 @@
-- type application and abstraction
inductive list : Π A : Type, Type {
cons : Π A : Type, A → list A → list A;
nil : Π A : Type, list A;
};
def id : Π A : Type, A → A := λ(A : Type) λ(x : A) x;
def hd : Π A : Type, list A → A := λ(A : Type) λl case l of { cons _ x _ := x };
def tl : Π A : Type, list A → list A := λ(A : Type) λl case l of { cons _ _ y := y };
def f := λ(A : Type) λ(x : A) λ(B : Type) λ(y : B) x + y;
def g := λ(A : Type) λ(xs : list A) λ(B : Type) λ(ys : list B) case xs of {
cons A' x _ := case ys of {
cons B' y _ := f A' x B' y;
nil _ := x;
};
nil _ := 0;
};
def main := g int (cons int 2 (nil int)) int (cons int 3 (nil int)) * f int 1 int (hd int (tl int (id (list int) (cons int 1 (cons int 2 (nil int))))));
main