tools/pas2c/PascalBasics.hs
branchsdl2transition
changeset 11362 ed5a6478e710
parent 10120 b7f632c12784
child 15988 24545642473f
equal deleted inserted replaced
11361:31570b766315 11362:ed5a6478e710
       
     1 {-# LANGUAGE FlexibleContexts, NoMonomorphismRestriction #-}
       
     2 module PascalBasics where
       
     3 
       
     4 import Text.Parsec.Combinator
       
     5 import Text.Parsec.Char
       
     6 import Text.Parsec.Prim
       
     7 import Text.Parsec.Token
       
     8 import Text.Parsec.Language
       
     9 import Data.Char
       
    10 import Control.Monad
       
    11 import Data.Functor.Identity
       
    12 
       
    13 char' :: Char -> Parsec String u ()
       
    14 char' = void . char
       
    15 
       
    16 string' :: String -> Parsec String u ()
       
    17 string' = void . string
       
    18 
       
    19 builtin :: [String]
       
    20 builtin = ["succ", "pred", "low", "high", "ord", "inc", "dec", "exit", "break", "continue", "length", "copy"]
       
    21 
       
    22 pascalLanguageDef :: GenLanguageDef String u Identity
       
    23 pascalLanguageDef
       
    24     = emptyDef
       
    25     { commentStart   = "(*"
       
    26     , commentEnd     = "*)"
       
    27     , commentLine    = "//"
       
    28     , nestedComments = False
       
    29     , identStart     = letter <|> oneOf "_"
       
    30     , identLetter    = alphaNum <|> oneOf "_"
       
    31     , opLetter       = letter
       
    32     , reservedNames  = [
       
    33             "begin", "end", "program", "unit", "interface"
       
    34             , "implementation", "and", "or", "xor", "shl"
       
    35             , "shr", "while", "do", "repeat", "until", "case", "of"
       
    36             , "type", "var", "const", "out", "array", "packed"
       
    37             , "procedure", "function", "with", "for", "to"
       
    38             , "downto", "div", "mod", "record", "set", "nil"
       
    39             , "cdecl", "external", "if", "then", "else"
       
    40             ] -- ++ builtin
       
    41     , caseSensitive  = False
       
    42     }
       
    43 
       
    44 preprocessorSwitch :: Stream String Identity Char => Parsec String u String
       
    45 preprocessorSwitch = do
       
    46     try $ string' "{$"
       
    47     s <- manyTill (noneOf "\n") $ char '}'
       
    48     return s
       
    49 
       
    50 caseInsensitiveString :: Stream String Identity Char => String -> Parsec String u String
       
    51 caseInsensitiveString s = do
       
    52     mapM_ (\a -> satisfy (\b -> toUpper a == toUpper b)) s <?> s
       
    53     return s
       
    54 
       
    55 pas :: GenTokenParser String u Identity
       
    56 pas = patch $ makeTokenParser pascalLanguageDef
       
    57     where
       
    58     patch tp = tp {stringLiteral = stringL}
       
    59 
       
    60 comment :: Stream String Identity Char => Parsec String u String
       
    61 comment = choice [
       
    62         char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}')
       
    63         , (try $ string "(*") >> manyTill anyChar (try $ string "*)")
       
    64         , (try $ string "//") >> manyTill anyChar (try newline)
       
    65         ]
       
    66 
       
    67 comments :: Parsec String u ()
       
    68 comments = do
       
    69     spaces
       
    70     skipMany $ do
       
    71         void $ preprocessorSwitch <|> comment
       
    72         spaces
       
    73 
       
    74 stringL :: Parsec String u String
       
    75 stringL = do
       
    76     char' '\''
       
    77     s <- (many $ noneOf "'")
       
    78     char' '\''
       
    79     ss <- many $ do
       
    80         char' '\''
       
    81         s' <- (many $ noneOf "'")
       
    82         char' '\''
       
    83         return $ '\'' : s'
       
    84     comments
       
    85     return $ concat (s:ss)