packages feed

fortran-vars 0.3.0 → 0.3.1

raw patch · 25 files changed

+429/−341 lines, 25 filesdep ~aesondep ~fortran-srcdep ~fortran-src-extrasPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: aeson, fortran-src, fortran-src-extras

API changes (from Hackage documentation)

- Language.Fortran.Vars.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.AST.Boz.Boz
- Language.Fortran.Vars.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.AST.Boz.BozPrefix
- Language.Fortran.Vars.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fortran.AST.Boz.Boz
- Language.Fortran.Vars.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fortran.AST.Boz.BozPrefix
+ Language.Fortran.Vars.BozConstant: bozToInt1 :: Boz -> ExpVal
+ Language.Fortran.Vars.Memory: getTypeSize :: Type -> Int
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.AST.Literal.Boz.Boz
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.AST.Literal.Boz.BozPrefix
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.AST.Literal.Boz.Conforming
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.Analysis.SemanticTypes.CharacterLen
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.Analysis.SemanticTypes.SemType
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.Util.Position.Position
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fortran.Util.Position.SrcSpan
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fortran.Analysis.SemanticTypes.CharacterLen
+ Language.Fortran.Vars.Orphans: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fortran.Analysis.SemanticTypes.SemType
- Language.Fortran.Vars.BozConstant: bozToInt :: Int -> ExpVal -> ExpVal
+ Language.Fortran.Vars.BozConstant: bozToInt :: Kind -> Boz -> ExpVal
- Language.Fortran.Vars.BozConstant: bozToInt2 :: ExpVal -> ExpVal
+ Language.Fortran.Vars.BozConstant: bozToInt2 :: Boz -> ExpVal
- Language.Fortran.Vars.BozConstant: bozToInt4 :: ExpVal -> ExpVal
+ Language.Fortran.Vars.BozConstant: bozToInt4 :: Boz -> ExpVal
- Language.Fortran.Vars.BozConstant: bozToInt8 :: ExpVal -> ExpVal
+ Language.Fortran.Vars.BozConstant: bozToInt8 :: Boz -> ExpVal
- Language.Fortran.Vars.MemoryLocation: getLocation :: Data a => SymbolTable -> Expression (Analysis a) -> Location
+ Language.Fortran.Vars.MemoryLocation: getLocation :: Data a => SymbolTable -> Expression (Analysis a) -> Maybe Location

Files

CHANGELOG.md view
@@ -1,4 +1,12 @@-## 0.3.0 (10 Jan 2021)+## 0.3.1 (22 Aug 2022)+  * Update to fortran-src 0.10.2+  * Do some type checking for logical operators used with non LOGICAL arguments+    #6+  * Add type checking for `imag`, `lshift` intrinsics+  * MemoryLocation: change `getLocation` to return a `Maybe` type+  * Memory: expose `getTypeSize` function++## 0.3.0 (10 Jan 2022)   * Update to fortran-src 0.8.0   * Replace BozDecomposed with new Boz type in fortran-src     * Due to how the BozConstant module was used, this should have minimal
fortran-vars.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           fortran-vars-version:        0.3.0+version:        0.3.1 synopsis:       Fortran memory model and other static analysis tools. description:    Various Fortran static analysis tools focusing on a memory model for Fortran types. Uses fortran-src for the syntax representation. category:       Language@@ -40,6 +40,7 @@       Language.Fortran.Vars.Memory       Language.Fortran.Vars.MemoryLocation       Language.Fortran.Vars.Operation+      Language.Fortran.Vars.Orphans       Language.Fortran.Vars.PureExpression       Language.Fortran.Vars.Range       Language.Fortran.Vars.StorageClass@@ -53,15 +54,18 @@       Paths_fortran_vars   hs-source-dirs:       src+  default-extensions:+      LambdaCase+      TypeApplications   build-depends:-      aeson >=1.2.3.0+      aeson >=1.5.0.0     , base >=4.7 && <5     , bytestring >=0.10.8.1     , containers >=0.5.7.1     , deepseq >=1.4.4.0     , fgl >=5-    , fortran-src >=0.8.0 && <0.9-    , fortran-src-extras >=0.2.0+    , fortran-src >=0.10.2 && <0.11+    , fortran-src-extras >=0.3.1 && <0.4     , text >=1.2.2.2     , uniplate >=1.6.10   default-language: Haskell2010@@ -72,16 +76,19 @@       Paths_fortran_vars   hs-source-dirs:       app+  default-extensions:+      LambdaCase+      TypeApplications   ghc-options: -threaded -rtsopts   build-depends:-      aeson >=1.2.3.0+      aeson >=1.5.0.0     , base >=4.7 && <5     , bytestring >=0.10.8.1     , containers >=0.5.7.1     , deepseq >=1.4.4.0     , fgl >=5-    , fortran-src >=0.8.0 && <0.9-    , fortran-src-extras >=0.2.0+    , fortran-src >=0.10.2 && <0.11+    , fortran-src-extras >=0.3.1 && <0.4     , fortran-vars     , text >=1.2.2.2     , uniplate >=1.6.10@@ -103,19 +110,22 @@       Paths_fortran_vars   hs-source-dirs:       test+  default-extensions:+      LambdaCase+      TypeApplications   ghc-options: -threaded -rtsopts   build-tool-depends:       hspec-discover:hspec-discover   build-depends:       HUnit-    , aeson >=1.2.3.0+    , aeson >=1.5.0.0     , base >=4.7 && <5     , bytestring >=0.10.8.1     , containers >=0.5.7.1     , deepseq >=1.4.4.0     , fgl >=5-    , fortran-src >=0.8.0 && <0.9-    , fortran-src-extras >=0.2.0+    , fortran-src >=0.10.2 && <0.11+    , fortran-src-extras >=0.3.1 && <0.4     , fortran-vars     , hspec     , text >=1.2.2.2
src/Language/Fortran/Vars/Assignments.hs view
@@ -29,12 +29,11 @@                                                 ( collectStructures ) import           Language.Fortran.Vars.SymbolTable                                                 ( collectSymbols )-import           Language.Fortran.Vars.Types-                                                ( SymbolTable+import           Language.Fortran.Vars.Types    ( SymbolTable                                                 , StructureTable                                                 , SymbolTableEntry(..)                                                 , Dimensions-                                                , Type(..)+                                                , Type                                                 , SemType(..)                                                 , TypeError(..)                                                 , typeError@@ -99,7 +98,8 @@   -> [Declarator (Analysis a)]   -> [Either TypeError (Type, Expression (Analysis a))] declarators strt symt = concatMap f where-  f (Declarator _ _ v ScalarDecl _ (Just e)) = pure $ (, e) <$> typeOf strt symt v+  f (Declarator _ _ v ScalarDecl _ (Just e)) =+    pure $ (, e) <$> typeOf strt symt v   f d@(Declarator _ _ (ExpValue _ s (ValVariable v)) ArrayDecl{} _ (Just (ExpInitialisation _ _ vals)))     = case M.lookup v symt of       Just (SVariable (TArray ty (Just dims)) _) ->
src/Language/Fortran/Vars/BozConstant.hs view
@@ -1,48 +1,36 @@ module Language.Fortran.Vars.BozConstant   ( resolveBozConstant   , bozToInt+  , bozToInt1   , bozToInt2   , bozToInt4   , bozToInt8   ) where -import           Data.Char                      ( digitToInt-                                                , intToDigit-                                                , toLower-                                                )-import qualified Data.Map                       as M-import           Numeric                        ( readInt-                                                , showIntAtBase-                                                )-import           Text.Read                      ( ReadS )+import qualified Data.Map                      as M -import qualified Language.Fortran.AST.Boz       as AST+import qualified Language.Fortran.AST.Literal.Boz as AST import           Language.Fortran.Vars.Types    ( SymbolTableEntry(..)-                                                , Type(..)                                                 , SemType(..)                                                 , Kind                                                 , ExpVal(..)                                                 , SymbolTable                                                 ) +import Data.Int+ -- | Given 'SymbolTable', contextual symbol name and BOZ Constant -- ('ExpVal' constructed with Boz String), resolve BOZ Constant considering -- contextual symbol. -- -- Currently, it only resolves BOZ Constants in context of INTEGER. resolveBozConstant :: SymbolTable -> String -> ExpVal -> ExpVal-resolveBozConstant symTable assignSymbol (Boz boz) =-  resolveBozConstant' symTable assignSymbol boz-resolveBozConstant _ _ _ = error "Can only resolve ExpVal Boz"--resolveBozConstant' :: SymbolTable -> String -> AST.Boz -> ExpVal-resolveBozConstant' symTable assignSymbol boz =-  let entry = M.lookup assignSymbol symTable-  in-    case entry of+resolveBozConstant symTable assignSymbol (Boz boz) = go boz+  where+    go boz = case entry of       Just (SVariable (TInteger kind) _) ->-        resolveBozConstantInContext boz kind+        bozToInt kind boz       Just (SVariable ty _) ->         error           $  assignSymbol@@ -59,28 +47,52 @@         ++ " could not be found. \                                           \Invalid fortran syntax"         )+    entry = M.lookup assignSymbol symTable -resolveBozConstantInContext :: AST.Boz -> Kind -> ExpVal-resolveBozConstantInContext boz kind =+resolveBozConstant _ _ _ = error "Can only resolve ExpVal Boz"++-- | Resolve a BOZ constant as an INTEGER(k).+--+-- Works on arbitrary kinds, including non-standard, assuming that kind+-- indicates size in bytes.+bozToInt :: Kind -> AST.Boz -> ExpVal+bozToInt kind boz = case kind of+  -- handle regular kinds via bitwise operations on sized machine integers,+  -- relying on overflow behaviour+  1 -> bozToInt1 boz+  2 -> bozToInt2 boz+  4 -> bozToInt4 boz+  8 -> bozToInt8 boz++  -- handle irregular kinds via explicit numeric operations+  -- (shouldn't really ever trigger, but no harm)+  k -> bozAsTwosCompExplicit boz k++--------------------------------------------------------------------------------++-- | Resolve a BOZ constant as an INTEGER(1).+bozToInt1 :: AST.Boz -> ExpVal+bozToInt1 = Int . fromIntegral . AST.bozAsTwosComp @Int8++-- | Resolve a BOZ constant as an INTEGER(2).+bozToInt2 :: AST.Boz -> ExpVal+bozToInt2 = Int . fromIntegral . AST.bozAsTwosComp @Int16++-- | Resolve a BOZ constant as an INTEGER(4).+bozToInt4 :: AST.Boz -> ExpVal+bozToInt4 = Int . fromIntegral . AST.bozAsTwosComp @Int32++-- | Resolve a BOZ constant as an INTEGER(8).+bozToInt8 :: AST.Boz -> ExpVal+bozToInt8 = Int . fromIntegral . AST.bozAsTwosComp @Int64++--------------------------------------------------------------------------------++bozAsTwosCompExplicit :: AST.Boz -> Kind -> ExpVal+bozAsTwosCompExplicit boz kind =   let allowedBinaryLength = kind * 8       maxBinaryValue      = 2 ^ (allowedBinaryLength - 1) - 1       minBinaryValue      = (-1) * 2 ^ (allowedBinaryLength - 1)       decimal             = AST.bozAsNatural boz       overflow            = decimal - maxBinaryValue   in  if overflow > 0 then Int (minBinaryValue + overflow - 1) else Int decimal---- Convert BOZ string to integer of specific kind-bozToInt :: Int -> ExpVal -> ExpVal-bozToInt kind (Boz boz) = resolveBozConstantInContext boz kind---- Convert BOZ string to integer*2-bozToInt2 :: ExpVal -> ExpVal-bozToInt2 = bozToInt 2---- Convert BOZ string to integer*4-bozToInt4 :: ExpVal -> ExpVal-bozToInt4 = bozToInt 4---- Convert BOZ string to integer*8-bozToInt8 :: ExpVal -> ExpVal-bozToInt8 = bozToInt 8
src/Language/Fortran/Vars/Call.hs view
@@ -13,6 +13,7 @@                                                 , Expression(..)                                                 , Argument(..)                                                 , aStrip+                                                , argExprNormalize                                                 ) import           Language.Fortran.Analysis      ( Analysis                                                 , srcName@@ -42,18 +43,16 @@  -- | Given a function call 'Expression', return the list of argument 'Expression' functionArguments :: Expression a -> [Expression a]-functionArguments (ExpFunctionCall _ _ _ args) = case args of-  Just args' -> map (\(Argument _ _ _ e) -> e) (aStrip args')-  Nothing    -> []+functionArguments (ExpFunctionCall _ _ _ args) =+  map (\(Argument _ _ _ e) -> argExprNormalize e) (aStrip args) functionArguments e =   error $ "Expression at " ++ show (getSpan e) ++ " is not a function call"   -- | Given a subroutine call 'Statement', return the list of argument 'Expression' subroutineArguments :: Statement a -> [Expression a]-subroutineArguments (StCall _ _ _ args) = case args of-  Just args' -> map (\(Argument _ _ _ e) -> e) (aStrip args')-  Nothing    -> []+subroutineArguments (StCall _ _ _ args) =+  map (\(Argument _ _ _ e) -> argExprNormalize e) (aStrip args) subroutineArguments s =   error $ "Statement at " ++ show (getSpan s) ++ " is not a subroutine call" 
src/Language/Fortran/Vars/CommonLayout.hs view
@@ -12,7 +12,7 @@                                                 , ProgramUnitModel                                                 , StorageClass(..)                                                 , Offset-                                                , Type(..)+                                                , Type                                                 , SemType(..)                                                 , CharacterLen(..)                                                 )
src/Language/Fortran/Vars/Equivalence.hs view
@@ -5,7 +5,10 @@  import           Data.Data                      ( Data ) import           Data.List                      ( foldl' )-import           Language.Fortran.Analysis      ( Analysis )+import           Data.Maybe                     ( fromMaybe )+import           Language.Fortran.Analysis      ( Analysis+                                                , srcName+                                                ) import           Language.Fortran.AST           ( AList                                                 , aStrip                                                 , Expression@@ -14,12 +17,10 @@  import           Language.Fortran.Vars.MemoryLocation                                                 ( getLocation )-import           Language.Fortran.Vars.Types-                                                ( Location+import           Language.Fortran.Vars.Types    ( Location                                                 , ProgramUnitModel                                                 )-import           Language.Fortran.Vars.Union-                                                ( union )+import           Language.Fortran.Vars.Union    ( union )  associate :: ProgramUnitModel -> [Location] -> ProgramUnitModel associate puModel locations =@@ -30,7 +31,7 @@  equivalence   :: Data a => ProgramUnitModel -> Statement (Analysis a) -> ProgramUnitModel-equivalence puModel0 (StEquivalence _ _ equivsList) = foldl'+equivalence puModel0 (StEquivalence _ ss equivsList) = foldl'   f   puModel0   (aStrip equivsList)@@ -41,7 +42,15 @@     -> AList Expression (Analysis a)     -> ProgramUnitModel   f model@(symTable, _) equivs =-    let locations = map (getLocation symTable) (aStrip equivs)+    let+      locations =+        (\x ->+            fromMaybe+                (error $ "Couldn't calculate location at " <> show ss <> srcName x+                )+              $ getLocation symTable x+          )+          <$> aStrip equivs     in  associate model locations equivalence model _ = model 
src/Language/Fortran/Vars/Eval.hs view
@@ -11,7 +11,7 @@                                                 , Expression(..)                                                 , Value(..)                                                 , AList(..)-                                                , Argument(..)+                                                , argExtractExpr                                                 ) import           Language.Fortran.Util.Position ( getSpan ) @@ -25,8 +25,7 @@                                                 , valueToExpVal'                                                 , intrinsicFunctionCall                                                 )-import           Language.Fortran.Vars.Types-                                                ( SymbolTableEntry(..)+import           Language.Fortran.Vars.Types    ( SymbolTableEntry(..)                                                 , ExpVal(..)                                                 , SymbolTable                                                 )@@ -44,17 +43,16 @@   ExpUnary _ _ op e -> transformEither (unaryOp' op) $ eval' symTable e   ExpBinary _ _ op e1 e2 ->     binaryTransformEither (binaryOp' op) (eval' symTable e1) (eval' symTable e2)-  ExpFunctionCall _ _ (ExpValue _ _ function) (Just (AList _ _ args)) ->-    transformEitherList intrinsicFunctionCall' $ evalArgs args+  ExpFunctionCall _ _ (ExpValue _ _ function) (AList _ _ args) ->+    transformEitherList intrinsicFunctionCall'+      $   eval' symTable+      .   argExtractExpr+      <$> args    where     intrinsicFunctionCall' = intrinsicFunctionCall $ functionName function     functionName (ValVariable  name) = name     functionName (ValIntrinsic name) = name     functionName _                   = ""-    evalArgs :: [Argument a] -> [Either String ExpVal]-    evalArgs []                           = []-    evalArgs [Argument _ _ _ arg        ] = [eval' symTable arg]-    evalArgs (Argument _ _ _ arg : args') = eval' symTable arg : evalArgs args'   _ -> Left $ "Unsupported expression at: " ++ show (getSpan expr)  -- | Given a 'SymbolTable' and some 'Expression', evaluate that expression
src/Language/Fortran/Vars/Kind.hs view
@@ -6,9 +6,9 @@   , getTypeSize   , setTypeSize   , deriveSemTypeFromBaseType-  ) where+  )+where -import           Data.Either                    ( either ) import           Data.Maybe                     ( fromJust ) import           Language.Fortran.Analysis      ( Analysis ) import           Language.Fortran.Analysis.Types@@ -25,13 +25,10 @@                                                 , setTypeSize                                                 ) -import           Language.Fortran.Vars.Errors-                                                ( invalidArg )-import           Language.Fortran.Vars.Eval-                                                ( eval' )-import           Language.Fortran.Vars.Types-                                                ( ExpVal(..)-                                                , Type(..)+import           Language.Fortran.Vars.Errors   ( invalidArg )+import           Language.Fortran.Vars.Eval     ( eval' )+import           Language.Fortran.Vars.Types    ( ExpVal(..)+                                                , Type                                                 , SemType(..)                                                 , CharacterLen(..)                                                 , SymbolTable
src/Language/Fortran/Vars/Memory.hs view
@@ -1,13 +1,14 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE TupleSections #-}  module Language.Fortran.Vars.Memory   ( allocateMemoryBlocks   , processCommon+  , getTypeSize   ) where -import           Language.Fortran.Extras-                                                ( allPUS )+import           Language.Fortran.Extras        ( allPUS ) import           Data.Data                      ( Data ) import           Data.List                      ( foldl' ) import           Data.Maybe                     ( fromMaybe )@@ -27,20 +28,17 @@  import           Language.Fortran.Vars.MemoryLocation                                                 ( getStartLocation )-import           Language.Fortran.Vars.Types-                                                ( SymbolTableEntry(..)+import           Language.Fortran.Vars.Types    ( SymbolTableEntry(..)                                                 , MemoryBlock(..)                                                 , ProgramUnitModel                                                 , SymbolTable                                                 , StorageClass(..)                                                 , StorageTable-                                                , Type(..)+                                                , Type                                                 , SemType(..)                                                 )-import           Language.Fortran.Vars.Kind-                                                ( getTypeKind )-import           Language.Fortran.Vars.Union-                                                ( union )+import           Language.Fortran.Vars.Kind     ( getTypeKind )+import           Language.Fortran.Vars.Union    ( union )  -- | Given a 'SymbolTable' and an 'Expression', return the size of -- the variable represented by the expression@@ -53,15 +51,17 @@         _          -> error "Unsupported expression"       Just entity = M.lookup symbol symTable   in  case entity of-        SVariable (TArray ty dims) _ ->-          fromMaybe (error "Can't calculate size of dynamic array")-            $   sizeOfStaticArray-            <$> getTypeKind ty-            <*> dims-        SVariable ty _ ->-          fromMaybe (error "Can't get size of dynamic variable")-            $ getTypeKind ty-        _ -> error (symbol ++ " is not a VariableEntry.")+        SVariable ty _ -> getTypeSize ty+        _              -> error (symbol ++ " is not a VariableEntry.")++getTypeSize :: Type -> Int+getTypeSize = \case+  TArray ty dims ->+    fromMaybe (error "Can't calculate size of dynamic array")+      $   sizeOfStaticArray+      <$> getTypeKind ty+      <*> dims+  ty -> fromMaybe (error "Can't get size of dynamic variable") $ getTypeKind ty  -- | Given a static array's 'kind' and 'dimension', calculate its size sizeOfStaticArray :: Int -> [(Int, Int)] -> Int
src/Language/Fortran/Vars/MemoryLocation.hs view
@@ -18,17 +18,12 @@                                                 , Value(..)                                                 ) -import           Language.Fortran.Vars.Eval-                                                ( eval )-import           Language.Fortran.Vars.Kind-                                                ( toInt+import           Language.Fortran.Vars.Eval     ( eval' )+import           Language.Fortran.Vars.Kind     ( toInt                                                 , getTypeKind                                                 )-import           Language.Fortran.Vars.Range-                                                ( Range )-import           Language.Fortran.Vars.Types-                                                ( SymbolTableEntry(..)-                                                , Type(..)+import           Language.Fortran.Vars.Range    ( Range )+import           Language.Fortran.Vars.Types    ( SymbolTableEntry(..)                                                 , SemType(..)                                                 , Location                                                 , Offset@@ -77,52 +72,59 @@       ++ " at offset "       ++ show offset -calculateOffset :: Data a => SymbolTable -> Name -> [Index (Analysis a)] -> Int+calculateOffset+  :: Data a => SymbolTable -> Name -> [Index (Analysis a)] -> Maybe Int -- array index c(2,4) calculateOffset symTable symbol indices@(IxSingle{} : _) =   let Just entry = M.lookup symbol symTable-  in  case entry of-        SVariable (TArray ty (Just dims)) _ ->-          let ixSingles    = takeWhile isIxSingle indices-              Just kind    = getTypeKind ty-              arrayIndices = map toIndices ixSingles-                 where-                  toIndices (IxSingle _ _ _ expr) = toInt $ eval symTable expr-                  toIndices _ = error "toIndices: unexpected input"-          in  linearizedIndex arrayIndices dims * kind-        _ ->-          error "Only array-typed VariableEntries are expected at this point"+  in+    case entry of+      SVariable (TArray ty (Just dims)) _ ->+        let+          ixSingles    = takeWhile isIxSingle indices+          Just kind    = getTypeKind ty+          arrayIndices = either (const Nothing) Just+            $ traverse toIndices ixSingles+           where+            toIndices (IxSingle _ _ _ expr) = toInt <$> eval' symTable expr+            toIndices _ = error "toIndices: unexpected input"+        in+          (\x -> linearizedIndex x dims * kind) <$> arrayIndices+      _ -> error "Only array-typed VariableEntries are expected at this point" -- substring c(:5)-calculateOffset _ _ (IxRange _ _ Nothing _ _ : _) = 0+calculateOffset _ _ (IxRange _ _ Nothing _ _ : _) = Just 0 -- substring c(5:) calculateOffset symTable _ (IxRange _ _ (Just lowerIndex) _ _ : _) =-  toInt (eval symTable lowerIndex) - 1+  let val = eval' symTable lowerIndex+  in  either (const Nothing) (\x -> Just $ toInt x - 1) val calculateOffset _ _ _ = error "calculateOffset: invalid index"  -- | Given a 'SymbolTable' and some 'Expression' (which is assumed to have been predetermined -- to be of some variable type), return the 'Location' that the variable in question will be -- located in memory-getLocation :: Data a => SymbolTable -> Expression (Analysis a) -> Location+getLocation+  :: Data a => SymbolTable -> Expression (Analysis a) -> Maybe Location -- variable getLocation symTable e@(ExpValue _ _ (ValVariable _)) =-  findBlockOffset symTable (srcName e) 0+  Just $ findBlockOffset symTable (srcName e) 0 -- array index c(2,4) -- substring c(5:10) getLocation symTable (ExpSubscript _ _ e@ExpValue{} (AList _ _ indices)) =   let symbol = srcName e       offset = calculateOffset symTable symbol indices-  in  findBlockOffset symTable symbol offset+  in  findBlockOffset symTable symbol <$> offset -- array index and substring c(2,4)(1:20) getLocation symTable (ExpSubscript _ _ (ExpSubscript _ _ e@ExpValue{} (AList _ _ indices)) (AList _ _ subs))   = let symbol = srcName e         offset =-            calculateOffset symTable symbol indices-              + calculateOffset symTable symbol subs-    in  findBlockOffset symTable symbol offset+            (+)+              <$> calculateOffset symTable symbol indices+              <*> calculateOffset symTable symbol subs+    in  findBlockOffset symTable symbol <$> offset -- array within common block with dimensions declaration: common /block/ a, b(10) getLocation symTable (ExpFunctionCall _ _ e@ExpValue{} _) =-  findBlockOffset symTable (srcName e) 0-getLocation _ _ = error "getLocation : Not a variable expression"+  Just $ findBlockOffset symTable (srcName e) 0+getLocation _ _ = Nothing  -- | Given a 'SymbolTable' and some 'Expression' (which is assumed to have been -- predetermined to be of some variable type), return the start 'Location' that
src/Language/Fortran/Vars/Operation.hs view
@@ -17,18 +17,13 @@                                                 , EQ                                                 , LT                                                 )-import           Data.Char                      ( toUpper-                                                , chr-                                                )-import           Data.Either                    ( either )-import           Text.Read                      ( readMaybe )+import           Data.Char                      ( chr )  import           Language.Fortran.AST           ( BinaryOp(..)                                                 , UnaryOp(..)                                                 , Value(..)                                                 )-import           Language.Fortran.AST.RealLit   ( readRealLit )-import           Language.Fortran.AST.Boz       ( prettyBoz )+import           Language.Fortran.AST.Literal.Real ( readRealLit ) import           Language.Fortran.Util.Position ( SrcSpan )  @@ -36,10 +31,8 @@                                                 ( bozToInt8                                                 , bozToInt                                                 )-import           Language.Fortran.Vars.Errors-                                                ( invalidArg' )-import           Language.Fortran.Vars.Types-                                                ( ExpVal(..) )+import           Language.Fortran.Vars.Errors   ( invalidArg' )+import           Language.Fortran.Vars.Types    ( ExpVal(..) )  import           Data.Bits                      ( (.|.)                                                 , complement@@ -86,12 +79,12 @@ -- by that 'Value'. valueToExpVal' :: SrcSpan -> Value a -> Either String ExpVal valueToExpVal' s val = case val of-  ValInteger   i  _ -> Right $ Int     $ read i-  ValReal      r  _ -> Right $ Real    $ readRealLit r-  ValLogical   l  _ -> Right $ Logical l-  ValString    s'   -> Right $ Str s'-  ValHollerith h    -> Right $ Str h-  ValBoz       b    -> Right $ Boz b+  ValInteger i _  -> Right $ Int $ read i+  ValReal    r _  -> Right $ Real $ readRealLit r+  ValLogical l _  -> Right $ Logical l+  ValString    s' -> Right $ Str s'+  ValHollerith h  -> Right $ Str h+  ValBoz       b  -> Right $ Boz b   _               -> Left ("toExpVal: unsupported value at " ++ show s)  -- | Given a 'SrcSpan' and the 'Value' returnthe 'ExpVal' held@@ -108,8 +101,8 @@ nonLogicalToLogical (Real r) = Right $ r /= 0.0 nonLogicalToLogical (Str _) =   Left "Cannot transform a string value to a logical value"-nonLogicalToLogical (  Logical l) = Right l-nonLogicalToLogical b@(Boz     _) = nonLogicalToLogical $ bozToInt8 b+nonLogicalToLogical (Logical l) = Right l+nonLogicalToLogical (Boz     b) = nonLogicalToLogical $ bozToInt8 b  -- | Given a string representing a function call and a list of ExpVal -- values holding inputs to the function, evaluate the function call@@ -159,7 +152,7 @@ int' :: [ExpVal] -> Either String ExpVal int' [Int  i] = Right $ Int i int' [Real r] = Right $ Int (truncate r)-int' v@[boz@(Boz _), Int k] =+int' v@[(Boz boz), Int k] =   if k `elem` [2, 4, 8] then Right $ bozToInt k boz else invalidArg' "int" v int' vs = invalidArg' "int" vs @@ -218,13 +211,13 @@   (LT, Real a, Real b) -> Right $ Logical (a < b)   (LT, Int a, Real b) -> Right $ Logical (fromIntegral a < b)   (LT, Real a, Int b) -> Right $ Logical (a < fromIntegral b)-  (LT, a@(Boz _), b) -> binaryOp' LT (bozToInt8 a) b-  (LT, a, b@(Boz _)) -> binaryOp' LT a (bozToInt8 b)+  (LT, Boz boz, b) -> binaryOp' LT (bozToInt8 boz) b+  (LT, a, Boz boz) -> binaryOp' LT a (bozToInt8 boz)    (EQ, Int a, Real b) -> Right $ Logical (fromIntegral a == b)   (EQ, Real a, Int b) -> Right $ Logical (a == fromIntegral b)-  (EQ, a@(Boz _), b) -> binaryOp' EQ (bozToInt8 a) b-  (EQ, a, b@(Boz _)) -> binaryOp' EQ a (bozToInt8 b)+  (EQ, Boz boz, b) -> binaryOp' EQ (bozToInt8 boz) b+  (EQ, a, Boz boz) -> binaryOp' EQ a (bozToInt8 boz)   (EQ, Logical True, Int b) -> Right $ Logical (1 == b)   (EQ, Logical False, Int b) -> Right $ Logical (0 == b)   (EQ, Int a, Logical True) -> Right $ Logical (a == 1)
+ src/Language/Fortran/Vars/Orphans.hs view
@@ -0,0 +1,21 @@+module Language.Fortran.Vars.Orphans where++import Language.Fortran.AST+import qualified Language.Fortran.AST.Literal.Boz as Boz+import Language.Fortran.Util.Position+import Language.Fortran.Analysis.SemanticTypes++import Data.Aeson ( ToJSON, FromJSON )++-- TODO temporary solution+instance   ToJSON SemType+instance FromJSON SemType+instance   ToJSON CharacterLen+instance FromJSON CharacterLen++instance FromJSON SrcSpan+instance FromJSON Position++instance FromJSON Boz.Boz+instance FromJSON Boz.BozPrefix+instance FromJSON Boz.Conforming
src/Language/Fortran/Vars/PureExpression.hs view
@@ -9,6 +9,10 @@                                                 , Value(..)                                                 , aStrip                                                 )+import           Language.Fortran.AST.Literal.Complex+                                                ( ComplexLit(..)+                                                , ComplexPart(..)+                                                ) import           Language.Fortran.Vars.Call                                                 ( functionArguments ) @@ -36,7 +40,7 @@ isPureValue :: Value a -> Bool isPureValue ValInteger{}       = True isPureValue ValReal{}          = True-isPureValue (ValComplex e1 e2) = isPureExpression e1 && isPureExpression e2+isPureValue (ValComplex c)     = complexLitIsPure c isPureValue ValString{}        = True isPureValue ValHollerith{}     = True isPureValue ValVariable{}      = True@@ -44,6 +48,14 @@ isPureValue ValLogical{}       = True isPureValue ValStar            = True isPureValue _                  = False++-- | Is the given COMPLEX literal "pure", i.e. does it have no named constant+--   components?+complexLitIsPure :: ComplexLit a -> Bool+complexLitIsPure c =+    check (complexLitRealPart c) && check (complexLitImagPart c)+  where check = \case ComplexPartNamed{} -> False+                      _                  -> True  -- | Given an 'Index', determine whether it is pure isPureIndex :: Index a -> Bool
src/Language/Fortran/Vars/StructureTable.hs view
@@ -30,25 +30,22 @@                                                 , DeclaratorType(..)                                                 , aStrip                                                 )-import           Language.Fortran.Extras-                                                ( allPUS+import           Language.Fortran.Extras        ( allPUS                                                 , allPU                                                 )  import           Language.Fortran.Vars.SymbolTable                                                 ( collectSymbols )-import           Language.Fortran.Vars.Types-                                                ( SymbolTable+import           Language.Fortran.Vars.Types    ( SymbolTable                                                 , StructureTableEntry(..)                                                 , Structure                                                 , StructureTable                                                 , ProgramStructureTables-                                                , Type(..)+                                                , Type                                                 , SemType(..)                                                 , TypeError(..)                                                 )-import           Language.Fortran.Vars.Utils-                                                ( typeSpecToArrayType+import           Language.Fortran.Vars.Utils    ( typeSpecToArrayType                                                 , typeSpecToScalarType                                                 ) 
src/Language/Fortran/Vars/SymbolTable.hs view
@@ -10,22 +10,19 @@                                                 ) import           Data.List                      ( foldl' ) import qualified Data.Map                      as M-import           Data.Maybe                     ( catMaybes )+import           Data.Maybe                     ( mapMaybe )  import           Language.Fortran.Analysis      ( Analysis                                                 , srcName                                                 ) import           Language.Fortran.AST           ( AList-                                                , Argument(..)                                                 , aStrip-                                                , BaseType(..)                                                 , Block(..)                                                 , CommonGroup(..)                                                 , Declarator(..)                                                 , DeclaratorType(..)                                                 , DimensionDeclarator(..)                                                 , Expression(..)-                                                , Index(..)                                                 , Name                                                 , ProgramUnit(..)                                                 , programUnitBody@@ -35,30 +32,25 @@                                                 , Value(..)                                                 ) -import           Language.Fortran.Vars.Eval-                                                ( eval+import           Language.Fortran.Vars.Eval     ( eval                                                 , eval'                                                 ) import           Language.Fortran.Vars.BozConstant                                                 ( resolveBozConstant )-import           Language.Fortran.Vars.Types-                                                ( ExpVal(..)+import           Language.Fortran.Vars.Types    ( ExpVal(..)                                                 , SymbolTableEntry(..)-                                                , Type(..)+                                                , Type                                                 , SemType(..)                                                 , CharacterLen(..)                                                 , SymbolTable                                                 )-import           Language.Fortran.Vars.Utils-                                                ( typeSpecToScalarType+import           Language.Fortran.Vars.Utils    ( typeSpecToScalarType                                                 , typeSpecToArrayType                                                 )-import           Language.Fortran.Vars.Kind-                                                ( getKind+import           Language.Fortran.Vars.Kind     ( getKind                                                 , getTypeKind                                                 , setTypeKind                                                 , getKindOfExpVal-                                                , toInt                                                 , typeOfExpVal                                                 , baseToType                                                 , isStr@@ -221,19 +213,24 @@ -- skipped. handleArrayDecl   :: Data a-  => SymbolTable -> Expression (Analysis a) -> [DimensionDeclarator (Analysis a)]+  => SymbolTable+  -> Expression (Analysis a)+  -> [DimensionDeclarator (Analysis a)]   -> SymbolTable handleArrayDecl symTable varExp dimDecls =-    let symbol = srcName varExp-        dims   = traverse (resolveDimensionDimensionDeclarator symTable) dimDecls-     in case M.lookup symbol symTable of-          Just (SVariable TArray{} _) -> error "invalid declarator: duplicate array declarations"-          Just (SVariable ty loc) ->-            let ste = SVariable (TArray ty dims) loc-             in M.insert symbol ste symTable-          Nothing -> -- add array info, use a placeholder for scalar type-            let ste = SVariable (TArray placeholderIntrinsicType dims) (symbol, 0)-             in M.insert symbol ste symTable+  let symbol = srcName varExp+      dims   = traverse (resolveDimensionDimensionDeclarator symTable) dimDecls+  in  case M.lookup symbol symTable of+        Just (SVariable TArray{} _) ->+          error "invalid declarator: duplicate array declarations"+        Just (SVariable ty loc) ->+          let ste = SVariable (TArray ty dims) loc+          in  M.insert symbol ste symTable+        Just var -> error $ "Invalid declarator: " <> show var+        Nothing -> -- add array info, use a placeholder for scalar type+          let ste =+                  SVariable (TArray placeholderIntrinsicType dims) (symbol, 0)+          in  M.insert symbol ste symTable   where placeholderIntrinsicType = TInteger 4  -- | Given a 'SymbolTable' and a 'Statement' found in a 'ProgramUnit', return a new 'SymbolTable'@@ -254,9 +251,9 @@     -- in a correct parser.     Declarator _ _ _ ScalarDecl _ _ ->       error "non-array declaration in a DIMENSION statement"-  handleCommon symt (CommonGroup _ _ mName decls) =-    let arrayDecls = catMaybes . map extractArrayDecl . aStrip $ decls-     in foldl' (uncurry . handleArrayDecl) symt arrayDecls+  handleCommon symt (CommonGroup _ _ _ decls) =+    let arrayDecls = mapMaybe extractArrayDecl . aStrip $ decls+    in  foldl' (uncurry . handleArrayDecl) symt arrayDecls   extractArrayDecl = \case     Declarator _ _ v (ArrayDecl d) _ _ -> Just (v, aStrip d)     Declarator _ _ _ ScalarDecl    _ _ -> Nothing@@ -280,8 +277,10 @@ upgradeScalarToArray symbol dimDecls symTable =   case M.lookup symbol symTable of     Just (SVariable TArray{} _) ->-      error $  symbol <> " is array-typed variable."-            <> " Invalid fortran syntax (Duplicate DIMENSION attribute)"+      error+        $  symbol+        <> " is array-typed variable."+        <> " Invalid fortran syntax (Duplicate DIMENSION attribute)"     Just (SVariable ty loc) ->       let mdims = traverse (resolveDimensionDimensionDeclarator symTable)                            (aStrip dimDecls)
src/Language/Fortran/Vars/TypeCheck.hs view
@@ -13,55 +13,57 @@                                                 , LT                                                 ) import qualified Data.Map                      as M-import           Data.Char                      ( toUpper ) import           Data.Data                      ( toConstr ) import           Data.Maybe                     ( fromJust )-import           Text.Read                      ( readMaybe ) import           Language.Fortran.AST           ( Expression(..)                                                 , Value(..)                                                 , AList(..)                                                 , aStrip                                                 , aStrip'                                                 , Argument(..)+                                                , argExprNormalize                                                 , DoSpecification(..)                                                 , Statement(..)                                                 , Name                                                 , BinaryOp(..)                                                 , Index(..)                                                 )-import           Language.Fortran.AST.RealLit   ( RealLit(..)+import           Language.Fortran.AST.Literal   ( KindParam(..) )+import           Language.Fortran.AST.Literal.Real+                                                ( RealLit(..)                                                 , Exponent(..)                                                 , ExponentLetter(..)                                                 )+import           Language.Fortran.AST.Literal.Complex+                                                ( ComplexLit(..)+                                                , ComplexPart(..)+                                                ) import           Language.Fortran.Intrinsics    ( getVersionIntrinsics                                                 , getIntrinsicReturnType                                                 , IntrinsicType(..)                                                 )-import           Language.Fortran.ParserMonad   ( FortranVersion(..) )+import           Language.Fortran.Version       ( FortranVersion(..) )  import           Language.Fortran.Util.Position ( SrcSpan                                                 , getSpan                                                 )-import           Language.Fortran.Vars.Types-                                                ( SymbolTableEntry(..)+import           Language.Fortran.Vars.Types    ( SymbolTableEntry(..)                                                 , ExpVal(..)                                                 , SymbolTable                                                 , StructureTable                                                 , Kind-                                                , Type(..)+                                                , Type                                                 , SemType(..)                                                 , CharacterLen(..)                                                 , TypeError(..)                                                 , TypeOf                                                 , typeError                                                 )-import           Language.Fortran.Vars.Kind-                                                ( getTypeKind+import           Language.Fortran.Vars.Kind     ( getTypeKind                                                 , setTypeKind                                                 , toInt                                                 )-import           Language.Fortran.Vars.Eval-                                                ( eval' )+import           Language.Fortran.Vars.Eval     ( eval' ) import           Language.Fortran.Vars.StructureTable                                                 ( lookupField ) @@ -77,10 +79,10 @@   ExpValue _ s val                -> typeOfValue s strTable symTable val   ExpUnary _ _ _ e                -> typeOf strTable symTable e   ExpBinary _ s op e1 e2 -> typeOfBinaryExp s strTable symTable op e1 e2-  ExpFunctionCall _ _ (ExpValue _ s (ValVariable name)) margs ->-    typeOfFunctionCall s strTable symTable name (aStrip' margs)-  ExpFunctionCall _ _ (ExpValue _ s (ValIntrinsic name)) margs ->-    typeOfFunctionCall s strTable symTable name (aStrip' margs)+  ExpFunctionCall _ _ (ExpValue _ s (ValVariable name)) args ->+    typeOfFunctionCall s strTable symTable name (aStrip args)+  ExpFunctionCall _ _ (ExpValue _ s (ValIntrinsic name)) args ->+    typeOfFunctionCall s strTable symTable name (aStrip args)   ExpSubscript _ s arr (AList _ _ args@(IxSingle{} : _)) ->     let isIxRange = \case           IxRange{} -> True@@ -138,6 +140,8 @@   Nothing -> Left $ UnboundVariable name  -- | Internal function to determine the 'Type' of a constant+--+-- TODO ignoring kind param errors (should report better) typeOfValue   :: SrcSpan   -> StructureTable@@ -148,29 +152,32 @@   ValInteger _ mkp -> Right $ TInteger (kpOrDef 4 mkp)   ValReal r _ -> -- TODO ignoring kind param     let k = case exponentLetter (realLitExponent r) of-              ExpLetterE ->  4-              ExpLetterD ->  8-              ExpLetterQ -> 16-     in Right $ TReal k-  ValComplex real imaginary -> do-    tr <- typeOf strTable symTable real-    ti <- typeOf strTable symTable imaginary+          ExpLetterE -> 4+          ExpLetterD -> 8+          ExpLetterQ -> 16+    in  Right $ TReal k+  ValComplex c -> do+    tr <- typeOfComplexPart strTable symTable $ complexLitRealPart c+    ti <- typeOfComplexPart strTable symTable $ complexLitImagPart c     if tr == TReal 8 || ti == TReal 8       then return (TComplex 16)       else return (TComplex 8)-  ValString    s -> Right $ TCharacter (CharLenInt (length s)) 1-  ValHollerith s -> Right . TByte $ length s-  ValLogical   _ mkp -> Right $ TLogical (kpOrDef 4 mkp)-  ValBoz       b -> Right $ TByte 4-  _              -> Left $ UnknownType sp+  ValString    s   -> Right $ TCharacter (CharLenInt (length s)) 1+  ValHollerith s   -> Right . TByte $ length s+  ValLogical _ mkp -> Right $ TLogical (kpOrDef 4 mkp)+  ValBoz _         -> Right $ TByte 4+  _                -> Left $ UnknownType sp   where-    evalMaybeKind k = either (const Nothing) (Just . toInt) $ eval' symTable k-    -- TODO ignoring kind param errors (should report better)+    kpOrDef :: Kind -> Maybe (KindParam a) -> Kind     kpOrDef kDef = \case-       Nothing -> kDef-       Just kp -> case evalMaybeKind kp of-                    Nothing -> kDef-                    Just k  -> k+      Nothing -> kDef+      Just kp -> case kp of+        KindParamInt _ _ kpLit -> read kpLit+        KindParamVar _ _ kpVar ->+          let kpVarExpr = ExpValue undefined undefined (ValVariable kpVar)+          in  case eval' symTable kpVarExpr of+                Left{} -> kDef+                Right k -> toInt k  promote :: Type -> Type -> Type promote t1 t2@@ -224,15 +231,25 @@   -- TODO   -- = Right . TCharacter $ (+) <$> k1 <*> k2   = case t1 of-      TCharacter l1 k1 ->-        case t2 of-          TCharacter l2 k2 -> Right $ TCharacter (charLenConcat l1 l2) k1-          _ -> error "shit 1"-      _ -> error "shit 2"+    TCharacter l1 k1' -> case t2 of+      TCharacter l2 _ -> Right $ TCharacter (charLenConcat l1 l2) k1'+      _               -> error "shit 1"+    _ -> error "shit 2"   |   -- Logical+  -- NB when integer's are used with logical operators you get bitwise+  -- arithmetic behaviour     op `elem` [And, Or, Equivalent, NotEquivalent, XOr]-  = Right . TLogical . fromJust $ max <$> k1 <*> k2+  = let+      ty = case (t1, t2) of+        (TLogical _, TLogical _) -> Right . TLogical+        (TInteger _, _         ) -> Right . TInteger+        (_         , TInteger _) -> Right . TInteger+        (TByte _   , _         ) -> Right . TInteger+        (_         , TByte _   ) -> Right . TInteger+        _                        -> const+          (Left $ typeError sp "Unexpected types used with logical operators")+    in  ty . fromJust $ max <$> k1 <*> k2   |   -- Arithmetic     op `elem` [Addition, Subtraction, Multiplication, Division, Exponentiation]@@ -260,10 +277,9 @@   isInteger $ traverse (typeOf strt symt) upper   pure $ TCharacter calcLen 1  where-  calcLen =-      case (\x y -> y - x + 1) <$> lowerIndex <*> upperIndex of-        Nothing  -> CharLenStar-        Just len -> CharLenInt len+  calcLen = case (\x y -> y - x + 1) <$> lowerIndex <*> upperIndex of+    Nothing  -> CharLenStar+    Just len -> CharLenInt len   isInteger = \case     Right (Just (TInteger _)) -> Right ()     Right Nothing -> Right ()@@ -289,36 +305,48 @@ typeOfFunctionCall sp strT symT name argList =   checkIntrinsicFunction <> checkF77IntrinsicFunction <> checkExternalFunction  where-  args = [ e | Argument _ _ _ e <- argList ]+  args = [ argExprNormalize e | Argument _ _ _ e <- argList ]   -- If the function is any of the intrinsics below, determine its return type   -- accordingly   checkIntrinsicFunction :: Either TypeError Type   checkIntrinsicFunction-    | name `elem` ["int", "nint"], length args == 1 = Right (TInteger 4)-    | name `elem` ["int", "nint"], length args == 2 = case-        eval' symT (args !! 1)-      of-        Right (Int k) -> Right (TInteger k)-        _             -> Left $ typeError-          sp-          (  "Unable to determine the second argument value of "-          <> name-          <> " function"-          )-    | name == "int2" = Right (TInteger 2)-    | name `elem` ["loc", "sizeof", "iachar"] = Right (TInteger 4)-    | name == "dfloat" = Right (TReal 8)-    | name `elem` ["ishft", "rshift", "ibset", "ibits"], not (null args) = typeOf-      strT-      symT-      (head args)-    | name `elem` ["iand", "ior", "ieor", "and"], length args == 2 = do+    | name `elem` ["int", "nint"], length args == 1+    = Right (TInteger 4)+    | name `elem` ["int", "nint"], length args == 2+    = case eval' symT (args !! 1) of+      Right (Int k) -> Right (TInteger k)+      _             -> Left $ typeError+        sp+        (  "Unable to determine the second argument value of "+        <> name+        <> " function"+        )+    | name == "int2"+    = Right (TInteger 2)+    | name `elem` ["loc", "sizeof", "iachar"]+    = Right (TInteger 4)+    | name == "dfloat"+    = Right (TReal 8)+    | name `elem` ["ishft", "lshift", "rshift", "ibset", "ibits"], not+      (null args)+    = typeOf strT symT (head args)+    | name `elem` ["iand", "ior", "ieor", "and"], length args == 2+    = do       t1 <- typeOf strT symT (head args)       t2 <- typeOf strT symT (args !! 1)       return $ promote t1 t2-    | name == "btest", length args == 2 = return $ TLogical 4-    | name == "not", length args == 1 = typeOf strT symT (head args)-    | otherwise = Left $ typeError+    | name == "imag", length args == 1+    = do+      ty <- typeOf strT symT (head args)+      case ty of+        TComplex x -> Right . TReal $ x `div` 2+        _          -> Left $ typeError sp "Invalid argument to imag"+    | name == "btest", length args == 2+    = return $ TLogical 4+    | name == "not", length args == 1+    = typeOf strT symT (head args)+    | otherwise+    = Left $ typeError       sp       (name <> " is not in the extra list of intrinsic functions") @@ -347,3 +375,10 @@   -- in the symbol table.   checkExternalFunction :: Either TypeError Type   checkExternalFunction = typeOfSymbol symT name++typeOfComplexPart :: StructureTable -> SymbolTable -> ComplexPart a -> Either TypeError Type+typeOfComplexPart strTable symTable = \case+  ComplexPartReal   _ ss cpReal mkp -> tOfVal ss (ValReal    cpReal mkp)+  ComplexPartInt    _ ss cpInt  mkp -> tOfVal ss (ValInteger cpInt  mkp)+  ComplexPartNamed  _ _ nm         -> typeOfSymbol symTable nm+  where tOfVal ss v = typeOfValue ss strTable symTable v
src/Language/Fortran/Vars/Types.hs view
@@ -8,9 +8,11 @@   , SemType(..)   , CharacterLen(..)   , Kind-  ) where+  )+where  import           Language.Fortran.Extras.Encoding+import           Language.Fortran.Vars.Orphans                                                 ( ) import           Data.Aeson                     ( FromJSON                                                 , ToJSON@@ -25,15 +27,16 @@ import           Language.Fortran.AST           ( Name                                                 , ProgramUnitName                                                 , Expression-                                                , Kind                                                 )-import qualified Language.Fortran.AST.Boz       as AST+import qualified Language.Fortran.AST.Literal.Boz      as AST import           Language.Fortran.Util.Position ( SrcSpan(..)                                                 , Position(..)                                                 ) import           Language.Fortran.Analysis.SemanticTypes                                                 ( SemType(..)-                                                , CharacterLen(..) )+                                                , CharacterLen(..)+                                                , Kind+                                                )  type Type = SemType @@ -46,10 +49,8 @@   | Boz     AST.Boz   deriving (Eq, Ord, Show, Data, Typeable, Generic, NFData) -instance FromJSON AST.Boz-instance ToJSON AST.Boz-instance FromJSON AST.BozPrefix-instance ToJSON AST.BozPrefix+-- instance FromJSON AST.Conforming+-- instance ToJSON AST.Conforming instance FromJSON ExpVal instance ToJSON ExpVal @@ -146,7 +147,7 @@  -- | Helper method for getting the FilePath out of SrcSpan typeError :: SrcSpan -> String -> TypeError-typeError sp = let SrcSpan p _ = sp in TypeError (filePath p) sp+typeError sp = let SrcSpan p _ = sp in TypeError (posFilePath p) sp  instance ToJSON TypeError instance FromJSON TypeError
src/Language/Fortran/Vars/Utils.hs view
@@ -2,18 +2,15 @@  import           Language.Fortran.Analysis      ( Analysis ) import           Language.Fortran.AST-import           Language.Fortran.Vars.Types-                                                ( SymbolTable+import           Language.Fortran.Vars.Types    ( SymbolTable                                                 , ExpVal(..)-                                                , Type(..)+                                                , Type                                                 , SemType(..)                                                 )-import           Language.Fortran.Vars.Eval-                                                ( eval+import           Language.Fortran.Vars.Eval     ( eval                                                 , eval'                                                 )-import           Language.Fortran.Vars.Kind-                                                ( setTypeKind+import           Language.Fortran.Vars.Kind     ( setTypeKind                                                 , kindOfBaseType                                                 , baseToType                                                 )
test/AssignmentsSpec.hs view
@@ -11,14 +11,10 @@ import           Language.Fortran.AST           ( Expression(..)                                                 , Value(..)                                                 )-import           Language.Fortran.Extras-                                                ( allPU )-import           Language.Fortran.Extras.Test-                                                ( getTestProgramAnalysis )+import           Language.Fortran.Extras        ( allPU )+import           Language.Fortran.Extras.Test   ( getTestProgramAnalysis ) import           Language.Fortran.Vars.Assignments-import           Language.Fortran.Vars.Types-                                                ( Type(..)-                                                , SemType(..)+import           Language.Fortran.Vars.Types    ( SemType(..)                                                 , CharacterLen(..)                                                 ) @@ -37,7 +33,7 @@     map fst stmts `shouldBe` replicate 9 (TReal 4)     let getVal = \case           ExpValue _ _ (ValInteger s _) -> s-          _                           -> error "Not value"+          _                             -> error "Not value"     map (getVal . snd) stmts       `shouldBe` ["1", "0", "0", "0", "1", "0", "0", "0", "1"] @@ -47,5 +43,6 @@     length errs `shouldBe` 0     length stmts `shouldBe` 1     case head stmts of-      (TCharacter CharLenStar _, ExpValue _ _ (ValString "ABCDEFGHI")) -> pure ()+      (TCharacter CharLenStar _, ExpValue _ _ (ValString "ABCDEFGHI")) ->+        pure ()       _ -> assertFailure "Wrong statement matched"
test/BozConstantSpec.hs view
@@ -1,5 +1,11 @@-module BozConstantSpec ( spec ) where+-- TODO 2022-08-22 raehik: essentially obsoleted by+-- @Language.Fortran.AST.Literal.BozSpec@ in fortran-src +module BozConstantSpec+  ( spec+  )+where+ import           Test.Hspec  import           Language.Fortran.Vars.BozConstant@@ -7,12 +13,11 @@                                                 , bozToInt4                                                 , bozToInt8                                                 )-import           Language.Fortran.Vars.Types-                                                ( ExpVal(..) )-import qualified Language.Fortran.AST.Boz       as AST+import           Language.Fortran.Vars.Types    ( ExpVal(..) )+import qualified Language.Fortran.AST.Literal.Boz      as AST -boz :: String -> ExpVal-boz = Boz . AST.parseBoz+boz :: String -> AST.Boz+boz = AST.parseBoz  spec :: Spec spec = describe "Boz Constant Conversion" $ do
test/StorageTableSpec.hs view
@@ -2,8 +2,7 @@  import           Test.Hspec -import           Language.Fortran.Util.Files-                                                ( flexReadFile )+import           Language.Fortran.Util.Files    ( flexReadFile ) import           Language.Fortran.Extras.ProgramFile                                                 ( versionedProgramFile ) import           Data.ByteString.Char8          ( ByteString )@@ -15,12 +14,11 @@ import           Language.Fortran.AST           ( Name                                                 , ProgramUnitName(..)                                                 )-import           Language.Fortran.ParserMonad   ( FortranVersion(..) )+import           Language.Fortran.Version       ( FortranVersion(..) ) import           Language.Fortran.Analysis      ( initAnalysis ) -import           Language.Fortran.Vars ( programFileModel )-import           Language.Fortran.Vars.Types-                                                ( SymbolTableEntry(..)+import           Language.Fortran.Vars          ( programFileModel )+import           Language.Fortran.Vars.Types    ( SymbolTableEntry(..)                                                 , Location                                                 , MemoryBlock(..)                                                 , MemoryBlockName@@ -28,7 +26,6 @@                                                 , StorageClass(..)                                                 , StorageTable                                                 , SymbolTable-                                                , Type(..)                                                 , SemType(..)                                                 , CharacterLen(..)                                                 )
test/StructureTableSpec.hs view
@@ -10,10 +10,8 @@                                                 , Statement(..)                                                 , Expression(..)                                                 )-import           Language.Fortran.Extras-                                                ( allPU )-import           Language.Fortran.Extras.Test-                                                ( getTestProgramAnalysis )+import           Language.Fortran.Extras        ( allPU )+import           Language.Fortran.Extras.Test   ( getTestProgramAnalysis )  import           Language.Fortran.Vars.StructureTable                                                 ( StructureTable@@ -23,9 +21,7 @@                                                 ) import           Language.Fortran.Vars.SymbolTable                                                 ( collectSymbols )-import           Language.Fortran.Vars.Types-                                                ( SymbolTable-                                                , Type(..)+import           Language.Fortran.Vars.Types    ( SymbolTable                                                 , SemType(..)                                                 , CharacterLen(..)                                                 )@@ -76,15 +72,16 @@      it "multiple layer structures" $ do       structTable <- getStructureTable "test/structure_table/structure3.f"-      let-        graultEntries = [FieldEntry "garply" (TCustom "quuz")]-        quuzEntries =-          [FieldEntry "corge" (TCustom "baz"), FieldEntry "foobar" (TInteger 2)]-        fooEntries = [FieldEntry "bar" (TInteger 8)]-        bazEntries =-          [ FieldEntry "qux"  (TCustom "foo")-          , FieldEntry "quux" (TCharacter (CharLenInt 10) 1)-          ]+      let graultEntries = [FieldEntry "garply" (TCustom "quuz")]+          quuzEntries =+            [ FieldEntry "corge"  (TCustom "baz")+            , FieldEntry "foobar" (TInteger 2)+            ]+          fooEntries = [FieldEntry "bar" (TInteger 8)]+          bazEntries =+            [ FieldEntry "qux"  (TCustom "foo")+            , FieldEntry "quux" (TCharacter (CharLenInt 10) 1)+            ]       structTable `shouldBe` M.fromList         [ ("grault", graultEntries)         , ("quuz"  , quuzEntries)@@ -169,7 +166,8 @@                     universeBi pf :: [Expression (Analysis ())]                   ]           -- check looking up the expression succeeds and gives the correct type-          typeOf structTable st expr `shouldBe` Right (TCharacter (CharLenInt 10) 1)+          typeOf structTable st expr+            `shouldBe` Right (TCharacter (CharLenInt 10) 1)      it "Get type of union data reference expression"       $ testStructureTable "test/structure_table/union_struct3.f"@@ -180,7 +178,8 @@                   | e@ExpDataRef{} <-                     universeBi pf :: [Expression (Analysis ())]                   ]-          typeOf structTable st expr `shouldBe` Right (TCharacter (CharLenInt 13) 1)+          typeOf structTable st expr+            `shouldBe` Right (TCharacter (CharLenInt 13) 1)      it "Get combination of data references and subscripts" $ do       pf <- getTestProgramAnalysis "test/structure_table/structure4.f"
test/SymbolTableSpec.hs view
@@ -4,21 +4,19 @@ import           Language.Fortran.Extras.Analysis                                                 ( versionedExpandedProgramAnalysis                                                 )-import           Language.Fortran.Util.Files-                                                ( flexReadFile )+import           Language.Fortran.Util.Files    ( flexReadFile ) import           Language.Fortran.Extras.ProgramFile                                                 ( versionedProgramFile ) import           Data.ByteString.Char8          ( ByteString ) import qualified Data.Map                      as M import           Language.Fortran.AST           ( ProgramUnitName(..) )-import           Language.Fortran.ParserMonad   ( FortranVersion(..) )+import           Language.Fortran.Version       ( FortranVersion(..) ) import           Language.Fortran.Analysis      ( initAnalysis ) import           Test.Hspec -import           Language.Fortran.Vars ( programFileModel )-import           Language.Fortran.Vars.Types-                                                ( SymbolTableEntry(..)-                                                , Type(..)+import           Language.Fortran.Vars          ( programFileModel )+import           Language.Fortran.Vars.Types    ( SymbolTableEntry(..)+                                                , Type                                                 , SemType(..)                                                 , CharacterLen(..)                                                 , ExpVal(..)@@ -73,9 +71,9 @@         SDummy (TArray (TCharacter CharLenStar _) Nothing) ->           "DummyArrayDynamicCharacter"         SDummy (TCharacter CharLenStar _) -> "DummyDynamicCharacter"-        SDummy (TArray _ Nothing  ) -> "DummyDynamicArray"-        SDummy (TArray _ (Just _) ) -> "DummyStaticArray"-        SDummy _                    -> "DummyStaticScalar"+        SDummy (TArray _ Nothing) -> "DummyDynamicArray"+        SDummy (TArray _ (Just _)) -> "DummyStaticArray"+        SDummy _ -> "DummyStaticScalar"         v -> error (name ++ " is not a DummyVariableEntry it is a " ++ show v)  isDummy :: String -> SymbolTable -> Bool@@ -87,9 +85,9 @@ isDynamic name symTable = case M.lookup name symTable of   Just (SVariable ty _) -> case ty of     TArray (TCharacter CharLenStar _) _ -> True-    TArray _ Nothing   -> True+    TArray _ Nothing -> True     TCharacter CharLenStar _ -> True-    _                  -> False+    _ -> False   _ -> False  spec :: Spec@@ -583,7 +581,8 @@     it "Dynamic character static array" $ do       contents <- flexReadFile path       let st = getSymTable path contents "f4"-      typeOf "arr" st `shouldBe` TArray (TCharacter CharLenStar 1) (Just [(1, 5)])+      typeOf "arr" st+        `shouldBe` TArray (TCharacter CharLenStar 1) (Just [(1, 5)])       isDynamic "arr" st `shouldBe` True      it "Static character dynamic array" $ do
test/TypeCheckSpec.hs view
@@ -6,19 +6,17 @@ import           Data.List                      ( find ) import qualified Data.Map                      as M import           Data.Data                      ( Data )-import           Language.Fortran.Extras-                                                ( allPUS+import           Language.Fortran.Extras        ( allPUS                                                 , allPU                                                 )-import           Language.Fortran.Extras.Test-                                                ( getTestProgramAnalysis )+import           Language.Fortran.Extras.Test   ( getTestProgramAnalysis ) import           Language.Fortran.AST import           Language.Fortran.Analysis      ( stripAnalysis )-import           Language.Fortran.Vars ( programFileModel )-import           Language.Fortran.Vars.Types-                                                ( Type(..)+import           Language.Fortran.Vars          ( programFileModel )+import           Language.Fortran.Vars.Types    ( Type                                                 , SemType(..)-                                                , CharacterLen(..) )+                                                , CharacterLen(..)+                                                ) import           Language.Fortran.Vars.TypeCheck                                                 ( typeOf                                                 , TypeOf@@ -275,10 +273,11 @@     it "Logical Expression" $ do       (typeof, rhs) <- helper path puName       typeof (rhs "le1") `shouldBe` Right (TLogical 4)-      typeof (rhs "le2") `shouldBe` Right (TLogical 8)+      typeof (rhs "le2") `shouldBe` Right (TInteger 8)       typeof (rhs "le3") `shouldBe` Right (TLogical 2)       typeof (rhs "le4") `shouldBe` Right (TLogical 2)       typeof (rhs "le5") `shouldBe` Right (TLogical 4)+      typeof (rhs "le6") `shouldSatisfy` typeError      it "More expressions" $ do       (typeof, rhs) <- helper path puName@@ -350,6 +349,8 @@       typeof (rhs "b36") `shouldBe` Right (TInteger 4)       typeof (rhs "b37") `shouldBe` Right (TInteger 8)       typeof (rhs "b38") `shouldBe` Right (TLogical 4)+      typeof (rhs "b39") `shouldBe` Right (TReal 8)+      typeof (rhs "b40") `shouldBe` Right (TInteger 8)    describe "Implied Do" $ it "data statements" $ do     ProgramFile _ (pu : _) <- getTestProgramAnalysis