Skip to content

Commit

Permalink
parens record update
Browse files Browse the repository at this point in the history
  • Loading branch information
janmasrovira committed Jul 31, 2023
1 parent 18367da commit f62e1ac
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 27 deletions.
13 changes: 13 additions & 0 deletions src/Juvix/Compiler/Concrete/Language.hs
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,7 @@ data Expression
| ExpressionFunction (Function 'Scoped)
| ExpressionHole (HoleType 'Scoped)
| ExpressionRecordUpdate RecordUpdateApp
| ExpressionParensRecordUpdate ParensRecordUpdate
| ExpressionBraces (WithLoc Expression)
| ExpressionIterator (Iterator 'Scoped)
| ExpressionNamedApplication (NamedApplication 'Scoped)
Expand Down Expand Up @@ -1293,6 +1294,11 @@ data RecordUpdateExtra = RecordUpdateExtra
}
deriving stock (Show)

newtype ParensRecordUpdate = ParensRecordUpdate
{ _parensRecordUpdate :: RecordUpdate 'Scoped
}
deriving stock (Show, Eq, Ord)

data RecordUpdate (s :: Stage) = RecordUpdate
{ _recordUpdateAtKw :: Irrelevant KeywordRef,
_recordUpdateDelims :: Irrelevant (KeywordRef, KeywordRef),
Expand Down Expand Up @@ -1508,6 +1514,7 @@ newtype ModuleIndex = ModuleIndex
}

makeLenses ''PatternArg
makeLenses ''ParensRecordUpdate
makeLenses ''RecordUpdateExtra
makeLenses ''RecordUpdate
makeLenses ''RecordUpdateApp
Expand Down Expand Up @@ -1614,6 +1621,7 @@ instance HasAtomicity Expression where
ExpressionIterator i -> atomicity i
ExpressionNamedApplication i -> atomicity i
ExpressionRecordUpdate {} -> Aggregate updateFixity
ExpressionParensRecordUpdate {} -> Atom

expressionAtomicity :: forall s. SingI s => ExpressionType s -> Atomicity
expressionAtomicity e = case sing :: SStage s of
Expand Down Expand Up @@ -1735,6 +1743,9 @@ instance SingI s => HasLoc (RecordUpdate s) where
instance HasLoc RecordUpdateApp where
getLoc r = getLoc (r ^. recordAppExpression) <> getLoc (r ^. recordAppUpdate)

instance HasLoc ParensRecordUpdate where
getLoc = getLoc . (^. parensRecordUpdate)

instance HasLoc Expression where
getLoc = \case
ExpressionIdentifier i -> getLoc i
Expand All @@ -1754,6 +1765,7 @@ instance HasLoc Expression where
ExpressionIterator i -> getLoc i
ExpressionNamedApplication i -> getLoc i
ExpressionRecordUpdate i -> getLoc i
ExpressionParensRecordUpdate i -> getLoc i

getLocIdentifierType :: forall s. SingI s => IdentifierType s -> Interval
getLocIdentifierType e = case sing :: SStage s of
Expand Down Expand Up @@ -2077,6 +2089,7 @@ instance IsApe Expression ApeLeaf where
ExpressionFunction a -> toApe a
ExpressionNamedApplication a -> toApe a
ExpressionRecordUpdate a -> toApe a
ExpressionParensRecordUpdate {} -> leaf
ExpressionParensIdentifier {} -> leaf
ExpressionIdentifier {} -> leaf
ExpressionList {} -> leaf
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 @@ -614,6 +614,9 @@ instance PrettyPrint IteratorSyntaxDef where
instance PrettyPrint RecordUpdateApp where
ppCode = apeHelper

instance PrettyPrint ParensRecordUpdate where
ppCode = parens . ppCode . (^. parensRecordUpdate)

instance PrettyPrint Expression where
ppCode = \case
ExpressionIdentifier n -> ppCode n
Expand All @@ -633,6 +636,7 @@ instance PrettyPrint Expression where
ExpressionIterator i -> ppCode i
ExpressionNamedApplication i -> ppCode i
ExpressionRecordUpdate i -> ppCode i
ExpressionParensRecordUpdate i -> ppCode i

instance PrettyPrint (WithSource Pragmas) where
ppCode pragma = do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2019,12 +2019,15 @@ checkParens ::
ExpressionAtoms 'Parsed ->
Sem r Expression
checkParens e@(ExpressionAtoms as _) = case as of
AtomIdentifier s :| [] -> do
scopedId <- checkName s
let scopedIdenNoFix = over scopedIden (set S.nameFixity Nothing) scopedId
return (ExpressionParensIdentifier scopedIdenNoFix)
AtomIterator i :| [] -> ExpressionIterator . set iteratorParens True <$> checkIterator i
AtomCase c :| [] -> ExpressionCase . set caseParens True <$> checkCase c
p :| [] -> case p of
AtomIdentifier s -> do
scopedId <- checkName s
let scopedIdenNoFix = over scopedIden (set S.nameFixity Nothing) scopedId
return (ExpressionParensIdentifier scopedIdenNoFix)
AtomIterator i -> ExpressionIterator . set iteratorParens True <$> checkIterator i
AtomCase c -> ExpressionCase . set caseParens True <$> checkCase c
AtomRecordUpdate u -> ExpressionParensRecordUpdate . ParensRecordUpdate <$> checkRecordUpdate u
_ -> checkParseExpressionAtoms e
_ -> checkParseExpressionAtoms e

checkExpressionAtoms ::
Expand Down
39 changes: 20 additions & 19 deletions src/Juvix/Compiler/Internal/Translation/FromConcrete.hs
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ goExpression = \case
ExpressionIterator i -> goIterator i
ExpressionNamedApplication i -> goNamedApplication i
ExpressionRecordUpdate i -> goRecordUpdateApp i
ExpressionParensRecordUpdate i -> Internal.ExpressionLambda <$> goRecordUpdate (i ^. parensRecordUpdate)
where
goNamedApplication :: Concrete.NamedApplication 'Scoped -> Sem r Internal.Expression
goNamedApplication = runNamedArguments >=> goExpression
Expand All @@ -832,25 +833,25 @@ goExpression = \case

mkArgs :: [Indexed Internal.VarName] -> Sem r [Internal.Expression]
mkArgs = execOutputList . go (uncurry Indexed <$> IntMap.toAscList fieldMap)
where
go :: [Indexed (RecordUpdateField 'Scoped)] -> [Indexed Internal.VarName] -> Sem (Output Internal.Expression ': r) ()
go fields = \case
[] -> return ()
Indexed idx var : vars' -> case getArg idx of
Nothing -> do
output (Internal.toExpression var)
go fields vars'
Just (arg, fields') -> do
let fieldVar = goSymbol (arg ^. fieldUpdateName)
val' <- goExpression (arg ^. fieldUpdateValue)
output (Internal.renameVar fieldVar var val')
go fields' vars'
where
getArg :: Int -> Maybe (RecordUpdateField 'Scoped, [Indexed (RecordUpdateField 'Scoped)])
getArg idx = do
Indexed fidx arg :| fs <- nonEmpty fields
guard (idx == fidx)
return (arg, fs)
where
go :: [Indexed (RecordUpdateField 'Scoped)] -> [Indexed Internal.VarName] -> Sem (Output Internal.Expression ': r) ()
go fields = \case
[] -> return ()
Indexed idx var : vars' -> case getArg idx of
Nothing -> do
output (Internal.toExpression var)
go fields vars'
Just (arg, fields') -> do
let fieldVar = goSymbol (arg ^. fieldUpdateName)
val' <- goExpression (arg ^. fieldUpdateValue)
output (Internal.renameVar fieldVar var val')
go fields' vars'
where
getArg :: Int -> Maybe (RecordUpdateField 'Scoped, [Indexed (RecordUpdateField 'Scoped)])
getArg idx = do
Indexed fidx arg :| fs <- nonEmpty fields
guard (idx == fidx)
return (arg, fs)

mkClause :: Sem r Internal.LambdaClause
mkClause = do
Expand Down
2 changes: 1 addition & 1 deletion tests/Compilation/positive/out/test060.out
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mkTriple 3 6 2
mkTriple 30 6 2
3 changes: 2 additions & 1 deletion tests/Compilation/positive/test060.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ main :=
fst := fst + 1;
snd := snd * 3
};
in p';
f : Triple Nat Nat Nat -> Triple Nat Nat Nat := (@Triple {fst := fst * 10});
in f p';

0 comments on commit f62e1ac

Please sign in to comment.