Skip to content

Commit

Permalink
Merge pull request #295 from camfort/fixboz
Browse files Browse the repository at this point in the history
Avoid interpreting CPP as Boz
  • Loading branch information
dorchard authored Dec 13, 2024
2 parents efb539f + fba734f commit 35c50b6
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/Language/Fortran/AST/Literal/Boz.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ parseBoz s =
| p' == 'x' = Just $ BozPrefixZ Nonconforming
| otherwise = Nothing
where p' = Char.toLower p
errInvalid = error "Language.Fortran.AST.BOZ.parseBoz: invalid BOZ string"
errInvalid = error ("Language.Fortran.AST.BOZ.parseBoz: invalid BOZ string: " <> show s)
-- | Remove the first and last elements in a list.
shave = tail . init

Expand Down
36 changes: 22 additions & 14 deletions src/Language/Fortran/Parser/Free/Lexer.x
Original file line number Diff line number Diff line change
Expand Up @@ -1105,20 +1105,28 @@ advance move position =

processLinePragma :: String -> AlexInput -> AlexInput
processLinePragma m ai =
case dropWhile ((`elem` ["#", "line", "#line"]) . map toLower) (words m) of
-- 'line' pragma - rewrite the current line and filename
lineStr:otherWords
| line <- readIntOrBoz lineStr -> do
let revdropWNQ = reverse . drop 1 . dropWhile (flip notElem "'\"")
let file = revdropWNQ . revdropWNQ $ unwords otherWords
-- if a newline is present, then the aiPosition is already on the next line
let maybe1 | elem '\n' m = 0 | otherwise = 1
-- lineOffs is the difference between the given line and the current next line
let lineOffs = fromIntegral line - (posLine (aiPosition ai) + maybe1)
let newP = (aiPosition ai) { posPragmaOffset = Just (lineOffs, file)
, posColumn = 1 }
ai { aiPosition = newP }
_ -> ai
let wordsm = words m
isLinePragma x = x `elem` ["#", "line", "#line"]
in -- If this is a line pragma then process this
if length wordsm > 0 && isLinePragma (head wordsm)
|| (length wordsm > 1 && isLinePragma (head (tail wordsm)))
then
case dropWhile ((`elem` ["#", "line", "#line"]) . map toLower) wordsm of
-- 'line' pragma - rewrite the current line and filename
lineStr:otherWords
| line <- readIntOrBoz lineStr -> do
let revdropWNQ = reverse . drop 1 . dropWhile (flip notElem "'\"")
let file = revdropWNQ . revdropWNQ $ unwords otherWords
-- if a newline is present, then the aiPosition is already on the next line
let maybe1 | elem '\n' m = 0 | otherwise = 1
-- lineOffs is the difference between the given line and the current next line
let lineOffs = fromIntegral line - (posLine (aiPosition ai) + maybe1)
let newP = (aiPosition ai) { posPragmaOffset = Just (lineOffs, file)
, posColumn = 1 }
ai { aiPosition = newP }
_ -> ai
-- Otherwise this is probably a CPP directive or some other pragma so ignore
else ai

-- Handle pragmas that begin with #
lexHash :: LexAction (Maybe Token)
Expand Down

0 comments on commit 35c50b6

Please sign in to comment.