Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependent default values #2446

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c719dee
wip
janmasrovira Oct 17, 2023
a16a030
add test
janmasrovira Oct 17, 2023
0e4dbbf
use type of arguments
janmasrovira Oct 17, 2023
6660d59
refactor RecordCreation
janmasrovira Oct 17, 2023
b314dcc
fix indices
janmasrovira Oct 17, 2023
3c0106e
wip
janmasrovira Oct 18, 2023
fc79e1f
properly type synonyms with holes
janmasrovira Oct 18, 2023
d0e8b57
implement type checking of dependent defaults
janmasrovira Oct 19, 2023
8bd5658
match and normalize let expressions
janmasrovira Oct 19, 2023
7d19de1
cloning
janmasrovira Oct 19, 2023
15df889
fix cloning
janmasrovira Oct 20, 2023
80ac38a
clone FunctionParameter
janmasrovira Oct 20, 2023
1e7380d
wip
janmasrovira Oct 20, 2023
f054be1
fix cloning of function types
janmasrovira Oct 20, 2023
59b3cb2
remove comment
janmasrovira Oct 20, 2023
78f5710
revert test
janmasrovira Oct 20, 2023
839245e
add non-mutual keyword
janmasrovira Oct 20, 2023
870c24d
allow recursive generated lets
janmasrovira Oct 20, 2023
682833e
move tests
janmasrovira Oct 20, 2023
9dfad64
Merge branch 'main' into 2445-allow-default-values-to-refer-to-previo…
janmasrovira Oct 20, 2023
64cec5d
ormolu
janmasrovira Oct 20, 2023
fffe1fa
typo
janmasrovira Oct 20, 2023
2d8ecb5
add missing file
janmasrovira Oct 21, 2023
6382cc6
adjust arity checker for dependent default arguments
janmasrovira Oct 22, 2023
36f4e9c
support implicit arities other than unit
janmasrovira Oct 22, 2023
5357115
add ArgInfo
janmasrovira Oct 23, 2023
aea61af
use effects
janmasrovira Oct 23, 2023
dc849c6
insert dependent defaults in arity checker
janmasrovira Oct 23, 2023
81b2c55
do not create helper let when no default args
janmasrovira Oct 24, 2023
753d184
fix Eq instance
janmasrovira Oct 24, 2023
d91acf3
ormolu
janmasrovira Oct 24, 2023
0e06f2b
move tests
janmasrovira Oct 24, 2023
e7c127f
Merge branch 'main' into 2445-allow-default-values-to-refer-to-previo…
janmasrovira Oct 24, 2023
5e189c3
fix
janmasrovira Oct 24, 2023
beb3efd
rename test modules
janmasrovira Oct 24, 2023
b1130d1
add test output
janmasrovira Oct 24, 2023
eb63211
add test with nested applications
janmasrovira Oct 24, 2023
9866da8
scan default arguments for termination
janmasrovira Oct 24, 2023
5512193
avoid overflow in test
janmasrovira Oct 24, 2023
0a5b328
add negative termination test
janmasrovira Oct 24, 2023
d6526d7
format
janmasrovira Oct 25, 2023
78ceb67
Merge branch 'main' into 2445-allow-default-values-to-refer-to-previo…
lukaszcz Oct 25, 2023
e886aa2
Detect default arguments cycles (#2471)
janmasrovira Oct 25, 2023
2898e74
fix compilation
lukaszcz Oct 25, 2023
bc38000
Merge branch 'main' into 2445-allow-default-values-to-refer-to-previo…
lukaszcz Oct 26, 2023
2ee8134
address review comments
janmasrovira Oct 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 42 additions & 21 deletions src/Juvix/Compiler/Concrete/Data/NameSignature/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ where
import Data.HashMap.Strict qualified as HashMap
import Juvix.Compiler.Concrete.Data.NameSignature.Error
import Juvix.Compiler.Concrete.Extra (symbolParsed)
import Juvix.Compiler.Concrete.Gen qualified as Gen
import Juvix.Compiler.Concrete.Translation.FromParsed.Analysis.Scoping.Error
import Juvix.Prelude

data NameSignatureBuilder s m a where
AddSymbol :: IsImplicit -> Maybe (ArgDefault s) -> Symbol -> NameSignatureBuilder s m ()
AddSymbol :: IsImplicit -> Maybe (ArgDefault s) -> SymbolType s -> ExpressionType s -> NameSignatureBuilder s m ()
EndBuild :: Proxy s -> NameSignatureBuilder s m a
-- | for debugging
GetBuilder :: NameSignatureBuilder s m (BuilderState s)
Expand All @@ -25,7 +26,7 @@ data BuilderState (s :: Stage) = BuilderState
{ _stateCurrentImplicit :: Maybe IsImplicit,
_stateNextIx :: Int,
-- | maps to itself
_stateSymbols :: HashMap Symbol Symbol,
_stateSymbols :: HashMap Symbol (SymbolType s),
_stateReverseClosedBlocks :: [NameBlock s],
_stateCurrentBlock :: HashMap Symbol (NameItem s)
}
Expand Down Expand Up @@ -60,7 +61,7 @@ instance (SingI s) => HasNameSignature s (InductiveDef s, ConstructorDef s) wher
where
addField :: RecordStatement s -> Sem r ()
addField = \case
RecordStatementField RecordField {..} -> addSymbol @s Explicit Nothing (symbolParsed _fieldName)
RecordStatementField RecordField {..} -> addSymbol @s Explicit Nothing _fieldName _fieldType
RecordStatementOperator {} -> return ()
addRhs :: ConstructorRhs s -> Sem r ()
addRhs = \case
Expand Down Expand Up @@ -121,12 +122,12 @@ addExpression = \case
addFunctionParameters (f ^. funParameters)
addExpression (f ^. funReturn)

addFunctionParameters :: forall s r. (SingI s, Members '[NameSignatureBuilder s] r) => FunctionParameters s -> Sem r ()
addFunctionParameters :: forall s r. (Members '[NameSignatureBuilder s] r) => FunctionParameters s -> Sem r ()
addFunctionParameters FunctionParameters {..} = forM_ _paramNames addParameter
where
addParameter :: FunctionParameter s -> Sem r ()
addParameter = \case
FunctionParameterName p -> addSymbol @s _paramImplicit Nothing (symbolParsed p)
FunctionParameterName p -> addSymbol @s _paramImplicit Nothing p _paramType
FunctionParameterWildcard {} -> endBuild (Proxy @s)

addExpressionType :: forall s r. (SingI s, Members '[NameSignatureBuilder s] r) => ExpressionType s -> Sem r ()
Expand All @@ -144,8 +145,12 @@ addAtoms atoms = addAtom . (^. expressionAtoms . _head1) $ atoms
addAtoms (f ^. funReturn)
_ -> endBuild (Proxy @'Parsed)

addInductiveParams' :: forall s r. (SingI s) => (Members '[NameSignatureBuilder s] r) => IsImplicit -> InductiveParameters s -> Sem r ()
addInductiveParams' i a = forM_ (a ^. inductiveParametersNames) (addSymbol @s i Nothing . symbolParsed)
addInductiveParams' :: forall s r. (SingI s, Members '[NameSignatureBuilder s] r) => IsImplicit -> InductiveParameters s -> Sem r ()
addInductiveParams' i a =
forM_ (a ^. inductiveParametersNames) $ \sym ->
addSymbol @s i Nothing sym defaultType
where
defaultType = run (runReader (getLoc a) Gen.smallUniverseExpression)

addInductiveParams :: (SingI s, Members '[NameSignatureBuilder s] r) => InductiveParameters s -> Sem r ()
addInductiveParams = addInductiveParams' Explicit
Expand All @@ -155,7 +160,14 @@ addConstructorParams = addInductiveParams' Implicit

addSigArg :: (SingI s, Members '[NameSignatureBuilder s] r) => SigArg s -> Sem r ()
addSigArg a = forM_ (a ^. sigArgNames) $ \case
ArgumentSymbol s -> addSymbol (a ^. sigArgImplicit) (a ^. sigArgDefault) (symbolParsed s)
ArgumentSymbol s ->
addSymbol
(a ^. sigArgImplicit)
(a ^. sigArgDefault)
s
(fromMaybe defaultType (a ^. sigArgType))
where
defaultType = run (runReader (getLoc a) Gen.smallUniverseExpression)
ArgumentWildcard {} -> return ()

type Re s r = State (BuilderState s) ': Error (BuilderState s) ': Error NameSignatureError ': r
Expand All @@ -166,13 +178,13 @@ re ::
Sem (NameSignatureBuilder s ': r) a ->
Sem (Re s r) a
re = reinterpret3 $ \case
AddSymbol impl mdef k -> addSymbol' impl mdef k
AddSymbol impl mdef k ty -> addSymbol' impl mdef k ty
EndBuild {} -> endBuild'
GetBuilder -> get
{-# INLINE re #-}

addSymbol' :: forall s r. (SingI s) => IsImplicit -> Maybe (ArgDefault s) -> Symbol -> Sem (Re s r) ()
addSymbol' impl mdef sym = do
addSymbol' :: forall s r. (SingI s) => IsImplicit -> Maybe (ArgDefault s) -> SymbolType s -> ExpressionType s -> Sem (Re s r) ()
addSymbol' impl mdef sym ty = do
curImpl <- gets @(BuilderState s) (^. stateCurrentImplicit)
if
| Just impl == curImpl -> addToCurrentBlock
Expand All @@ -183,18 +195,25 @@ addSymbol' impl mdef sym = do
throw $
ErrDuplicateName
DuplicateName
{ _dupNameSecond = sym,
{ _dupNameSecond = symbolParsed sym,
..
}

addToCurrentBlock :: Sem (Re s r) ()
addToCurrentBlock = do
idx <- gets @(BuilderState s) (^. stateNextIx)
let itm = NameItem sym idx mdef
let itm =
NameItem
{ _nameItemDefault = mdef,
_nameItemSymbol = sym,
_nameItemIndex = idx,
_nameItemType = ty
}
psym = symbolParsed sym
modify' @(BuilderState s) (over stateNextIx succ)
whenJustM (gets @(BuilderState s) (^. stateSymbols . at sym)) errDuplicateName
modify' @(BuilderState s) (set (stateSymbols . at sym) (Just sym))
modify' @(BuilderState s) (set (stateCurrentBlock . at sym) (Just itm))
whenJustM (gets @(BuilderState s) (^. stateSymbols . at psym)) (errDuplicateName . symbolParsed)
modify' @(BuilderState s) (set (stateSymbols . at psym) (Just sym))
modify' @(BuilderState s) (set (stateCurrentBlock . at psym) (Just itm))

startNewBlock :: Sem (Re s r) ()
startNewBlock = do
Expand All @@ -205,17 +224,19 @@ addSymbol' impl mdef sym = do
modify' @(BuilderState s) (set stateNextIx 0)
whenJust mcurImpl $ \curImpl ->
modify' (over stateReverseClosedBlocks (NameBlock curBlock curImpl :))
addSymbol' impl mdef sym
addSymbol' impl mdef sym ty

endBuild' :: forall s r a. Sem (Re s r) a
endBuild' = get @(BuilderState s) >>= throw

mkRecordNameSignature :: RhsRecord 'Parsed -> RecordNameSignature
mkRecordNameSignature :: forall s. (SingI s) => RhsRecord s -> RecordNameSignature s
mkRecordNameSignature rhs =
RecordNameSignature
( HashMap.fromList
[ (s, (NameItem s idx Nothing))
| (Indexed idx field) <- indexFrom 0 (toList (rhs ^.. rhsRecordStatements . each . _RecordStatementField)),
let s = field ^. fieldName
[ (symbolParsed _nameItemSymbol, NameItem {..})
| (Indexed _nameItemIndex field) <- indexFrom 0 (toList (rhs ^.. rhsRecordStatements . each . _RecordStatementField)),
let _nameItemSymbol :: SymbolType s = field ^. fieldName
_nameItemType = field ^. fieldType
_nameItemDefault :: Maybe (ArgDefault s) = Nothing
]
)
5 changes: 3 additions & 2 deletions src/Juvix/Compiler/Concrete/Data/Scope/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ data ScopeParameters = ScopeParameters

data RecordInfo = RecordInfo
{ _recordInfoConstructor :: S.Symbol,
_recordInfoSignature :: RecordNameSignature
_recordInfoSignature :: RecordNameSignature 'Parsed
}

data ScoperState = ScoperState
Expand All @@ -64,7 +64,8 @@ data ScoperState = ScoperState
-- | Indexed by the inductive type. This is used for record updates
_scoperRecordFields :: HashMap S.NameId RecordInfo,
-- | Indexed by constructor. This is used for record patterns
_scoperConstructorFields :: HashMap S.NameId RecordNameSignature
_scoperConstructorFields :: HashMap S.NameId (RecordNameSignature 'Parsed),
_scoperScopedConstructorFields :: HashMap S.NameId (RecordNameSignature 'Scoped)
}

data SymbolOperator = SymbolOperator
Expand Down
4 changes: 2 additions & 2 deletions src/Juvix/Compiler/Concrete/Extra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ flattenStatement = \case
StatementModule m -> concatMap flattenStatement (m ^. moduleBody)
s -> [s]

recordNameSignatureByIndex :: RecordNameSignature -> IntMap Symbol
recordNameSignatureByIndex :: forall s. (SingI s) => RecordNameSignature s -> IntMap Symbol
recordNameSignatureByIndex = IntMap.fromList . (^.. recordNames . each . to mkAssoc)
where
mkAssoc :: NameItem s -> (Int, Symbol)
mkAssoc NameItem {..} = (_nameItemIndex, _nameItemSymbol)
mkAssoc NameItem {..} = (_nameItemIndex, symbolParsed _nameItemSymbol)

getExpressionAtomIden :: ExpressionAtom 'Scoped -> Maybe S.Name
getExpressionAtomIden = \case
Expand Down
11 changes: 11 additions & 0 deletions src/Juvix/Compiler/Concrete/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ kw k = do
_keywordRefUnicode = Ascii,
_keywordRefInterval = loc
}

smallUniverseExpression :: forall s r. (SingI s) => (Members '[Reader Interval] r) => Sem r (ExpressionType s)
smallUniverseExpression = do
loc <- ask @Interval
return $ case sing :: SStage s of
SScoped -> ExpressionUniverse (smallUniverse loc)
SParsed ->
ExpressionAtoms
{ _expressionAtomsLoc = Irrelevant loc,
_expressionAtoms = pure (AtomUniverse (smallUniverse loc))
}
18 changes: 9 additions & 9 deletions src/Juvix/Compiler/Concrete/Language.hs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ type family ImportType s = res | res -> s where
type RecordNameSignatureType :: Stage -> GHC.Type
type family RecordNameSignatureType s = res | res -> s where
RecordNameSignatureType 'Parsed = ()
RecordNameSignatureType 'Scoped = RecordNameSignature
RecordNameSignatureType 'Scoped = RecordNameSignature 'Parsed

type NameSignatureType :: Stage -> GHC.Type
type family NameSignatureType s = res | res -> s where
Expand Down Expand Up @@ -149,8 +149,9 @@ type family ModuleEndType t = res | res -> t where
type ParsedPragmas = WithLoc (WithSource Pragmas)

data NameItem (s :: Stage) = NameItem
{ _nameItemSymbol :: Symbol,
{ _nameItemSymbol :: SymbolType s,
_nameItemIndex :: Int,
_nameItemType :: ExpressionType s,
_nameItemDefault :: Maybe (ArgDefault s)
}

Expand All @@ -166,8 +167,8 @@ newtype NameSignature (s :: Stage) = NameSignature
{ _nameSignatureArgs :: [NameBlock s]
}

newtype RecordNameSignature = RecordNameSignature
{ _recordNames :: HashMap Symbol (NameItem 'Parsed)
newtype RecordNameSignature s = RecordNameSignature
{ _recordNames :: HashMap Symbol (NameItem s)
}

data Argument (s :: Stage)
Expand Down Expand Up @@ -859,6 +860,7 @@ deriving stock instance Ord (RecordPatternItem 'Scoped)

data RecordPattern (s :: Stage) = RecordPattern
{ _recordPatternConstructor :: IdentifierType s,
-- TODO remove this field. This information should be retrieved from the scoper state.
_recordPatternSignature :: Irrelevant (RecordNameSignatureType s),
_recordPatternItems :: [RecordPatternItem s]
}
Expand Down Expand Up @@ -1578,14 +1580,12 @@ deriving stock instance Ord (ArgumentBlock 'Scoped)
data RecordUpdateExtra = RecordUpdateExtra
{ _recordUpdateExtraConstructor :: S.Symbol,
-- | Implicitly bound fields sorted by index
_recordUpdateExtraVars :: [S.Symbol],
_recordUpdateExtraSignature :: RecordNameSignature
_recordUpdateExtraVars :: [S.Symbol]
}

data RecordCreationExtra = RecordCreationExtra
newtype RecordCreationExtra = RecordCreationExtra
{ -- | Implicitly bound fields sorted by index
_recordCreationExtraVars :: [S.Symbol],
_recordCreationExtraSignature :: RecordNameSignature
_recordCreationExtraVars :: [S.Symbol]
}

newtype ParensRecordUpdate = ParensRecordUpdate
Expand Down
2 changes: 1 addition & 1 deletion src/Juvix/Compiler/Concrete/Print/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ instance (SingI s) => PrettyPrint (NameItem s) where
let defaultVal = do
d <- _nameItemDefault
return (noLoc C.kwAssign <+> ppExpressionType (d ^. argDefaultValue))
ppCode _nameItemSymbol <> ppCode Kw.kwExclamation <> noLoc (pretty _nameItemIndex)
ppSymbolType _nameItemSymbol <> ppCode Kw.kwExclamation <> noLoc (pretty _nameItemIndex)
<+?> defaultVal

instance (SingI s) => PrettyPrint (NameBlock s) where
Expand Down
Loading