Skip to content

Commit

Permalink
puns for named application
Browse files Browse the repository at this point in the history
  • Loading branch information
janmasrovira committed Jul 15, 2024
1 parent 5a76e5d commit 07e046d
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 19 deletions.
5 changes: 5 additions & 0 deletions src/Juvix/Compiler/Concrete/Data/Name.hs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ moduleNameToTopModulePath = \case
NameUnqualified s -> TopModulePath [] s
NameQualified (QualifiedName (SymbolPath p) s) -> TopModulePath (toList p) s

fromUnqualified' :: Name -> Symbol
fromUnqualified' = \case
NameUnqualified s -> s
NameQualified {} -> impossible

splitName :: Name -> ([Symbol], Symbol)
splitName = \case
NameQualified (QualifiedName (SymbolPath p) s) -> (toList p, s)
Expand Down
41 changes: 39 additions & 2 deletions src/Juvix/Compiler/Concrete/Language/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ type family ModuleIdType s t = res where
ModuleIdType 'Scoped 'ModuleLocal = ()
ModuleIdType 'Scoped 'ModuleTop = ModuleId

type PunSymbolType :: Stage -> GHCType
type family PunSymbolType s = res | res -> s where
PunSymbolType 'Parsed = ()
PunSymbolType 'Scoped = ScopedIden

type SymbolType :: Stage -> GHCType
type family SymbolType s = res | res -> s where
SymbolType 'Parsed = Symbol
Expand Down Expand Up @@ -2304,8 +2309,35 @@ deriving stock instance Ord (NamedArgumentFunctionDef 'Parsed)

deriving stock instance Ord (NamedArgumentFunctionDef 'Scoped)

newtype NamedArgumentNew (s :: Stage)
data NamedArgumentPun (s :: Stage) = NamedArgumentPun
{ _namedArgumentPunSymbol :: SymbolType s,
_namedArgumentReferencedSymbol :: PunSymbolType s
}
deriving stock (Generic)

instance Serialize (NamedArgumentPun 'Scoped)

instance NFData (NamedArgumentPun 'Scoped)

instance Serialize (NamedArgumentPun 'Parsed)

instance NFData (NamedArgumentPun 'Parsed)

deriving stock instance Show (NamedArgumentPun 'Parsed)

deriving stock instance Show (NamedArgumentPun 'Scoped)

deriving stock instance Eq (NamedArgumentPun 'Parsed)

deriving stock instance Eq (NamedArgumentPun 'Scoped)

deriving stock instance Ord (NamedArgumentPun 'Parsed)

deriving stock instance Ord (NamedArgumentPun 'Scoped)

data NamedArgumentNew (s :: Stage)
= NamedArgumentNewFunction (NamedArgumentFunctionDef s)
| NamedArgumentItemPun (NamedArgumentPun s)
deriving stock (Generic)

instance Serialize (NamedArgumentNew 'Scoped)
Expand Down Expand Up @@ -2628,6 +2660,7 @@ deriving stock instance Ord (JudocAtom 'Scoped)

makeLenses ''SideIfs
makeLenses ''NamedArgumentFunctionDef
makeLenses ''NamedArgumentPun
makeLenses ''IsExhaustive
makeLenses ''SideIfBranch
makeLenses ''RhsExpression
Expand Down Expand Up @@ -2938,6 +2971,9 @@ instance HasLoc (List s) where
instance (SingI s) => HasLoc (NamedApplication s) where
getLoc NamedApplication {..} = getLocIdentifierType _namedAppName <> getLoc (last _namedAppArgs)

instance (SingI s) => HasLoc (NamedArgumentPun s) where
getLoc NamedArgumentPun {..} = getLocSymbolType _namedArgumentPunSymbol

instance (SingI s) => HasLoc (NamedApplicationNew s) where
getLoc NamedApplicationNew {..} = getLocIdentifierType _namedApplicationNewName

Expand Down Expand Up @@ -3223,8 +3259,9 @@ _RecordStatementField f x = case x of
RecordStatementField p -> RecordStatementField <$> f p
_ -> pure x

namedArgumentNewSymbol :: Lens' (NamedArgumentNew s) (SymbolType s)
namedArgumentNewSymbol :: Lens' (NamedArgumentNew 'Parsed) Symbol
namedArgumentNewSymbol f = \case
NamedArgumentItemPun a -> NamedArgumentItemPun <$> namedArgumentPunSymbol f a
NamedArgumentNewFunction a ->
NamedArgumentNewFunction
<$> (namedArgumentFunctionDef . signName) f a
Expand Down
4 changes: 4 additions & 0 deletions src/Juvix/Compiler/Concrete/Print/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,13 @@ instance (SingI s) => PrettyPrint (NamedApplicationNew s) where
instance (SingI s) => PrettyPrint (NamedArgumentFunctionDef s) where
ppCode (NamedArgumentFunctionDef f) = ppCode f

instance (SingI s) => PrettyPrint (NamedArgumentPun s) where
ppCode = ppSymbolType . (^. namedArgumentPunSymbol)

instance (SingI s) => PrettyPrint (NamedArgumentNew s) where
ppCode = \case
NamedArgumentNewFunction f -> ppCode f
NamedArgumentItemPun f -> ppCode f

instance (SingI s) => PrettyPrint (RecordStatement s) where
ppCode = \case
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1563,8 +1563,8 @@ checkSections sec = topBindings helper
failMaybe $
mkRec
^? constructorRhs
. _ConstructorRhsRecord
. to mkRecordNameSignature
. _ConstructorRhsRecord
. to mkRecordNameSignature
let info =
RecordInfo
{ _recordInfoSignature = fs,
Expand Down Expand Up @@ -2573,16 +2573,23 @@ checkExpressionAtom e = case e of
reserveNamedArgumentName :: (Members '[Error ScoperError, NameIdGen, State ScoperSyntax, State Scope, State ScoperState, Reader BindingStrategy, InfoTableBuilder, Reader InfoTable] r) => NamedArgumentNew 'Parsed -> Sem r ()
reserveNamedArgumentName a = case a of
NamedArgumentNewFunction f -> void (reserveFunctionSymbol (f ^. namedArgumentFunctionDef))
NamedArgumentItemPun {} -> return ()

checkNamedApplicationNew :: forall r. (Members '[HighlightBuilder, Error ScoperError, State Scope, State ScoperState, Reader ScopeParameters, InfoTableBuilder, Reader InfoTable, NameIdGen, Reader Package] r) => NamedApplicationNew 'Parsed -> Sem r (NamedApplicationNew 'Scoped)
checkNamedApplicationNew ::
forall r.
(Members '[HighlightBuilder, Error ScoperError, State Scope, State ScoperState, Reader ScopeParameters, InfoTableBuilder, Reader InfoTable, NameIdGen, Reader Package] r) =>
NamedApplicationNew 'Parsed ->
Sem r (NamedApplicationNew 'Scoped)
checkNamedApplicationNew napp = do
let nargs = napp ^. namedApplicationNewArguments
aname <- checkScopedIden (napp ^. namedApplicationNewName)
sig <- if null nargs then return $ NameSignature [] else getNameSignature aname
let snames = HashSet.fromList (concatMap (HashMap.keys . (^. nameBlock)) (sig ^. nameSignatureArgs))
let namesInSignature = hashSet (concatMap (HashMap.keys . (^. nameBlock)) (sig ^. nameSignatureArgs))
forM_ nargs (checkNameInSignature namesInSignature . (^. namedArgumentNewSymbol))
puns <- scopePuns
args' <- withLocalScope . localBindings . ignoreSyntax $ do
mapM_ reserveNamedArgumentName nargs
mapM (checkNamedArgumentNew snames) nargs
mapM (checkNamedArgumentNew puns) nargs
let enames =
HashSet.fromList
. concatMap (HashMap.keys . (^. nameBlock))
Expand All @@ -2598,25 +2605,50 @@ checkNamedApplicationNew napp = do
_namedApplicationNewArguments = args',
_namedApplicationNewExhaustive = napp ^. namedApplicationNewExhaustive
}
where
checkNameInSignature :: HashSet Symbol -> Symbol -> Sem r ()
checkNameInSignature namesInSig fname =
unless (HashSet.member fname namesInSig) $
throw (ErrUnexpectedArgument (UnexpectedArgument fname))

scopePuns :: Sem r (HashMap Symbol ScopedIden)
scopePuns =
hashMap
<$> mapWithM
scopePun
(napp ^.. namedApplicationNewArguments . each . _NamedArgumentItemPun . namedArgumentPunSymbol)
where
scopePun :: Symbol -> Sem r ScopedIden
scopePun = checkScopedIden . NameUnqualified

checkNamedArgumentNew ::
(Members '[HighlightBuilder, Error ScoperError, State Scope, State ScoperState, Reader ScopeParameters, InfoTableBuilder, Reader InfoTable, NameIdGen, Reader Package] r) =>
HashSet Symbol ->
HashMap Symbol ScopedIden ->
NamedArgumentNew 'Parsed ->
Sem r (NamedArgumentNew 'Scoped)
checkNamedArgumentNew snames = \case
NamedArgumentNewFunction f -> NamedArgumentNewFunction <$> checkNamedArgumentFunctionDef snames f
checkNamedArgumentNew puns = \case
NamedArgumentNewFunction f -> NamedArgumentNewFunction <$> checkNamedArgumentFunctionDef f
NamedArgumentItemPun f -> NamedArgumentItemPun <$> checkNamedArgumentItemPun puns f

checkNamedArgumentItemPun ::
(Members '[Error ScoperError, NameIdGen, State Scope, InfoTableBuilder, Reader InfoTable, State ScoperState] r) =>
HashMap Symbol ScopedIden ->
NamedArgumentPun 'Parsed ->
Sem r (NamedArgumentPun 'Scoped)
checkNamedArgumentItemPun puns NamedArgumentPun {..} = localBindings . ignoreSyntax $ do
sym' <- getReservedDefinitionSymbol _namedArgumentPunSymbol
return
NamedArgumentPun
{ _namedArgumentPunSymbol = sym',
_namedArgumentReferencedSymbol = fromJust (puns ^. at _namedArgumentPunSymbol)
}

checkNamedArgumentFunctionDef ::
(Members '[HighlightBuilder, Error ScoperError, State Scope, State ScoperState, Reader ScopeParameters, InfoTableBuilder, Reader InfoTable, NameIdGen, Reader Package] r) =>
HashSet Symbol ->
NamedArgumentFunctionDef 'Parsed ->
Sem r (NamedArgumentFunctionDef 'Scoped)
checkNamedArgumentFunctionDef snames NamedArgumentFunctionDef {..} = do
checkNamedArgumentFunctionDef NamedArgumentFunctionDef {..} = do
def <- localBindings . ignoreSyntax $ checkFunctionDef _namedArgumentFunctionDef
let fname = def ^. signName . nameConcrete
unless (HashSet.member fname snames) $
throw (ErrUnexpectedArgument (UnexpectedArgument fname))
return
NamedArgumentFunctionDef
{ _namedArgumentFunctionDef = def
Expand Down
16 changes: 15 additions & 1 deletion src/Juvix/Compiler/Concrete/Translation/FromSource.hs
Original file line number Diff line number Diff line change
Expand Up @@ -983,11 +983,25 @@ pnamedArgumentFunctionDef = do
{ _namedArgumentFunctionDef = fun
}

pnamedArgumentItemPun ::
forall r.
(Members '[ParserResultBuilder, PragmasStash, JudocStash] r) =>
ParsecS r (NamedArgumentPun 'Parsed)
pnamedArgumentItemPun = do
sym <- symbol
return
NamedArgumentPun
{ _namedArgumentPunSymbol = sym,
_namedArgumentReferencedSymbol = ()
}

namedArgumentNew ::
forall r.
(Members '[ParserResultBuilder, PragmasStash, JudocStash] r) =>
ParsecS r (NamedArgumentNew 'Parsed)
namedArgumentNew = NamedArgumentNewFunction <$> pnamedArgumentFunctionDef
namedArgumentNew =
P.try (NamedArgumentItemPun <$> pnamedArgumentItemPun)
<|> NamedArgumentNewFunction <$> pnamedArgumentFunctionDef

pisExhaustive ::
forall r.
Expand Down
15 changes: 12 additions & 3 deletions src/Juvix/Compiler/Internal/Translation/FromConcrete.hs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,11 @@ createArgumentBlocks appargs =
. evalState args0
. mapM_ goBlock
where
args0 :: HashSet S.Symbol = hashSet ((^. namedArgumentNewSymbol) <$> appargs)
namedArgumentRefSymbol :: NamedArgumentNew 'Scoped -> S.Symbol
namedArgumentRefSymbol = \case
NamedArgumentNewFunction p -> p ^. namedArgumentFunctionDef . signName
NamedArgumentItemPun p -> over S.nameConcrete fromUnqualified' (p ^. namedArgumentReferencedSymbol . scopedIdenFinal)
args0 :: HashSet S.Symbol = hashSet (namedArgumentRefSymbol <$> appargs)
goBlock ::
forall r.
(Members '[State (HashSet S.Symbol), Output (ArgumentBlock 'Scoped)] r) =>
Expand All @@ -738,7 +742,7 @@ createArgumentBlocks appargs =
HashSet.intersection
(HashMap.keysSet _nameBlock)
(HashSet.map (^. S.nameConcrete) args)
argNames :: HashMap Symbol S.Symbol = hashMap . map (\n -> (n ^. S.nameConcrete, n)) $ toList args
argNames :: HashMap Symbol S.Symbol = indexedByHash (^. S.nameConcrete) args
getName sym = fromJust (argNames ^. at sym)
whenJust (nonEmpty namesInBlock) $ \(namesInBlock1 :: NonEmpty Symbol) -> do
let block' =
Expand All @@ -755,7 +759,12 @@ createArgumentBlocks appargs =
NamedArgumentAssign
{ _namedArgName = sym,
_namedArgAssignKw = Irrelevant dummyKw,
_namedArgValue = Concrete.ExpressionIdentifier (ScopedIden name Nothing)
_namedArgValue =
Concrete.ExpressionIdentifier
ScopedIden
{ _scopedIdenFinal = name,
_scopedIdenAlias = Nothing
}
}
where
name :: S.Name = over S.nameConcrete NameUnqualified sym
Expand Down

0 comments on commit 07e046d

Please sign in to comment.