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

Allow record fields to be iterators #2909

Merged
merged 5 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion src/Juvix/Compiler/Concrete/Data/NameSignature/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ instance (SingI s) => HasNameSignature s (InductiveDef s, ConstructorDef s) wher
addField :: RecordStatement s -> Sem r ()
addField = \case
RecordStatementField RecordField {..} -> addSymbol @s Explicit Nothing _fieldName _fieldType
RecordStatementOperator {} -> return ()
RecordStatementSyntax d -> goSyntax d

goSyntax :: RecordSyntaxDef s -> Sem r ()
goSyntax = \case
RecordSyntaxOperator {} -> return ()
RecordSyntaxIterator {} -> return ()

addRhs :: ConstructorRhs s -> Sem r ()
addRhs = \case
ConstructorRhsGadt g -> addExpressionType (g ^. rhsGadtType)
Expand Down
33 changes: 31 additions & 2 deletions src/Juvix/Compiler/Concrete/Language/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,10 @@ data ParsedIteratorInfo = ParsedIteratorInfo
}
deriving stock (Show, Eq, Ord, Generic)

instance Serialize ParsedIteratorInfo

instance NFData ParsedIteratorInfo

data SyntaxDef (s :: Stage)
= SyntaxFixity (FixitySyntaxDef s)
| SyntaxOperator OperatorSyntaxDef
Expand Down Expand Up @@ -487,7 +491,11 @@ data IteratorSyntaxDef = IteratorSyntaxDef
_iterSyntaxKw :: KeywordRef,
_iterIteratorKw :: KeywordRef
}
deriving stock (Show, Eq, Ord)
deriving stock (Show, Eq, Ord, Generic)

instance Serialize IteratorSyntaxDef

instance NFData IteratorSyntaxDef

instance HasLoc IteratorSyntaxDef where
getLoc IteratorSyntaxDef {..} = getLoc _iterSyntaxKw <> getLoc _iterSymbol
Expand Down Expand Up @@ -2397,9 +2405,30 @@ deriving stock instance Ord (NamedApplicationNew 'Parsed)

deriving stock instance Ord (NamedApplicationNew 'Scoped)

data RecordSyntaxDef (s :: Stage)
= RecordSyntaxOperator OperatorSyntaxDef
| RecordSyntaxIterator IteratorSyntaxDef
deriving stock (Generic)

instance Serialize (RecordSyntaxDef 'Scoped)

instance NFData (RecordSyntaxDef 'Scoped)

deriving stock instance Show (RecordSyntaxDef 'Parsed)

deriving stock instance Show (RecordSyntaxDef 'Scoped)

deriving stock instance Eq (RecordSyntaxDef 'Parsed)

deriving stock instance Eq (RecordSyntaxDef 'Scoped)

deriving stock instance Ord (RecordSyntaxDef 'Parsed)

deriving stock instance Ord (RecordSyntaxDef 'Scoped)

data RecordStatement (s :: Stage)
= RecordStatementField (RecordField s)
| RecordStatementOperator OperatorSyntaxDef
| RecordStatementSyntax (RecordSyntaxDef s)
deriving stock (Generic)

instance Serialize (RecordStatement 'Scoped)
Expand Down
7 changes: 6 additions & 1 deletion src/Juvix/Compiler/Concrete/Print/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,15 @@ instance (SingI s) => PrettyPrint (NamedArgumentNew s) where
NamedArgumentNewFunction f -> ppCode f
NamedArgumentItemPun f -> ppCode f

instance PrettyPrint (RecordSyntaxDef s) where
ppCode = \case
RecordSyntaxOperator d -> ppCode d
RecordSyntaxIterator d -> ppCode d

instance (SingI s) => PrettyPrint (RecordStatement s) where
ppCode = \case
RecordStatementField f -> ppCode f
RecordStatementOperator f -> ppCode f
RecordStatementSyntax f -> ppCode f

instance (SingI s) => PrettyPrint (RecordUpdateField s) where
ppCode RecordUpdateField {..} =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1203,14 +1203,17 @@ checkInductiveDef InductiveDef {..} = do
return rhs'
where
checkRecordStatements :: [RecordStatement 'Parsed] -> Sem r [RecordStatement 'Scoped]
checkRecordStatements = \case
[] -> return []
f : fs -> case f of
RecordStatementOperator d ->
(RecordStatementOperator d :) <$> checkRecordStatements fs
RecordStatementField d -> do
d' <- checkField d
(RecordStatementField d' :) <$> checkRecordStatements fs
checkRecordStatements = mapM checkRecordStatement

checkRecordSyntaxDef :: RecordSyntaxDef 'Parsed -> Sem r (RecordSyntaxDef 'Scoped)
checkRecordSyntaxDef = \case
RecordSyntaxOperator d -> return (RecordSyntaxOperator d)
RecordSyntaxIterator d -> return (RecordSyntaxIterator d)

checkRecordStatement :: RecordStatement 'Parsed -> Sem r (RecordStatement 'Scoped)
checkRecordStatement = \case
RecordStatementField d -> RecordStatementField <$> checkField d
RecordStatementSyntax s -> RecordStatementSyntax <$> checkRecordSyntaxDef s

checkField :: RecordField 'Parsed -> Sem r (RecordField 'Scoped)
checkField RecordField {..} = do
Expand Down Expand Up @@ -1611,11 +1614,13 @@ checkSections sec = topBindings helper
where
goRecordStatement :: RecordStatement 'Parsed -> Sem '[State Int] (Statement 'Parsed)
goRecordStatement = \case
RecordStatementOperator f -> StatementSyntax . SyntaxOperator <$> goOperator f
RecordStatementSyntax f -> StatementSyntax <$> goSyntax f
RecordStatementField f -> goField f
where
goOperator :: OperatorSyntaxDef -> Sem '[State Int] OperatorSyntaxDef
goOperator = pure
goSyntax :: RecordSyntaxDef 'Parsed -> Sem s (SyntaxDef 'Parsed)
goSyntax = \case
RecordSyntaxOperator d -> return (SyntaxOperator d)
RecordSyntaxIterator d -> return (SyntaxIterator d)

goField :: RecordField 'Parsed -> Sem '[State Int] (Statement 'Parsed)
goField f = do
Expand Down
9 changes: 5 additions & 4 deletions src/Juvix/Compiler/Concrete/Translation/FromSource.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1549,13 +1549,14 @@ rhsRecord = P.label "<constructor record>" $ do

recordStatement :: forall r. (Members '[ParserResultBuilder, PragmasStash, JudocStash] r) => ParsecS r (RecordStatement 'Parsed)
recordStatement =
RecordStatementOperator <$> operator
RecordStatementSyntax <$> syntax
<|> RecordStatementField <$> recordField
where
operator :: ParsecS r OperatorSyntaxDef
operator = do
syntax :: ParsecS r (RecordSyntaxDef 'Parsed)
syntax = do
syn <- kw kwSyntax
operatorSyntaxDef syn
RecordSyntaxIterator <$> iteratorSyntaxDef syn
<|> RecordSyntaxOperator <$> operatorSyntaxDef syn

pconstructorRhs :: (Members '[ParserResultBuilder, PragmasStash, JudocStash] r) => ParsecS r (ConstructorRhs 'Parsed)
pconstructorRhs =
Expand Down
2 changes: 1 addition & 1 deletion src/Juvix/Compiler/Internal/Translation/FromConcrete.hs
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ goConstructorDef retTy ConstructorDef {..} = do
where
goRecordStatement :: Concrete.RecordStatement 'Scoped -> Sem r (Maybe Internal.FunctionParameter)
goRecordStatement = \case
Concrete.RecordStatementOperator {} -> return Nothing
Concrete.RecordStatementSyntax {} -> return Nothing
Concrete.RecordStatementField RecordField {..} -> do
ty' <- goExpression _fieldType
return $
Expand Down
6 changes: 5 additions & 1 deletion test/Scope/Positive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -249,5 +249,9 @@ tests =
posTest
"Named argument puns"
$(mkRelDir ".")
$(mkRelFile "Puns.juvix")
$(mkRelFile "Puns.juvix"),
posTest
"Record field iterator"
$(mkRelDir ".")
$(mkRelFile "RecordIterator.juvix")
]
22 changes: 22 additions & 0 deletions tests/positive/RecordIterator.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module RecordIterator;

trait
type Foldable (container elem : Type) :=
mkFoldable {
syntax iterator for {init := 1; range := 1};
for : {B : Type} -> (B -> elem -> B) -> B -> container -> B;

syntax iterator rfor {init := 1; range := 1};
rfor : {B : Type} -> (B -> elem -> B) -> B → container → B
};

open Foldable;

foldl
{container elem}
{{Foldable container elem}}
{B : Type}
(g : B -> elem -> B)
(ini : B)
(ls : container)
: B := for (acc := ini) (x in ls) {g acc x};
Loading