1
1
mirror of https://github.com/anoma/juvix.git synced 2025-01-08 08:39:26 +03:00

Conversion of Nat representation to JuvixCore integers (#1661)

* nat to int wip

* nat to int wip

* fix condition

* nats in core

* bugfixes

* tests

* make ormolu happy

* fix case
This commit is contained in:
Łukasz Czajka 2022-12-20 11:17:39 +01:00 committed by GitHub
parent af0379a310
commit 445376e338
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 387 additions and 108 deletions

View File

@ -1,6 +1,6 @@
module Juvix.Compiler.Core.Data.BinderList where module Juvix.Compiler.Core.Data.BinderList where
import Juvix.Compiler.Core.Language hiding (cons, lookup, uncons) import Juvix.Compiler.Core.Language hiding (cons, drop, lookup, uncons)
import Juvix.Prelude qualified as Prelude import Juvix.Prelude qualified as Prelude
-- | if we have \x\y. b, the binderlist in b is [y, x] -- | if we have \x\y. b, the binderlist in b is [y, x]
@ -14,11 +14,11 @@ makeLenses ''BinderList
fromList :: [a] -> BinderList a fromList :: [a] -> BinderList a
fromList l = BinderList (length l) l fromList l = BinderList (length l) l
drop' :: Int -> BinderList a -> BinderList a drop :: Int -> BinderList a -> BinderList a
drop' k (BinderList n l) = BinderList (n - k) (dropExact k l) drop k (BinderList n l) = BinderList (n - k) (dropExact k l)
tail' :: BinderList a -> BinderList a tail :: BinderList a -> BinderList a
tail' = snd . fromJust . uncons tail = snd . fromJust . uncons
uncons :: BinderList a -> Maybe (a, BinderList a) uncons :: BinderList a -> Maybe (a, BinderList a)
uncons l = second helper <$> Prelude.uncons (l ^. blMap) uncons l = second helper <$> Prelude.uncons (l ^. blMap)
@ -60,7 +60,7 @@ lookupsSortedRev bl = go [] 0 bl
(v : vs) -> (v : vs) ->
let skipped = v ^. varIndex - off let skipped = v ^. varIndex - off
off' = off + skipped off' = off + skipped
ctx' = drop' skipped ctx ctx' = drop skipped ctx
in go ((v, head' ctx') : acc) off' ctx' vs in go ((v, head' ctx') : acc) off' ctx' vs
head' :: BinderList a -> a head' :: BinderList a -> a
head' = lookup 0 head' = lookup 0

View File

@ -1,5 +1,10 @@
module Juvix.Compiler.Core.Data.InfoTable where module Juvix.Compiler.Core.Data.InfoTable
( module Juvix.Compiler.Core.Data.InfoTable,
module Juvix.Compiler.Concrete.Data.Builtins,
)
where
import Juvix.Compiler.Concrete.Data.Builtins
import Juvix.Compiler.Core.Language import Juvix.Compiler.Core.Language
type IdentContext = HashMap Symbol Node type IdentContext = HashMap Symbol Node
@ -43,7 +48,8 @@ data IdentifierInfo = IdentifierInfo
_identifierType :: Type, _identifierType :: Type,
_identifierArgsNum :: Int, _identifierArgsNum :: Int,
_identifierArgsInfo :: [ArgumentInfo], _identifierArgsInfo :: [ArgumentInfo],
_identifierIsExported :: Bool _identifierIsExported :: Bool,
_identifierBuiltin :: Maybe BuiltinFunction
} }
data ArgumentInfo = ArgumentInfo data ArgumentInfo = ArgumentInfo
@ -60,7 +66,8 @@ data InductiveInfo = InductiveInfo
_inductiveKind :: Type, _inductiveKind :: Type,
_inductiveConstructors :: [ConstructorInfo], _inductiveConstructors :: [ConstructorInfo],
_inductiveParams :: [ParameterInfo], _inductiveParams :: [ParameterInfo],
_inductivePositive :: Bool _inductivePositive :: Bool,
_inductiveBuiltin :: Maybe BuiltinInductive
} }
data ConstructorInfo = ConstructorInfo data ConstructorInfo = ConstructorInfo
@ -69,7 +76,8 @@ data ConstructorInfo = ConstructorInfo
_constructorTag :: Tag, _constructorTag :: Tag,
_constructorType :: Type, _constructorType :: Type,
_constructorArgsNum :: Int, _constructorArgsNum :: Int,
_constructorInductive :: Symbol _constructorInductive :: Symbol,
_constructorBuiltin :: Maybe BuiltinConstructor
} }
data ParameterInfo = ParameterInfo data ParameterInfo = ParameterInfo

View File

@ -24,6 +24,21 @@ getConstructorInfo tag = do
tab <- getInfoTable tab <- getInfoTable
return $ fromJust (HashMap.lookup tag (tab ^. infoConstructors)) return $ fromJust (HashMap.lookup tag (tab ^. infoConstructors))
getInductiveInfo :: Member InfoTableBuilder r => Symbol -> Sem r InductiveInfo
getInductiveInfo sym = do
tab <- getInfoTable
return $ fromJust (HashMap.lookup sym (tab ^. infoInductives))
getIdentifierInfo :: Member InfoTableBuilder r => Symbol -> Sem r IdentifierInfo
getIdentifierInfo sym = do
tab <- getInfoTable
return $ fromJust (HashMap.lookup sym (tab ^. infoIdentifiers))
getBoolSymbol :: Member InfoTableBuilder r => Sem r Symbol
getBoolSymbol = do
ci <- getConstructorInfo (BuiltinTag TagTrue)
return $ ci ^. constructorInductive
checkSymbolDefined :: Member InfoTableBuilder r => Symbol -> Sem r Bool checkSymbolDefined :: Member InfoTableBuilder r => Symbol -> Sem r Bool
checkSymbolDefined sym = do checkSymbolDefined sym = do
tab <- getInfoTable tab <- getInfoTable

View File

@ -7,5 +7,6 @@ data TransformationId
| TopEtaExpand | TopEtaExpand
| RemoveTypeArgs | RemoveTypeArgs
| MoveApps | MoveApps
| NatToInt
| Identity | Identity
deriving stock (Data) deriving stock (Data)

View File

@ -46,6 +46,7 @@ pcompletions = do
Identity -> strIdentity Identity -> strIdentity
RemoveTypeArgs -> strRemoveTypeArgs RemoveTypeArgs -> strRemoveTypeArgs
MoveApps -> strMoveApps MoveApps -> strMoveApps
NatToInt -> strNatToInt
lexeme :: MonadParsec e Text m => m a -> m a lexeme :: MonadParsec e Text m => m a -> m a
lexeme = L.lexeme L.hspace lexeme = L.lexeme L.hspace
@ -63,6 +64,7 @@ transformation =
<|> symbol strTopEtaExpand $> TopEtaExpand <|> symbol strTopEtaExpand $> TopEtaExpand
<|> symbol strRemoveTypeArgs $> RemoveTypeArgs <|> symbol strRemoveTypeArgs $> RemoveTypeArgs
<|> symbol strMoveApps $> MoveApps <|> symbol strMoveApps $> MoveApps
<|> symbol strNatToInt $> NatToInt
allStrings :: [Text] allStrings :: [Text]
allStrings = allStrings =
@ -87,3 +89,6 @@ strRemoveTypeArgs = "remove-type-args"
strMoveApps :: Text strMoveApps :: Text
strMoveApps = "move-apps" strMoveApps = "move-apps"
strNatToInt :: Text
strNatToInt = "nat-to-int"

View File

@ -70,10 +70,10 @@ eval !ctx !env0 = convertRuntimeNodes . eval' env0
let !vs' = map (eval' env' . (^. letItemValue)) (toList vs) let !vs' = map (eval' env' . (^. letItemValue)) (toList vs)
!env' = revAppend vs' env !env' = revAppend vs' env
in foldr GHC.pseq (eval' env' b) vs' in foldr GHC.pseq (eval' env' b) vs'
NCase (Case i v bs def) -> NCase (Case i sym v bs def) ->
case eval' env v of case eval' env v of
NCtr (Constr _ tag args) -> branch n env args tag def bs NCtr (Constr _ tag args) -> branch n env args tag def bs
v' -> evalError "matching on non-data" (substEnv env (mkCase i v' bs def)) v' -> evalError "matching on non-data" (substEnv env (mkCase i sym v' bs def))
NMatch (Match _ vs bs) -> NMatch (Match _ vs bs) ->
let !vs' = map' (eval' env) (toList vs) let !vs' = map' (eval' env) (toList vs)
in match n env vs' bs in match n env vs' bs

View File

@ -55,6 +55,9 @@ mkLambda i bi b = NLam (Lambda i bi b)
mkLambda' :: Node -> Node mkLambda' :: Node -> Node
mkLambda' = mkLambda Info.empty emptyBinder mkLambda' = mkLambda Info.empty emptyBinder
mkLambdaTy :: Node -> Node -> Node
mkLambdaTy ty = mkLambda Info.empty (Binder "?" Nothing ty)
mkLetItem' :: Node -> LetItem mkLetItem' :: Node -> LetItem
mkLetItem' = LetItem emptyBinder mkLetItem' = LetItem emptyBinder
@ -70,10 +73,10 @@ mkLetRec i vs b = NRec (LetRec i vs b)
mkLetRec' :: NonEmpty Node -> Node -> Node mkLetRec' :: NonEmpty Node -> Node -> Node
mkLetRec' = mkLetRec Info.empty . fmap mkLetItem' mkLetRec' = mkLetRec Info.empty . fmap mkLetItem'
mkCase :: Info -> Node -> [CaseBranch] -> Maybe Node -> Node mkCase :: Info -> Symbol -> Node -> [CaseBranch] -> Maybe Node -> Node
mkCase i v bs def = NCase (Case i v bs def) mkCase i sym v bs def = NCase (Case i sym v bs def)
mkCase' :: Node -> [CaseBranch] -> Maybe Node -> Node mkCase' :: Symbol -> Node -> [CaseBranch] -> Maybe Node -> Node
mkCase' = mkCase Info.empty mkCase' = mkCase Info.empty
mkMatch :: Info -> NonEmpty Node -> [MatchBranch] -> Node mkMatch :: Info -> NonEmpty Node -> [MatchBranch] -> Node
@ -82,8 +85,8 @@ mkMatch i vs bs = NMatch (Match i vs bs)
mkMatch' :: NonEmpty Node -> [MatchBranch] -> Node mkMatch' :: NonEmpty Node -> [MatchBranch] -> Node
mkMatch' = mkMatch Info.empty mkMatch' = mkMatch Info.empty
mkIf :: Info -> Node -> Node -> Node -> Node mkIf :: Info -> Symbol -> Node -> Node -> Node -> Node
mkIf i v b1 b2 = mkCase i v [br] (Just b2) mkIf i sym v b1 b2 = mkCase i sym v [br] (Just b2)
where where
br = br =
CaseBranch CaseBranch
@ -94,7 +97,7 @@ mkIf i v b1 b2 = mkCase i v [br] (Just b2)
_caseBranchBody = b1 _caseBranchBody = b1
} }
mkIf' :: Node -> Node -> Node -> Node mkIf' :: Symbol -> Node -> Node -> Node -> Node
mkIf' = mkIf Info.empty mkIf' = mkIf Info.empty
{------------------------------------------------------------------------} {------------------------------------------------------------------------}
@ -480,7 +483,7 @@ destruct = \case
] ]
in mkLetRec i' items' (b' ^. childNode) in mkLetRec i' items' (b' ^. childNode)
} }
NCase (Case i v brs mdef) -> NCase (Case i sym v brs mdef) ->
let branchChildren :: [([Binder], NodeChild)] let branchChildren :: [([Binder], NodeChild)]
branchChildren = branchChildren =
[ (binders, manyBinders binders (br ^. caseBranchBody)) [ (binders, manyBinders binders (br ^. caseBranchBody))
@ -520,7 +523,7 @@ destruct = \case
_nodeSubinfos = map (^. caseBranchInfo) brs, _nodeSubinfos = map (^. caseBranchInfo) brs,
_nodeChildren = noBinders v : allNodes, _nodeChildren = noBinders v : allNodes,
_nodeReassemble = someChildrenI $ \i' is' (v' :| allNodes') -> _nodeReassemble = someChildrenI $ \i' is' (v' :| allNodes') ->
mkCase i' (v' ^. childNode) (mkBranches is' allNodes') Nothing mkCase i' sym (v' ^. childNode) (mkBranches is' allNodes') Nothing
} }
Just def -> Just def ->
NodeDetails NodeDetails
@ -528,7 +531,7 @@ destruct = \case
_nodeSubinfos = map (^. caseBranchInfo) brs, _nodeSubinfos = map (^. caseBranchInfo) brs,
_nodeChildren = noBinders v : noBinders def : allNodes, _nodeChildren = noBinders v : noBinders def : allNodes,
_nodeReassemble = twoManyChildrenI $ \i' is' v' def' allNodes' -> _nodeReassemble = twoManyChildrenI $ \i' is' v' def' allNodes' ->
mkCase i' (v' ^. childNode) (mkBranches is' allNodes') (Just (def' ^. childNode)) mkCase i' sym (v' ^. childNode) (mkBranches is' allNodes') (Just (def' ^. childNode))
} }
NMatch (Match i vs branches) -> NMatch (Match i vs branches) ->
let allNodes :: [NodeChild] let allNodes :: [NodeChild]

View File

@ -112,6 +112,14 @@ fromRecur c =
fromPair :: Functor g => d -> g (c, Node) -> g (Recur' (c, d)) fromPair :: Functor g => d -> g (c, Node) -> g (Recur' (c, d))
fromPair d = fmap (\(c, x) -> Recur' ((c, d), x)) fromPair d = fmap (\(c, x) -> Recur' ((c, d), x))
fromRecur' :: Functor g => d -> g (Recur' c) -> g (Recur' (c, d))
fromRecur' d =
fmap
( \case
End' x -> End' x
Recur' (c, x) -> Recur' ((c, d), x)
)
nodeMapG' :: nodeMapG' ::
Monad m => Monad m =>
Sing dir -> Sing dir ->

View File

@ -6,21 +6,21 @@ import Juvix.Compiler.Core.Extra.Recursors.Map
import Juvix.Compiler.Core.Extra.Recursors.Parameters import Juvix.Compiler.Core.Extra.Recursors.Parameters
dmapLRM :: Monad m => (BinderList Binder -> Node -> m Recur) -> Node -> m Node dmapLRM :: Monad m => (BinderList Binder -> Node -> m Recur) -> Node -> m Node
dmapLRM f = nodeMapG' STopDown binderInfoCollector (\bi -> fromRecur bi . f bi) dmapLRM f = dmapLRM' (mempty, f)
dmapLM :: Monad m => (BinderList Binder -> Node -> m Node) -> Node -> m Node dmapLM :: Monad m => (BinderList Binder -> Node -> m Node) -> Node -> m Node
dmapLM f = nodeMapG' STopDown binderInfoCollector (\bi -> fromSimple bi . f bi) dmapLM f = dmapLM' (mempty, f)
umapLM :: Monad m => (BinderList Binder -> Node -> m Node) -> Node -> m Node umapLM :: Monad m => (BinderList Binder -> Node -> m Node) -> Node -> m Node
umapLM f = nodeMapG' SBottomUp binderInfoCollector f umapLM f = nodeMapG' SBottomUp binderInfoCollector f
dmapNRM :: Monad m => (Index -> Node -> m Recur) -> Node -> m Node dmapNRM :: Monad m => (Level -> Node -> m Recur) -> Node -> m Node
dmapNRM f = nodeMapG' STopDown binderNumCollector (\bi -> fromRecur bi . f bi) dmapNRM f = dmapNRM' (0, f)
dmapNM :: Monad m => (Index -> Node -> m Node) -> Node -> m Node dmapNM :: Monad m => (Level -> Node -> m Node) -> Node -> m Node
dmapNM f = nodeMapG' STopDown binderNumCollector (\bi -> fromSimple bi . f bi) dmapNM f = dmapNM' (0, f)
umapNM :: Monad m => (Index -> Node -> m Node) -> Node -> m Node umapNM :: Monad m => (Level -> Node -> m Node) -> Node -> m Node
umapNM f = nodeMapG' SBottomUp binderNumCollector f umapNM f = nodeMapG' SBottomUp binderNumCollector f
dmapRM :: Monad m => (Node -> m Recur) -> Node -> m Node dmapRM :: Monad m => (Node -> m Recur) -> Node -> m Node
@ -41,13 +41,13 @@ dmapLM' f = nodeMapG' STopDown (binderInfoCollector' (fst f)) (\bi -> fromSimple
umapLM' :: Monad m => (BinderList Binder, BinderList Binder -> Node -> m Node) -> Node -> m Node umapLM' :: Monad m => (BinderList Binder, BinderList Binder -> Node -> m Node) -> Node -> m Node
umapLM' f = nodeMapG' SBottomUp (binderInfoCollector' (fst f)) (snd f) umapLM' f = nodeMapG' SBottomUp (binderInfoCollector' (fst f)) (snd f)
dmapNRM' :: Monad m => (Index, Index -> Node -> m Recur) -> Node -> m Node dmapNRM' :: Monad m => (Level, Level -> Node -> m Recur) -> Node -> m Node
dmapNRM' f = nodeMapG' STopDown (binderNumCollector' (fst f)) (\bi -> fromRecur bi . snd f bi) 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' :: Monad m => (Level, Level -> Node -> m Node) -> Node -> m Node
dmapNM' f = nodeMapG' STopDown (binderNumCollector' (fst f)) (\bi -> fromSimple bi . snd f bi) 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' :: Monad m => (Level, Level -> Node -> m Node) -> Node -> m Node
umapNM' f = nodeMapG' SBottomUp (binderNumCollector' (fst f)) (snd f) umapNM' f = nodeMapG' SBottomUp (binderNumCollector' (fst f)) (snd f)
dmapLR :: (BinderList Binder -> Node -> Recur) -> Node -> Node dmapLR :: (BinderList Binder -> Node -> Recur) -> Node -> Node
@ -59,13 +59,13 @@ dmapL f = runIdentity . dmapLM (embedIden f)
umapL :: (BinderList Binder -> Node -> Node) -> Node -> Node umapL :: (BinderList Binder -> Node -> Node) -> Node -> Node
umapL f = runIdentity . umapLM (embedIden f) umapL f = runIdentity . umapLM (embedIden f)
dmapNR :: (Index -> Node -> Recur) -> Node -> Node dmapNR :: (Level -> Node -> Recur) -> Node -> Node
dmapNR f = runIdentity . dmapNRM (embedIden f) dmapNR f = runIdentity . dmapNRM (embedIden f)
dmapN :: (Index -> Node -> Node) -> Node -> Node dmapN :: (Level -> Node -> Node) -> Node -> Node
dmapN f = runIdentity . dmapNM (embedIden f) dmapN f = runIdentity . dmapNM (embedIden f)
umapN :: (Index -> Node -> Node) -> Node -> Node umapN :: (Level -> Node -> Node) -> Node -> Node
umapN f = runIdentity . umapNM (embedIden f) umapN f = runIdentity . umapNM (embedIden f)
dmapR :: (Node -> Recur) -> Node -> Node dmapR :: (Node -> Recur) -> Node -> Node
@ -86,28 +86,46 @@ dmapL' f = runIdentity . dmapLM' (embedIden f)
umapL' :: (BinderList Binder, BinderList Binder -> Node -> Node) -> Node -> Node umapL' :: (BinderList Binder, BinderList Binder -> Node -> Node) -> Node -> Node
umapL' f = runIdentity . umapLM' (embedIden f) umapL' f = runIdentity . umapLM' (embedIden f)
dmapNR' :: (Index, Index -> Node -> Recur) -> Node -> Node dmapNR' :: (Level, Level -> Node -> Recur) -> Node -> Node
dmapNR' f = runIdentity . dmapNRM' (embedIden f) dmapNR' f = runIdentity . dmapNRM' (embedIden f)
dmapN' :: (Index, Index -> Node -> Node) -> Node -> Node dmapN' :: (Level, Level -> Node -> Node) -> Node -> Node
dmapN' f = runIdentity . dmapNM' (embedIden f) dmapN' f = runIdentity . dmapNM' (embedIden f)
umapN' :: (Index, Index -> Node -> Node) -> Node -> Node umapN' :: (Level, Level -> Node -> Node) -> Node -> Node
umapN' f = runIdentity . umapNM' (embedIden f) umapN' f = runIdentity . umapNM' (embedIden f)
dmapCLM :: Monad m => (c -> BinderList Binder -> Node -> m (c, Node)) -> c -> Node -> m Node dmapCLM' :: Monad m => (BinderList Binder, 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) dmapCLM' f ini = nodeMapG' STopDown (pairCollector (identityCollector ini) (binderInfoCollector' (fst f))) (\(c, bi) -> fromPair bi . snd f c bi)
dmapCNM :: Monad m => (c -> Index -> Node -> m (c, Node)) -> c -> Node -> m Node dmapCLRM' :: Monad m => (BinderList Binder, c -> BinderList Binder -> Node -> m (Recur' c)) -> c -> Node -> m Node
dmapCLRM' f ini = nodeMapG' STopDown (pairCollector (identityCollector ini) (binderInfoCollector' (fst f))) (\(c, bi) -> fromRecur' bi . snd f c bi)
dmapCNRM' :: Monad m => (Level, c -> Level -> Node -> m (Recur' c)) -> c -> Node -> m Node
dmapCNRM' f ini = nodeMapG' STopDown (pairCollector (identityCollector ini) (binderNumCollector' (fst f))) (\(c, bi) -> fromRecur' bi . snd f c bi)
dmapCLM :: Monad m => (c -> BinderList Binder -> Node -> m (c, Node)) -> c -> Node -> m Node
dmapCLM f = dmapCLM' (mempty, f)
dmapCNM :: Monad m => (c -> Level -> Node -> m (c, Node)) -> c -> Node -> m Node
dmapCNM f ini = nodeMapG' STopDown (pairCollector (identityCollector ini) binderNumCollector) (\(c, bi) -> fromPair bi . f c bi) 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 :: Monad m => (c -> Node -> m (c, Node)) -> c -> Node -> m Node
dmapCM f ini = nodeMapG' STopDown (identityCollector ini) (\c -> fmap Recur' . f c) dmapCM f ini = nodeMapG' STopDown (identityCollector ini) (\c -> fmap Recur' . f c)
dmapCL' :: (BinderList Binder, c -> BinderList Binder -> Node -> (c, Node)) -> c -> Node -> Node
dmapCL' f ini = runIdentity . dmapCLM' (embedIden f) ini
dmapCLR' :: (BinderList Binder, c -> BinderList Binder -> Node -> Recur' c) -> c -> Node -> Node
dmapCLR' f ini = runIdentity . dmapCLRM' (embedIden f) ini
dmapCNR' :: (Level, c -> Level -> Node -> Recur' c) -> c -> Node -> Node
dmapCNR' f ini = runIdentity . dmapCNRM' (embedIden f) ini
dmapCL :: (c -> BinderList Binder -> Node -> (c, Node)) -> c -> Node -> Node dmapCL :: (c -> BinderList Binder -> Node -> (c, Node)) -> c -> Node -> Node
dmapCL f ini = runIdentity . dmapCLM (embedIden f) ini dmapCL f ini = runIdentity . dmapCLM (embedIden f) ini
dmapCN :: (c -> Index -> Node -> (c, Node)) -> c -> Node -> Node dmapCN :: (c -> Level -> Node -> (c, Node)) -> c -> Node -> Node
dmapCN f ini = runIdentity . dmapCNM (embedIden f) ini dmapCN f ini = runIdentity . dmapCNM (embedIden f) ini
dmapC :: (c -> Node -> (c, Node)) -> c -> Node -> Node dmapC :: (c -> Node -> (c, Node)) -> c -> Node -> Node

View File

@ -52,5 +52,5 @@ mkLet i v b = NLet (Let i item b)
mkLet' :: Node -> Node -> Node mkLet' :: Node -> Node -> Node
mkLet' = mkLet (LetInfo "" Nothing TyDynamic) mkLet' = mkLet (LetInfo "" Nothing TyDynamic)
mkCase :: CaseInfo -> Node -> [CaseBranch] -> Maybe Node -> Node mkCase :: CaseInfo -> Symbol -> Node -> [CaseBranch] -> Maybe Node -> Node
mkCase ci v bs def = NCase (Case ci v bs def) mkCase ci sym v bs def = NCase (Case ci sym v bs def)

View File

@ -10,6 +10,7 @@ import Juvix.Data.Keyword.All
( kwAny, ( kwAny,
kwAssign, kwAssign,
kwBind, kwBind,
kwBuiltin,
kwCase, kwCase,
kwColon, kwColon,
kwComma, kwComma,
@ -52,6 +53,7 @@ allKeywordStrings = keywordsStrings allKeywords
allKeywords :: [Keyword] allKeywords :: [Keyword]
allKeywords = allKeywords =
[ kwAssign, [ kwAssign,
kwBuiltin,
kwLet, kwLet,
kwLetRec, kwLetRec,
kwIn, kwIn,

View File

@ -114,6 +114,7 @@ data LetRec' i a ty = LetRec
-- branches default`. `Case` is lazy: only the selected branch is evaluated. -- branches default`. `Case` is lazy: only the selected branch is evaluated.
data Case' i bi a = Case data Case' i bi a = Case
{ _caseInfo :: i, { _caseInfo :: i,
_caseInductive :: Symbol,
_caseValue :: !a, _caseValue :: !a,
_caseBranches :: ![CaseBranch' bi a], _caseBranches :: ![CaseBranch' bi a],
_caseDefault :: !(Maybe a) _caseDefault :: !(Maybe a)
@ -338,7 +339,7 @@ instance Eq a => Eq (Constr' i a) where
(Constr _ tag1 args1) == (Constr _ tag2 args2) = tag1 == tag2 && args1 == args2 (Constr _ tag1 args1) == (Constr _ tag2 args2) = tag1 == tag2 && args1 == args2
instance Eq a => Eq (Case' i bi a) where instance Eq a => Eq (Case' i bi a) where
(Case _ v1 bs1 def1) == (Case _ v2 bs2 def2) = v1 == v2 && bs1 == bs2 && def1 == def2 (Case _ sym1 v1 bs1 def1) == (Case _ sym2 v2 bs2 def2) = sym1 == sym2 && v1 == v2 && bs1 == bs2 && def1 == def2
instance Eq a => Eq (CaseBranch' i a) where instance Eq a => Eq (CaseBranch' i a) where
(==) = (==) =

View File

@ -158,7 +158,19 @@ ppCodeLet' name mty lt = do
return $ kwLet <+> n' <> tty <+> kwAssign <+> v' <+> kwIn <> line <> b' return $ kwLet <+> n' <> tty <+> kwAssign <+> v' <+> kwIn <> line <> b'
ppCodeCase' :: (PrettyCode a, Member (Reader Options) r) => [[Text]] -> [Text] -> Case' i bi a -> Sem r (Doc Ann) ppCodeCase' :: (PrettyCode a, Member (Reader Options) r) => [[Text]] -> [Text] -> Case' i bi a -> Sem r (Doc Ann)
ppCodeCase' branchBinderNames branchTagNames Case {..} = do ppCodeCase' branchBinderNames branchTagNames Case {..} =
case _caseBranches of
[CaseBranch _ (BuiltinTag TagTrue) _ _ br1, CaseBranch _ (BuiltinTag TagTrue) _ _ br2] -> do
br1' <- ppCode br1
br2' <- ppCode br2
v <- ppCode _caseValue
return $ kwIf <+> v <+> kwThen <+> br1' <+> kwElse <+> br2'
[CaseBranch _ (BuiltinTag TagTrue) _ _ br1] | isJust _caseDefault -> do
br1' <- ppCode br1
br2' <- ppCode (fromJust _caseDefault)
v <- ppCode _caseValue
return $ kwIf <+> v <+> kwThen <+> br1' <+> kwElse <+> br2'
_ -> do
let branchBodies = map (^. caseBranchBody) _caseBranches let branchBodies = map (^. caseBranchBody) _caseBranches
bns <- mapM (mapM (ppName KNameLocal)) branchBinderNames bns <- mapM (mapM (ppName KNameLocal)) branchBinderNames
cns <- mapM (ppName KNameConstructor) branchTagNames cns <- mapM (ppName KNameConstructor) branchTagNames
@ -505,6 +517,15 @@ kwMatch = keyword Str.match_
kwWith :: Doc Ann kwWith :: Doc Ann
kwWith = keyword Str.with_ kwWith = keyword Str.with_
kwIf :: Doc Ann
kwIf = keyword Str.if_
kwThen :: Doc Ann
kwThen = keyword Str.then_
kwElse :: Doc Ann
kwElse = keyword Str.else_
kwDefault :: Doc Ann kwDefault :: Doc Ann
kwDefault = keyword Str.underscore kwDefault = keyword Str.underscore

View File

@ -14,6 +14,7 @@ import Juvix.Compiler.Core.Transformation.Eta
import Juvix.Compiler.Core.Transformation.Identity import Juvix.Compiler.Core.Transformation.Identity
import Juvix.Compiler.Core.Transformation.LambdaLifting import Juvix.Compiler.Core.Transformation.LambdaLifting
import Juvix.Compiler.Core.Transformation.MoveApps import Juvix.Compiler.Core.Transformation.MoveApps
import Juvix.Compiler.Core.Transformation.NatToInt
import Juvix.Compiler.Core.Transformation.RemoveTypeArgs import Juvix.Compiler.Core.Transformation.RemoveTypeArgs
import Juvix.Compiler.Core.Transformation.TopEtaExpand import Juvix.Compiler.Core.Transformation.TopEtaExpand
@ -27,3 +28,4 @@ applyTransformations ts tbl = foldl' (flip appTrans) tbl ts
TopEtaExpand -> topEtaExpand TopEtaExpand -> topEtaExpand
RemoveTypeArgs -> removeTypeArgs RemoveTypeArgs -> removeTypeArgs
MoveApps -> moveApps MoveApps -> moveApps
NatToInt -> natToInt

View File

@ -57,7 +57,8 @@ lambdaLiftNode aboveBl top =
_identifierType = typeFromArgs argsInfo, _identifierType = typeFromArgs argsInfo,
_identifierArgsNum = length allfreevars, _identifierArgsNum = length allfreevars,
_identifierArgsInfo = argsInfo, _identifierArgsInfo = argsInfo,
_identifierIsExported = False _identifierIsExported = False,
_identifierBuiltin = Nothing
} }
registerIdentNode f fBody' registerIdentNode f fBody'
let fApp = mkApps' (mkIdent mempty f) (map NVar allfreevars) let fApp = mkApps' (mkIdent mempty f) (map NVar allfreevars)
@ -117,7 +118,8 @@ lambdaLiftNode aboveBl top =
_identifierType = typeFromArgs argsInfo, _identifierType = typeFromArgs argsInfo,
_identifierArgsNum = length recItemsFreeVars, _identifierArgsNum = length recItemsFreeVars,
_identifierArgsInfo = argsInfo, _identifierArgsInfo = argsInfo,
_identifierIsExported = False _identifierIsExported = False,
_identifierBuiltin = Nothing
} }
| (sym, (itemBinder, b)) <- zipExact topSyms (zipExact letRecBinders' liftedDefs) | (sym, (itemBinder, b)) <- zipExact topSyms (zipExact letRecBinders' liftedDefs)
] ]

View File

@ -0,0 +1,93 @@
module Juvix.Compiler.Core.Transformation.NatToInt (natToInt) where
import Data.HashMap.Strict qualified as HashMap
import Data.List qualified as List
import Juvix.Compiler.Core.Extra
import Juvix.Compiler.Core.Info qualified as Info
import Juvix.Compiler.Core.Info.NameInfo
import Juvix.Compiler.Core.Transformation.Base
convertNode :: InfoTable -> Node -> Node
convertNode tab = convert [] 0
where
convert :: [Level] -> Level -> Node -> Node
convert levels bl node = dmapCNR' (bl, go) levels node
go :: [Level] -> Level -> Node -> Recur' [Level]
go levels bl node = case node of
NVar (Var {..}) ->
End' (mkVar _varInfo (_varIndex + length (filter (\x -> x >= bl - _varIndex) levels)))
NApp (App _ (NApp (App _ (NIdt (Ident {..})) l)) r) ->
Recur' (levels, convertIdentApp node (\op -> mkBuiltinApp _identInfo op [l, r]) _identSymbol)
NApp (App _ (NIdt (Ident {..})) l) ->
Recur' (levels, convertIdentApp node (\op -> mkLambdaTy mkTypeInteger' $ mkBuiltinApp _identInfo op [l, mkVar' 0]) _identSymbol)
NIdt (Ident {..}) ->
Recur'
( levels,
convertIdentApp
node
( \op ->
mkLambdaTy mkTypeInteger' $
mkLambdaTy mkTypeInteger' $
mkBuiltinApp _identInfo op [mkVar' 1, mkVar' 0]
)
_identSymbol
)
NCtr (Constr {..}) ->
let ci = fromJust $ HashMap.lookup _constrTag (tab ^. infoConstructors)
in case ci ^. constructorBuiltin of
Just BuiltinNatZero ->
Recur' (levels, mkConstant _constrInfo (ConstInteger 0))
Just BuiltinNatSuc ->
Recur' (levels, mkBuiltinApp _constrInfo OpIntAdd (_constrArgs ++ [mkConstant' (ConstInteger 1)]))
_ -> Recur' (levels, node)
NCase (Case {..}) ->
let ii = fromJust $ HashMap.lookup _caseInductive (tab ^. infoInductives)
in case ii ^. inductiveBuiltin of
Just BuiltinNat ->
case _caseBranches of
[br] -> makeIf br (maybeBranch _caseDefault)
[br1, br2] ->
if
| br1 ^. caseBranchBindersNum == 1 && br2 ^. caseBranchBindersNum == 0 ->
makeIf br1 (br2 ^. caseBranchBody)
| br2 ^. caseBranchBindersNum == 1 && br1 ^. caseBranchBindersNum == 0 ->
makeIf br2 (br1 ^. caseBranchBody)
| otherwise ->
impossible
[] -> Recur' (levels, fromJust _caseDefault)
_ -> impossible
_ -> Recur' (levels, node)
where
makeIf :: CaseBranch -> Node -> Recur' [Level]
makeIf CaseBranch {..} br =
let ci = fromJust $ HashMap.lookup (BuiltinTag TagTrue) (tab ^. infoConstructors)
sym = ci ^. constructorInductive
in case _caseBranchBindersNum of
0 ->
Recur' (levels, mkIf _caseInfo sym (mkBuiltinApp' OpEq [_caseValue, mkConstant' (ConstInteger 0)]) _caseBranchBody br)
1 ->
End' $
mkLet mempty (emptyBinder {_binderName = name}) (mkBuiltinApp' OpIntSub [convert levels bl _caseValue, mkConstant' (ConstInteger 1)]) $
mkIf
_caseInfo
sym
(mkBuiltinApp' OpIntLe [mkConstant' (ConstInteger 0), mkVar (Info.singleton (NameInfo name)) 0])
(convert levels (bl + 1) _caseBranchBody)
(convert (bl : levels) bl br)
where
name = List.head _caseBranchBinders ^. binderName
_ -> impossible
maybeBranch :: Maybe Node -> Node
maybeBranch = fromMaybe (mkBuiltinApp' OpFail [mkConstant' (ConstString "no matching branch")])
_ -> Recur' (levels, node)
convertIdentApp :: Node -> (BuiltinOp -> Node) -> Symbol -> Node
convertIdentApp node f sym =
let ii = fromJust $ HashMap.lookup sym (tab ^. infoIdentifiers)
in case ii ^. identifierBuiltin of
Just BuiltinNatPlus -> f OpIntAdd
_ -> node
natToInt :: InfoTable -> InfoTable
natToInt tab = mapT (const (convertNode tab)) tab

View File

@ -49,7 +49,7 @@ convertNode tab = convert mempty
args' = filterArgs ty _constrArgs args' = filterArgs ty _constrArgs
in End (mkConstr _constrInfo _constrTag (map (convert vars) args')) in End (mkConstr _constrInfo _constrTag (map (convert vars) args'))
NCase (Case {..}) -> NCase (Case {..}) ->
End (mkCase _caseInfo (convert vars _caseValue) (map convertBranch _caseBranches) (fmap (convert vars) _caseDefault)) End (mkCase _caseInfo _caseInductive (convert vars _caseValue) (map convertBranch _caseBranches) (fmap (convert vars) _caseDefault))
where where
convertBranch :: CaseBranch -> CaseBranch convertBranch :: CaseBranch -> CaseBranch
convertBranch br@CaseBranch {..} = convertBranch br@CaseBranch {..} =

View File

@ -121,7 +121,8 @@ goInductiveDef i = do
_inductiveKind = mkDynamic', _inductiveKind = mkDynamic',
_inductiveConstructors = ctorInfos, _inductiveConstructors = ctorInfos,
_inductiveParams = [], _inductiveParams = [],
_inductivePositive = i ^. Internal.inductivePositive _inductivePositive = i ^. Internal.inductivePositive,
_inductiveBuiltin = i ^. Internal.inductiveBuiltin
} }
registerInductive (mkIdentIndex (i ^. Internal.inductiveName)) info registerInductive (mkIdentIndex (i ^. Internal.inductiveName)) info
@ -132,7 +133,8 @@ goConstructor ::
Internal.InductiveConstructorDef -> Internal.InductiveConstructorDef ->
Sem r ConstructorInfo Sem r ConstructorInfo
goConstructor sym ctor = do goConstructor sym ctor = do
tag <- mBuiltin >>= ctorTag mblt <- mBuiltin
tag <- ctorTag mblt
ty <- ctorType ty <- ctorType
let info = let info =
ConstructorInfo ConstructorInfo
@ -141,7 +143,8 @@ goConstructor sym ctor = do
_constructorTag = tag, _constructorTag = tag,
_constructorType = ty, _constructorType = ty,
_constructorArgsNum = length (ctor ^. Internal.inductiveConstructorParameters), _constructorArgsNum = length (ctor ^. Internal.inductiveConstructorParameters),
_constructorInductive = sym _constructorInductive = sym,
_constructorBuiltin = mblt
} }
registerConstructor (mkIdentIndex (ctor ^. Internal.inductiveConstructorName)) info registerConstructor (mkIdentIndex (ctor ^. Internal.inductiveConstructorName)) info
return info return info
@ -198,7 +201,8 @@ goFunctionDefIden (f, sym) = do
_identifierType = funTy, _identifierType = funTy,
_identifierArgsNum = 0, _identifierArgsNum = 0,
_identifierArgsInfo = [], _identifierArgsInfo = [],
_identifierIsExported = False _identifierIsExported = False,
_identifierBuiltin = f ^. Internal.funDefBuiltin
} }
registerIdent (mkIdentIndex (f ^. Internal.funDefName)) info registerIdent (mkIdentIndex (f ^. Internal.funDefName)) info
when (f ^. Internal.funDefName . Internal.nameText == Str.main) (registerMain sym) when (f ^. Internal.funDefName . Internal.nameText == Str.main) (registerMain sym)
@ -286,7 +290,8 @@ goAxiomInductive a = whenJust (a ^. Internal.axiomBuiltin) builtinInductive
_inductiveKind = mkDynamic', _inductiveKind = mkDynamic',
_inductiveConstructors = [], _inductiveConstructors = [],
_inductiveParams = [], _inductiveParams = [],
_inductivePositive = False _inductivePositive = False,
_inductiveBuiltin = Nothing
} }
registerInductive (mkIdentIndex (a ^. Internal.axiomName)) info registerInductive (mkIdentIndex (a ^. Internal.axiomName)) info
@ -307,7 +312,8 @@ goAxiomDef a = case a ^. Internal.axiomBuiltin >>= builtinBody of
_identifierType = ty, _identifierType = ty,
_identifierArgsNum = 0, _identifierArgsNum = 0,
_identifierArgsInfo = [], _identifierArgsInfo = [],
_identifierIsExported = False _identifierIsExported = False,
_identifierBuiltin = Nothing
} }
registerIdent (mkIdentIndex (a ^. Internal.axiomName)) info registerIdent (mkIdentIndex (a ^. Internal.axiomName)) info
registerIdentNode sym body registerIdentNode sym body
@ -554,9 +560,10 @@ goApplication a = do
funInfo <- HashMap.lookupDefault impossible n <$> asks (^. Internal.infoFunctions) funInfo <- HashMap.lookupDefault impossible n <$> asks (^. Internal.infoFunctions)
case funInfo ^. Internal.functionInfoDef . Internal.funDefBuiltin of case funInfo ^. Internal.functionInfoDef . Internal.funDefBuiltin of
Just Internal.BuiltinBoolIf -> do Just Internal.BuiltinBoolIf -> do
sym <- getBoolSymbol
as <- exprArgs as <- exprArgs
case as of case as of
(v : b1 : b2 : xs) -> return (mkApps' (mkIf' v b1 b2) xs) (v : b1 : b2 : xs) -> return (mkApps' (mkIf' sym v b1 b2) xs)
_ -> error "if must be called with 3 arguments" _ -> error "if must be called with 3 arguments"
_ -> app _ -> app
_ -> app _ -> app

View File

@ -45,34 +45,36 @@ guardSymbolNotDefined sym err = do
createBuiltinConstr :: createBuiltinConstr ::
Symbol -> Symbol ->
BuiltinDataTag -> Tag ->
Text -> Text ->
Type -> Type ->
Interval -> Interval ->
Maybe BuiltinConstructor ->
Sem r ConstructorInfo Sem r ConstructorInfo
createBuiltinConstr sym btag nameTxt ty i = do createBuiltinConstr sym tag nameTxt ty i cblt = do
let n = builtinConstrArgsNum btag
return $ return $
ConstructorInfo ConstructorInfo
{ _constructorName = nameTxt, { _constructorName = nameTxt,
_constructorLocation = Just i, _constructorLocation = Just i,
_constructorTag = BuiltinTag btag, _constructorTag = tag,
_constructorType = ty, _constructorType = ty,
_constructorArgsNum = n, _constructorArgsNum = length (typeArgs ty),
_constructorInductive = sym _constructorInductive = sym,
_constructorBuiltin = cblt
} }
declareInductiveBuiltins :: declareInductiveBuiltins ::
Member InfoTableBuilder r => Member InfoTableBuilder r =>
Text -> Text ->
[(BuiltinDataTag, Text, Type -> Type)] -> Maybe BuiltinInductive ->
[(Tag, Text, Type -> Type, Maybe BuiltinConstructor)] ->
ParsecS r () ParsecS r ()
declareInductiveBuiltins indName ctrs = do declareInductiveBuiltins indName blt ctrs = do
loc <- curLoc loc <- curLoc
let i = mkInterval loc loc let i = mkInterval loc loc
sym <- lift freshSymbol sym <- lift freshSymbol
let ty = mkIdent' sym let ty = mkIdent' sym
constrs <- lift $ mapM (\(tag, name, fty) -> createBuiltinConstr sym tag name (fty ty) i) ctrs constrs <- lift $ mapM (\(tag, name, fty, cblt) -> createBuiltinConstr sym tag name (fty ty) i cblt) ctrs
lift $ lift $
registerInductive registerInductive
indName indName
@ -83,7 +85,8 @@ declareInductiveBuiltins indName ctrs = do
_inductiveKind = mkDynamic', _inductiveKind = mkDynamic',
_inductiveConstructors = constrs, _inductiveConstructors = constrs,
_inductivePositive = True, _inductivePositive = True,
_inductiveParams = [] _inductiveParams = [],
_inductiveBuiltin = blt
} }
) )
lift $ mapM_ (\ci -> registerConstructor (ci ^. constructorName) ci) constrs lift $ mapM_ (\ci -> registerConstructor (ci ^. constructorName) ci) constrs
@ -92,18 +95,31 @@ declareIOBuiltins :: Member InfoTableBuilder r => ParsecS r ()
declareIOBuiltins = declareIOBuiltins =
declareInductiveBuiltins declareInductiveBuiltins
"IO" "IO"
[ (TagReturn, "return", mkPi' mkDynamic'), Nothing
(TagBind, "bind", \ty -> mkPi' ty (mkPi' (mkPi' mkDynamic' ty) ty)), [ (BuiltinTag TagReturn, "return", mkPi' mkDynamic', Nothing),
(TagWrite, "write", mkPi' mkDynamic'), (BuiltinTag TagBind, "bind", \ty -> mkPi' ty (mkPi' (mkPi' mkDynamic' ty) ty), Nothing),
(TagReadLn, "readLn", id) (BuiltinTag TagWrite, "write", mkPi' mkDynamic', Nothing),
(BuiltinTag TagReadLn, "readLn", id, Nothing)
] ]
declareBoolBuiltins :: Member InfoTableBuilder r => ParsecS r () declareBoolBuiltins :: Member InfoTableBuilder r => ParsecS r ()
declareBoolBuiltins = declareBoolBuiltins =
declareInductiveBuiltins declareInductiveBuiltins
"bool" "bool"
[ (TagTrue, "true", id), (Just BuiltinBool)
(TagFalse, "false", id) [ (BuiltinTag TagTrue, "true", id, Just BuiltinBoolTrue),
(BuiltinTag TagFalse, "false", id, Just BuiltinBoolFalse)
]
declareNatBuiltins :: Member InfoTableBuilder r => ParsecS r ()
declareNatBuiltins = do
tagZero <- lift freshTag
tagSuc <- lift freshTag
declareInductiveBuiltins
"nat"
(Just BuiltinNat)
[ (tagZero, "zero", id, Just BuiltinNatZero),
(tagSuc, "suc", \x -> mkPi' x x, Just BuiltinNatSuc)
] ]
parseToplevel :: parseToplevel ::
@ -112,6 +128,7 @@ parseToplevel ::
parseToplevel = do parseToplevel = do
declareIOBuiltins declareIOBuiltins
declareBoolBuiltins declareBoolBuiltins
declareNatBuiltins
space space
P.endBy statement (kw kwSemicolon) P.endBy statement (kw kwSemicolon)
r <- optional expression r <- optional expression
@ -121,11 +138,23 @@ parseToplevel = do
statement :: statement ::
Member InfoTableBuilder r => Member InfoTableBuilder r =>
ParsecS r () ParsecS r ()
statement = statementDef <|> statementInductive statement = statementBuiltin <|> void statementDef <|> statementInductive
statementBuiltin ::
Member InfoTableBuilder r =>
ParsecS r ()
statementBuiltin = do
off <- P.getOffset
kw kwBuiltin
sym <- statementDef
ii <- lift $ getIdentifierInfo sym
case ii ^. identifierName of
"plus" -> lift $ registerIdent (ii ^. identifierName) ii {_identifierBuiltin = Just BuiltinNatPlus}
_ -> parseFailure off "unrecorgnized builtin definition"
statementDef :: statementDef ::
Member InfoTableBuilder r => Member InfoTableBuilder r =>
ParsecS r () ParsecS r Symbol
statementDef = do statementDef = do
kw kwDef kw kwDef
off <- P.getOffset off <- P.getOffset
@ -140,6 +169,7 @@ statementDef = do
let fi = fromMaybe impossible $ HashMap.lookup sym (tab ^. infoIdentifiers) let fi = fromMaybe impossible $ HashMap.lookup sym (tab ^. infoIdentifiers)
ty = fi ^. identifierType ty = fi ^. identifierType
parseDefinition sym ty parseDefinition sym ty
return sym
Just IdentInd {} -> Just IdentInd {} ->
parseFailure off ("duplicate identifier: " ++ fromText txt) parseFailure off ("duplicate identifier: " ++ fromText txt)
Just IdentConstr {} -> Just IdentConstr {} ->
@ -156,10 +186,12 @@ statementDef = do
_identifierType = ty, _identifierType = ty,
_identifierArgsNum = 0, _identifierArgsNum = 0,
_identifierArgsInfo = [], _identifierArgsInfo = [],
_identifierIsExported = False _identifierIsExported = False,
_identifierBuiltin = Nothing
} }
lift $ registerIdent txt info lift $ registerIdent txt info
void $ optional (parseDefinition sym ty) void $ optional (parseDefinition sym ty)
return sym
parseDefinition :: parseDefinition ::
Member InfoTableBuilder r => Member InfoTableBuilder r =>
@ -208,7 +240,8 @@ statementInductive = do
_inductiveKind = fromMaybe (mkUniv' 0) mty, _inductiveKind = fromMaybe (mkUniv' 0) mty,
_inductiveConstructors = [], _inductiveConstructors = [],
_inductiveParams = [], _inductiveParams = [],
_inductivePositive = True _inductivePositive = True,
_inductiveBuiltin = Nothing
} }
lift $ registerInductive txt ii lift $ registerInductive txt ii
ctrs <- braces $ P.sepEndBy (constrDecl sym) (kw kwSemicolon) ctrs <- braces $ P.sepEndBy (constrDecl sym) (kw kwSemicolon)
@ -233,7 +266,8 @@ constrDecl symInd = do
_constructorTag = tag, _constructorTag = tag,
_constructorArgsNum = length (typeArgs ty), _constructorArgsNum = length (typeArgs ty),
_constructorType = ty, _constructorType = ty,
_constructorInductive = symInd _constructorInductive = symInd,
_constructorBuiltin = Nothing
} }
lift $ registerConstructor txt ci lift $ registerConstructor txt ci
return ci return ci
@ -742,11 +776,23 @@ exprCase' off value varsNum vars = do
bs <- P.sepEndBy (caseBranchP varsNum vars) (kw kwSemicolon) bs <- P.sepEndBy (caseBranchP varsNum vars) (kw kwSemicolon)
let bss = map fromLeft' $ filter isLeft bs let bss = map fromLeft' $ filter isLeft bs
let def' = map fromRight' $ filter isRight bs let def' = map fromRight' $ filter isRight bs
case bss of
CaseBranch {..} : _ -> do
ci <- lift $ getConstructorInfo _caseBranchTag
let sym = ci ^. constructorInductive
case def' of case def' of
[def] -> [def] ->
return $ mkCase' value bss (Just def) return $ mkCase' sym value bss (Just def)
[] -> [] ->
return $ mkCase' value bss Nothing return $ mkCase' sym value bss Nothing
_ ->
parseFailure off "multiple default branches"
[] ->
case def' of
[_] ->
parseFailure off "case with only the default branch not allowed"
[] ->
parseFailure off "case without branches not allowed"
_ -> _ ->
parseFailure off "multiple default branches" parseFailure off "multiple default branches"
@ -818,7 +864,8 @@ exprIf varsNum vars = do
br1 <- bracedExpr varsNum vars br1 <- bracedExpr varsNum vars
kw kwElse kw kwElse
br2 <- bracedExpr varsNum vars br2 <- bracedExpr varsNum vars
return $ mkIf Info.empty value br1 br2 sym <- lift getBoolSymbol
return $ mkIf mempty sym value br1 br2
exprMatch :: exprMatch ::
Member InfoTableBuilder r => Member InfoTableBuilder r =>

View File

@ -259,5 +259,10 @@ tests =
"Applications with lets and cases in function position" "Applications with lets and cases in function position"
"." "."
"test046.jvc" "test046.jvc"
"out/test046.out" "out/test046.out",
PosTest
"Builtin natural numbers"
"."
"test047.jvc"
"out/test047.out"
] ]

View File

@ -3,7 +3,7 @@ module Core.Transformation where
import Base import Base
import Core.Transformation.Identity qualified as Identity import Core.Transformation.Identity qualified as Identity
import Core.Transformation.Lifting qualified as Lifting import Core.Transformation.Lifting qualified as Lifting
import Core.Transformation.RemoveTypeArgs qualified as RemoveTypeArgs import Core.Transformation.Pipeline qualified as Pipeline
import Core.Transformation.TopEtaExpand qualified as TopEtaExpand import Core.Transformation.TopEtaExpand qualified as TopEtaExpand
allTests :: TestTree allTests :: TestTree
@ -13,5 +13,5 @@ allTests =
[ Identity.allTests, [ Identity.allTests,
TopEtaExpand.allTests, TopEtaExpand.allTests,
Lifting.allTests, Lifting.allTests,
RemoveTypeArgs.allTests Pipeline.allTests
] ]

View File

@ -1,4 +1,4 @@
module Core.Transformation.RemoveTypeArgs (allTests) where module Core.Transformation.Pipeline (allTests) where
import Base import Base
import Core.Eval.Positive qualified as Eval import Core.Eval.Positive qualified as Eval
@ -6,10 +6,10 @@ import Core.Transformation.Base
import Juvix.Compiler.Core.Transformation import Juvix.Compiler.Core.Transformation
allTests :: TestTree allTests :: TestTree
allTests = testGroup "Move applications and remove type arguments" (map liftTest Eval.tests) allTests = testGroup "Transformation pipeline" (map liftTest Eval.tests)
pipe :: [TransformationId] pipe :: [TransformationId]
pipe = [LambdaLifting, MoveApps, RemoveTypeArgs] pipe = [NatToInt, LambdaLifting, MoveApps, RemoveTypeArgs, TopEtaExpand]
liftTest :: Eval.PosTest -> TestTree liftTest :: Eval.PosTest -> TestTree
liftTest _testEval = liftTest _testEval =

View File

@ -0,0 +1,3 @@
3
136
true

View File

@ -9,11 +9,11 @@ def snd := \p case p of { pair _ x := x };
def compose := \f \g \x f (g x); def compose := \f \g \x f (g x);
def zero := \f \x x; def czero := \f \x x;
def num := \n def num := \n
if n = 0 then if n = 0 then
zero czero
else else
\f compose f (num (n - 1) f); \f compose f (num (n - 1) f);
@ -32,7 +32,7 @@ def pred := \n
pair (fst x) (succ (snd x)) pair (fst x) (succ (snd x))
else else
pair (succ (fst x)) (succ (snd x))) pair (succ (fst x)) (succ (snd x)))
(pair zero zero) (pair czero czero)
); );
def toInt := \n n (+ 1) 0; def toInt := \n n (+ 1) 0;
@ -41,11 +41,11 @@ def writeLn := \x write x >> write "\n";
def fib := \n def fib := \n
if isZero n then if isZero n then
zero czero
else else
let n' := pred n in let n' := pred n in
if isZero n' then if isZero n' then
succ zero succ czero
else else
add (fib n') (fib (pred n')); add (fib n') (fib (pred n'));

View File

@ -5,7 +5,7 @@ inductive list {
cons : any -> list -> list; cons : any -> list -> list;
}; };
def f := \l (case l of { cons x _ := x; nil := \x x } ) (let y := \x x in (let z := \x x in case l of { _ := \x x } z) y) 7; def f := \l (case l of { cons x _ := x; nil := \x x } ) (let y := \x x in (let z := \x x in case l of { cons _ _ := \x x } z) y) 7;
def main := f (cons (\x \y x y + 2) nil); def main := f (cons (\x \y x y + 2) nil);

View File

@ -0,0 +1,38 @@
-- builtin natural numbers
builtin def plus := \x \y case x of {
zero := y;
suc x' := suc (plus x' y);
};
def from_int := \n if n = 0 then zero else suc (from_int (n - 1));
def to_int := \x case x of {
suc x' := to_int x' + 1;
zero := 0;
};
def even := \x case x of {
suc x' := case x' of {
zero := false;
suc y := even y;
};
_ := true;
};
def f := \x case x of {
suc x' := (\z case z of {
zero := even x';
suc y := f y;
}) x';
_ := even x;
};
def writeLn := \x write x >> write "\n";
def main :=
writeLn (to_int (if even (from_int 124) then plus (suc zero) (suc (suc zero)) else zero)) >>
writeLn (to_int (plus (from_int 126) (from_int 10))) >>
writeLn (f (from_int 65));
main