Skip to content

Commit

Permalink
Improve Core parser error handling (#3300)
Browse files Browse the repository at this point in the history
* Use `CoreError` for errors unrelated to parsing proper (e.g. scoping
errors like undeclared identifier)
* Adds negative parsing tests
* Fixes parsing of side-conditions in match branches
* Fixes a bug in redundant pattern detection with side-conditions
  • Loading branch information
lukaszcz authored Feb 3, 2025
1 parent ec0003c commit f3e1588
Show file tree
Hide file tree
Showing 46 changed files with 545 additions and 225 deletions.
14 changes: 7 additions & 7 deletions app/Commands/Dev/Core/Repl.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ runCommand opts = do
showReplWelcome
runRepl opts mempty

parseText :: Core.InfoTable -> Text -> Either Core.MegaparsecError (Core.InfoTable, Maybe Core.Node)
parseText :: Core.InfoTable -> Text -> Either JuvixError (Core.InfoTable, Maybe Core.Node)
parseText = Core.runParser replPath defaultModuleId

runRepl :: forall r. (Members '[EmbedIO, App] r) => CoreReplOptions -> Core.InfoTable -> Sem r ()
Expand All @@ -40,7 +40,7 @@ runRepl opts tab = do
':' : 'p' : ' ' : s' ->
case parseText tab (fromString s') of
Left err -> do
printJuvixError (JuvixError err)
printJuvixError err
runRepl opts tab
Right (tab', Just node) -> do
renderStdOut (Core.ppOut opts node)
Expand All @@ -51,7 +51,7 @@ runRepl opts tab = do
':' : 'e' : ' ' : s' ->
case parseText tab (fromString s') of
Left err -> do
printJuvixError (JuvixError err)
printJuvixError err
runRepl opts tab
Right (tab', Just node) ->
replEval True tab' node
Expand All @@ -60,7 +60,7 @@ runRepl opts tab = do
':' : 'n' : ' ' : s' ->
case parseText tab (fromString s') of
Left err -> do
printJuvixError (JuvixError err)
printJuvixError err
runRepl opts tab
Right (tab', Just node) ->
replNormalize tab' node
Expand All @@ -69,7 +69,7 @@ runRepl opts tab = do
':' : 't' : ' ' : s' ->
case parseText tab (fromString s') of
Left err -> do
printJuvixError (JuvixError err)
printJuvixError err
runRepl opts tab
Right (tab', Just node) ->
replType tab' node
Expand All @@ -80,7 +80,7 @@ runRepl opts tab = do
sf <- someBaseToAbs' (someFile f)
case Core.runParser sf defaultModuleId mempty s' of
Left err -> do
printJuvixError (JuvixError err)
printJuvixError err
runRepl opts tab
Right (tab', mnode) -> case mnode of
Nothing -> runRepl opts tab'
Expand All @@ -90,7 +90,7 @@ runRepl opts tab = do
_ ->
case parseText tab s of
Left err -> do
printJuvixError (JuvixError err)
printJuvixError err
runRepl opts tab
Right (tab', Just node) ->
replEval False tab' node
Expand Down
12 changes: 12 additions & 0 deletions src/Juvix/Compiler/Core/Extra/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,18 @@ isPatConstr = \case
PatConstr {} -> True
PatWildcard {} -> False

{------------------------------------------------------------------------}
{- match branch -}

isMatchBranchRhsExpression :: MatchBranch -> Bool
isMatchBranchRhsExpression MatchBranch {..} =
case _matchBranchRhs of
MatchBranchRhsExpression {} -> True
MatchBranchRhsIfs {} -> False

isMatchBranchRhsIf :: MatchBranch -> Bool
isMatchBranchRhsIf = not . isMatchBranchRhsExpression

{------------------------------------------------------------------------}
{- generic Node destruction -}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ detectConstantSideConditions md = mapAllNodesM (umapM go) md
Just ifs0' -> return $ Just $ set matchBranchRhs (MatchBranchRhsIfs ifs0') br
SideIfBranch {..} : ifs1' -> do
fCoverage <- asks (^. optCheckCoverage)
unless (not fCoverage || null ifs1') $
when (fCoverage && not (null ifs1')) $
throw
CoreError
{ _coreErrorMsg = "Redundant side condition",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ goDetectRedundantPatterns md node = case node of
defaultLoc = singletonInterval (mkInitialLoc mockFile)

checkMatch :: Match -> Sem r ()
checkMatch Match {..} = case _matchBranches of
checkMatch Match {..} = case dropWhile isMatchBranchRhsIf $ _matchBranches of
[] -> return ()
MatchBranch {..} : brs -> go [toList _matchBranchPatterns] brs
where
Expand Down
Loading

0 comments on commit f3e1588

Please sign in to comment.