diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-04-17 22:06:30 +0200 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-04-17 22:06:30 +0200 |
commit | b03980fcbff57e6ac8c5d8e16e032ba050471ce5 (patch) | |
tree | 375760dcbeed0fd48f8b1163f72ba715f33f0411 /src | |
parent | 761dbf9a6dea9db82657265928bc02b8f48470b3 (diff) |
better error message for mismatching operator fixities
Diffstat (limited to 'src')
-rw-r--r-- | src/LambdaCube/Compiler.hs | 2 | ||||
-rw-r--r-- | src/LambdaCube/Compiler/Lexer.hs | 4 | ||||
-rw-r--r-- | src/LambdaCube/Compiler/Parser.hs | 27 |
3 files changed, 22 insertions, 11 deletions
diff --git a/src/LambdaCube/Compiler.hs b/src/LambdaCube/Compiler.hs index 250fa94d..8530e20a 100644 --- a/src/LambdaCube/Compiler.hs +++ b/src/LambdaCube/Compiler.hs | |||
@@ -198,7 +198,7 @@ loadModule ex imp mname_ = do | |||
198 | let (res, err) = case sequence ms of | 198 | let (res, err) = case sequence ms of |
199 | Left err -> (ex mempty, Left err) | 199 | Left err -> (ex mempty, Left err) |
200 | Right ms@(mconcat -> (ds, ge)) -> case runExcept $ runDefParser ds $ definitions e of | 200 | Right ms@(mconcat -> (ds, ge)) -> case runExcept $ runDefParser ds $ definitions e of |
201 | Left err -> (ex mempty, Left err) | 201 | Left err -> (ex mempty, Left $ show err) |
202 | Right (defs, dsinfo) -> (,) (ex (is, defs)) $ case res of | 202 | Right (defs, dsinfo) -> (,) (ex (is, defs)) $ case res of |
203 | Left err -> Left (show err) | 203 | Left err -> Left (show err) |
204 | Right (mconcat -> newge) -> | 204 | Right (mconcat -> newge) -> |
diff --git a/src/LambdaCube/Compiler/Lexer.hs b/src/LambdaCube/Compiler/Lexer.hs index b44dca20..b0d2e8a3 100644 --- a/src/LambdaCube/Compiler/Lexer.hs +++ b/src/LambdaCube/Compiler/Lexer.hs | |||
@@ -412,7 +412,7 @@ type Fixity = (FixityDef, Int) | |||
412 | type FixityMap = Map.Map SName Fixity | 412 | type FixityMap = Map.Map SName Fixity |
413 | 413 | ||
414 | calcPrec | 414 | calcPrec |
415 | :: (Show e, Show f, MonadError String m) | 415 | :: (Show e, Show f, MonadError (f, f){-operator mismatch-} m) |
416 | => (f -> e -> e -> e) | 416 | => (f -> e -> e -> e) |
417 | -> (f -> Fixity) | 417 | -> (f -> Fixity) |
418 | -> e | 418 | -> e |
@@ -424,7 +424,7 @@ calcPrec app getFixity = compileOps [] | |||
424 | compileOps acc@ ~(((dir', i'), op', e'): acc') e es@ ~((op, e''): es') | 424 | compileOps acc@ ~(((dir', i'), op', e'): acc') e es@ ~((op, e''): es') |
425 | | c == LT || c == EQ && dir == dir' && dir == InfixL = compileOps acc' (app op' e' e) es | 425 | | c == LT || c == EQ && dir == dir' && dir == InfixL = compileOps acc' (app op' e' e) es |
426 | | c == GT || c == EQ && dir == dir' && dir == InfixR = compileOps ((pr, op, e): acc) e'' es' | 426 | | c == GT || c == EQ && dir == dir' && dir == InfixR = compileOps ((pr, op, e): acc) e'' es' |
427 | | otherwise = throwError $ "fixity error:" ++ show (op, op') | 427 | | otherwise = throwError (op', op) -- operator mismatch |
428 | where | 428 | where |
429 | pr@(dir, i) = getFixity op | 429 | pr@(dir, i) = getFixity op |
430 | c | null es = LT | 430 | c | null es = LT |
diff --git a/src/LambdaCube/Compiler/Parser.hs b/src/LambdaCube/Compiler/Parser.hs index 00ef3e49..fcda3145 100644 --- a/src/LambdaCube/Compiler/Parser.hs +++ b/src/LambdaCube/Compiler/Parser.hs | |||
@@ -341,7 +341,18 @@ trSExp f = g where | |||
341 | 341 | ||
342 | type P = Parse DesugarInfo PostponedCheck | 342 | type P = Parse DesugarInfo PostponedCheck |
343 | 343 | ||
344 | type PostponedCheck = Maybe String | 344 | data LCParseError |
345 | = MultiplePatternVars [[SIName]] | ||
346 | | OperatorMismatch (SIName, Fixity) (SIName, Fixity) | ||
347 | | ParseError ParseError | ||
348 | |||
349 | instance Show LCParseError where | ||
350 | show = \case | ||
351 | MultiplePatternVars xs -> "multiple pattern vars:\n" ++ unlines [n ++ " is defined at " ++ ppShow si | ns <- xs, (si, n) <- ns] | ||
352 | OperatorMismatch (op, f) (op', f') -> "Operator precedences don't match:\n" ++ show f ++ " at " ++ showSI (fst op) ++ "\n" ++ show f' ++ " at " ++ showSI (fst op') | ||
353 | ParseError p -> show p | ||
354 | |||
355 | type PostponedCheck = Maybe LCParseError | ||
345 | 356 | ||
346 | getFixity :: DesugarInfo -> SName -> Fixity | 357 | getFixity :: DesugarInfo -> SName -> Fixity |
347 | getFixity (fm, _) n = fromMaybe (InfixL, 9) $ Map.lookup n fm | 358 | getFixity (fm, _) n = fromMaybe (InfixL, 9) $ Map.lookup n fm |
@@ -501,7 +512,7 @@ parseTerm_ prec = case prec of | |||
501 | cont [] = return $ Right [] | 512 | cont [] = return $ Right [] |
502 | cont _ = error "impossible" | 513 | cont _ = error "impossible" |
503 | 514 | ||
504 | calcPrec' = (postponedCheck .) . calcPrec (\op x y -> SGlobal op `SAppV` x `SAppV` y) (getFixity dcls . snd) | 515 | calcPrec' = (postponedCheck dcls .) . calcPrec (\op x y -> SGlobal op `SAppV` x `SAppV` y) (getFixity dcls . snd) |
505 | 516 | ||
506 | generator, letdecl, boolExpression :: P (SExp -> SExp) | 517 | generator, letdecl, boolExpression :: P (SExp -> SExp) |
507 | generator = do | 518 | generator = do |
@@ -648,7 +659,7 @@ parsePat = \case | |||
648 | patType p (Wildcard SType) = p | 659 | patType p (Wildcard SType) = p |
649 | patType p t = PatType (ParPat [p]) t | 660 | patType p t = PatType (ParPat [p]) t |
650 | 661 | ||
651 | calculatePatPrecs dcls (e, xs) = postponedCheck $ calcPrec (\op x y -> PCon op $ ParPat . (:[]) <$> [x, y]) (getFixity dcls . snd) e xs | 662 | calculatePatPrecs dcls (e, xs) = postponedCheck dcls $ calcPrec (\op x y -> PCon op $ ParPat . (:[]) <$> [x, y]) (getFixity dcls . snd) e xs |
652 | 663 | ||
653 | longPattern = parsePat PrecAnn <&> (getPVars &&& id) | 664 | longPattern = parsePat PrecAnn <&> (getPVars &&& id) |
654 | --patternAtom = parsePat PrecAtom <&> (getPVars &&& id) | 665 | --patternAtom = parsePat PrecAtom <&> (getPVars &&& id) |
@@ -664,10 +675,10 @@ checkPattern ns = lift $ tell $ pure $ | |||
664 | case [ns' | ns' <- group . sort . filter (not . null . snd) $ ns | 675 | case [ns' | ns' <- group . sort . filter (not . null . snd) $ ns |
665 | , not . null . tail $ ns'] of | 676 | , not . null . tail $ ns'] of |
666 | [] -> Nothing | 677 | [] -> Nothing |
667 | xs -> Just $ "multiple pattern vars:\n" ++ unlines [n ++ " is defined at " ++ ppShow si | ns <- xs, (si, n) <- ns] | 678 | xs -> Just $ MultiplePatternVars xs |
668 | 679 | ||
669 | postponedCheck x = do | 680 | postponedCheck dcls x = do |
670 | lift $ tell [either Just (const Nothing) x] | 681 | lift $ tell [either (\(op, op') -> Just $ OperatorMismatch (op, getFixity dcls $ snd op) (op', getFixity dcls $ snd op')) (const Nothing) x] |
671 | return $ either (const $ error "impossible") id x | 682 | return $ either (const $ error "impossible") id x |
672 | 683 | ||
673 | -------------------------------------------------------------------------------- pattern match compilation | 684 | -------------------------------------------------------------------------------- pattern match compilation |
@@ -1161,12 +1172,12 @@ parseLC fid f str | |||
1161 | = fst $ parseString (FileInfo fid f str) () parseModule str | 1172 | = fst $ parseString (FileInfo fid f str) () parseModule str |
1162 | 1173 | ||
1163 | --type DefParser = DesugarInfo -> (Either ParseError [Stmt], [PostponedCheck]) | 1174 | --type DefParser = DesugarInfo -> (Either ParseError [Stmt], [PostponedCheck]) |
1164 | runDefParser :: (MonadFix m, MonadError String m) => DesugarInfo -> DefParser -> m ([Stmt], DesugarInfo) | 1175 | runDefParser :: (MonadFix m, MonadError LCParseError m) => DesugarInfo -> DefParser -> m ([Stmt], DesugarInfo) |
1165 | runDefParser ds_ dp = do | 1176 | runDefParser ds_ dp = do |
1166 | 1177 | ||
1167 | (defs, dns, ds) <- mfix $ \ ~(_, _, ds) -> do | 1178 | (defs, dns, ds) <- mfix $ \ ~(_, _, ds) -> do |
1168 | let (x, dns) = dp (ds <> ds_) | 1179 | let (x, dns) = dp (ds <> ds_) |
1169 | defs <- either (throwError . show) return x | 1180 | defs <- either (throwError . ParseError) return x |
1170 | return (defs, dns, mkDesugarInfo defs) | 1181 | return (defs, dns, mkDesugarInfo defs) |
1171 | 1182 | ||
1172 | mapM_ (maybe (return ()) throwError) dns | 1183 | mapM_ (maybe (return ()) throwError) dns |