tools/pas2c.hs
author koda
Fri, 06 Jan 2012 01:51:04 +0100
changeset 6551 a2f39cb9af62
parent 6520 6fecdc5d182f
child 6552 91adc9ee7b8c
permissions -rw-r--r--
fix a couple of loose ends: sdl_mixer is informed of that OGG is provided by Tremor with its own macro, there is no more a segfault on Tremor cleanup, added new event type and timestamp entry for SDL, removed spurious characters from the japanese translation, uSound errors now are output with SDLTry, uSound doesn't need sound preloading any more
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
     1
module Pas2C where
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
     2
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
     3
import Text.PrettyPrint.HughesPJ
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
     4
import Data.Maybe
6277
627b5752733a A try to improve parser move (has regressions)
unc0rr
parents: 6275
diff changeset
     5
import Data.Char
6511
bc6e67598dde Ok, State monad instead
unc0rr
parents: 6509
diff changeset
     6
import Text.Parsec.Prim hiding (State)
6417
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
     7
import Control.Monad.State
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
     8
import System.IO
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
     9
import System.Directory
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
    10
import Control.Monad.IO.Class
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
    11
import PascalPreprocessor
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
    12
import Control.Exception
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
    13
import System.IO.Error
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    14
import qualified Data.Map as Map
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
    15
import Data.List (find)
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
    16
6467
090269e528df - Improve parsing of prefix operators
unc0rr
parents: 6455
diff changeset
    17
import PascalParser
090269e528df - Improve parsing of prefix operators
unc0rr
parents: 6455
diff changeset
    18
import PascalUnitSyntaxTree
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
    19
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    20
data RenderState = RenderState 
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    21
    {
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    22
        currentScope :: [(String, String)],
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    23
        namespaces :: Map.Map String [(String, String)]
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    24
    }
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
    25
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    26
pas2C :: String -> IO ()
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    27
pas2C fn = do
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    28
    setCurrentDirectory "../hedgewars/"
6455
d2b13364eddd More verbose progress log, dump the result
unc0rr
parents: 6453
diff changeset
    29
    s <- flip execStateT initState $ f fn
6514
8ba891d34eba - Fix type2C id2C call
unc0rr
parents: 6512
diff changeset
    30
    renderCFiles s
6417
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
    31
    where
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
    32
    printLn = liftIO . hPutStrLn stderr
6455
d2b13364eddd More verbose progress log, dump the result
unc0rr
parents: 6453
diff changeset
    33
    print = liftIO . hPutStr stderr
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    34
    initState = Map.empty
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    35
    f :: String -> StateT (Map.Map String PascalUnit) IO ()
6417
eae5900fd8a4 Improve parser a bit, preparation to parsing whole program at once and compiling it into single C file
unc0rr
parents: 6399
diff changeset
    36
    f fileName = do
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    37
        processed <- gets $ Map.member fileName
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    38
        unless processed $ do
6455
d2b13364eddd More verbose progress log, dump the result
unc0rr
parents: 6453
diff changeset
    39
            print ("Preprocessing '" ++ fileName ++ ".pas'... ")
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    40
            fc' <- liftIO 
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    41
                $ tryJust (guard . isDoesNotExistError) 
6455
d2b13364eddd More verbose progress log, dump the result
unc0rr
parents: 6453
diff changeset
    42
                $ preprocess (fileName ++ ".pas")
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    43
            case fc' of
6453
11c578d30bd3 Countless imporvements to the parser and countless help to the parser in sources.
unc0rr
parents: 6450
diff changeset
    44
                (Left a) -> do
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
    45
                    modify (Map.insert fileName (System []))
6453
11c578d30bd3 Countless imporvements to the parser and countless help to the parser in sources.
unc0rr
parents: 6450
diff changeset
    46
                    printLn "doesn't exist"
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    47
                (Right fc) -> do
6455
d2b13364eddd More verbose progress log, dump the result
unc0rr
parents: 6453
diff changeset
    48
                    print "ok, parsing... "
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    49
                    let ptree = parse pascalUnit fileName fc
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    50
                    case ptree of
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    51
                         (Left a) -> do
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    52
                            liftIO $ writeFile "preprocess.out" fc
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    53
                            printLn $ show a ++ "\nsee preprocess.out for preprocessed source"
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    54
                            fail "stop"
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    55
                         (Right a) -> do
6455
d2b13364eddd More verbose progress log, dump the result
unc0rr
parents: 6453
diff changeset
    56
                            printLn "ok"
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    57
                            modify (Map.insert fileName a)
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
    58
                            mapM_ f (usesFiles a)
6455
d2b13364eddd More verbose progress log, dump the result
unc0rr
parents: 6453
diff changeset
    59
6514
8ba891d34eba - Fix type2C id2C call
unc0rr
parents: 6512
diff changeset
    60
8ba891d34eba - Fix type2C id2C call
unc0rr
parents: 6512
diff changeset
    61
renderCFiles :: Map.Map String PascalUnit -> IO ()
8ba891d34eba - Fix type2C id2C call
unc0rr
parents: 6512
diff changeset
    62
renderCFiles units = do
8ba891d34eba - Fix type2C id2C call
unc0rr
parents: 6512
diff changeset
    63
    let u = Map.toList units
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    64
    let ns = Map.map toNamespace units
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    65
    mapM_ (toCFiles ns) u
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    66
    where
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    67
    toNamespace :: PascalUnit -> [(String, String)]
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    68
    toNamespace = concatMap tv2id . extractTVs
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    69
    
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    70
    extractTVs (System tv) = tv
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    71
    extractTVs (Program {}) = []
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    72
    extractTVs (Unit _ (Interface _ (TypesAndVars tv)) _ _ _) = tv
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    73
    
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    74
    tv2id :: TypeVarDeclaration -> [(String, String)]
6520
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
    75
    tv2id (TypeDeclaration i (Sequence ids)) = map (\(Identifier i _) -> fi i) $ i : ids
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
    76
    tv2id (TypeDeclaration (Identifier i _) _) = [(map toLower i, i)]
6520
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
    77
    tv2id (VarDeclaration _ (ids, _) _) = map (\(Identifier i _) -> fi i) ids
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
    78
    tv2id (FunctionDeclaration (Identifier i _) _ _ _) = [fi i]
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
    79
    tv2id (OperatorDeclaration i _ _ _ _) = [fi i]
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
    80
    fi i = (map toLower i, i)
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    81
    
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    82
    
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    83
toCFiles :: Map.Map String [(String, String)] -> (String, PascalUnit) -> IO ()
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    84
toCFiles _ (_, System _) = return ()
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    85
toCFiles ns p@(fn, pu) = do
6474
42e9773eedfd - Improve renderer a bit, disallow nested functions
unc0rr
parents: 6467
diff changeset
    86
    hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..."
42e9773eedfd - Improve renderer a bit, disallow nested functions
unc0rr
parents: 6467
diff changeset
    87
    toCFiles' p
42e9773eedfd - Improve renderer a bit, disallow nested functions
unc0rr
parents: 6467
diff changeset
    88
    where
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    89
    toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render2C (RenderState [] ns) . pascal2C) p
6474
42e9773eedfd - Improve renderer a bit, disallow nested functions
unc0rr
parents: 6467
diff changeset
    90
    toCFiles' (fn, (Unit _ interface implementation _ _)) = do
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    91
        let (a, s) = runState (interface2C interface) (RenderState [] ns)
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    92
        writeFile (fn ++ ".h") $ "#pragma once\n" ++ (render a)
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    93
        writeFile (fn ++ ".c") $ (render2C s . implementation2C) implementation
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
    94
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    95
    render2C :: RenderState -> State RenderState Doc -> String
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
    96
    render2C a = render . flip evalState a
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
    97
6467
090269e528df - Improve parsing of prefix operators
unc0rr
parents: 6455
diff changeset
    98
usesFiles :: PascalUnit -> [String]
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
    99
usesFiles (Program _ (Implementation uses _) _) = "pas2cSystem" : uses2List uses
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   100
usesFiles (Unit _ (Interface uses1 _) (Implementation uses2 _) _ _) = "pas2cSystem" : uses2List uses1 ++ uses2List uses2
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   101
usesFiles (System {}) = []
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
   102
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
   103
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   104
pascal2C :: PascalUnit -> State RenderState Doc
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   105
pascal2C (Unit _ interface implementation init fin) =
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   106
    liftM2 ($+$) (interface2C interface) (implementation2C implementation)
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   107
    
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   108
pascal2C (Program _ implementation mainFunction) = do
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   109
    impl <- implementation2C implementation
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   110
    main <- tvar2C True 
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   111
        (FunctionDeclaration (Identifier "main" BTInt) (SimpleType $ Identifier "int" BTInt) [] (Just (TypesAndVars [], mainFunction)))
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   112
    return $ impl $+$ main
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   113
6467
090269e528df - Improve parsing of prefix operators
unc0rr
parents: 6455
diff changeset
   114
    
090269e528df - Improve parsing of prefix operators
unc0rr
parents: 6455
diff changeset
   115
    
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   116
interface2C :: Interface -> State RenderState Doc
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   117
interface2C (Interface uses tvars) = liftM2 ($+$) (uses2C uses) (typesAndVars2C True tvars)
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   118
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   119
implementation2C :: Implementation -> State RenderState Doc
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   120
implementation2C (Implementation uses tvars) = liftM2 ($+$) (uses2C uses) (typesAndVars2C True tvars)
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   121
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   122
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   123
typesAndVars2C :: Bool -> TypesAndVars -> State RenderState Doc
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   124
typesAndVars2C b (TypesAndVars ts) = liftM vcat $ mapM (tvar2C b) ts
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   125
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   126
uses2C :: Uses -> State RenderState Doc
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   127
uses2C uses@(Uses unitIds) = do
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   128
    mapM_ injectNamespace (Identifier "pas2cSystem" undefined : unitIds)
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   129
    return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   130
    where
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
   131
    injectNamespace (Identifier i _) = do
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   132
        getNS <- gets (flip Map.lookup . namespaces)
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   133
        let f = flip (foldl (\a b -> b:a)) (fromMaybe [] (getNS i))
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   134
        modify (\s -> s{currentScope = f $ currentScope s})
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
   135
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
   136
uses2List :: Uses -> [String]
6489
e1f0058cfedd Add base type tags to identifiers
unc0rr
parents: 6474
diff changeset
   137
uses2List (Uses ids) = map (\(Identifier i _) -> i) ids
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   138
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   139
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   140
id2C :: Bool -> Identifier -> State RenderState Doc
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   141
id2C True (Identifier i _) = do
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   142
    modify (\s -> s{currentScope = (map toLower i, i) : currentScope s})
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   143
    return $ text i
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   144
id2C False (Identifier i _) = do
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   145
    let i' = map toLower i
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   146
    v <- gets $ find (\(a, _) -> a == i') . currentScope
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   147
    --ns <- gets currentScope
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   148
    if isNothing v then 
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   149
        error $ "Not defined: '" ++ i' ++ "'"-- ++ show ns
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   150
        else 
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   151
        return . text . snd . fromJust $ v
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   152
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   153
    
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   154
tvar2C :: Bool -> TypeVarDeclaration -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   155
tvar2C _ (FunctionDeclaration name returnType params Nothing) = do
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   156
    t <- type2C returnType 
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   157
    p <- liftM hcat $ mapM (tvar2C False) params
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   158
    n <- id2C True name
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   159
    return $ t <+> n <> parens p <> text ";"
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
   160
    
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   161
tvar2C True (FunctionDeclaration name returnType params (Just (tvars, phrase))) = do
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   162
    t <- type2C returnType 
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   163
    p <- liftM hcat $ mapM (tvar2C False) params
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   164
    ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase)
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   165
    n <- id2C True name
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   166
    return $ 
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   167
        t <+> n <> parens p
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
   168
        $+$
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   169
        text "{" 
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   170
        $+$ 
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   171
        nest 4 ph
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   172
        $+$
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   173
        text "}"
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
   174
    where
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   175
    phrase2C' (Phrases p) = liftM vcat $ mapM phrase2C p
6425
1ef4192aa80d - Parse unions, sets, function type, packed arrays and some more imporvements to the parser. Now it parses uVariable, uConsts and even SDLh.pas
unc0rr
parents: 6417
diff changeset
   176
    phrase2C' p = phrase2C p
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
   177
    
6489
e1f0058cfedd Add base type tags to identifiers
unc0rr
parents: 6474
diff changeset
   178
tvar2C False (FunctionDeclaration (Identifier name _) _ _ _) = error $ "nested functions not allowed: " ++ name
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   179
tvar2C _ (TypeDeclaration i' t) = do
6499
33180b479efa Start converting into monadic code using Reader monad (will be used to store information about namespace)
unc0rr
parents: 6489
diff changeset
   180
    tp <- type2C t
6516
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   181
    i <- id2C True i'
addaeb1b9539 Further progress on dealing with namespaces
unc0rr
parents: 6514
diff changeset
   182
    return $ text "type" <+> i <+> tp <> text ";"
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
   183
    
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   184
tvar2C _ (VarDeclaration isConst (ids, t) mInitExpr) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   185
    t' <- type2C t
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   186
    i <- mapM (id2C True) ids
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   187
    ie <- initExpr mInitExpr
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   188
    return $ if isConst then text "const" else empty
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   189
        <+> t'
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   190
        <+> (hsep . punctuate (char ',') $ i)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   191
        <+> ie
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   192
        <> text ";"
6355
734fed7aefd3 Introduce initialization expressions
unc0rr
parents: 6317
diff changeset
   193
    where
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   194
    initExpr Nothing = return $ empty
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   195
    initExpr (Just e) = liftM (text "=" <+>) (initExpr2C e)
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
   196
    
6474
42e9773eedfd - Improve renderer a bit, disallow nested functions
unc0rr
parents: 6467
diff changeset
   197
tvar2C f (OperatorDeclaration op _ ret params body) = 
6489
e1f0058cfedd Add base type tags to identifiers
unc0rr
parents: 6474
diff changeset
   198
    tvar2C f (FunctionDeclaration (Identifier ("<op " ++ op ++ ">") Unknown) ret params body)
6355
734fed7aefd3 Introduce initialization expressions
unc0rr
parents: 6317
diff changeset
   199
6517
67ea290ea843 Format code a bit
unc0rr
parents: 6516
diff changeset
   200
    
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   201
initExpr2C :: InitExpression -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   202
initExpr2C (InitBinOp op expr1 expr2) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   203
    e1 <- initExpr2C expr1
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   204
    e2 <- initExpr2C expr2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   205
    o <- op2C op
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   206
    return $ parens $ e1 <+> o <+> e2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   207
initExpr2C (InitNumber s) = return $ text s
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   208
initExpr2C (InitFloat s) = return $ text s
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   209
initExpr2C (InitHexNumber s) = return $ text "0x" <> (text . map toLower $ s)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   210
initExpr2C (InitString s) = return $ doubleQuotes $ text s 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   211
initExpr2C (InitReference i) = id2C False i
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   212
initExpr2C _ = return $ text "<<expression>>"
6391
bd5851ab3157 - Parse sets initialization
unc0rr
parents: 6355
diff changeset
   213
bd5851ab3157 - Parse sets initialization
unc0rr
parents: 6355
diff changeset
   214
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   215
type2C :: TypeDecl -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   216
type2C UnknownType = return $ text "void"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   217
type2C (String l) = return $ text $ "string" ++ show l
6514
8ba891d34eba - Fix type2C id2C call
unc0rr
parents: 6512
diff changeset
   218
type2C (SimpleType i) = id2C False i
6520
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
   219
type2C (PointerTo (SimpleType i)) = liftM (<> text "*") $ id2C True i
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   220
type2C (PointerTo t) = liftM (<> text "*") $ type2C t
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   221
type2C (RecordType tvs union) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   222
    t <- mapM (tvar2C False) tvs
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   223
    return $ text "{" $+$ (nest 4 . vcat $ t) $+$ text "}"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   224
type2C (RangeType r) = return $ text "<<range type>>"
6520
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
   225
type2C (Sequence ids) = do
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
   226
    mapM_ (id2C True) ids
6fecdc5d182f Some more work on scopes
unc0rr
parents: 6517
diff changeset
   227
    return $ text "<<sequence type>>"
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   228
type2C (ArrayDecl r t) = return $ text "<<array type>>"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   229
type2C (Set t) = return $ text "<<set>>"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   230
type2C (FunctionType returnType params) = return $ text "<<function>>"
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   231
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   232
phrase2C :: Phrase -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   233
phrase2C (Phrases p) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   234
    ps <- mapM phrase2C p
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   235
    return $ text "{" $+$ (nest 4 . vcat $ ps) $+$ text "}"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   236
phrase2C (ProcCall f@(FunCall {}) []) = liftM (<> semi) $ ref2C f
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   237
phrase2C (ProcCall ref params) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   238
    r <- ref2C ref
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   239
    ps <- mapM expr2C params
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   240
    return $ r <> parens (hsep . punctuate (char ',') $ ps) <> semi
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   241
phrase2C (IfThenElse (expr) phrase1 mphrase2) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   242
    e <- expr2C expr
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   243
    p1 <- (phrase2C . wrapPhrase) phrase1
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   244
    el <- elsePart
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   245
    return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   246
        text "if" <> parens e $+$ p1 $+$ el
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   247
    where
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   248
    elsePart | isNothing mphrase2 = return $ empty
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   249
             | otherwise = liftM (text "else" $$) $ (phrase2C . wrapPhrase) (fromJust mphrase2)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   250
phrase2C (Assignment ref expr) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   251
    r <- ref2C ref 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   252
    e <- expr2C expr
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   253
    return $
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   254
        r <> text " = " <> e <> semi
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   255
phrase2C (WhileCycle expr phrase) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   256
    e <- expr2C expr
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   257
    p <- phrase2C $ wrapPhrase phrase
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   258
    return $ text "while" <> parens e $$ p
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   259
phrase2C (SwitchCase expr cases mphrase) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   260
    e <- expr2C expr
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   261
    cs <- mapM case2C cases
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   262
    return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   263
        text "switch" <> parens e <> text "of" $+$ (nest 4 . vcat) cs
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   264
    where
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   265
    case2C :: ([InitExpression], Phrase) -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   266
    case2C (e, p) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   267
        ie <- mapM initExpr2C e
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   268
        ph <- phrase2C p
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   269
        return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   270
            text "case" <+> parens (hsep . punctuate (char ',') $ ie) <> char ':' <> nest 4 (ph $+$ text "break;")
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   271
phrase2C (WithBlock ref p) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   272
    r <- ref2C ref 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   273
    ph <- phrase2C $ wrapPhrase p
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   274
    return $ text "namespace" <> parens r $$ ph
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   275
phrase2C (ForCycle i' e1' e2' p) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   276
    i <- id2C False i'
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   277
    e1 <- expr2C e1'
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   278
    e2 <- expr2C e2'
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   279
    ph <- phrase2C (wrapPhrase p)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   280
    return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   281
        text "for" <> (parens . hsep . punctuate (char ';') $ [i <+> text "=" <+> e1, i <+> text "<=" <+> e2, text "++" <> i])
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   282
        $$
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   283
        ph
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   284
phrase2C (RepeatCycle e' p') = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   285
    e <- expr2C e'
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   286
    p <- phrase2C (Phrases p')
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   287
    return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   288
phrase2C NOP = return $ text ";"
6355
734fed7aefd3 Introduce initialization expressions
unc0rr
parents: 6317
diff changeset
   289
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   290
6307
25cfd9f4a567 Even more improvements to the parser and converter
unc0rr
parents: 6277
diff changeset
   291
wrapPhrase p@(Phrases _) = p
25cfd9f4a567 Even more improvements to the parser and converter
unc0rr
parents: 6277
diff changeset
   292
wrapPhrase p = Phrases [p]
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   293
6355
734fed7aefd3 Introduce initialization expressions
unc0rr
parents: 6317
diff changeset
   294
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   295
expr2C :: Expression -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   296
expr2C (Expression s) = return $ text s
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   297
expr2C (BinOp op expr1 expr2) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   298
    e1 <- expr2C expr1
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   299
    e2 <- expr2C expr2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   300
    o <- op2C op
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   301
    return $ parens $ e1 <+> o <+> e2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   302
expr2C (NumberLiteral s) = return $ text s
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   303
expr2C (FloatLiteral s) = return $ text s
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   304
expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   305
expr2C (StringLiteral s) = return $ doubleQuotes $ text s 
6277
627b5752733a A try to improve parser move (has regressions)
unc0rr
parents: 6275
diff changeset
   306
expr2C (Reference ref) = ref2C ref
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   307
expr2C (PrefixOp op expr) = liftM2 (<+>) (op2C op) (expr2C expr)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   308
expr2C Null = return $ text "NULL"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   309
expr2C (BuiltInFunCall params ref) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   310
    r <- ref2C ref 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   311
    ps <- mapM expr2C params
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   312
    return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   313
        r <> parens (hsep . punctuate (char ',') $ ps)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   314
expr2C _ = return $ text "<<expression>>"
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   315
6307
25cfd9f4a567 Even more improvements to the parser and converter
unc0rr
parents: 6277
diff changeset
   316
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   317
ref2C :: Reference -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   318
ref2C (ArrayElement exprs ref) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   319
    r <- ref2C ref 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   320
    es <- mapM expr2C exprs
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   321
    return $ r <> (brackets . hcat) (punctuate comma es)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   322
ref2C (SimpleReference name) = id2C False name
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   323
ref2C (RecordField (Dereference ref1) ref2) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   324
    r1 <- ref2C ref1 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   325
    r2 <- ref2C ref2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   326
    return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   327
        r1 <> text "->" <> r2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   328
ref2C (RecordField ref1 ref2) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   329
    r1 <- ref2C ref1 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   330
    r2 <- ref2C ref2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   331
    return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   332
        r1 <> text "." <> r2
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   333
ref2C (Dereference ref) = liftM ((parens $ text "*") <>) $ ref2C ref
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   334
ref2C (FunCall params ref) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   335
    r <- ref2C ref
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   336
    ps <- mapM expr2C params
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   337
    return $ 
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   338
        r <> parens (hsep . punctuate (char ',') $ ps)
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   339
ref2C (Address ref) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   340
    r <- ref2C ref
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   341
    return $ text "&" <> parens r
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   342
ref2C (TypeCast t' expr) = do
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   343
    t <- id2C False t'
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   344
    e <- expr2C expr
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   345
    return $ parens t <> e
6467
090269e528df - Improve parsing of prefix operators
unc0rr
parents: 6455
diff changeset
   346
ref2C (RefExpression expr) = expr2C expr
6355
734fed7aefd3 Introduce initialization expressions
unc0rr
parents: 6317
diff changeset
   347
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   348
6512
0df7f6697939 "System" unit to help converter
unc0rr
parents: 6511
diff changeset
   349
op2C :: String -> State RenderState Doc
6509
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   350
op2C "or" = return $ text "|"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   351
op2C "and" = return $ text "&"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   352
op2C "not" = return $ text "!"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   353
op2C "xor" = return $ text "^"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   354
op2C "div" = return $ text "/"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   355
op2C "mod" = return $ text "%"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   356
op2C "shl" = return $ text "<<"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   357
op2C "shr" = return $ text ">>"
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   358
op2C "<>" = return $ text "!="
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   359
op2C "=" = return $ text "=="
648caa66991b Convert into Reader monad
unc0rr
parents: 6499
diff changeset
   360
op2C a = return $ text a
6273
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   361
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   362
maybeVoid "" = "void"
13262c6e5027 Starting pas2C using library called 'pretty'
unc0rr
parents:
diff changeset
   363
maybeVoid a = a