module Language.Qux.Annotated.Exception (
TypeException,
duplicateFunctionName, duplicateParameterName, invalidArgumentsCount, mismatchedType,
undefinedFunctionCall
) where
import Data.List (intercalate)
import Language.Qux.Annotated.Parser (SourcePos, sourceName, sourceLine, sourceColumn)
import Language.Qux.Annotated.PrettyPrinter
import qualified Language.Qux.Annotated.Syntax as Ann
import Language.Qux.Syntax
import Text.PrettyPrint (doubleQuotes)
data TypeException = TypeException SourcePos String
instance Show TypeException where
show (TypeException pos message) = show pos ++ ":\n" ++ message
duplicateFunctionName :: Ann.Decl SourcePos -> TypeException
duplicateFunctionName (Ann.FunctionDecl pos (Ann.Id _ name) _ _) = TypeException pos ("duplicate function name \"" ++ name ++ "\"")
duplicateParameterName :: Ann.Id SourcePos -> TypeException
duplicateParameterName (Ann.Id pos name) = TypeException pos ("duplicate parameter name \"" ++ name ++ "\"")
invalidArgumentsCount :: Ann.Expr SourcePos -> Int -> TypeException
invalidArgumentsCount (Ann.ApplicationExpr pos _ arguments) expected = TypeException pos $ intercalate " " [
"invalid arguments count", show $ length arguments,
"\nexpecting", show expected
]
mismatchedType :: Ann.Type SourcePos -> [Type] -> TypeException
mismatchedType received expects = TypeException (Ann.ann received) $ intercalate " " [
"unexpected type", renderOneLine $ doubleQuotes (pPrint received),
"\nexpecting", sentence "or" (map (renderOneLine . doubleQuotes . pPrint) expects)
]
undefinedFunctionCall :: Ann.Expr SourcePos -> TypeException
undefinedFunctionCall (Ann.ApplicationExpr pos (Ann.Id _ name) _) = TypeException pos ("call to undefined function \"" ++ name ++ "\"")
sentence :: String -> [String] -> String
sentence _ [x] = x
sentence sep xs = intercalate " " [intercalate ", " (map show $ init xs), sep, show $ last xs]