{- This module was generated from data in the Kate syntax
   highlighting file rust.xml, version 0.9, by  -}

module Text.Highlighting.Kate.Syntax.Rust
          (highlight, parseExpression, syntaxName, syntaxExtensions)
where
import Text.Highlighting.Kate.Types
import Text.Highlighting.Kate.Common
import Text.ParserCombinators.Parsec hiding (State)
import Control.Monad.State
import Data.Char (isSpace)
import qualified Data.Set as Set

-- | Full name of language.
syntaxName :: String
syntaxName = "Rust"

-- | Filename extensions for this language.
syntaxExtensions :: String
syntaxExtensions = "*.rs;*.rc"

-- | Highlight source code using this syntax definition.
highlight :: String -> [SourceLine]
highlight input = evalState (mapM parseSourceLine $ lines input) startingState

parseSourceLine :: String -> State SyntaxState SourceLine
parseSourceLine = mkParseSourceLine (parseExpression Nothing)

-- | Parse an expression using appropriate local context.
parseExpression :: Maybe (String,String)
                -> KateParser Token
parseExpression mbcontext = do
  (lang,cont) <- maybe currentContext return mbcontext
  result <- parseRules (lang,cont)
  optional $ do eof
                updateState $ \st -> st{ synStPrevChar = '\n' }
                pEndLine
  return result

startingState = SyntaxState {synStContexts = [("Rust","Normal")], synStLineNumber = 0, synStPrevChar = '\n', synStPrevNonspace = False, synStCaseSensitive = True, synStKeywordCaseSensitive = True, synStCaptures = []}

pEndLine = do
  updateState $ \st -> st{ synStPrevNonspace = False }
  context <- currentContext
  contexts <- synStContexts `fmap` getState
  if length contexts >= 2
    then case context of
      ("Rust","Normal") -> return ()
      ("Rust","Attribute") -> return ()
      ("Rust","Function") -> return ()
      ("Rust","Type") -> return ()
      ("Rust","String") -> return ()
      ("Rust","Character") -> (popContext) >> pEndLine
      ("Rust","CharEscape") -> (popContext) >> pEndLine
      ("Rust","Commentar 1") -> (popContext) >> pEndLine
      ("Rust","Commentar 2") -> return ()
      _ -> return ()
    else return ()

withAttribute attr txt = do
  when (null txt) $ fail "Parser matched no text"
  updateState $ \st -> st { synStPrevChar = last txt
                          , synStPrevNonspace = synStPrevNonspace st || not (all isSpace txt) }
  return (attr, txt)

list_fn = Set.fromList $ words $ "fn"
list_type = Set.fromList $ words $ "type"
list_keywords = Set.fromList $ words $ "as break continue do drop else enum extern for if impl let loop match mod mut priv pub ref return static struct super trait unsafe use while"
list_traits = Set.fromList $ words $ "Const Copy Send Owned Sized Eq Ord Num Ptr Drop Add Sub Mul Quot Rem Neg BitAnd BitOr BitXor Shl Shr Index Not"
list_types = Set.fromList $ words $ "bool int uint i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 float char str Either Option Result Self"
list_ctypes = Set.fromList $ words $ "c_float c_double c_void FILE fpos_t DIR dirent c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong size_t ptrdiff_t clock_t time_t c_longlong c_ulonglong intptr_t uintptr_t off_t dev_t ino_t pid_t mode_t ssize_t"
list_self = Set.fromList $ words $ "self"
list_constants = Set.fromList $ words $ "true false Some None Left Right Ok Err Success Failure Cons Nil"
list_cconstants = Set.fromList $ words $ "EXIT_FAILURE EXIT_SUCCESS RAND_MAX EOF SEEK_SET SEEK_CUR SEEK_END _IOFBF _IONBF _IOLBF BUFSIZ FOPEN_MAX FILENAME_MAX L_tmpnam TMP_MAX O_RDONLY O_WRONLY O_RDWR O_APPEND O_CREAT O_EXCL O_TRUNC S_IFIFO S_IFCHR S_IFBLK S_IFDIR S_IFREG S_IFMT S_IEXEC S_IWRITE S_IREAD S_IRWXU S_IXUSR S_IWUSR S_IRUSR F_OK R_OK W_OK X_OK STDIN_FILENO STDOUT_FILENO STDERR_FILENO"

regex_0x'5b0'2d9a'2dfA'2dF'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex "0x[0-9a-fA-F_]+([iu](8|16|32|64)?)?"
regex_0o'5b0'2d7'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex "0o[0-7_]+([iu](8|16|32|64)?)?"
regex_0b'5b0'2d1'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex "0b[0-1_]+([iu](8|16|32|64)?)?"
regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'5c'2e'5b0'2d9'5f'5d'2a'28'5beE'5d'5b'2b'2d'5d'3f'5b0'2d9'5f'5d'2b'29'3f'28f32'7cf64'7cf'29'3f = compileRegex "[0-9][0-9_]*\\.[0-9_]*([eE][+-]?[0-9_]+)?(f32|f64|f)?"
regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex "[0-9][0-9_]*([iu](8|16|32|64)?)?"
regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'3a'3a = compileRegex "[a-zA-Z_][a-zA-Z_0-9]*::"
regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'21 = compileRegex "[a-zA-Z_][a-zA-Z_0-9]*!"
regex_'27'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'28'3f'21'27'29 = compileRegex "'[a-zA-Z_][a-zA-Z_0-9]*(?!')"
regex_x'5b0'2d9a'2dfA'2dF'5d'7b2'7d = compileRegex "x[0-9a-fA-F]{2}"
regex_u'5b0'2d9a'2dfA'2dF'5d'7b4'7d = compileRegex "u[0-9a-fA-F]{4}"
regex_U'5b0'2d9a'2dfA'2dF'5d'7b8'7d = compileRegex "U[0-9a-fA-F]{8}"
regex_'2e = compileRegex "."

parseRules ("Rust","Normal") =
  (((pDetectSpaces >>= withAttribute NormalTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_fn >>= withAttribute KeywordTok) >>~ pushContext ("Rust","Function"))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_type >>= withAttribute KeywordTok) >>~ pushContext ("Rust","Type"))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_keywords >>= withAttribute KeywordTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_types >>= withAttribute KeywordTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_traits >>= withAttribute KeywordTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_ctypes >>= withAttribute NormalTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_self >>= withAttribute KeywordTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_constants >>= withAttribute KeywordTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_cconstants >>= withAttribute NormalTok))
   <|>
   ((pDetect2Chars False '/' '/' >>= withAttribute CommentTok) >>~ pushContext ("Rust","Commentar 1"))
   <|>
   ((pDetect2Chars False '/' '*' >>= withAttribute CommentTok) >>~ pushContext ("Rust","Commentar 2"))
   <|>
   ((pRegExpr regex_0x'5b0'2d9a'2dfA'2dF'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_0o'5b0'2d7'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_0b'5b0'2d1'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'5c'2e'5b0'2d9'5f'5d'2a'28'5beE'5d'5b'2b'2d'5d'3f'5b0'2d9'5f'5d'2b'29'3f'28f32'7cf64'7cf'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pDetect2Chars False '#' '[' >>= withAttribute OtherTok) >>~ pushContext ("Rust","Attribute"))
   <|>
   ((pRegExpr regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'3a'3a >>= withAttribute NormalTok))
   <|>
   ((pRegExpr regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'21 >>= withAttribute OtherTok))
   <|>
   ((pRegExpr regex_'27'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'28'3f'21'27'29 >>= withAttribute OtherTok))
   <|>
   ((pDetectChar False '{' >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False '}' >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False '"' >>= withAttribute StringTok) >>~ pushContext ("Rust","String"))
   <|>
   ((pDetectChar False '\'' >>= withAttribute CharTok) >>~ pushContext ("Rust","Character"))
   <|>
   ((pDetectChar False '[' >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False ']' >>= withAttribute NormalTok))
   <|>
   ((pDetectIdentifier >>= withAttribute NormalTok))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Normal")) >> pDefault >>= withAttribute NormalTok))

parseRules ("Rust","Attribute") =
  (((pDetectChar False ']' >>= withAttribute OtherTok) >>~ (popContext))
   <|>
   ((parseRules ("Rust","Normal")))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Attribute")) >> pDefault >>= withAttribute OtherTok))

parseRules ("Rust","Function") =
  (((pDetectSpaces >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False '(' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   ((pDetectChar False '<' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Function")) >> pDefault >>= withAttribute NormalTok))

parseRules ("Rust","Type") =
  (((pDetectSpaces >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False '=' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   ((pDetectChar False '<' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Type")) >> pDefault >>= withAttribute NormalTok))

parseRules ("Rust","String") =
  (((pLineContinue >>= withAttribute StringTok))
   <|>
   ((pDetectChar False '\\' >>= withAttribute CharTok) >>~ pushContext ("Rust","CharEscape"))
   <|>
   ((pDetectChar False '"' >>= withAttribute StringTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","String")) >> pDefault >>= withAttribute StringTok))

parseRules ("Rust","Character") =
  (((pDetectChar False '\\' >>= withAttribute CharTok) >>~ pushContext ("Rust","CharEscape"))
   <|>
   ((pDetectChar False '\'' >>= withAttribute CharTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Character")) >> pDefault >>= withAttribute CharTok))

parseRules ("Rust","CharEscape") =
  (((pAnyChar "nrt\\'\"" >>= withAttribute CharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_x'5b0'2d9a'2dfA'2dF'5d'7b2'7d >>= withAttribute CharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_u'5b0'2d9a'2dfA'2dF'5d'7b4'7d >>= withAttribute CharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_U'5b0'2d9a'2dfA'2dF'5d'7b8'7d >>= withAttribute CharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_'2e >>= withAttribute ErrorTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","CharEscape")) >> pDefault >>= withAttribute CharTok))

parseRules ("Rust","Commentar 1") =
  (currentContext >>= \x -> guard (x == ("Rust","Commentar 1")) >> pDefault >>= withAttribute CommentTok)

parseRules ("Rust","Commentar 2") =
  (((pDetectSpaces >>= withAttribute CommentTok))
   <|>
   ((pDetect2Chars False '*' '/' >>= withAttribute CommentTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Commentar 2")) >> pDefault >>= withAttribute CommentTok))


parseRules x = parseRules ("Rust","Normal") <|> fail ("Unknown context" ++ show x)