Skip to content

Commit 0ea0cb0

Browse files
authored
Merge pull request #289 from camfort/localDeclInfo
Store source names for declMaps in mod files
2 parents faf651b + fd46091 commit 0ea0cb0

File tree

7 files changed

+38
-21
lines changed

7 files changed

+38
-21
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
### 0.16.3
2+
* Store source names for local declarations in .fsmod files.
3+
14
### 0.16.2 (Sep 13, 2024)
25
* Small change to allow a path to be added when building mod-file naming map
36
* Improvements to the power of constant propagation and constant expression evaluation.

app/Main.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ programName :: String
5151
programName = "fortran-src"
5252

5353
showVersion :: String
54-
showVersion = "0.16.2"
54+
showVersion = "0.16.3"
5555

5656
main :: IO ()
5757
main = do

fortran-src.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cabal-version: 1.12
55
-- see: https://github.com/sol/hpack
66

77
name: fortran-src
8-
version: 0.16.2
8+
version: 0.16.3
99
synopsis: Parsers and analyses for Fortran standards 66, 77, 90, 95 and 2003 (partial).
1010
description: Provides lexing, parsing, and basic analyses of Fortran code covering standards: FORTRAN 66, FORTRAN 77, Fortran 90, Fortran 95, Fortran 2003 (partial) and some legacy extensions. Includes data flow and basic block analysis, a renamer, and type analysis. For example usage, see the @<https://hackage.haskell.org/package/camfort CamFort>@ project, which uses fortran-src as its front end.
1111
category: Language

package.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: fortran-src
2-
version: '0.16.2'
2+
version: '0.16.3'
33
synopsis: Parsers and analyses for Fortran standards 66, 77, 90, 95 and 2003 (partial).
44
description: >-
55
Provides lexing, parsing, and basic analyses of Fortran code covering

src/Language/Fortran/Repr/Eval/Value.hs

+7
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ evalBOp bop l r = do
272272
case (l', r') of
273273
(FSVInt li, FSVInt ri) ->
274274
pure $ MkFScalarValue $ FSVInt $ fIntBOpInplace (^) li ri
275+
(FSVReal lr, FSVReal ri) ->
276+
pure $ MkFScalarValue $ FSVReal $ fRealBOpInplace' (**) (**) lr ri
277+
(FSVReal lr, FSVInt ri) ->
278+
-- Handle case of a real raised to an integer power.
279+
pure $ MkFScalarValue $ FSVReal $ fRealBOpInplace' (**) (**) lr (FReal8 $ withFInt ri)
280+
281+
-- _ -> err $ ELazy "exponentiation: unsupported types"
275282

276283
F.Concatenation ->
277284
case (l', r') of

src/Language/Fortran/Util/ModFile.hs

+24-17
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ data DeclContext = DCMain | DCBlockData | DCModule F.ProgramUnitName
104104
instance Binary DeclContext
105105

106106
-- | Map of unique variable name to the unique name of the program
107-
-- unit where it was defined, and the corresponding SrcSpan.
108-
type DeclMap = M.Map F.Name (DeclContext, P.SrcSpan)
107+
-- unit where it was defined, its source name,
108+
-- and the corresponding SrcSpan.
109+
type DeclMap = M.Map F.Name (DeclContext, F.Name, P.SrcSpan)
109110

110111
-- | A map of aliases => strings, in order to save space and share
111112
-- structure for repeated strings.
@@ -121,7 +122,8 @@ data ModFile = ModFile { mfFilename :: String
121122
, mfDeclMap :: DeclMap
122123
, mfTypeEnv :: FAT.TypeEnv
123124
, mfParamVarMap :: ParamVarMap
124-
, mfOtherData :: M.Map String LB.ByteString }
125+
, mfOtherData :: M.Map String LB.ByteString
126+
}
125127
deriving (Eq, Show, Data, Typeable, Generic)
126128

127129
instance Binary ModFile
@@ -251,18 +253,23 @@ moduleFilename = mfFilename
251253

252254
-- | Create a map that links all unique variable/function names in the
253255
-- ModFiles to their corresponding *originating* filename (i.e., where they are declared)
254-
genUniqNameToFilenameMap :: FilePath -> ModFiles -> M.Map F.Name String
255-
genUniqNameToFilenameMap localPath = M.unions . map perMF
256+
-- paired with their source name (maybe)
257+
genUniqNameToFilenameMap :: FilePath -> ModFiles -> M.Map F.Name (String, Maybe F.Name)
258+
genUniqNameToFilenameMap localPath m = M.unions . map perMF $ m
256259
where
257260
perMF mf = M.fromList
258-
[ (n, normalise $ localPath </> fname)
259-
| modEnv <- M.elems localModuleMap
260-
, (n, _) <- M.elems modEnv ]
261+
$ [ (n, (fname, Nothing))
262+
| (_p, modEnv) <- M.toList localModuleMap
263+
, (n, _) <- M.elems modEnv ]
264+
-- decl map information
265+
<> [(n, (fname, Just srcName)) | (n, (_dc, srcName, _)) <- M.toList declMap ]
266+
261267
where
262268
-- Make sure that we remove imported declarations so we can
263269
-- properly localise declarations to the originator file.
264270
localModuleMap = localisedModuleMap $ mfModuleMap mf
265-
fname = mfFilename mf
271+
declMap = mfDeclMap mf
272+
fname = normalise $ localPath </> mfFilename mf
266273

267274
--------------------------------------------------
268275

@@ -289,28 +296,28 @@ extractDeclMap pf = M.fromList . concatMap (blockDecls . nameAndBlocks) $ univer
289296
where
290297
-- Extract variable names, source spans from declarations (and
291298
-- from function return variable if present)
292-
blockDecls :: (DeclContext, Maybe (F.Name, P.SrcSpan), [F.Block (FA.Analysis a)]) -> [(F.Name, (DeclContext, P.SrcSpan))]
299+
blockDecls :: (DeclContext, Maybe (F.Name, F.Name, P.SrcSpan), [F.Block (FA.Analysis a)]) -> [(F.Name, (DeclContext, F.Name, P.SrcSpan))]
293300
blockDecls (dc, mret, bs)
294301
| Nothing <- mret = map decls (universeBi bs)
295-
| Just (ret, ss) <- mret = (ret, (dc, ss)):map decls (universeBi bs)
302+
| Just (ret, srcName, ss) <- mret = (ret, (dc, srcName, ss)):map decls (universeBi bs)
296303
where
297-
decls d = let (v, ss) = declVarName d in (v, (dc, ss))
304+
decls d = let (v, srcName, ss) = declVarName d in (v, (dc, srcName, ss))
298305

299306
-- Extract variable name and source span from declaration
300-
declVarName :: F.Declarator (FA.Analysis a) -> (F.Name, P.SrcSpan)
301-
declVarName (F.Declarator _ _ e _ _ _) = (FA.varName e, P.getSpan e)
307+
declVarName :: F.Declarator (FA.Analysis a) -> (F.Name, F.Name, P.SrcSpan)
308+
declVarName (F.Declarator _ _ e _ _ _) = (FA.varName e, FA.srcName e, P.getSpan e)
302309

303310
-- Extract context identifier, a function return value (+ source
304311
-- span) if present, and a list of contained blocks
305-
nameAndBlocks :: F.ProgramUnit (FA.Analysis a) -> (DeclContext, Maybe (F.Name, P.SrcSpan), [F.Block (FA.Analysis a)])
312+
nameAndBlocks :: F.ProgramUnit (FA.Analysis a) -> (DeclContext, Maybe (F.Name, F.Name, P.SrcSpan), [F.Block (FA.Analysis a)])
306313
nameAndBlocks pu = case pu of
307314
F.PUMain _ _ _ b _ -> (DCMain, Nothing, b)
308315
F.PUModule _ _ _ b _ -> (DCModule $ FA.puName pu, Nothing, b)
309316
F.PUSubroutine _ _ _ _ _ b _ -> (DCSubroutine (FA.puName pu, FA.puSrcName pu), Nothing, b)
310317
F.PUFunction _ _ _ _ _ _ mret b _
311318
| Nothing <- mret
312-
, F.Named n <- FA.puName pu -> (DCFunction (FA.puName pu, FA.puSrcName pu), Just (n, P.getSpan pu), b)
313-
| Just ret <- mret -> (DCFunction (FA.puName pu, FA.puSrcName pu), Just (FA.varName ret, P.getSpan ret), b)
319+
, F.Named n <- FA.puName pu -> (DCFunction (FA.puName pu, FA.puSrcName pu), Just (n, n, P.getSpan pu), b)
320+
| Just ret <- mret -> (DCFunction (FA.puName pu, FA.puSrcName pu), Just (FA.varName ret, FA.srcName ret, P.getSpan ret), b)
314321
| otherwise -> error $ "nameAndBlocks: un-named function with no return value! " ++ show (FA.puName pu) ++ " at source-span " ++ show (P.getSpan pu)
315322
F.PUBlockData _ _ _ b -> (DCBlockData, Nothing, b)
316323
F.PUComment {} -> (DCBlockData, Nothing, []) -- no decls inside of comments, so ignore it

test/Language/Fortran/Analysis/ModFileSpec.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ testModuleMaps = do
4242
-- get unique name to filemap
4343
let mmap = genUniqNameToFilenameMap "" modFiles
4444
-- check that `constant` is declared in leaf.f90
45-
let Just leaf = M.lookup "leaf_constant_1" mmap
45+
let Just (leaf, _) = M.lookup "leaf_constant_1" mmap
4646
leaf `shouldBe` ("test-data" </> "module" </> "leaf.f90")
4747

0 commit comments

Comments
 (0)