summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-04-17 22:06:30 +0200
committerPéter Diviánszky <divipp@gmail.com>2016-04-17 22:06:30 +0200
commitb03980fcbff57e6ac8c5d8e16e032ba050471ce5 (patch)
tree375760dcbeed0fd48f8b1163f72ba715f33f0411 /src
parent761dbf9a6dea9db82657265928bc02b8f48470b3 (diff)
better error message for mismatching operator fixities
Diffstat (limited to 'src')
-rw-r--r--src/LambdaCube/Compiler.hs2
-rw-r--r--src/LambdaCube/Compiler/Lexer.hs4
-rw-r--r--src/LambdaCube/Compiler/Parser.hs27
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)
412type FixityMap = Map.Map SName Fixity 412type FixityMap = Map.Map SName Fixity
413 413
414calcPrec 414calcPrec
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
342type P = Parse DesugarInfo PostponedCheck 342type P = Parse DesugarInfo PostponedCheck
343 343
344type PostponedCheck = Maybe String 344data LCParseError
345 = MultiplePatternVars [[SIName]]
346 | OperatorMismatch (SIName, Fixity) (SIName, Fixity)
347 | ParseError ParseError
348
349instance 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
355type PostponedCheck = Maybe LCParseError
345 356
346getFixity :: DesugarInfo -> SName -> Fixity 357getFixity :: DesugarInfo -> SName -> Fixity
347getFixity (fm, _) n = fromMaybe (InfixL, 9) $ Map.lookup n fm 358getFixity (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
653longPattern = parsePat PrecAnn <&> (getPVars &&& id) 664longPattern = 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
669postponedCheck x = do 680postponedCheck 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])
1164runDefParser :: (MonadFix m, MonadError String m) => DesugarInfo -> DefParser -> m ([Stmt], DesugarInfo) 1175runDefParser :: (MonadFix m, MonadError LCParseError m) => DesugarInfo -> DefParser -> m ([Stmt], DesugarInfo)
1165runDefParser ds_ dp = do 1176runDefParser 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