tools/pas2c/PascalPreprocessor.hs
author unc0rr
Wed, 12 Feb 2014 00:50:15 +0400
changeset 10131 4b4a043111f4
parent 10120 b7f632c12784
child 10240 bfae7354d42f
permissions -rw-r--r--
- pas2c recognizes typecasts in initialization expressions - Forbid incompatible pointer types - Fixes and new functions to fpcrtl
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     1
{-# LANGUAGE ScopedTypeVariables #-}
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     2
module PascalPreprocessor where
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     3
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     4
import Text.Parsec
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     5
import Control.Monad.IO.Class
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     6
import Control.Monad
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     7
import System.IO
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     8
import qualified Data.Map as Map
10119
7e05a397602f Fix build with old base package
unc0rr
parents: 10113
diff changeset
     9
import qualified Control.Exception as E
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    10
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    11
char' :: Char -> ParsecT String u IO ()
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    12
char' = void . char
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    13
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    14
string' :: String -> ParsecT String u IO ()
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    15
string' = void . string
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    16
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    17
-- comments are removed
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    18
comment :: ParsecT String u IO String
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    19
comment = choice [
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    20
        char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}') >> return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    21
        , (try $ string "(*") >> manyTill anyChar (try $ string "*)") >> return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    22
        , (try $ string "//") >> manyTill anyChar (try newline) >> return "\n"
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    23
        ]
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    24
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    25
preprocess :: String -> String -> String -> [String] -> IO String
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    26
preprocess inputPath alternateInputPath fn symbols = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    27
    r <- runParserT (preprocessFile (inputPath ++ fn)) (Map.fromList $ map (\s -> (s, "")) symbols, [True]) "" ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    28
    case r of
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    29
         (Left a) -> do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    30
             hPutStrLn stderr (show a)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    31
             return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    32
         (Right a) -> return a
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    33
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    34
    where
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    35
    preprocessFile fn' = do
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    36
        f <- liftIO (readFile fn')
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    37
        setInput f
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    38
        preprocessor
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    39
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    40
    preprocessor, codeBlock, switch :: ParsecT String (Map.Map String String, [Bool]) IO String
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    41
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    42
    preprocessor = chainr codeBlock (return (++)) ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    43
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    44
    codeBlock = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    45
        s <- choice [
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    46
            switch
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    47
            , comment
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    48
            , char '\'' >> many (noneOf "'\n") >>= \s -> char '\'' >> return ('\'' : s ++ "'")
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    49
            , identifier >>= replace
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    50
            , noneOf "{" >>= \a -> return [a]
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    51
            ]
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    52
        (_, ok) <- getState
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    53
        return $ if and ok then s else ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    54
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    55
    --otherChar c = c `notElem` "{/('_" && not (isAlphaNum c)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    56
    identifier = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    57
        c <- letter <|> oneOf "_"
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    58
        s <- many (alphaNum <|> oneOf "_")
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    59
        return $ c:s
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    60
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    61
    switch = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    62
        try $ string' "{$"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    63
        s <- choice [
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    64
            include
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    65
            , ifdef
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    66
            , if'
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    67
            , elseSwitch
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    68
            , endIf
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    69
            , define
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    70
            , unknown
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    71
            ]
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    72
        return s
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    73
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    74
    include = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    75
        try $ string' "INCLUDE"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    76
        spaces
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    77
        (char' '"')
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    78
        ifn <- many1 $ noneOf "\"\n"
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    79
        char' '"'
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    80
        spaces
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    81
        char' '}'
10119
7e05a397602f Fix build with old base package
unc0rr
parents: 10113
diff changeset
    82
        f <- liftIO (readFile (inputPath ++ ifn) 
7e05a397602f Fix build with old base package
unc0rr
parents: 10113
diff changeset
    83
            `E.catch` (\(_ :: E.IOException) -> readFile (alternateInputPath ++ ifn) 
10120
b7f632c12784 Pas2C recognizes ansistrings
unc0rr
parents: 10119
diff changeset
    84
                `E.catch` (\(_ :: E.IOException) -> error $ "File not found: " ++ ifn)
b7f632c12784 Pas2C recognizes ansistrings
unc0rr
parents: 10119
diff changeset
    85
                )
b7f632c12784 Pas2C recognizes ansistrings
unc0rr
parents: 10119
diff changeset
    86
            )
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    87
        c <- getInput
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    88
        setInput $ f ++ c
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    89
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    90
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    91
    ifdef = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    92
        s <- try (string "IFDEF") <|> try (string "IFNDEF")
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    93
        let f = if s == "IFNDEF" then not else id
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    94
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    95
        spaces
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    96
        d <- identifier
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    97
        spaces
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    98
        char' '}'
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    99
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   100
        updateState $ \(m, b) ->
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   101
            (m, (f $ d `Map.member` m) : b)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   102
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   103
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   104
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   105
    if' = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   106
        try (string' "IF" >> notFollowedBy alphaNum)
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   107
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   108
        void $ manyTill anyChar (char' '}')
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   109
        --char '}'
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   110
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   111
        updateState $ \(m, b) ->
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   112
            (m, False : b)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   113
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   114
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   115
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   116
    elseSwitch = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   117
        try $ string' "ELSE}"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   118
        updateState $ \(m, b:bs) -> (m, (not b):bs)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   119
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   120
    endIf = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   121
        try $ string' "ENDIF}"
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   122
        updateState $ \(m, _:bs) -> (m, bs)
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   123
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   124
    define = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   125
        try $ string' "DEFINE"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   126
        spaces
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   127
        i <- identifier
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   128
        d <- ((string ":=" >> return ()) <|> spaces) >> many (noneOf "}")
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   129
        char' '}'
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   130
        updateState $ \(m, b) -> (if (and b) && (head i /= '_') then Map.insert i d m else m, b)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   131
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   132
    replace s = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   133
        (m, _) <- getState
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   134
        return $ Map.findWithDefault s s m
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   135
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   136
    unknown = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   137
        un <- many1 $ noneOf "}\n"
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   138
        char' '}'
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   139
        return $ "{$" ++ un ++ "}"