{- |
Module      :  ./CSL/ASUtils.hs
Description :  Utils for the abstract syntax of EnCL
Copyright   :  (c) Dominik Dietrich, Ewaryst Schulz, DFKI Bremen 2011
License     :  GPLv2 or higher, see LICENSE.txt

Maintainer  :  Ewaryst.Schulz@dfki.de
Stability   :  experimental
Portability :  portable


Utils to create and access abstract syntax data
-}

module CSL.ASUtils
    ( getDefiniens        -- accessor function for AssDefinition
    , getArguments        -- accessor function for AssDefinition
    , isFunDef            -- predicate for AssDefinition
    , isInterval          -- predicate for EXPRESSION
    , mkDefinition        -- constructor for AssDefinition
    , updateDefinition    -- updates the definiens
    , mapExpr             -- maps function over EXPRESSION arguments

    , varDeclName
    , varDeclToVar
    , opDeclToOp

    , mkVar               -- Variable constructor
    , mkOp                -- Simple Operator constructor
    , mkPredefOp          -- Simple Operator constructor for predefined ops
    , mkUserdefOp

    , mkAndAnalyzeOp
    , mkAndAnalyzeOp'
    , toElimConst         -- Constant naming for elim constants, see Analysis.hs
    , simpleName
    , setOfUserDefined
    , setOfConstsAndEPSpecs
    ) where

import Common.Id as Id

import qualified Data.Set as Set
import Data.List (sort, mapAccumL)

import CSL.AS_BASIC_CSL
import CSL.Fold

{- ---------------------------------------------------------------------------
Preliminaries and Utilities
--------------------------------------------------------------------------- -}

-- | A simple operator constructor from given operator name and arguments
mkOp :: String -> [EXPRESSION] -> EXPRESSION
mkOp :: String -> [EXPRESSION] -> EXPRESSION
mkOp s :: String
s el :: [EXPRESSION]
el = OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op (ConstantName -> OPID
OpUser (ConstantName -> OPID) -> ConstantName -> OPID
forall a b. (a -> b) -> a -> b
$ String -> ConstantName
SimpleConstant String
s) [] [EXPRESSION]
el Range
nullRange

-- | A variable constructor
mkVar :: String -> EXPRESSION
mkVar :: String -> EXPRESSION
mkVar = Token -> EXPRESSION
Var (Token -> EXPRESSION) -> (String -> Token) -> String -> EXPRESSION
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Token
mkSimpleId

-- | A simple operator constructor from given operator id and arguments
mkPredefOp :: OPNAME -> [EXPRESSION] -> EXPRESSION
mkPredefOp :: OPNAME -> [EXPRESSION] -> EXPRESSION
mkPredefOp n :: OPNAME
n el :: [EXPRESSION]
el = OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op (OPNAME -> OPID
OpId OPNAME
n) [] [EXPRESSION]
el Range
nullRange

-- | A simple operator constructor from given operator id and arguments
mkUserdefOp :: String -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
mkUserdefOp :: String -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
mkUserdefOp n :: String
n = OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op (ConstantName -> OPID
OpUser (ConstantName -> OPID) -> ConstantName -> OPID
forall a b. (a -> b) -> a -> b
$ String -> ConstantName
SimpleConstant String
n)


foldNaryToBinary :: OPID -> Range -> [EXPRESSION] -> EXPRESSION
foldNaryToBinary :: OPID -> Range -> [EXPRESSION] -> EXPRESSION
foldNaryToBinary op :: OPID
op rg :: Range
rg exps :: [EXPRESSION]
exps = (EXPRESSION -> EXPRESSION -> EXPRESSION)
-> EXPRESSION -> [EXPRESSION] -> EXPRESSION
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl EXPRESSION -> EXPRESSION -> EXPRESSION
f (EXPRESSION -> EXPRESSION -> EXPRESSION
f ([EXPRESSION] -> EXPRESSION
forall a. [a] -> a
head [EXPRESSION]
exps) ([EXPRESSION]
exps [EXPRESSION] -> Int -> EXPRESSION
forall a. [a] -> Int -> a
!! 1)) ([EXPRESSION] -> EXPRESSION) -> [EXPRESSION] -> EXPRESSION
forall a b. (a -> b) -> a -> b
$ Int -> [EXPRESSION] -> [EXPRESSION]
forall a. Int -> [a] -> [a]
drop 2 [EXPRESSION]
exps
    where f :: EXPRESSION -> EXPRESSION -> EXPRESSION
f e' :: EXPRESSION
e' e'' :: EXPRESSION
e'' = OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op OPID
op [] [EXPRESSION
e', EXPRESSION
e''] Range
rg

mkAndAnalyzeOp :: OperatorState st => st -> String -> [EXTPARAM] -> [EXPRESSION]
               -> Range -> EXPRESSION

mkAndAnalyzeOp :: st -> String -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
mkAndAnalyzeOp st :: st
st s :: String
s eps :: [EXTPARAM]
eps exps :: [EXPRESSION]
exps rg :: Range
rg =
    (String -> EXPRESSION)
-> (EXPRESSION -> EXPRESSION)
-> Either String EXPRESSION
-> EXPRESSION
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> EXPRESSION
forall a. String -> a
f EXPRESSION -> EXPRESSION
forall p. p -> p
g (Either String EXPRESSION -> EXPRESSION)
-> Either String EXPRESSION -> EXPRESSION
forall a b. (a -> b) -> a -> b
$ Bool
-> st
-> String
-> [EXTPARAM]
-> [EXPRESSION]
-> Range
-> Either String EXPRESSION
forall st.
OperatorState st =>
Bool
-> st
-> String
-> [EXTPARAM]
-> [EXPRESSION]
-> Range
-> Either String EXPRESSION
mkAndAnalyzeOp' Bool
False st
st String
s [EXTPARAM]
eps [EXPRESSION]
exps Range
rg
    where f :: String -> a
f = String -> a
forall a. HasCallStack => String -> a
error
          g :: p -> p
g e :: p
e = p
e

-- | Lookup the string in the given 'OperatorState'
mkAndAnalyzeOp' :: OperatorState st => Bool -- ^ process binders
                -> st -> String -> [EXTPARAM] -> [EXPRESSION]
               -> Range -> Either String EXPRESSION
mkAndAnalyzeOp' :: Bool
-> st
-> String
-> [EXTPARAM]
-> [EXPRESSION]
-> Range
-> Either String EXPRESSION
mkAndAnalyzeOp' b :: Bool
b st :: st
st s :: String
s eps :: [EXTPARAM]
eps exps :: [EXPRESSION]
exps rg :: Range
rg =
    case st -> String -> Int -> Either Bool OpInfo
forall a.
OperatorState a =>
a -> String -> Int -> Either Bool OpInfo
lookupOperator st
st String
s ([EXPRESSION] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EXPRESSION]
exps) of
      Left False
          | st -> String -> Bool
forall a. OperatorState a => a -> String -> Bool
isVar st
st String
s -> if [EXPRESSION] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [EXPRESSION]
exps Bool -> Bool -> Bool
&& [EXTPARAM] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [EXTPARAM]
eps
                          then EXPRESSION -> Either String EXPRESSION
forall a b. b -> Either a b
Right (EXPRESSION -> Either String EXPRESSION)
-> EXPRESSION -> Either String EXPRESSION
forall a b. (a -> b) -> a -> b
$ Token -> EXPRESSION
Var Token :: String -> Range -> Token
Token { tokStr :: String
tokStr = String
s, tokPos :: Range
tokPos = Range
rg }
                          else String -> Either String EXPRESSION
forall a b. a -> Either a b
Left "Variable requires no (extended) parameters"
          | Bool
otherwise -> [EXPRESSION] -> OPID -> Either String EXPRESSION
forall a. [EXPRESSION] -> OPID -> Either a EXPRESSION
f [EXPRESSION]
exps (OPID -> Either String EXPRESSION)
-> OPID -> Either String EXPRESSION
forall a b. (a -> b) -> a -> b
$ ConstantName -> OPID
OpUser (ConstantName -> OPID) -> ConstantName -> OPID
forall a b. (a -> b) -> a -> b
$ String -> ConstantName
SimpleConstant String
s
      {- if registered it must be registered with the given arity or
      as flex-op, otherwise we don't accept it -}
      Left True -> String -> Either String EXPRESSION
forall a b. a -> Either a b
Left "Wrong arity"
      Right oi :: OpInfo
oi
          | [EXTPARAM] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [EXTPARAM]
eps ->
              if OpInfo -> Bool
foldNAry OpInfo
oi Bool -> Bool -> Bool
&& [EXPRESSION] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EXPRESSION]
exps Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 2
              then EXPRESSION -> Either String EXPRESSION
forall a b. b -> Either a b
Right (EXPRESSION -> Either String EXPRESSION)
-> EXPRESSION -> Either String EXPRESSION
forall a b. (a -> b) -> a -> b
$ OPID -> Range -> [EXPRESSION] -> EXPRESSION
foldNaryToBinary (OPNAME -> OPID
OpId (OPNAME -> OPID) -> OPNAME -> OPID
forall a b. (a -> b) -> a -> b
$ OpInfo -> OPNAME
opname OpInfo
oi) Range
rg [EXPRESSION]
exps
              else let exps' :: [EXPRESSION]
exps' =
                        case OpInfo -> Maybe BindInfo
bind OpInfo
oi of
                          Just x :: BindInfo
x -> if Bool
b then BindInfo -> [EXPRESSION] -> [EXPRESSION]
processBinderArgs BindInfo
x [EXPRESSION]
exps else [EXPRESSION]
exps
                          _ -> [EXPRESSION]
exps
                   in [EXPRESSION] -> OPID -> Either String EXPRESSION
forall a. [EXPRESSION] -> OPID -> Either a EXPRESSION
f [EXPRESSION]
exps' (OPID -> Either String EXPRESSION)
-> OPID -> Either String EXPRESSION
forall a b. (a -> b) -> a -> b
$ OPNAME -> OPID
OpId (OPNAME -> OPID) -> OPNAME -> OPID
forall a b. (a -> b) -> a -> b
$ OpInfo -> OPNAME
opname OpInfo
oi

          | Bool
otherwise -> String -> Either String EXPRESSION
forall a b. a -> Either a b
Left "No extended parameters allowed"
    where f :: [EXPRESSION] -> OPID -> Either a EXPRESSION
f exps' :: [EXPRESSION]
exps' op :: OPID
op = EXPRESSION -> Either a EXPRESSION
forall a b. b -> Either a b
Right (EXPRESSION -> Either a EXPRESSION)
-> EXPRESSION -> Either a EXPRESSION
forall a b. (a -> b) -> a -> b
$ OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op OPID
op [EXTPARAM]
eps [EXPRESSION]
exps' Range
rg

{- | For given binder arguments we replace the constant-expressions at the
bound variable positions by variable-expressions and also all constants with
the name of a variable in the arguments at binder body positions. -}
processBinderArgs :: BindInfo -> [EXPRESSION] -> [EXPRESSION]
processBinderArgs :: BindInfo -> [EXPRESSION] -> [EXPRESSION]
processBinderArgs (BindInfo {bindingVarPos :: BindInfo -> [Int]
bindingVarPos = [Int]
bvl, boundBodyPos :: BindInfo -> [Int]
boundBodyPos = [Int]
bbl}) exps :: [EXPRESSION]
exps =
    let bvl' :: [Int]
bvl' = [Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort [Int]
bvl
        (vs :: Set String
vs, vl :: [EXPRESSION]
vl) = [EXPRESSION] -> (Set String, [EXPRESSION])
varSet ([EXPRESSION] -> (Set String, [EXPRESSION]))
-> [EXPRESSION] -> (Set String, [EXPRESSION])
forall a b. (a -> b) -> a -> b
$ (Int -> EXPRESSION) -> [Int] -> [EXPRESSION]
forall a b. (a -> b) -> [a] -> [b]
map ([EXPRESSION]
exps [EXPRESSION] -> Int -> EXPRESSION
forall a. [a] -> Int -> a
!!) [Int]
bvl'
        g :: [(Int, EXPRESSION)]
-> (Int, EXPRESSION) -> ([(Int, EXPRESSION)], EXPRESSION)
g l' :: [(Int, EXPRESSION)]
l'@((j :: Int
j, ve :: EXPRESSION
ve) : l :: [(Int, EXPRESSION)]
l) (i :: Int
i, e :: EXPRESSION
e)
            | Int
j Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
i -- at bound variable position
                = ([(Int, EXPRESSION)]
l, EXPRESSION
ve)
            | Bool
otherwise = ([(Int, EXPRESSION)]
l', (Int, EXPRESSION) -> EXPRESSION
g' (Int
i, EXPRESSION
e))
        g l :: [(Int, EXPRESSION)]
l x :: (Int, EXPRESSION)
x = ([(Int, EXPRESSION)]
l, (Int, EXPRESSION) -> EXPRESSION
g' (Int, EXPRESSION)
x)
        g' :: (Int, EXPRESSION) -> EXPRESSION
g' (i :: Int
i, e :: EXPRESSION
e)
            | Int -> [Int] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Int
i [Int]
bbl -- at binder body position
                = Set String -> EXPRESSION -> EXPRESSION
constsToVars Set String
vs EXPRESSION
e
            | Bool
otherwise = EXPRESSION
e
    in ([(Int, EXPRESSION)], [EXPRESSION]) -> [EXPRESSION]
forall a b. (a, b) -> b
snd (([(Int, EXPRESSION)], [EXPRESSION]) -> [EXPRESSION])
-> ([(Int, EXPRESSION)], [EXPRESSION]) -> [EXPRESSION]
forall a b. (a -> b) -> a -> b
$ ([(Int, EXPRESSION)]
 -> (Int, EXPRESSION) -> ([(Int, EXPRESSION)], EXPRESSION))
-> [(Int, EXPRESSION)]
-> [(Int, EXPRESSION)]
-> ([(Int, EXPRESSION)], [EXPRESSION])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL [(Int, EXPRESSION)]
-> (Int, EXPRESSION) -> ([(Int, EXPRESSION)], EXPRESSION)
g ([Int] -> [EXPRESSION] -> [(Int, EXPRESSION)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
bvl' [EXPRESSION]
vl) ([(Int, EXPRESSION)] -> ([(Int, EXPRESSION)], [EXPRESSION]))
-> [(Int, EXPRESSION)] -> ([(Int, EXPRESSION)], [EXPRESSION])
forall a b. (a -> b) -> a -> b
$ [Int] -> [EXPRESSION] -> [(Int, EXPRESSION)]
forall a b. [a] -> [b] -> [(a, b)]
zip [0 ..] [EXPRESSION]
exps


mapExpr :: (EXPRESSION -> EXPRESSION) -> EXPRESSION -> EXPRESSION
mapExpr :: (EXPRESSION -> EXPRESSION) -> EXPRESSION -> EXPRESSION
mapExpr f :: EXPRESSION -> EXPRESSION
f e :: EXPRESSION
e =
    case EXPRESSION
e of
      Op oi :: OPID
oi epl :: [EXTPARAM]
epl args :: [EXPRESSION]
args rg :: Range
rg -> OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op OPID
oi [EXTPARAM]
epl ((EXPRESSION -> EXPRESSION) -> [EXPRESSION] -> [EXPRESSION]
forall a b. (a -> b) -> [a] -> [b]
map EXPRESSION -> EXPRESSION
f [EXPRESSION]
args) Range
rg
      List exps :: [EXPRESSION]
exps rg :: Range
rg -> [EXPRESSION] -> Range -> EXPRESSION
List ((EXPRESSION -> EXPRESSION) -> [EXPRESSION] -> [EXPRESSION]
forall a b. (a -> b) -> [a] -> [b]
map EXPRESSION -> EXPRESSION
f [EXPRESSION]
exps) Range
rg
      _ -> EXPRESSION
e


-- | Transforms Op-Expressions to a set of op-names and a Var-list
varSet :: [EXPRESSION] -> (Set.Set String, [EXPRESSION])
varSet :: [EXPRESSION] -> (Set String, [EXPRESSION])
varSet l :: [EXPRESSION]
l =
    let opToVar' :: Set String -> EXPRESSION -> (Set String, EXPRESSION)
opToVar' s :: Set String
s (Op v :: OPID
v _ _ rg' :: Range
rg') =
            ( String -> Set String -> Set String
forall a. Ord a => a -> Set a -> Set a
Set.insert (OPID -> String
simpleName OPID
v) Set String
s
            , Token -> EXPRESSION
Var Token :: String -> Range -> Token
Token { tokStr :: String
tokStr = OPID -> String
simpleName OPID
v, tokPos :: Range
tokPos = Range
rg' } )
        opToVar' s :: Set String
s v :: EXPRESSION
v@(Var tok :: Token
tok) = (String -> Set String -> Set String
forall a. Ord a => a -> Set a -> Set a
Set.insert (Token -> String
tokStr Token
tok) Set String
s, EXPRESSION
v)
        opToVar' _ x :: EXPRESSION
x =
            String -> (Set String, EXPRESSION)
forall a. HasCallStack => String -> a
error (String -> (Set String, EXPRESSION))
-> String -> (Set String, EXPRESSION)
forall a b. (a -> b) -> a -> b
$ "varSet: not supported varexpression at " String -> String -> String
forall a. [a] -> [a] -> [a]
++ EXPRESSION -> String
forall a. Show a => a -> String
show EXPRESSION
x
    in (Set String -> EXPRESSION -> (Set String, EXPRESSION))
-> Set String -> [EXPRESSION] -> (Set String, [EXPRESSION])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL Set String -> EXPRESSION -> (Set String, EXPRESSION)
opToVar' Set String
forall a. Set a
Set.empty [EXPRESSION]
l

-- | Replaces Op occurrences to Var if the op is in the given set
constsToVars :: Set.Set String -> EXPRESSION -> EXPRESSION
constsToVars :: Set String -> EXPRESSION -> EXPRESSION
constsToVars env :: Set String
env e :: EXPRESSION
e =
    let substRec :: Record CMD EXPRESSION
substRec =
         Record CMD EXPRESSION
idRecord
         { foldOp :: EXPRESSION
-> OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
foldOp =
            \ _ s :: OPID
s epl' :: [EXTPARAM]
epl' args :: [EXPRESSION]
args rg' :: Range
rg' ->
                if String -> Set String -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member (OPID -> String
simpleName OPID
s) Set String
env then
                    if [EXPRESSION] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [EXPRESSION]
args
                    then Token -> EXPRESSION
Var Token :: String -> Range -> Token
Token { tokStr :: String
tokStr = OPID -> String
simpleName OPID
s, tokPos :: Range
tokPos = Range
rg' }
                    else String -> EXPRESSION
forall a. HasCallStack => String -> a
error (String -> EXPRESSION) -> String -> EXPRESSION
forall a b. (a -> b) -> a -> b
$ "constsToVars: variable must not have"
                             String -> String -> String
forall a. [a] -> [a] -> [a]
++ " arguments:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [EXPRESSION] -> String
forall a. Show a => a -> String
show [EXPRESSION]
args
                else OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op OPID
s [EXTPARAM]
epl' [EXPRESSION]
args Range
rg'
         , foldList :: EXPRESSION -> [EXPRESSION] -> Range -> EXPRESSION
foldList = \ _ l :: [EXPRESSION]
l rg' :: Range
rg' -> [EXPRESSION] -> Range -> EXPRESSION
List [EXPRESSION]
l Range
rg'
         }
    in Record CMD EXPRESSION -> EXPRESSION -> EXPRESSION
forall a b. Record a b -> EXPRESSION -> b
foldTerm Record CMD EXPRESSION
substRec EXPRESSION
e


updateDefinition :: EXPRESSION -> AssDefinition -> AssDefinition
updateDefinition :: EXPRESSION -> AssDefinition -> AssDefinition
updateDefinition e' :: EXPRESSION
e' (ConstDef _) = EXPRESSION -> AssDefinition
ConstDef EXPRESSION
e'
updateDefinition e' :: EXPRESSION
e' (FunDef l :: [String]
l _) = [String] -> EXPRESSION -> AssDefinition
FunDef [String]
l EXPRESSION
e'


mkDefinition :: [String] -> EXPRESSION -> AssDefinition
mkDefinition :: [String] -> EXPRESSION -> AssDefinition
mkDefinition l :: [String]
l e :: EXPRESSION
e = if [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
l then EXPRESSION -> AssDefinition
ConstDef EXPRESSION
e else [String] -> EXPRESSION -> AssDefinition
FunDef [String]
l EXPRESSION
e

getDefiniens :: AssDefinition -> EXPRESSION
getDefiniens :: AssDefinition -> EXPRESSION
getDefiniens (ConstDef e :: EXPRESSION
e) = EXPRESSION
e
getDefiniens (FunDef _ e :: EXPRESSION
e) = EXPRESSION
e

getArguments :: AssDefinition -> [String]
getArguments :: AssDefinition -> [String]
getArguments (FunDef l :: [String]
l _) = [String]
l
getArguments _ = []

isFunDef :: AssDefinition -> Bool
isFunDef :: AssDefinition -> Bool
isFunDef (FunDef _ _) = Bool
True
isFunDef _ = Bool
False

isInterval :: EXPRESSION -> Bool
isInterval :: EXPRESSION -> Bool
isInterval (Interval {}) = Bool
True
isInterval _ = Bool
False

simpleName :: OPID -> String
simpleName :: OPID -> String
simpleName (OpId n :: OPNAME
n) = OPNAME -> String
showOPNAME OPNAME
n
simpleName (OpUser (SimpleConstant s :: String
s)) = String
s
simpleName (OpUser x :: ConstantName
x) = String -> String
forall a. HasCallStack => String -> a
error "simpleName: ElimConstant not supported: " String -> String -> String
forall a. [a] -> [a] -> [a]
++
                        ConstantName -> String
forall a. Show a => a -> String
show ConstantName
x

toElimConst :: ConstantName -> Int -> ConstantName
toElimConst :: ConstantName -> Int -> ConstantName
toElimConst (SimpleConstant s :: String
s) i :: Int
i = String -> Int -> ConstantName
ElimConstant String
s Int
i
toElimConst ec :: ConstantName
ec _ = String -> ConstantName
forall a. HasCallStack => String -> a
error (String -> ConstantName) -> String -> ConstantName
forall a b. (a -> b) -> a -> b
$ "toElimConst: already an elim const " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ConstantName -> String
forall a. Show a => a -> String
show ConstantName
ec

varDeclName :: VarDecl -> String
varDeclName :: VarDecl -> String
varDeclName (VarDecl n :: Token
n _) = Token -> String
Id.tokStr Token
n

varDeclToVar :: VarDecl -> EXPRESSION
varDeclToVar :: VarDecl -> EXPRESSION
varDeclToVar (VarDecl n :: Token
n _) = Token -> EXPRESSION
Var Token
n

opDeclToOp :: OpDecl -> EXPRESSION
opDeclToOp :: OpDecl -> EXPRESSION
opDeclToOp (OpDecl n :: ConstantName
n epl :: [EXTPARAM]
epl vdl :: [VarDecl]
vdl rg :: Range
rg ) = OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION
Op (ConstantName -> OPID
OpUser ConstantName
n) [EXTPARAM]
epl ((VarDecl -> EXPRESSION) -> [VarDecl] -> [EXPRESSION]
forall a b. (a -> b) -> [a] -> [b]
map VarDecl -> EXPRESSION
varDeclToVar [VarDecl]
vdl) Range
rg

-- | Returns a set of user defined constants ignoring 'EXTPARAM' instantiation.
setOfUserDefined :: EXPRESSION -> Set.Set String
setOfUserDefined :: EXPRESSION -> Set String
setOfUserDefined = Set String -> EXPRESSION -> Set String
g Set String
forall a. Set a
Set.empty
    where
      g :: Set String -> EXPRESSION -> Set String
g s :: Set String
s x :: EXPRESSION
x =
       case EXPRESSION
x of
         Op oi :: OPID
oi@(OpUser _) _ al :: [EXPRESSION]
al _ -> (Set String -> EXPRESSION -> Set String)
-> Set String -> [EXPRESSION] -> Set String
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Set String -> EXPRESSION -> Set String
g (String -> Set String -> Set String
forall a. Ord a => a -> Set a -> Set a
Set.insert (OPID -> String
simpleName OPID
oi) Set String
s) [EXPRESSION]
al
         -- handle also non-userdefined ops.
         Op _ _ al :: [EXPRESSION]
al _ -> (Set String -> EXPRESSION -> Set String)
-> Set String -> [EXPRESSION] -> Set String
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Set String -> EXPRESSION -> Set String
g Set String
s [EXPRESSION]
al
         -- ignoring lists (TODO: they should be removed soon anyway)
         _ -> Set String
s

-- | Returns a set of user defined constants and 'EXTPARAM' specifications.
setOfConstsAndEPSpecs :: EXPRESSION -> (Set.Set String, Set.Set EXTPARAM)
setOfConstsAndEPSpecs :: EXPRESSION -> (Set String, Set EXTPARAM)
setOfConstsAndEPSpecs = (Set String, Set EXTPARAM)
-> EXPRESSION -> (Set String, Set EXTPARAM)
g (Set String
forall a. Set a
Set.empty, Set EXTPARAM
forall a. Set a
Set.empty)
    where
      g :: (Set String, Set EXTPARAM)
-> EXPRESSION -> (Set String, Set EXTPARAM)
g s :: (Set String, Set EXTPARAM)
s@(s1 :: Set String
s1, s2 :: Set EXTPARAM
s2) x :: EXPRESSION
x =
       case EXPRESSION
x of
         Op oi :: OPID
oi@(OpUser _) epl :: [EXTPARAM]
epl al :: [EXPRESSION]
al _ ->
             ((Set String, Set EXTPARAM)
 -> EXPRESSION -> (Set String, Set EXTPARAM))
-> (Set String, Set EXTPARAM)
-> [EXPRESSION]
-> (Set String, Set EXTPARAM)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Set String, Set EXTPARAM)
-> EXPRESSION -> (Set String, Set EXTPARAM)
g ( String -> Set String -> Set String
forall a. Ord a => a -> Set a -> Set a
Set.insert (OPID -> String
simpleName OPID
oi) Set String
s1
                     , (EXTPARAM -> Set EXTPARAM -> Set EXTPARAM)
-> Set EXTPARAM -> [EXTPARAM] -> Set EXTPARAM
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr EXTPARAM -> Set EXTPARAM -> Set EXTPARAM
forall a. Ord a => a -> Set a -> Set a
Set.insert Set EXTPARAM
s2 [EXTPARAM]
epl) [EXPRESSION]
al
         -- handle also non-userdefined ops.
         Op _ _ al :: [EXPRESSION]
al _ -> ((Set String, Set EXTPARAM)
 -> EXPRESSION -> (Set String, Set EXTPARAM))
-> (Set String, Set EXTPARAM)
-> [EXPRESSION]
-> (Set String, Set EXTPARAM)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Set String, Set EXTPARAM)
-> EXPRESSION -> (Set String, Set EXTPARAM)
g (Set String, Set EXTPARAM)
s [EXPRESSION]
al
         -- ignoring lists (TODO: they should be removed soon anyway)
         _ -> (Set String, Set EXTPARAM)
s