module Language.Fortran.Transformation.Disambiguation.FunctionSpec (spec) where import Test.Hspec import TestUtil import Language.Fortran.AST import Language.Fortran.Transformer disambiguateFunction :: ProgramFile () -> ProgramFile () disambiguateFunction = transform [ DisambiguateIntrinsic, DisambiguateFunction ] 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") Nothing) (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") (Just $ AList () u [ Argument () u Nothing (intGen 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") (Just $ AList () u [ Argument () u Nothing (ExpFunctionCall () u (ExpValue () u $ ValVariable "f") (Just $ AList () u [ Argument () u Nothing (intGen 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") (Just $ AList () u [ Argument () u Nothing (intGen 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") (Just $ AList () u [ Argument () u Nothing (intGen 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: