fortran-src-0.10.0: test/Language/Fortran/Transformation/Disambiguation/FunctionSpec.hs
module Language.Fortran.Transformation.Disambiguation.FunctionSpec (spec) where
import Test.Hspec
import TestUtil
import Language.Fortran.AST
import Language.Fortran.Transformation.Monad
import Language.Fortran.Transformation.Disambiguation.Function
import Language.Fortran.Transformation.Disambiguation.Intrinsic
import Data.Data
disambiguateFunction' :: Data a => ProgramFile a -> ProgramFile a
disambiguateFunction' = transformWith $ sequence_ [ disambiguateIntrinsic
, disambiguateFunction ]
transformWith :: Data a => Transform a () -> ProgramFile a -> ProgramFile a
transformWith = runTransform mempty mempty
spec :: Spec
spec = do
describe "Function statement disambiguation" $
it "disambiguates function statements in example 1" $ do
let pf = disambiguateFunction' $ resetSrcSpan ex1
pf `shouldBe'` expectedEx1
describe "Function call disambiguation" $
it "disambiguates function calls in example 2" $ do
let pf = disambiguateFunction' $ resetSrcSpan ex2
pf `shouldBe'` expectedEx2
describe "Function call / Intrinsic disambiguation" $
it "disambiguates function calls / intrinsics in example 3" $ do
let pf = disambiguateFunction' $ resetSrcSpan ex3
pf `shouldBe'` expectedEx3
describe "Function call / Variable disambiguation" $
it "disambiguates function calls in example 4" $ do
let pf = disambiguateFunction' $ resetSrcSpan ex4
pf `shouldBe'` expectedEx4
describe "Implicit Function call / Variable disambiguation" $
it "disambiguates function calls in example 5" $ do
let pf = disambiguateFunction' $ resetSrcSpan ex5
pf `shouldBe'` expectedEx5
describe "Implicit array declaration with dimension disambiguation" $
it "Should not disambiguation to a function call in example 6" $ do
let pf = disambiguateFunction' $ resetSrcSpan ex6
pf `shouldBe'` expectedEx6
{-
- program Main
- integer a, b(1), c, e
- dimension a(1)
- a(1) = 1
- b(1) = 1
- c(x) = 1
- d(x) = 1
- e() = 1
- end
-}
ex1 :: ProgramFile ()
ex1 = ProgramFile mi77 [ ex1pu1 ]
ex1pu1 :: ProgramUnit ()
ex1pu1 = PUMain () u (Just "main") ex1pu1bs Nothing
ex1pu1bs :: [Block ()]
ex1pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ declVarGen "a"
, Declarator () u (varGen "b") (ArrayDecl (AList () u [ DimensionDeclarator () u Nothing (Just $ intGen 1) ])) Nothing Nothing
, declVarGen "c" ]))
, BlStatement () u Nothing (StDimension () u (AList () u
[ Declarator () u (varGen "a") (ArrayDecl (AList () u [ DimensionDeclarator () u Nothing (Just $ intGen 1) ])) Nothing Nothing ]))
, BlStatement () u Nothing (StExpressionAssign () u
(ExpSubscript () u (varGen "a") (AList () u [ ixSinGen 1 ])) (intGen 1))
, BlStatement () u Nothing (StExpressionAssign () u
(ExpSubscript () u (varGen "b") (AList () u [ ixSinGen 1 ])) (intGen 1))
, BlStatement () u Nothing (StExpressionAssign () u
(ExpSubscript () u (varGen "c") (AList () u [ IxSingle () u Nothing $ varGen "x" ])) (intGen 1))
, BlStatement () u Nothing (StExpressionAssign () u
(ExpSubscript () u (varGen "d") (AList () u [ IxSingle () u Nothing $ varGen "x" ])) (intGen 1))
, BlStatement () u Nothing (StExpressionAssign () u
(ExpFunctionCall () u (varGen "e") (aEmpty () u)) (intGen 1)) ]
expectedEx1 :: ProgramFile ()
expectedEx1 = ProgramFile mi77 [ expectedEx1pu1 ]
expectedEx1pu1 :: ProgramUnit ()
expectedEx1pu1 = PUMain () u (Just "main") expectedEx1pu1bs Nothing
expectedEx1pu1bs :: [Block ()]
expectedEx1pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ declVarGen "a"
, Declarator () u (varGen "b") (ArrayDecl (AList () u [ DimensionDeclarator () u Nothing (Just $ intGen 1) ])) Nothing Nothing
, declVarGen "c" ]))
, BlStatement () u Nothing (StDimension () u (AList () u
[ Declarator () u (varGen "a") (ArrayDecl (AList () u [ DimensionDeclarator () u Nothing (Just $ intGen 1) ])) Nothing Nothing ]))
, BlStatement () u Nothing (StExpressionAssign () u
(ExpSubscript () u (varGen "a") (AList () u [ ixSinGen 1 ])) (intGen 1))
, BlStatement () u Nothing (StExpressionAssign () u
(ExpSubscript () u (varGen "b") (AList () u [ ixSinGen 1 ])) (intGen 1))
, BlStatement () u Nothing (StFunction () u
(ExpValue () u $ ValVariable "c") (AList () u [ varGen "x" ]) (intGen 1))
, BlStatement () u Nothing (StFunction () u
(ExpValue () u $ ValVariable "d") (AList () u [ varGen "x" ]) (intGen 1))
, BlStatement () u Nothing (StFunction () u
(ExpValue () u $ ValVariable "e") (AList () u []) (intGen 1)) ]
{-
- program
- integer k(1)
- f(x) = 1
- i = 1 + f(1)
- l = k(1)
- j = y(1,1) + a
- end
-
- function y(i,j)
- end
-}
ex2 :: ProgramFile ()
ex2 = ProgramFile mi77 [ ex2pu1, ex2pu2 ]
ex2pu1 :: ProgramUnit ()
ex2pu1 = PUMain () u Nothing ex2pu1bs Nothing
ex2pu2 :: ProgramUnit ()
ex2pu2 = PUFunction () u Nothing emptyPrefixSuffix "y" (Just $ AList () u [ varGen "i", varGen "j" ]) Nothing [ ] Nothing
ex2pu1bs :: [Block ()]
ex2pu1bs =
[ BlStatement () u Nothing
(StFunction () u
(ExpValue () u (ValVariable "f"))
(AList () u [ varGen "x" ])
(intGen 1))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "i")
(ExpBinary () u Addition
(intGen 1)
(ExpSubscript () u
(varGen "f")
(AList () u [ ixSinGen 1 ])))) ]
expectedEx2 :: ProgramFile ()
expectedEx2 = ProgramFile mi77 [ expectedEx2pu1, ex2pu2 ]
expectedEx2pu1 :: ProgramUnit ()
expectedEx2pu1 = PUMain () u Nothing expectedEx2pu1bs Nothing
expectedEx2pu1bs :: [Block ()]
expectedEx2pu1bs =
[ BlStatement () u Nothing
(StFunction () u
(ExpValue () u (ValVariable "f"))
(AList () u [ varGen "x" ])
(intGen 1))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "i")
(ExpBinary () u Addition
(intGen 1)
(ExpFunctionCall () u
(ExpValue () u $ ValVariable "f")
(AList () u [ Argument () u Nothing (aintGen 1) ])))) ]
ex3 :: ProgramFile ()
ex3 = ProgramFile mi77 [ ex3pu1, ex3pu2 ]
ex3pu1 :: ProgramUnit ()
ex3pu1 = PUMain () u Nothing ex3pu1bs Nothing
ex3pu2 :: ProgramUnit ()
ex3pu2 = PUFunction () u Nothing emptyPrefixSuffix "y" (Just $ AList () u [ varGen "i", varGen "j" ]) Nothing [ ] Nothing
ex3pu1bs :: [Block ()]
ex3pu1bs =
[ BlStatement () u Nothing
(StFunction () u
(ExpValue () u (ValVariable "f"))
(AList () u [ varGen "x" ])
(intGen 1))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "i")
(ExpSubscript () u (varGen "abs")
(AList () u [
IxSingle () u Nothing (ExpSubscript () u (varGen "f") (AList () u [ ixSinGen 1 ]))]))) ]
expectedEx3 :: ProgramFile ()
expectedEx3 = ProgramFile mi77 [ expectedEx3pu1, ex3pu2 ]
expectedEx3pu1 :: ProgramUnit ()
expectedEx3pu1 = PUMain () u Nothing expectedEx3pu1bs Nothing
expectedEx3pu1bs :: [Block ()]
expectedEx3pu1bs =
[ BlStatement () u Nothing
(StFunction () u
(ExpValue () u (ValVariable "f"))
(AList () u [ varGen "x" ])
(intGen 1))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "i")
(ExpFunctionCall () u (ExpValue () u $ ValIntrinsic "abs")
(AList () u [ Argument () u Nothing
(ArgExpr $ ExpFunctionCall () u (ExpValue () u $ ValVariable "f")
(AList () u [ Argument () u Nothing (aintGen 1) ])) ]))) ]
{-
- program Main
- integer a, f
- a = f(1)
- end
-}
ex4 :: ProgramFile ()
ex4 = ProgramFile mi77 [ ex4pu1 ]
ex4pu1 :: ProgramUnit ()
ex4pu1 = PUMain () u (Just "main") ex4pu1bs Nothing
ex4pu1bs :: [Block ()]
ex4pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ declVarGen "a"
, declVarGen "f" ]))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "a") (ExpSubscript () u (varGen "f") (AList () u [ ixSinGen 1 ]))) ]
expectedEx4 :: ProgramFile ()
expectedEx4 = ProgramFile mi77 [ expectedEx4pu1 ]
expectedEx4pu1 :: ProgramUnit ()
expectedEx4pu1 = PUMain () u (Just "main") expectedEx4pu1bs Nothing
expectedEx4pu1bs :: [Block ()]
expectedEx4pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ declVarGen "a"
, declVarGen "f" ]))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "a")
(ExpFunctionCall () u (ExpValue () u $ ValVariable "f")
(AList () u [ Argument () u Nothing (aintGen 1) ] ))) ]
{-
- program Main
- integer a
- a = f(1)
- end
-}
ex5 :: ProgramFile ()
ex5 = ProgramFile mi77 [ ex5pu1 ]
ex5pu1 :: ProgramUnit ()
ex5pu1 = PUMain () u (Just "main") ex5pu1bs Nothing
ex5pu1bs :: [Block ()]
ex5pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ declVarGen "a" ]))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "a") (ExpSubscript () u (varGen "f") (AList () u [ ixSinGen 1 ]))) ]
expectedEx5 :: ProgramFile ()
expectedEx5 = ProgramFile mi77 [ expectedEx5pu1 ]
expectedEx5pu1 :: ProgramUnit ()
expectedEx5pu1 = PUMain () u (Just "main") expectedEx5pu1bs Nothing
expectedEx5pu1bs :: [Block ()]
expectedEx5pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ declVarGen "a" ]))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "a")
(ExpFunctionCall () u (ExpValue () u $ ValVariable "f")
(AList () u [ Argument () u Nothing (aintGen 1) ] ))) ]
{-
- program Main
- integer a
- dimension f(10)
- a = f(1)
- end
-}
ex6 :: ProgramFile ()
ex6 = ProgramFile mi77 [ ex6pu1 ]
ex6pu1 :: ProgramUnit ()
ex6pu1 = PUMain () u (Just "main") ex6pu1bs Nothing
ex6pu1bs :: [Block ()]
ex6pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ declVarGen "a"
]))
, BlStatement () u Nothing (StDimension () u (AList () u
[ Declarator () u (varGen "f") (ArrayDecl (AList () u [ DimensionDeclarator () u Nothing (Just $ intGen 10) ])) Nothing Nothing ]))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "a") (ExpSubscript () u (varGen "f") (AList () u [ ixSinGen 1 ]))) ]
expectedEx6 :: ProgramFile ()
expectedEx6 = ProgramFile mi77 [ expectedEx6pu1 ]
expectedEx6pu1 :: ProgramUnit ()
expectedEx6pu1 = PUMain () u (Just "main") expectedEx6pu1bs Nothing
expectedEx6pu1bs :: [Block ()]
expectedEx6pu1bs =
[ BlStatement () u Nothing (StDeclaration () u (TypeSpec () u TypeInteger Nothing) Nothing (AList () u
[ Declarator () u (varGen "a") ScalarDecl Nothing Nothing ]))
, BlStatement () u Nothing (StDimension () u (AList () u
[ Declarator () u (varGen "f") (ArrayDecl (AList () u [ DimensionDeclarator () u Nothing (Just $ intGen 10 ) ])) Nothing Nothing ]))
, BlStatement () u Nothing
(StExpressionAssign () u (varGen "a") (ExpSubscript () u (varGen "f") (AList () u [ ixSinGen 1 ]))) ]
-- Local variables:
-- mode: haskell
-- haskell-program-name: "cabal repl test-suite:spec"
-- End: