language-puppet-1.5.1: src/Puppet/Parser/Types.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
-- | All the types used for parsing, and helpers working on these types.
module Puppet.Parser.Types
( -- ** Expressions
Expression (..),
SelectorCase (..),
UnresolvedValue (..),
LambdaFunc (..),
HOLambdaCall (..),
ChainableRes (..),
HasHOLambdaCall (..),
LambdaParameter (..),
LambdaParameters,
CompRegex (..),
CollectorType (..),
Virtuality (..),
NodeDesc (..),
LinkType (..),
-- ** Synonyms
Parser,
PuppetParseError,
-- ** Datatypes
UDataType (..),
-- ** Search Expressions
SearchExpression (..),
-- ** Declaration
AttributeDecl (..),
ArrowOp (..),
ConditionalDecl (..),
ClassDecl (..),
ResDefaultDecl (..),
DepDecl (..),
Statement (..),
ResDecl (..),
ResOverrideDecl (..),
DefineDecl (..),
NodeDecl (..),
VarAssignDecl (..),
MainFuncDecl (..),
HigherOrderLambdaDecl (..),
ResCollDecl (..),
Parameters,
)
where
import qualified Data.Maybe.Strict as S
import qualified Data.Text as Text
import qualified Data.Vector as V
import qualified GHC.Exts as Exts
import Puppet.Language
import Text.Megaparsec
import XPrelude hiding (show)
type PuppetParseError = ParseError Char Void
type Parser = Parsec Void Text
-- | /High Order lambdas/.
newtype LambdaFunc = LambdaFunc Text deriving (Eq, Show)
-- | Lambda block parameters:
type LambdaParameters = Vector LambdaParameter
data LambdaParameter
= LambdaParam !(Maybe UDataType) !Text
deriving (Eq, Show)
-- The description of the /higher level lambda/ call.
data HOLambdaCall = HOLambdaCall
{ _hoLambdaFunc :: !LambdaFunc,
_hoLambdaExpr :: !(Vector Expression),
_hoLambdaParams :: !LambdaParameters,
_hoLambdaStatements :: !(Vector Statement),
_hoLambdaLastExpr :: !(S.Maybe Expression)
}
deriving (Eq, Show)
data ChainableRes
= ChainResColl !ResCollDecl
| ChainResDecl !ResDecl
| ChainResRefr !Text [Expression] !PPosition
deriving (Show, Eq)
data AttributeDecl
= AttributeDecl !Text !ArrowOp !Expression
| AttributeWildcard !Expression
deriving (Show, Eq)
data ArrowOp
= -- | `+>`
AppendArrow
| -- | `=>`
AssignArrow
deriving (Show, Eq)
-- | An unresolved value, typically the parser's output.
data UnresolvedValue
= -- | Special tokens generated when parsing the @true@ or @false@ literals.
UBoolean !Bool
| -- | Raw string.
UString !Text
| -- | A string that might contain variable references. The type should be refined at one point.
UInterpolable !(Vector Expression)
| -- | Special token that is generated when parsing the @undef@ literal.
UUndef
| -- | Alike @Resource[reference]@
UResourceReference !Text !Expression
| UArray !(Vector Expression)
| UHash !(Vector (Pair Expression Expression))
| -- | The regular expression compilation is performed during parsing.
URegexp !CompRegex
| UVariableReference !Text
| UFunctionCall !Text !(Vector Expression)
| UHOLambdaCall !HOLambdaCall
| UNumber !Scientific
| UDataType UDataType
deriving (Show, Eq)
instance Exts.IsList UnresolvedValue where
type Item UnresolvedValue = Expression
fromList = UArray . V.fromList
toList u = case u of
UArray lst -> V.toList lst
_ -> [Terminal u]
instance IsString UnresolvedValue where
fromString = UString . Text.pack
data SelectorCase
= SelectorValue !UnresolvedValue
| SelectorType !UDataType
| SelectorDefault
deriving (Eq, Show)
-- | The 'Expression's
data Expression
= Equal !Expression !Expression
| Different !Expression !Expression
| Not !Expression
| And !Expression !Expression
| Or !Expression !Expression
| LessThan !Expression !Expression
| MoreThan !Expression !Expression
| LessEqualThan !Expression !Expression
| MoreEqualThan !Expression !Expression
| RegexMatch !Expression !Expression
| NotRegexMatch !Expression !Expression
| Contains !Expression !Expression
| Addition !Expression !Expression
| Substraction !Expression !Expression
| Division !Expression !Expression
| Multiplication !Expression !Expression
| Modulo !Expression !Expression
| RightShift !Expression !Expression
| LeftShift !Expression !Expression
| -- | Hash lookup @$var[\'key0\'][\'key1\']@
Lookup !Expression !Expression
| Negate !Expression
| -- | All conditionals are stored in this format.
ConditionalValue !Expression !(Vector (Pair SelectorCase Expression))
| -- | This is for /higher order functions/.
FunctionApplication !Expression !Expression
| -- | Terminal object contains no expression
Terminal !UnresolvedValue
deriving (Eq, Show)
data UDataType
= UDTType
| UDTString (Maybe Int) (Maybe Int)
| UDTInteger (Maybe Int) (Maybe Int)
| UDTFloat (Maybe Double) (Maybe Double)
| UDTBoolean
| UDTArray UDataType Int (Maybe Int)
| UDTHash UDataType UDataType Int (Maybe Int)
| UDTUndef
| UDTScalar
| UDTData
| UDTOptional UDataType
| UNotUndef
| UDTVariant (NonEmpty UDataType)
| UDTPattern (NonEmpty CompRegex)
| UDTEnum (NonEmpty Expression)
| UDTAny
| UDTCollection
| UDTRegexp (Maybe CompRegex)
| UDTDeferred
| UDTSensitive UDataType
-- Tuple (NonEmpty DataType) Integer Integer
-- DTDefault
-- Struct TODO
deriving (Eq, Show)
instance Exts.IsList Expression where
type Item Expression = Expression
fromList = Terminal . Exts.fromList
toList u = case u of
Terminal t -> Exts.toList t
_ -> [u]
instance Num Expression where
(+) = Addition
(-) = Substraction
(*) = Multiplication
fromInteger = Terminal . UNumber . fromInteger
abs x = ConditionalValue (MoreEqualThan x 0) (V.fromList [SelectorValue (UBoolean True) :!: x, SelectorDefault :!: negate x])
signum x =
ConditionalValue
(MoreThan x 0)
( V.fromList
[ SelectorValue (UBoolean True) :!: 1,
SelectorDefault
:!: ConditionalValue (Equal x 0) (V.fromList [SelectorValue (UBoolean True) :!: 0, SelectorDefault :!: (-1)])
]
)
instance Fractional Expression where
(/) = Division
recip x = 1 / x
fromRational = Terminal . UNumber . fromRational
instance IsString Expression where
fromString = Terminal . fromString
-- | Search expression inside collector @ \<| searchexpr |> @
data SearchExpression
= EqualitySearch !Text !Expression
| NonEqualitySearch !Text !Expression
| AndSearch !SearchExpression !SearchExpression
| OrSearch !SearchExpression !SearchExpression
| AlwaysTrue
deriving (Eq, Show)
data CollectorType
= -- | Single angle brackets @\<| |>@
Collector
| -- | Double angle brackets @\<\<| |>>@
ExportedCollector
deriving (Eq, Show)
data NodeDesc
= NodeName !Text
| NodeMatch !CompRegex
| NodeDefault
deriving (Show, Eq)
-- | Resource declaration:
--
-- @ file { mode => 755} @
data ResDecl = ResDecl !Text !Expression !(Vector AttributeDecl) !Virtuality !PPosition deriving (Eq, Show)
-- | Resource default:
--
-- @ File { mode => 755 } @
--
-- <https://docs.puppetlabs.com/puppet/latest/reference/lang_defaults.html#language:-resource-default-statements puppet reference>.
data ResDefaultDecl = ResDefaultDecl !Text !(Vector AttributeDecl) !PPosition deriving (Eq, Show)
-- | Resource override:
--
-- @ File['title'] { mode => 755} @
--
-- See <https://docs.puppetlabs.com/puppet/latest/reference/lang_resources_advanced.html#amending-attributes-with-a-resource-reference puppet reference>.
data ResOverrideDecl = ResOverrideDecl !Text !Expression !(Vector AttributeDecl) !PPosition deriving (Eq, Show)
-- | All types of conditional statements : @case@, @if@, ...
--
-- Stored as an ordered list of pair @ (condition, statements) @.
-- Interpreted as "if first cond is true, choose first statements, else take the next pair, check the condition ..."
data ConditionalDecl = ConditionalDecl !(Vector (Pair Expression (Vector Statement))) !PPosition deriving (Eq, Show)
-- | Declare a class with
--
-- * a name
-- * a list of parameters
-- * an optional inherits
-- * a list of statements
-- * a position
data ClassDecl = ClassDecl !Text !Parameters !(S.Maybe Text) !(Vector Statement) !PPosition deriving (Eq, Show)
-- | Declare a define with
-- * a name
-- * a list of parameters
-- * a list of statements
-- * a position
data DefineDecl = DefineDecl !Text !Parameters !(Vector Statement) !PPosition deriving (Eq, Show)
type Parameters = Vector (Pair (Pair Text (S.Maybe UDataType)) (S.Maybe Expression))
-- | A node is a collection of statements + maybe an inherit node.
data NodeDecl = NodeDecl !NodeDesc !(Vector Statement) !(S.Maybe NodeDesc) !PPosition deriving (Eq, Show)
-- | @ $newvar = 'world' @
data VarAssignDecl = VarAssignDecl
{ _vadtype :: Maybe UDataType,
_vadnames :: [Text],
_vadvalue :: !Expression,
_vadpos :: !PPosition
}
deriving (Eq, Show)
data MainFuncDecl = MainFuncDecl !Text !(Vector Expression) !PPosition deriving (Eq, Show)
-- | /Higher order function/ call.
data HigherOrderLambdaDecl = HigherOrderLambdaDecl !HOLambdaCall !PPosition deriving (Eq, Show)
-- | Resource Collector including exported collector (`\<\<| |>>`)
--
-- @ User \<| title == 'jenkins' |> { groups +> "docker"} @
--
-- See <https://docs.puppetlabs.com/puppet/latest/reference/lang_collectors.html#language:-resource-collectors puppet reference>
data ResCollDecl = ResCollDecl !CollectorType !Text !SearchExpression !(Vector AttributeDecl) !PPosition deriving (Eq, Show)
data DepDecl = DepDecl !(Pair Text Expression) !(Pair Text Expression) !LinkType !PPosition deriving (Eq, Show)
-- | All possible statements.
data Statement
= ResourceDeclaration !ResDecl
| ResourceDefaultDeclaration !ResDefaultDecl
| ResourceOverrideDeclaration !ResOverrideDecl
| ResourceCollectionDeclaration !ResCollDecl
| ClassDeclaration !ClassDecl
| DefineDeclaration !DefineDecl
| NodeDeclaration !NodeDecl
| ConditionalDeclaration !ConditionalDecl
| VarAssignmentDeclaration !VarAssignDecl
| MainFunctionDeclaration !MainFuncDecl
| HigherOrderLambdaDeclaration !HigherOrderLambdaDecl
| DependencyDeclaration !DepDecl
| -- | Special statement used to include the expressions that are top level. Certainly buggy, but probably just like the original implementation.
TopContainer !(Vector Statement) !Statement
deriving (Eq, Show)
makeClassy ''HOLambdaCall