Alan Zimmerman pushed to branch wip/az/ghc-cpp at Glasgow Haskell Compiler / GHC

Commits:

2 changed files:

Changes:

  • compiler/GHC/Parser/Errors/Types.hs
    ... ... @@ -516,7 +516,7 @@ data PsMessage
    516 516
           !Bool -- ^ Is ExplicitNamespaces on?
    
    517 517
     
    
    518 518
        -- | An error originating from processing a GHC_CPP directive
    
    519
    -   | PsErrGhcCpp !SDoc
    
    519
    +   | PsErrGhcCpp !SDoc -- AZ:TODO: consider finer granularity
    
    520 520
     
    
    521 521
        deriving Generic
    
    522 522
     
    

  • compiler/GHC/Parser/PreProcess/Macro.hs
    ... ... @@ -51,78 +51,97 @@ import GHC.Utils.Outputable
    51 51
     cppCond :: SrcSpan -> String -> PP Bool
    
    52 52
     cppCond loc str = do
    
    53 53
         s <- getPpState
    
    54
    -    let
    
    55
    -        expanded = expand (pp_defines s) str
    
    54
    +    expanded <- expand loc (pp_defines s) str
    
    56 55
         v <- case Parser.parseExpr expanded of
    
    57 56
             Left err -> do
    
    58
    -            addGhcCPPError loc
    
    59
    -              (hang (text "Error evaluating CPP condition:") 2
    
    60
    -               (text err <+> text "of" $+$ text expanded))
    
    57
    +            addGhcCPPError
    
    58
    +                loc
    
    59
    +                ( hang
    
    60
    +                    (text "Error evaluating CPP condition:")
    
    61
    +                    2
    
    62
    +                    (text err <+> text "of" $+$ text expanded)
    
    63
    +                )
    
    61 64
                 return 0
    
    62 65
             Right tree -> return (eval tree)
    
    63 66
         return (toBool v)
    
    64 67
     
    
    65 68
     -- ---------------------------------------------------------------------
    
    66 69
     
    
    67
    -expand :: MacroDefines -> String -> String
    
    68
    -expand s str = expanded
    
    69
    -  where
    
    70
    -    -- TODO: repeat until re-expand or fixpoint
    
    71
    -    toks = case cppLex False str of
    
    72
    -        Left err -> error $ "expand:" ++ show (err, str)
    
    73
    -        Right tks -> tks
    
    74
    -    expanded = combineToks $ map t_str $ expandToks maxExpansions s toks
    
    70
    +expand :: SrcSpan -> MacroDefines -> String -> PP String
    
    71
    +expand loc s str = do
    
    72
    +    toks <- case cppLex False str of
    
    73
    +        Left err -> do
    
    74
    +            addGhcCPPError
    
    75
    +                loc
    
    76
    +                ( hang
    
    77
    +                    (text "Error evaluating CPP condition1:") -- AZ:TODO remove 1
    
    78
    +                    2
    
    79
    +                    (text err <+> text "of" $+$ text str)
    
    80
    +                )
    
    81
    +            return []
    
    82
    +        Right tks -> return tks
    
    83
    +    expandedToks <- expandToks loc maxExpansions s toks
    
    84
    +    return $ combineToks $ map t_str expandedToks
    
    75 85
     
    
    76 86
     maxExpansions :: Int
    
    77 87
     maxExpansions = 15
    
    78 88
     
    
    79
    -expandToks :: Int -> MacroDefines -> [Token] -> [Token]
    
    80
    -expandToks 0 _ ts = error $ "macro_expansion limit (" ++ show maxExpansions ++ ") hit, aborting. ts=" ++ show ts
    
    81
    -expandToks cnt s ts =
    
    82
    -    let
    
    83
    -        (!expansionDone, !r) = doExpandToks False s ts
    
    84
    -     in
    
    85
    -        if expansionDone
    
    86
    -            then expandToks (cnt - 1) s r
    
    87
    -            else r
    
    88
    -
    
    89
    -doExpandToks :: Bool -> MacroDefines -> [Token] -> (Bool, [Token])
    
    90
    -doExpandToks ed _ [] = (ed, [])
    
    91
    -doExpandToks ed s (TIdentifierLParen n : ts) =
    
    89
    +expandToks :: SrcSpan -> Int -> MacroDefines -> [Token] -> PP [Token]
    
    90
    +expandToks loc 0 _ ts = do
    
    91
    +    -- error $ "macro_expansion limit (" ++ show maxExpansions ++ ") hit, aborting. ts=" ++ show ts
    
    92
    +    addGhcCPPError
    
    93
    +        loc
    
    94
    +        ( hang
    
    95
    +            (text "CPP macro expansion limit hit:")
    
    96
    +            2
    
    97
    +            (text (combineToks $ map t_str ts))
    
    98
    +        )
    
    99
    +    return ts
    
    100
    +expandToks loc cnt s ts = do
    
    101
    +    (!expansionDone, !r) <- doExpandToks loc False s ts
    
    102
    +    if expansionDone
    
    103
    +        then expandToks loc (cnt - 1) s r
    
    104
    +        else return r
    
    105
    +
    
    106
    +doExpandToks :: SrcSpan -> Bool -> MacroDefines -> [Token] -> PP (Bool, [Token])
    
    107
    +doExpandToks _loc ed _ [] = return (ed, [])
    
    108
    +doExpandToks loc ed s (TIdentifierLParen n : ts) =
    
    92 109
         -- TIdentifierLParen has no meaning here (only in a #define), so
    
    93 110
         -- restore it to its constituent tokens
    
    94
    -    doExpandToks ed s (TIdentifier (init n) : TOpenParen "(" : ts)
    
    95
    -doExpandToks _ s (TIdentifier "defined" : ts) = (True, rest)
    
    96
    -  where
    
    97
    -    -- See Note: [defined unary operator] below
    
    98
    -
    
    99
    -    rest = case getExpandArgs ts of
    
    100
    -        (Just [[TIdentifier macro_name]], rest0) ->
    
    101
    -            case Map.lookup macro_name s of
    
    102
    -                Nothing -> TInteger "0" : rest0
    
    103
    -                Just _ -> TInteger "1" : rest0
    
    104
    -        (Nothing, TIdentifier macro_name : ts0) ->
    
    105
    -            case Map.lookup macro_name s of
    
    106
    -                Nothing -> TInteger "0" : ts0
    
    107
    -                Just _ -> TInteger "1" : ts0
    
    108
    -        (Nothing, _) -> error $ "defined: expected an identifier, got:" ++ show ts
    
    109
    -        (Just args, _) -> error $ "defined: expected a single arg, got:" ++ show args
    
    110
    -doExpandToks ed s (TIdentifier n : ts) = (ed'', expanded ++ rest)
    
    111
    -  where
    
    112
    -    (ed', expanded, ts') = case Map.lookup n s of
    
    113
    -        Nothing -> (ed, [TIdentifier n], ts)
    
    114
    -        Just defs -> (ed0, r, rest1)
    
    115
    -          where
    
    116
    -            (args, rest0) = getExpandArgs ts
    
    117
    -            fallbackArgs = fromMaybe (Nothing, [TIdentifier n]) (Map.lookup Nothing defs)
    
    118
    -            (m_args, rhs) = fromMaybe fallbackArgs (Map.lookup (arg_arity args) defs)
    
    119
    -            (ed0, r, rest1) = case m_args of
    
    120
    -                Nothing -> (True, rhs, ts)
    
    121
    -                Just _ -> (True, replace_args args m_args rhs, rest0)
    
    122
    -    (ed'', rest) = doExpandToks ed' s ts'
    
    123
    -doExpandToks ed s (t : ts) = (ed', t : r)
    
    124
    -  where
    
    125
    -    (ed', r) = doExpandToks ed s ts
    
    111
    +    doExpandToks loc ed s (TIdentifier (init n) : TOpenParen "(" : ts)
    
    112
    +doExpandToks loc _ s (TIdentifier "defined" : ts) = do
    
    113
    +    let
    
    114
    +        -- See Note: [defined unary operator] below
    
    115
    +
    
    116
    +        rest = case getExpandArgs ts of
    
    117
    +            (Just [[TIdentifier macro_name]], rest0) ->
    
    118
    +                case Map.lookup macro_name s of
    
    119
    +                    Nothing -> TInteger "0" : rest0
    
    120
    +                    Just _ -> TInteger "1" : rest0
    
    121
    +            (Nothing, TIdentifier macro_name : ts0) ->
    
    122
    +                case Map.lookup macro_name s of
    
    123
    +                    Nothing -> TInteger "0" : ts0
    
    124
    +                    Just _ -> TInteger "1" : ts0
    
    125
    +            (Nothing, _) -> error $ "defined: expected an identifier, got:" ++ show ts
    
    126
    +            (Just args, _) -> error $ "defined: expected a single arg, got:" ++ show args
    
    127
    +    return (True, rest)
    
    128
    +doExpandToks loc ed s (TIdentifier n : ts) = do
    
    129
    +    let
    
    130
    +        (ed', expanded, ts') = case Map.lookup n s of
    
    131
    +            Nothing -> (ed, [TIdentifier n], ts)
    
    132
    +            Just defs -> (ed0, r, rest1)
    
    133
    +              where
    
    134
    +                (args, rest0) = getExpandArgs ts
    
    135
    +                fallbackArgs = fromMaybe (Nothing, [TIdentifier n]) (Map.lookup Nothing defs)
    
    136
    +                (m_args, rhs) = fromMaybe fallbackArgs (Map.lookup (arg_arity args) defs)
    
    137
    +                (ed0, r, rest1) = case m_args of
    
    138
    +                    Nothing -> (True, rhs, ts)
    
    139
    +                    Just _ -> (True, replace_args args m_args rhs, rest0)
    
    140
    +    (ed'', rest) <- doExpandToks loc ed' s ts'
    
    141
    +    return (ed'', expanded ++ rest)
    
    142
    +doExpandToks loc ed s (t : ts) = do
    
    143
    +    (ed', r) <- doExpandToks loc ed s ts
    
    144
    +    return (ed', t : r)
    
    126 145
     
    
    127 146
     {-
    
    128 147
     Note: [defined unary operator]