tools/pas2c/PascalPreprocessor.hs
author unc0rr
Fri, 07 Feb 2014 00:46:49 +0400
changeset 10113 b26c2772e754
parent 10015 4feced261c68
child 10119 7e05a397602f
permissions -rw-r--r--
Fix tons and tons of pas2c warnings (but still not all of them)
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
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
     9
import Control.Exception(catch, IOException)
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    10
import Prelude
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    11
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    12
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
    13
char' = void . char
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    14
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    15
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
    16
string' = void . string
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    17
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    18
-- comments are removed
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    19
comment :: ParsecT String u IO String
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    20
comment = choice [
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    21
        char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}') >> return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    22
        , (try $ string "(*") >> manyTill anyChar (try $ string "*)") >> return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    23
        , (try $ string "//") >> manyTill anyChar (try newline) >> return "\n"
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
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    26
preprocess :: String -> String -> String -> [String] -> IO String
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    27
preprocess inputPath alternateInputPath fn symbols = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    28
    r <- runParserT (preprocessFile (inputPath ++ fn)) (Map.fromList $ map (\s -> (s, "")) symbols, [True]) "" ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    29
    case r of
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    30
         (Left a) -> do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    31
             hPutStrLn stderr (show a)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    32
             return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    33
         (Right a) -> return a
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    34
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    35
    where
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    36
    preprocessFile fn' = do
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    37
        f <- liftIO (readFile fn')
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    38
        setInput f
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    39
        preprocessor
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    40
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    41
    preprocessor, codeBlock, switch :: ParsecT String (Map.Map String String, [Bool]) IO String
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    42
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    43
    preprocessor = chainr codeBlock (return (++)) ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    44
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    45
    codeBlock = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    46
        s <- choice [
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    47
            switch
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    48
            , comment
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    49
            , char '\'' >> many (noneOf "'\n") >>= \s -> char '\'' >> return ('\'' : s ++ "'")
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    50
            , identifier >>= replace
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    51
            , noneOf "{" >>= \a -> return [a]
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    52
            ]
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    53
        (_, ok) <- getState
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    54
        return $ if and ok then s else ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    55
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    56
    --otherChar c = c `notElem` "{/('_" && not (isAlphaNum c)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    57
    identifier = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    58
        c <- letter <|> oneOf "_"
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    59
        s <- many (alphaNum <|> oneOf "_")
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    60
        return $ c:s
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    61
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    62
    switch = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    63
        try $ string' "{$"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    64
        s <- choice [
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    65
            include
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    66
            , ifdef
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    67
            , if'
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    68
            , elseSwitch
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    69
            , endIf
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    70
            , define
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    71
            , unknown
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    72
            ]
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    73
        return s
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    74
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    75
    include = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    76
        try $ string' "INCLUDE"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    77
        spaces
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    78
        (char' '"')
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    79
        ifn <- many1 $ noneOf "\"\n"
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    80
        char' '"'
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    81
        spaces
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    82
        char' '}'
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    83
        f <- liftIO (readFile (inputPath ++ ifn) `catch` (\(_ :: IOException) -> readFile (alternateInputPath ++ ifn) `catch` (\(_ :: IOException) -> error ("File not found: " ++ fn))))
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    84
        c <- getInput
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    85
        setInput $ f ++ c
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    86
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    87
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    88
    ifdef = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    89
        s <- try (string "IFDEF") <|> try (string "IFNDEF")
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    90
        let f = if s == "IFNDEF" then not else id
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    91
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    92
        spaces
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    93
        d <- identifier
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    94
        spaces
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
    95
        char' '}'
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    96
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    97
        updateState $ \(m, b) ->
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
    98
            (m, (f $ d `Map.member` m) : b)
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
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   101
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   102
    if' = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   103
        try (string' "IF" >> notFollowedBy alphaNum)
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   104
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   105
        void $ manyTill anyChar (char' '}')
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   106
        --char '}'
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   107
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   108
        updateState $ \(m, b) ->
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   109
            (m, False : b)
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
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   112
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   113
    elseSwitch = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   114
        try $ string' "ELSE}"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   115
        updateState $ \(m, b:bs) -> (m, (not b):bs)
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   116
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   117
    endIf = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   118
        try $ string' "ENDIF}"
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   119
        updateState $ \(m, _:bs) -> (m, bs)
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   120
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   121
    define = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   122
        try $ string' "DEFINE"
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   123
        spaces
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   124
        i <- identifier
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   125
        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
   126
        char' '}'
10015
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   127
        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
   128
        return ""
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   129
    replace s = do
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   130
        (m, _) <- getState
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   131
        return $ Map.findWithDefault s s m
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   132
4feced261c68 partial merge of the webgl branch
koda
parents: 9982
diff changeset
   133
    unknown = do
10113
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   134
        un <- many1 $ noneOf "}\n"
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   135
        char' '}'
b26c2772e754 Fix tons and tons of pas2c warnings (but still not all of them)
unc0rr
parents: 10015
diff changeset
   136
        return $ "{$" ++ un ++ "}"