{- -----------------------------------------------------------------------------
Copyright 2019-2021 Kevin P. Barry

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
----------------------------------------------------------------------------- -}

-- Author: Kevin P. Barry [ta0kira@gmail.com]

{-# LANGUAGE Safe #-}

module Types.Procedure (
  ArgValues(..),
  Assignable(..),
  ExecutableProcedure(..),
  Expression(..),
  ExpressionStart(..),
  ExpressionType,
  FunctionCall(..),
  FunctionQualifier(..),
  FunctionSpec(..),
  IfElifElse(..),
  InputValue(..),
  InstanceOrInferred(..),
  IteratedLoop(..),
  MacroName(..),
  Operator(..),
  OutputValue(..),
  PragmaProcedure(..),
  Procedure(..),
  ReturnValues(..),
  ScopedBlock(..),
  Statement(..),
  TestProcedure(..),
  TraceType(..),
  ValueLiteral(..),
  ValueOperation(..),
  VariableName(..),
  VoidExpression(..),
  assignableName,
  getExpressionContext,
  getOperatorContext,
  getOperatorName,
  getStatementContext,
  isDiscardedInput,
  isFunctionOperator,
  isLiteralCategory,
  isNoTrace,
  isTraceCreation,
  isRawCodeLine,
  isUnnamedReturns,
) where

import Data.List (intercalate)

import Base.Positional
import Types.Builtin
import Types.TypeCategory
import Types.TypeInstance


-- NOTE: Requires FunctionType and SymbolScope to compile, but those might not
-- be available when this needs to be parsed.
data ExecutableProcedure c =
  ExecutableProcedure {
    ExecutableProcedure c -> [c]
epContext :: [c],
    ExecutableProcedure c -> [PragmaProcedure c]
epPragmas :: [PragmaProcedure c],
    ExecutableProcedure c -> [c]
epEnd :: [c],
    ExecutableProcedure c -> FunctionName
epName :: FunctionName,
    ExecutableProcedure c -> ArgValues c
epArgs :: ArgValues c,
    ExecutableProcedure c -> ReturnValues c
epReturns :: ReturnValues c,
    ExecutableProcedure c -> Procedure c
epProcedure :: Procedure c
  }
  deriving (Int -> ExecutableProcedure c -> ShowS
[ExecutableProcedure c] -> ShowS
ExecutableProcedure c -> String
(Int -> ExecutableProcedure c -> ShowS)
-> (ExecutableProcedure c -> String)
-> ([ExecutableProcedure c] -> ShowS)
-> Show (ExecutableProcedure c)
forall c. Show c => Int -> ExecutableProcedure c -> ShowS
forall c. Show c => [ExecutableProcedure c] -> ShowS
forall c. Show c => ExecutableProcedure c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExecutableProcedure c] -> ShowS
$cshowList :: forall c. Show c => [ExecutableProcedure c] -> ShowS
show :: ExecutableProcedure c -> String
$cshow :: forall c. Show c => ExecutableProcedure c -> String
showsPrec :: Int -> ExecutableProcedure c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> ExecutableProcedure c -> ShowS
Show) -- TODO: Remove Show? Or add proper formatting.

data ArgValues c =
  ArgValues {
    ArgValues c -> [c]
avContext :: [c],
    ArgValues c -> Positional (InputValue c)
avNames :: Positional (InputValue c)
  }

instance Show c => Show (ArgValues c) where
  show :: ArgValues c -> String
show (ArgValues [c]
c Positional (InputValue c)
v) =
    String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
",\n" ((InputValue c -> String) -> [InputValue c] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map InputValue c -> String
forall a. Show a => a -> String
show ([InputValue c] -> [String]) -> [InputValue c] -> [String]
forall a b. (a -> b) -> a -> b
$ Positional (InputValue c) -> [InputValue c]
forall a. Positional a -> [a]
pValues Positional (InputValue c)
v) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" String -> ShowS
forall a. [a] -> [a] -> [a]
++
    String
" /*" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [c] -> String
forall a. Show a => [a] -> String
formatFullContext [c]
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"*/"

data ReturnValues c =
  NamedReturns {
    ReturnValues c -> [c]
nrContext :: [c],
    ReturnValues c -> Positional (OutputValue c)
nrNames :: Positional (OutputValue c)
  } |
  UnnamedReturns {
    ReturnValues c -> [c]
urContext :: [c]
  }

isUnnamedReturns :: ReturnValues c -> Bool
isUnnamedReturns :: ReturnValues c -> Bool
isUnnamedReturns (UnnamedReturns [c]
_) = Bool
True
isUnnamedReturns ReturnValues c
_                  = Bool
False

instance Show c => Show (ReturnValues c) where
  show :: ReturnValues c -> String
show (NamedReturns [c]
c Positional (OutputValue c)
v) =
    String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
",\n" ((OutputValue c -> String) -> [OutputValue c] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map OutputValue c -> String
forall a. Show a => a -> String
show ([OutputValue c] -> [String]) -> [OutputValue c] -> [String]
forall a b. (a -> b) -> a -> b
$ Positional (OutputValue c) -> [OutputValue c]
forall a. Positional a -> [a]
pValues Positional (OutputValue c)
v) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" String -> ShowS
forall a. [a] -> [a] -> [a]
++
    String
" /*" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [c] -> String
forall a. Show a => [a] -> String
formatFullContext [c]
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"*/"
  show (UnnamedReturns [c]
c) = String
"/*unnamed returns: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [c] -> String
forall a. Show a => [a] -> String
formatFullContext [c]
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"*/"

data VariableName =
  VariableName {
    VariableName -> String
vnName :: String
  }
  deriving (VariableName -> VariableName -> Bool
(VariableName -> VariableName -> Bool)
-> (VariableName -> VariableName -> Bool) -> Eq VariableName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VariableName -> VariableName -> Bool
$c/= :: VariableName -> VariableName -> Bool
== :: VariableName -> VariableName -> Bool
$c== :: VariableName -> VariableName -> Bool
Eq,Eq VariableName
Eq VariableName
-> (VariableName -> VariableName -> Ordering)
-> (VariableName -> VariableName -> Bool)
-> (VariableName -> VariableName -> Bool)
-> (VariableName -> VariableName -> Bool)
-> (VariableName -> VariableName -> Bool)
-> (VariableName -> VariableName -> VariableName)
-> (VariableName -> VariableName -> VariableName)
-> Ord VariableName
VariableName -> VariableName -> Bool
VariableName -> VariableName -> Ordering
VariableName -> VariableName -> VariableName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: VariableName -> VariableName -> VariableName
$cmin :: VariableName -> VariableName -> VariableName
max :: VariableName -> VariableName -> VariableName
$cmax :: VariableName -> VariableName -> VariableName
>= :: VariableName -> VariableName -> Bool
$c>= :: VariableName -> VariableName -> Bool
> :: VariableName -> VariableName -> Bool
$c> :: VariableName -> VariableName -> Bool
<= :: VariableName -> VariableName -> Bool
$c<= :: VariableName -> VariableName -> Bool
< :: VariableName -> VariableName -> Bool
$c< :: VariableName -> VariableName -> Bool
compare :: VariableName -> VariableName -> Ordering
$ccompare :: VariableName -> VariableName -> Ordering
$cp1Ord :: Eq VariableName
Ord)

instance Show VariableName where
  show :: VariableName -> String
show (VariableName String
n) = String
n

data InputValue c =
  InputValue {
    InputValue c -> [c]
ivContext :: [c],
    InputValue c -> VariableName
ivName :: VariableName
  } |
  DiscardInput {
    InputValue c -> [c]
iiContext :: [c]
  }

isDiscardedInput :: InputValue c -> Bool
isDiscardedInput :: InputValue c -> Bool
isDiscardedInput (DiscardInput [c]
_) = Bool
True
isDiscardedInput InputValue c
_                = Bool
False

discardInputName :: VariableName
discardInputName :: VariableName
discardInputName = String -> VariableName
VariableName String
"_"

instance Show c => Show (InputValue c) where
  show :: InputValue c -> String
show (InputValue [c]
c VariableName
v) = VariableName -> String
forall a. Show a => a -> String
show VariableName
v String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" /*" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [c] -> String
forall a. Show a => [a] -> String
formatFullContext [c]
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"*/"
  show (DiscardInput [c]
c) = String
"_" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" /*" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [c] -> String
forall a. Show a => [a] -> String
formatFullContext [c]
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"*/"

data OutputValue c =
  OutputValue {
    OutputValue c -> [c]
ovContext :: [c],
    OutputValue c -> VariableName
ovName :: VariableName
  }

instance Show c => Show (OutputValue c) where
  show :: OutputValue c -> String
show (OutputValue [c]
c VariableName
v) = VariableName -> String
forall a. Show a => a -> String
show VariableName
v String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" /*" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [c] -> String
forall a. Show a => [a] -> String
formatFullContext [c]
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"*/"

data TestProcedure c =
  TestProcedure {
    TestProcedure c -> [c]
tpContext :: [c],
    TestProcedure c -> FunctionName
tpName :: FunctionName,
    TestProcedure c -> Procedure c
tpProcedure :: Procedure c
  }
  deriving (Int -> TestProcedure c -> ShowS
[TestProcedure c] -> ShowS
TestProcedure c -> String
(Int -> TestProcedure c -> ShowS)
-> (TestProcedure c -> String)
-> ([TestProcedure c] -> ShowS)
-> Show (TestProcedure c)
forall c. Show c => Int -> TestProcedure c -> ShowS
forall c. Show c => [TestProcedure c] -> ShowS
forall c. Show c => TestProcedure c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TestProcedure c] -> ShowS
$cshowList :: forall c. Show c => [TestProcedure c] -> ShowS
show :: TestProcedure c -> String
$cshow :: forall c. Show c => TestProcedure c -> String
showsPrec :: Int -> TestProcedure c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> TestProcedure c -> ShowS
Show)

data Procedure c =
  Procedure [c] [Statement c]
  deriving (Int -> Procedure c -> ShowS
[Procedure c] -> ShowS
Procedure c -> String
(Int -> Procedure c -> ShowS)
-> (Procedure c -> String)
-> ([Procedure c] -> ShowS)
-> Show (Procedure c)
forall c. Show c => Int -> Procedure c -> ShowS
forall c. Show c => [Procedure c] -> ShowS
forall c. Show c => Procedure c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Procedure c] -> ShowS
$cshowList :: forall c. Show c => [Procedure c] -> ShowS
show :: Procedure c -> String
$cshow :: forall c. Show c => Procedure c -> String
showsPrec :: Int -> Procedure c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> Procedure c -> ShowS
Show)

data Statement c =
  EmptyReturn [c] |
  ExplicitReturn [c] (Positional (Expression c)) |
  LoopBreak [c] |
  LoopContinue [c] |
  FailCall [c] (Expression c) |
  RawFailCall String |
  IgnoreValues [c] (Expression c) |
  Assignment [c] (Positional (Assignable c)) (Expression c) |
  NoValueExpression [c] (VoidExpression c) |
  MarkReadOnly [c] [VariableName] |
  MarkHidden [c] [VariableName] |
  RawCodeLine String
  deriving (Int -> Statement c -> ShowS
[Statement c] -> ShowS
Statement c -> String
(Int -> Statement c -> ShowS)
-> (Statement c -> String)
-> ([Statement c] -> ShowS)
-> Show (Statement c)
forall c. Show c => Int -> Statement c -> ShowS
forall c. Show c => [Statement c] -> ShowS
forall c. Show c => Statement c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Statement c] -> ShowS
$cshowList :: forall c. Show c => [Statement c] -> ShowS
show :: Statement c -> String
$cshow :: forall c. Show c => Statement c -> String
showsPrec :: Int -> Statement c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> Statement c -> ShowS
Show)

isRawCodeLine :: Statement c -> Bool
isRawCodeLine :: Statement c -> Bool
isRawCodeLine (RawCodeLine String
_) = Bool
True
isRawCodeLine Statement c
_               = Bool
False

getStatementContext :: Statement c -> [c]
getStatementContext :: Statement c -> [c]
getStatementContext (EmptyReturn [c]
c)         = [c]
c
getStatementContext (ExplicitReturn [c]
c Positional (Expression c)
_)    = [c]
c
getStatementContext (LoopBreak [c]
c)           = [c]
c
getStatementContext (LoopContinue [c]
c)        = [c]
c
getStatementContext (FailCall [c]
c Expression c
_)          = [c]
c
getStatementContext (RawFailCall String
_)         = []
getStatementContext (IgnoreValues [c]
c Expression c
_)      = [c]
c
getStatementContext (Assignment [c]
c Positional (Assignable c)
_ Expression c
_)      = [c]
c
getStatementContext (NoValueExpression [c]
c VoidExpression c
_) = [c]
c
getStatementContext (MarkReadOnly [c]
c [VariableName]
_)      = [c]
c
getStatementContext (MarkHidden [c]
c [VariableName]
_)        = [c]
c
getStatementContext (RawCodeLine String
_)         = []

data Assignable c =
  CreateVariable [c] ValueType VariableName |
  ExistingVariable (InputValue c)
  deriving (Int -> Assignable c -> ShowS
[Assignable c] -> ShowS
Assignable c -> String
(Int -> Assignable c -> ShowS)
-> (Assignable c -> String)
-> ([Assignable c] -> ShowS)
-> Show (Assignable c)
forall c. Show c => Int -> Assignable c -> ShowS
forall c. Show c => [Assignable c] -> ShowS
forall c. Show c => Assignable c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Assignable c] -> ShowS
$cshowList :: forall c. Show c => [Assignable c] -> ShowS
show :: Assignable c -> String
$cshow :: forall c. Show c => Assignable c -> String
showsPrec :: Int -> Assignable c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> Assignable c -> ShowS
Show)

assignableName :: Assignable c -> VariableName
assignableName :: Assignable c -> VariableName
assignableName (CreateVariable [c]
_ ValueType
_ VariableName
n)              = VariableName
n
assignableName (ExistingVariable (InputValue [c]
_ VariableName
n)) = VariableName
n
assignableName Assignable c
_                                   = VariableName
discardInputName

data VoidExpression c =
  Conditional (IfElifElse c) |
  Loop (IteratedLoop c) |
  WithScope (ScopedBlock c) |
  Unconditional (Procedure c) |
  LineComment String
  deriving (Int -> VoidExpression c -> ShowS
[VoidExpression c] -> ShowS
VoidExpression c -> String
(Int -> VoidExpression c -> ShowS)
-> (VoidExpression c -> String)
-> ([VoidExpression c] -> ShowS)
-> Show (VoidExpression c)
forall c. Show c => Int -> VoidExpression c -> ShowS
forall c. Show c => [VoidExpression c] -> ShowS
forall c. Show c => VoidExpression c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VoidExpression c] -> ShowS
$cshowList :: forall c. Show c => [VoidExpression c] -> ShowS
show :: VoidExpression c -> String
$cshow :: forall c. Show c => VoidExpression c -> String
showsPrec :: Int -> VoidExpression c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> VoidExpression c -> ShowS
Show)

data IfElifElse c =
  IfStatement [c] (Expression c) (Procedure c) (IfElifElse c) |
  ElseStatement [c] (Procedure c) |
  TerminateConditional
  deriving (Int -> IfElifElse c -> ShowS
[IfElifElse c] -> ShowS
IfElifElse c -> String
(Int -> IfElifElse c -> ShowS)
-> (IfElifElse c -> String)
-> ([IfElifElse c] -> ShowS)
-> Show (IfElifElse c)
forall c. Show c => Int -> IfElifElse c -> ShowS
forall c. Show c => [IfElifElse c] -> ShowS
forall c. Show c => IfElifElse c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IfElifElse c] -> ShowS
$cshowList :: forall c. Show c => [IfElifElse c] -> ShowS
show :: IfElifElse c -> String
$cshow :: forall c. Show c => IfElifElse c -> String
showsPrec :: Int -> IfElifElse c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> IfElifElse c -> ShowS
Show)

data IteratedLoop c =
  WhileLoop [c] (Expression c) (Procedure c) (Maybe (Procedure c)) |
  TraverseLoop [c] (Expression c) [c] (Assignable c) (Procedure c)
  deriving (Int -> IteratedLoop c -> ShowS
[IteratedLoop c] -> ShowS
IteratedLoop c -> String
(Int -> IteratedLoop c -> ShowS)
-> (IteratedLoop c -> String)
-> ([IteratedLoop c] -> ShowS)
-> Show (IteratedLoop c)
forall c. Show c => Int -> IteratedLoop c -> ShowS
forall c. Show c => [IteratedLoop c] -> ShowS
forall c. Show c => IteratedLoop c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IteratedLoop c] -> ShowS
$cshowList :: forall c. Show c => [IteratedLoop c] -> ShowS
show :: IteratedLoop c -> String
$cshow :: forall c. Show c => IteratedLoop c -> String
showsPrec :: Int -> IteratedLoop c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> IteratedLoop c -> ShowS
Show)

data ScopedBlock c =
  ScopedBlock [c] (Procedure c) (Maybe (Procedure c)) [c] (Statement c)
  deriving (Int -> ScopedBlock c -> ShowS
[ScopedBlock c] -> ShowS
ScopedBlock c -> String
(Int -> ScopedBlock c -> ShowS)
-> (ScopedBlock c -> String)
-> ([ScopedBlock c] -> ShowS)
-> Show (ScopedBlock c)
forall c. Show c => Int -> ScopedBlock c -> ShowS
forall c. Show c => [ScopedBlock c] -> ShowS
forall c. Show c => ScopedBlock c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ScopedBlock c] -> ShowS
$cshowList :: forall c. Show c => [ScopedBlock c] -> ShowS
show :: ScopedBlock c -> String
$cshow :: forall c. Show c => ScopedBlock c -> String
showsPrec :: Int -> ScopedBlock c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> ScopedBlock c -> ShowS
Show)

data Expression c =
  Expression [c] (ExpressionStart c) [ValueOperation c] |
  Literal (ValueLiteral c) |
  UnaryExpression [c] (Operator c) (Expression c) |
  InfixExpression [c] (Expression c) (Operator c) (Expression c) |
  InitializeValue [c] (Maybe TypeInstance) (Positional (Expression c)) |
  RawExpression ExpressionType ExpressionValue
  deriving (Int -> Expression c -> ShowS
[Expression c] -> ShowS
Expression c -> String
(Int -> Expression c -> ShowS)
-> (Expression c -> String)
-> ([Expression c] -> ShowS)
-> Show (Expression c)
forall c. Show c => Int -> Expression c -> ShowS
forall c. Show c => [Expression c] -> ShowS
forall c. Show c => Expression c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Expression c] -> ShowS
$cshowList :: forall c. Show c => [Expression c] -> ShowS
show :: Expression c -> String
$cshow :: forall c. Show c => Expression c -> String
showsPrec :: Int -> Expression c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> Expression c -> ShowS
Show)

type ExpressionType = Positional ValueType

data FunctionQualifier c =
  CategoryFunction [c] CategoryName |
  TypeFunction [c] TypeInstanceOrParam |
  -- TODO: Does this need to allow conversion calls?
  ValueFunction [c] (Expression c) |
  UnqualifiedFunction
  deriving (Int -> FunctionQualifier c -> ShowS
[FunctionQualifier c] -> ShowS
FunctionQualifier c -> String
(Int -> FunctionQualifier c -> ShowS)
-> (FunctionQualifier c -> String)
-> ([FunctionQualifier c] -> ShowS)
-> Show (FunctionQualifier c)
forall c. Show c => Int -> FunctionQualifier c -> ShowS
forall c. Show c => [FunctionQualifier c] -> ShowS
forall c. Show c => FunctionQualifier c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FunctionQualifier c] -> ShowS
$cshowList :: forall c. Show c => [FunctionQualifier c] -> ShowS
show :: FunctionQualifier c -> String
$cshow :: forall c. Show c => FunctionQualifier c -> String
showsPrec :: Int -> FunctionQualifier c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> FunctionQualifier c -> ShowS
Show)

data InstanceOrInferred c =
  AssignedInstance [c] GeneralInstance |
  InferredInstance [c]
  deriving (Int -> InstanceOrInferred c -> ShowS
[InstanceOrInferred c] -> ShowS
InstanceOrInferred c -> String
(Int -> InstanceOrInferred c -> ShowS)
-> (InstanceOrInferred c -> String)
-> ([InstanceOrInferred c] -> ShowS)
-> Show (InstanceOrInferred c)
forall c. Show c => Int -> InstanceOrInferred c -> ShowS
forall c. Show c => [InstanceOrInferred c] -> ShowS
forall c. Show c => InstanceOrInferred c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InstanceOrInferred c] -> ShowS
$cshowList :: forall c. Show c => [InstanceOrInferred c] -> ShowS
show :: InstanceOrInferred c -> String
$cshow :: forall c. Show c => InstanceOrInferred c -> String
showsPrec :: Int -> InstanceOrInferred c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> InstanceOrInferred c -> ShowS
Show)

data FunctionSpec c =
  FunctionSpec [c] (FunctionQualifier c) FunctionName (Positional (InstanceOrInferred c))
  deriving (Int -> FunctionSpec c -> ShowS
[FunctionSpec c] -> ShowS
FunctionSpec c -> String
(Int -> FunctionSpec c -> ShowS)
-> (FunctionSpec c -> String)
-> ([FunctionSpec c] -> ShowS)
-> Show (FunctionSpec c)
forall c. Show c => Int -> FunctionSpec c -> ShowS
forall c. Show c => [FunctionSpec c] -> ShowS
forall c. Show c => FunctionSpec c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FunctionSpec c] -> ShowS
$cshowList :: forall c. Show c => [FunctionSpec c] -> ShowS
show :: FunctionSpec c -> String
$cshow :: forall c. Show c => FunctionSpec c -> String
showsPrec :: Int -> FunctionSpec c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> FunctionSpec c -> ShowS
Show)

data Operator c =
  NamedOperator [c] String |
  FunctionOperator [c] (FunctionSpec c)
  deriving (Int -> Operator c -> ShowS
[Operator c] -> ShowS
Operator c -> String
(Int -> Operator c -> ShowS)
-> (Operator c -> String)
-> ([Operator c] -> ShowS)
-> Show (Operator c)
forall c. Show c => Int -> Operator c -> ShowS
forall c. Show c => [Operator c] -> ShowS
forall c. Show c => Operator c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Operator c] -> ShowS
$cshowList :: forall c. Show c => [Operator c] -> ShowS
show :: Operator c -> String
$cshow :: forall c. Show c => Operator c -> String
showsPrec :: Int -> Operator c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> Operator c -> ShowS
Show)

getOperatorContext :: Operator c -> [c]
getOperatorContext :: Operator c -> [c]
getOperatorContext (NamedOperator [c]
c String
_)    = [c]
c
getOperatorContext (FunctionOperator [c]
c FunctionSpec c
_) = [c]
c

isFunctionOperator :: Operator c -> Bool
isFunctionOperator :: Operator c -> Bool
isFunctionOperator (FunctionOperator [c]
_ FunctionSpec c
_) = Bool
True
isFunctionOperator Operator c
_                      = Bool
False

getOperatorName :: Operator c -> FunctionName
getOperatorName :: Operator c -> FunctionName
getOperatorName (NamedOperator [c]
_ String
n)                         = String -> FunctionName
FunctionName String
n
getOperatorName (FunctionOperator [c]
_ (FunctionSpec [c]
_ FunctionQualifier c
_ FunctionName
n Positional (InstanceOrInferred c)
_)) = FunctionName
n

getExpressionContext :: Expression c -> [c]
getExpressionContext :: Expression c -> [c]
getExpressionContext (Expression [c]
c ExpressionStart c
_ [ValueOperation c]
_)        = [c]
c
getExpressionContext (Literal ValueLiteral c
l)               = ValueLiteral c -> [c]
forall c. ValueLiteral c -> [c]
getValueLiteralContext ValueLiteral c
l
getExpressionContext (UnaryExpression [c]
c Operator c
_ Expression c
_)   = [c]
c
getExpressionContext (InfixExpression [c]
c Expression c
_ Operator c
_ Expression c
_) = [c]
c
getExpressionContext (InitializeValue [c]
c Maybe TypeInstance
_ Positional (Expression c)
_)   = [c]
c
getExpressionContext (RawExpression ExpressionType
_ ExpressionValue
_)       = []

data FunctionCall c =
  FunctionCall [c] FunctionName (Positional (InstanceOrInferred c)) (Positional (Expression c))
  deriving (Int -> FunctionCall c -> ShowS
[FunctionCall c] -> ShowS
FunctionCall c -> String
(Int -> FunctionCall c -> ShowS)
-> (FunctionCall c -> String)
-> ([FunctionCall c] -> ShowS)
-> Show (FunctionCall c)
forall c. Show c => Int -> FunctionCall c -> ShowS
forall c. Show c => [FunctionCall c] -> ShowS
forall c. Show c => FunctionCall c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FunctionCall c] -> ShowS
$cshowList :: forall c. Show c => [FunctionCall c] -> ShowS
show :: FunctionCall c -> String
$cshow :: forall c. Show c => FunctionCall c -> String
showsPrec :: Int -> FunctionCall c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> FunctionCall c -> ShowS
Show)

data ExpressionStart c =
  NamedVariable (OutputValue c) |
  NamedMacro [c] MacroName |
  CategoryCall [c] CategoryName (FunctionCall c) |
  TypeCall [c] TypeInstanceOrParam (FunctionCall c) |
  UnqualifiedCall [c] (FunctionCall c) |
  BuiltinCall [c] (FunctionCall c) |
  ParensExpression [c] (Expression c) |
  InlineAssignment [c] VariableName (Expression c)
  deriving (Int -> ExpressionStart c -> ShowS
[ExpressionStart c] -> ShowS
ExpressionStart c -> String
(Int -> ExpressionStart c -> ShowS)
-> (ExpressionStart c -> String)
-> ([ExpressionStart c] -> ShowS)
-> Show (ExpressionStart c)
forall c. Show c => Int -> ExpressionStart c -> ShowS
forall c. Show c => [ExpressionStart c] -> ShowS
forall c. Show c => ExpressionStart c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExpressionStart c] -> ShowS
$cshowList :: forall c. Show c => [ExpressionStart c] -> ShowS
show :: ExpressionStart c -> String
$cshow :: forall c. Show c => ExpressionStart c -> String
showsPrec :: Int -> ExpressionStart c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> ExpressionStart c -> ShowS
Show)

data ValueLiteral c =
  StringLiteral [c] String |
  CharLiteral [c] Char |
  IntegerLiteral [c] Bool Integer |
  DecimalLiteral [c] Integer Integer |
  BoolLiteral [c] Bool |
  EmptyLiteral [c]
  deriving (Int -> ValueLiteral c -> ShowS
[ValueLiteral c] -> ShowS
ValueLiteral c -> String
(Int -> ValueLiteral c -> ShowS)
-> (ValueLiteral c -> String)
-> ([ValueLiteral c] -> ShowS)
-> Show (ValueLiteral c)
forall c. Show c => Int -> ValueLiteral c -> ShowS
forall c. Show c => [ValueLiteral c] -> ShowS
forall c. Show c => ValueLiteral c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ValueLiteral c] -> ShowS
$cshowList :: forall c. Show c => [ValueLiteral c] -> ShowS
show :: ValueLiteral c -> String
$cshow :: forall c. Show c => ValueLiteral c -> String
showsPrec :: Int -> ValueLiteral c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> ValueLiteral c -> ShowS
Show)

getValueLiteralContext :: ValueLiteral c -> [c]
getValueLiteralContext :: ValueLiteral c -> [c]
getValueLiteralContext (StringLiteral [c]
c String
_)    = [c]
c
getValueLiteralContext (CharLiteral [c]
c Char
_)      = [c]
c
getValueLiteralContext (IntegerLiteral [c]
c Bool
_ Integer
_) = [c]
c
getValueLiteralContext (DecimalLiteral [c]
c Integer
_ Integer
_) = [c]
c
getValueLiteralContext (BoolLiteral [c]
c Bool
_)      = [c]
c
getValueLiteralContext (EmptyLiteral [c]
c)       = [c]
c

isLiteralCategory :: CategoryName -> Bool
isLiteralCategory :: CategoryName -> Bool
isLiteralCategory CategoryName
BuiltinBool   = Bool
True
isLiteralCategory CategoryName
BuiltinChar   = Bool
True
isLiteralCategory CategoryName
BuiltinInt    = Bool
True
isLiteralCategory CategoryName
BuiltinFloat  = Bool
True
isLiteralCategory CategoryName
BuiltinString = Bool
True
isLiteralCategory CategoryName
_             = Bool
False

data ValueOperation c =
  ConvertedCall [c] TypeInstance (FunctionCall c) |
  ValueCall [c] (FunctionCall c)
  deriving (Int -> ValueOperation c -> ShowS
[ValueOperation c] -> ShowS
ValueOperation c -> String
(Int -> ValueOperation c -> ShowS)
-> (ValueOperation c -> String)
-> ([ValueOperation c] -> ShowS)
-> Show (ValueOperation c)
forall c. Show c => Int -> ValueOperation c -> ShowS
forall c. Show c => [ValueOperation c] -> ShowS
forall c. Show c => ValueOperation c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ValueOperation c] -> ShowS
$cshowList :: forall c. Show c => [ValueOperation c] -> ShowS
show :: ValueOperation c -> String
$cshow :: forall c. Show c => ValueOperation c -> String
showsPrec :: Int -> ValueOperation c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> ValueOperation c -> ShowS
Show)

newtype MacroName =
  MacroName {
    MacroName -> String
mnName :: String
  }
  deriving (MacroName -> MacroName -> Bool
(MacroName -> MacroName -> Bool)
-> (MacroName -> MacroName -> Bool) -> Eq MacroName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MacroName -> MacroName -> Bool
$c/= :: MacroName -> MacroName -> Bool
== :: MacroName -> MacroName -> Bool
$c== :: MacroName -> MacroName -> Bool
Eq,Eq MacroName
Eq MacroName
-> (MacroName -> MacroName -> Ordering)
-> (MacroName -> MacroName -> Bool)
-> (MacroName -> MacroName -> Bool)
-> (MacroName -> MacroName -> Bool)
-> (MacroName -> MacroName -> Bool)
-> (MacroName -> MacroName -> MacroName)
-> (MacroName -> MacroName -> MacroName)
-> Ord MacroName
MacroName -> MacroName -> Bool
MacroName -> MacroName -> Ordering
MacroName -> MacroName -> MacroName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MacroName -> MacroName -> MacroName
$cmin :: MacroName -> MacroName -> MacroName
max :: MacroName -> MacroName -> MacroName
$cmax :: MacroName -> MacroName -> MacroName
>= :: MacroName -> MacroName -> Bool
$c>= :: MacroName -> MacroName -> Bool
> :: MacroName -> MacroName -> Bool
$c> :: MacroName -> MacroName -> Bool
<= :: MacroName -> MacroName -> Bool
$c<= :: MacroName -> MacroName -> Bool
< :: MacroName -> MacroName -> Bool
$c< :: MacroName -> MacroName -> Bool
compare :: MacroName -> MacroName -> Ordering
$ccompare :: MacroName -> MacroName -> Ordering
$cp1Ord :: Eq MacroName
Ord)

instance Show MacroName where
  show :: MacroName -> String
show = MacroName -> String
mnName

data TraceType = NoTrace | TraceCreation deriving (Int -> TraceType -> ShowS
[TraceType] -> ShowS
TraceType -> String
(Int -> TraceType -> ShowS)
-> (TraceType -> String)
-> ([TraceType] -> ShowS)
-> Show TraceType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TraceType] -> ShowS
$cshowList :: [TraceType] -> ShowS
show :: TraceType -> String
$cshow :: TraceType -> String
showsPrec :: Int -> TraceType -> ShowS
$cshowsPrec :: Int -> TraceType -> ShowS
Show)

data PragmaProcedure c =
  PragmaTracing {
    PragmaProcedure c -> [c]
ptContext :: [c],
    PragmaProcedure c -> TraceType
ptType :: TraceType
  }
  deriving (Int -> PragmaProcedure c -> ShowS
[PragmaProcedure c] -> ShowS
PragmaProcedure c -> String
(Int -> PragmaProcedure c -> ShowS)
-> (PragmaProcedure c -> String)
-> ([PragmaProcedure c] -> ShowS)
-> Show (PragmaProcedure c)
forall c. Show c => Int -> PragmaProcedure c -> ShowS
forall c. Show c => [PragmaProcedure c] -> ShowS
forall c. Show c => PragmaProcedure c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PragmaProcedure c] -> ShowS
$cshowList :: forall c. Show c => [PragmaProcedure c] -> ShowS
show :: PragmaProcedure c -> String
$cshow :: forall c. Show c => PragmaProcedure c -> String
showsPrec :: Int -> PragmaProcedure c -> ShowS
$cshowsPrec :: forall c. Show c => Int -> PragmaProcedure c -> ShowS
Show)

isNoTrace :: PragmaProcedure c -> Bool
isNoTrace :: PragmaProcedure c -> Bool
isNoTrace (PragmaTracing [c]
_ TraceType
NoTrace) = Bool
True
isNoTrace PragmaProcedure c
_                         = Bool
False

isTraceCreation :: PragmaProcedure c -> Bool
isTraceCreation :: PragmaProcedure c -> Bool
isTraceCreation (PragmaTracing [c]
_ TraceType
TraceCreation) = Bool
True
isTraceCreation PragmaProcedure c
_                               = Bool
False