{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
module Camfort.Specification.Stencils.Synthesis
( formatSpec
, formatSpecNoComment
, offsetToIx
) where
import Camfort.Analysis.Annotations
import Camfort.Specification.Stencils.Syntax
import Data.List hiding (span)
import qualified Language.Fortran.AST as F
import qualified Language.Fortran.Analysis as FA
import Language.Fortran.Util.Position
import qualified Language.Fortran.Util.Position as FU
import Prelude hiding (span)
formatSpec :: F.MetaInfo -> Int -> Char
-> (FU.SrcSpan, Either [([Variable], Specification)] (String,Variable))
-> String
formatSpec :: MetaInfo
-> Int
-> Char
-> (SrcSpan,
Either [([Variable], Specification)] (Variable, Variable))
-> Variable
formatSpec MetaInfo
mi Int
indent Char
marker (SrcSpan
_, Right (Variable
evalInfo, Variable
name)) =
MetaInfo -> Int -> Variable -> Variable
buildCommentText MetaInfo
mi Int
indent (Variable -> Variable) -> Variable -> Variable
forall a b. (a -> b) -> a -> b
$
Char
marker Char -> Variable -> Variable
forall a. a -> [a] -> [a]
: Variable
" "
Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
evalInfo
Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ (if Variable
name Variable -> Variable -> Bool
forall a. Eq a => a -> a -> Bool
/= Variable
"" then Variable
" :: " Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
name else Variable
"") Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
"\n"
formatSpec MetaInfo
_ Int
_ Char
_ (SrcSpan
_, Left []) = Variable
""
formatSpec MetaInfo
mi Int
indent Char
marker (SrcSpan
_, Left [([Variable], Specification)]
specs) =
Variable -> [Variable] -> Variable
forall a. [a] -> [[a]] -> [a]
intercalate Variable
"\n" ([Variable] -> Variable) -> [Variable] -> Variable
forall a b. (a -> b) -> a -> b
$ (([Variable], Specification) -> Variable)
-> [([Variable], Specification)] -> [Variable]
forall a b. (a -> b) -> [a] -> [b]
map ([Variable], Specification) -> Variable
commentText [([Variable], Specification)]
specs
where
commentText :: ([Variable], Specification) -> Variable
commentText ([Variable], Specification)
s = MetaInfo -> Int -> Variable -> Variable
buildCommentText MetaInfo
mi Int
indent (Char
marker Char -> Variable -> Variable
forall a. a -> [a] -> [a]
: Variable
" " Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ ([Variable], Specification) -> Variable
forall a. Show a => ([Variable], a) -> Variable
doSpec ([Variable], Specification)
s)
commaSep :: [Variable] -> Variable
commaSep = Variable -> [Variable] -> Variable
forall a. [a] -> [[a]] -> [a]
intercalate Variable
", "
doSpec :: ([Variable], a) -> Variable
doSpec ([Variable]
arrayVar, a
spec) =
a -> Variable
forall a. Show a => a -> Variable
show (a -> a
forall p. p -> p
fixSpec a
spec) Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
" :: " Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ [Variable] -> Variable
commaSep [Variable]
arrayVar
fixSpec :: p -> p
fixSpec p
s = p
s
formatSpecNoComment ::
(FU.SrcSpan, Either [([Variable], Specification)] (String,Variable))
-> String
(SrcSpan
span, Right (Variable
evalInfo, Variable
name)) =
SrcSpan -> Variable
forall a. Show a => a -> Variable
show SrcSpan
span Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
" " Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
evalInfo Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ (if Variable
name Variable -> Variable -> Bool
forall a. Eq a => a -> a -> Bool
/= Variable
"" then Variable
" :: " Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
name else Variable
"") Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
"\n"
formatSpecNoComment (SrcSpan
_, Left []) = Variable
""
formatSpecNoComment (SrcSpan
span, Left [([Variable], Specification)]
specs) =
Variable -> [Variable] -> Variable
forall a. [a] -> [[a]] -> [a]
intercalate Variable
"\n" ([Variable] -> Variable)
-> ([([Variable], Specification)] -> [Variable])
-> [([Variable], Specification)]
-> Variable
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Variable], Specification) -> Variable)
-> [([Variable], Specification)] -> [Variable]
forall a b. (a -> b) -> [a] -> [b]
map (\([Variable], Specification)
s -> SrcSpan -> Variable
forall a. Show a => a -> Variable
show SrcSpan
span Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
" " Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ ([Variable], Specification) -> Variable
forall a. Show a => ([Variable], a) -> Variable
doSpec ([Variable], Specification)
s) ([([Variable], Specification)] -> Variable)
-> [([Variable], Specification)] -> Variable
forall a b. (a -> b) -> a -> b
$ [([Variable], Specification)]
specs
where
commaSep :: [Variable] -> Variable
commaSep = Variable -> [Variable] -> Variable
forall a. [a] -> [[a]] -> [a]
intercalate Variable
", "
doSpec :: ([Variable], a) -> Variable
doSpec ([Variable]
arrayVar, a
spec) =
a -> Variable
forall a. Show a => a -> Variable
show (a -> a
forall p. p -> p
fixSpec a
spec) Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ Variable
" :: " Variable -> Variable -> Variable
forall a. [a] -> [a] -> [a]
++ [Variable] -> Variable
commaSep [Variable]
arrayVar
fixSpec :: p -> p
fixSpec p
s = p
s
offsetToIx :: F.Name -> Int -> F.Index (FA.Analysis A)
offsetToIx :: Variable -> Int -> Index (Analysis A)
offsetToIx Variable
v Int
o
| Int
o Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
absoluteRep
= Analysis A
-> SrcSpan
-> Maybe Variable
-> Expression (Analysis A)
-> Index (Analysis A)
forall a. a -> SrcSpan -> Maybe Variable -> Expression a -> Index a
F.IxSingle Analysis A
a SrcSpan
s Maybe Variable
forall a. Maybe a
Nothing (Analysis A
-> SrcSpan -> Value (Analysis A) -> Expression (Analysis A)
forall a. a -> SrcSpan -> Value a -> Expression a
F.ExpValue Analysis A
a SrcSpan
s (Variable -> Value (Analysis A)
forall a. Variable -> Value a
F.ValInteger Variable
"0"))
| Int
o Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Analysis A
-> SrcSpan
-> Maybe Variable
-> Expression (Analysis A)
-> Index (Analysis A)
forall a. a -> SrcSpan -> Maybe Variable -> Expression a -> Index a
F.IxSingle Analysis A
a SrcSpan
s Maybe Variable
forall a. Maybe a
Nothing (Analysis A
-> SrcSpan -> Value (Analysis A) -> Expression (Analysis A)
forall a. a -> SrcSpan -> Value a -> Expression a
F.ExpValue Analysis A
a SrcSpan
s (Variable -> Value (Analysis A)
forall a. Variable -> Value a
F.ValVariable Variable
v))
| Int
o Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Analysis A
-> SrcSpan
-> Maybe Variable
-> Expression (Analysis A)
-> Index (Analysis A)
forall a. a -> SrcSpan -> Maybe Variable -> Expression a -> Index a
F.IxSingle Analysis A
a SrcSpan
s Maybe Variable
forall a. Maybe a
Nothing (Analysis A
-> SrcSpan
-> BinaryOp
-> Expression (Analysis A)
-> Expression (Analysis A)
-> Expression (Analysis A)
forall a.
a
-> SrcSpan
-> BinaryOp
-> Expression a
-> Expression a
-> Expression a
F.ExpBinary Analysis A
a SrcSpan
s BinaryOp
F.Addition
(Analysis A
-> SrcSpan -> Value (Analysis A) -> Expression (Analysis A)
forall a. a -> SrcSpan -> Value a -> Expression a
F.ExpValue Analysis A
a SrcSpan
s (Variable -> Value (Analysis A)
forall a. Variable -> Value a
F.ValVariable Variable
v))
(Analysis A
-> SrcSpan -> Value (Analysis A) -> Expression (Analysis A)
forall a. a -> SrcSpan -> Value a -> Expression a
F.ExpValue Analysis A
a SrcSpan
s (Variable -> Value (Analysis A)
forall a. Variable -> Value a
F.ValInteger (Variable -> Value (Analysis A)) -> Variable -> Value (Analysis A)
forall a b. (a -> b) -> a -> b
$ Int -> Variable
forall a. Show a => a -> Variable
show Int
o)))
| Bool
otherwise = Analysis A
-> SrcSpan
-> Maybe Variable
-> Expression (Analysis A)
-> Index (Analysis A)
forall a. a -> SrcSpan -> Maybe Variable -> Expression a -> Index a
F.IxSingle Analysis A
a SrcSpan
s Maybe Variable
forall a. Maybe a
Nothing (Analysis A
-> SrcSpan
-> BinaryOp
-> Expression (Analysis A)
-> Expression (Analysis A)
-> Expression (Analysis A)
forall a.
a
-> SrcSpan
-> BinaryOp
-> Expression a
-> Expression a
-> Expression a
F.ExpBinary Analysis A
a SrcSpan
s BinaryOp
F.Subtraction
(Analysis A
-> SrcSpan -> Value (Analysis A) -> Expression (Analysis A)
forall a. a -> SrcSpan -> Value a -> Expression a
F.ExpValue Analysis A
a SrcSpan
s (Variable -> Value (Analysis A)
forall a. Variable -> Value a
F.ValVariable Variable
v))
(Analysis A
-> SrcSpan -> Value (Analysis A) -> Expression (Analysis A)
forall a. a -> SrcSpan -> Value a -> Expression a
F.ExpValue Analysis A
a SrcSpan
s (Variable -> Value (Analysis A)
forall a. Variable -> Value a
F.ValInteger (Variable -> Value (Analysis A)) -> Variable -> Value (Analysis A)
forall a b. (a -> b) -> a -> b
$ Int -> Variable
forall a. Show a => a -> Variable
show (Int -> Int
forall a. Num a => a -> a
abs Int
o))))
where
a :: Analysis A
a = ([Analysis A] -> Analysis A
forall a. [a] -> a
head ([Analysis A] -> Analysis A) -> [Analysis A] -> Analysis A
forall a b. (a -> b) -> a -> b
$ [A] -> [Analysis A]
forall (b :: * -> *) a. Functor b => b a -> b (Analysis a)
FA.initAnalysis [A
unitAnnotation]) { insLabel :: Maybe Int
FA.insLabel = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0 }
s :: SrcSpan
s = Position -> Position -> SrcSpan
SrcSpan (Int -> Int -> Int -> Variable -> Maybe (Int, Variable) -> Position
Position Int
0 Int
0 Int
0 Variable
"" Maybe (Int, Variable)
forall a. Maybe a
Nothing) (Int -> Int -> Int -> Variable -> Maybe (Int, Variable) -> Position
Position Int
0 Int
0 Int
0 Variable
"" Maybe (Int, Variable)
forall a. Maybe a
Nothing)