nova-nix-0.1.4.0: src/Nix/Expr/Types.hs
-- | Core AST types for the Nix expression language.
--
-- Every Nix source file parses into an 'Expr'. The AST is a direct
-- representation of the language grammar — no desugaring at parse time.
-- The evaluator ('Nix.Eval') reduces expressions to values.
module Nix.Expr.Types
( -- * Expressions
Expr (..),
-- * Atoms
NixAtom (..),
-- * Attribute paths
AttrPath,
AttrKey (..),
-- * Bindings
Binding (..),
-- * Formals (function parameters)
Formals (..),
Formal (..),
-- * Operators
UnaryOp (..),
BinaryOp (..),
-- * String parts (interpolation)
StringPart (..),
)
where
import Data.Text (Text)
-- | Atomic (literal) values.
data NixAtom
= NixInt !Integer
| NixFloat !Double
| NixBool !Bool
| NixNull
| NixUri !Text
| NixPath !Text
deriving (Eq, Show)
-- | A part of an interpolated string (@"hello ${name}"@).
data StringPart
= -- | Literal text.
StrLit !Text
| -- | Interpolated expression (@${expr}@).
StrInterp !Expr
deriving (Eq, Show)
-- | An attribute key: either a static identifier or a dynamic expression.
data AttrKey
= -- | Static key: @{ foo = val; }@
StaticKey !Text
| -- | Dynamic key: @{ ${expr} = val; }@
DynamicKey !Expr
deriving (Eq, Show)
-- | Attribute path: @a.b.c@ is @[StaticKey "a", StaticKey "b", StaticKey "c"]@.
type AttrPath = [AttrKey]
-- | A binding in an attribute set or let expression.
data Binding
= -- | @path = expr;@
NamedBinding !AttrPath !Expr
| -- | @inherit expr;@ or @inherit (from) attrs;@
Inherit !(Maybe Expr) ![Text]
deriving (Eq, Show)
-- | A single formal parameter with optional default.
data Formal = Formal
{ fName :: !Text,
fDefault :: !(Maybe Expr)
}
deriving (Eq, Show)
-- | Function parameter pattern.
data Formals
= -- | Single identifier: @x: body@
FormalName !Text
| -- | Attribute set pattern with optional ellipsis: @{ a, b }: body@
FormalSet ![Formal] !Bool
| -- | Named set pattern: @args\@{ a, b }: body@
FormalNamedSet !Text ![Formal] !Bool
deriving (Eq, Show)
-- | Unary operators.
data UnaryOp
= OpNot
| OpNegate
deriving (Eq, Show)
-- | Binary operators.
data BinaryOp
= OpAdd
| OpSub
| OpMul
| OpDiv
| OpAnd
| OpOr
| OpImpl
| OpEq
| OpNeq
| OpLt
| OpLte
| OpGt
| OpGte
| OpConcat
| OpUpdate
deriving (Eq, Show)
-- | The Nix expression AST.
--
-- This covers the full Nix language as documented in the Nix manual.
-- Every constructor is strict in its children to prevent thunk buildup
-- during parsing.
data Expr
= -- | Literal value.
ELit !NixAtom
| -- | String with possible interpolations.
EStr ![StringPart]
| -- | Indented string (double single-quoted).
EIndStr ![StringPart]
| -- | Variable reference.
EVar !Text
| -- | Attribute set: @{ bindings }@ or @rec { bindings }@.
EAttrs !Bool ![Binding]
| -- | List: @[ e1 e2 e3 ]@.
EList ![Expr]
| -- | Attribute selection: @expr.attrpath@ or @expr.attrpath or default@.
ESelect !Expr !AttrPath !(Maybe Expr)
| -- | Has attribute: @expr ? attrpath@.
EHasAttr !Expr !AttrPath
| -- | Function application: @f x@.
EApp !Expr !Expr
| -- | Lambda: @formals: body@.
ELambda !Formals !Expr
| -- | Let binding: @let bindings in body@.
ELet ![Binding] !Expr
| -- | If-then-else: @if cond then t else f@.
EIf !Expr !Expr !Expr
| -- | With expression: @with expr; body@.
EWith !Expr !Expr
| -- | Assert: @assert cond; body@.
EAssert !Expr !Expr
| -- | Unary operator application.
EUnary !UnaryOp !Expr
| -- | Binary operator application.
EBinary !BinaryOp !Expr !Expr
| -- | Search path lookup: @\<nixpkgs\>@ is @ESearchPath "nixpkgs"@.
ESearchPath !Text
deriving (Eq, Show)