{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Nix.Expr.Shorthands where
import Data.Fix
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid
import Data.Text (Text)
import Nix.Atoms
import Nix.Expr.Types
import Text.Megaparsec.Pos (SourcePos)
mkInt :: Integer -> NExpr
mkInt = Fix . mkIntF
mkIntF :: Integer -> NExprF a
mkIntF = NConstant . NInt
mkFloat :: Float -> NExpr
mkFloat = Fix . mkFloatF
mkFloatF :: Float -> NExprF a
mkFloatF = NConstant . NFloat
mkStr :: Text -> NExpr
mkStr = Fix . NStr . DoubleQuoted . \case
"" -> []
x -> [Plain x]
mkIndentedStr :: Int -> Text -> NExpr
mkIndentedStr w = Fix . NStr . Indented w . \case
"" -> []
x -> [Plain x]
mkPath :: Bool -> FilePath -> NExpr
mkPath b = Fix . mkPathF b
mkPathF :: Bool -> FilePath -> NExprF a
mkPathF False = NLiteralPath
mkPathF True = NEnvPath
mkEnvPath :: FilePath -> NExpr
mkEnvPath = Fix . mkEnvPathF
mkEnvPathF :: FilePath -> NExprF a
mkEnvPathF = mkPathF True
mkRelPath :: FilePath -> NExpr
mkRelPath = Fix . mkRelPathF
mkRelPathF :: FilePath -> NExprF a
mkRelPathF = mkPathF False
mkSym :: Text -> NExpr
mkSym = Fix . mkSymF
mkSymF :: Text -> NExprF a
mkSymF = NSym
mkSelector :: Text -> NAttrPath NExpr
mkSelector = (:| []) . StaticKey
mkBool :: Bool -> NExpr
mkBool = Fix . mkBoolF
mkBoolF :: Bool -> NExprF a
mkBoolF = NConstant . NBool
mkNull :: NExpr
mkNull = Fix mkNullF
mkNullF :: NExprF a
mkNullF = NConstant NNull
mkOper :: NUnaryOp -> NExpr -> NExpr
mkOper op = Fix . NUnary op
mkOper2 :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkOper2 op a = Fix . NBinary op a
mkParamset :: [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkParamset params variadic = ParamSet params variadic Nothing
mkRecSet :: [Binding NExpr] -> NExpr
mkRecSet = Fix . NRecSet
mkNonRecSet :: [Binding NExpr] -> NExpr
mkNonRecSet = Fix . NSet
mkLets :: [Binding NExpr] -> NExpr -> NExpr
mkLets bindings = Fix . NLet bindings
mkList :: [NExpr] -> NExpr
mkList = Fix . NList
mkWith :: NExpr -> NExpr -> NExpr
mkWith e = Fix . NWith e
mkAssert :: NExpr -> NExpr -> NExpr
mkAssert e = Fix . NWith e
mkIf :: NExpr -> NExpr -> NExpr -> NExpr
mkIf e1 e2 = Fix . NIf e1 e2
mkFunction :: Params NExpr -> NExpr -> NExpr
mkFunction params = Fix . NAbs params
inherit :: [NKeyName e] -> SourcePos -> Binding e
inherit = Inherit Nothing
inheritFrom :: e -> [NKeyName e] -> SourcePos -> Binding e
inheritFrom expr = Inherit (Just expr)
bindTo :: Text -> NExpr -> Binding NExpr
bindTo name x = NamedVar (mkSelector name) x nullPos
($=) :: Text -> NExpr -> Binding NExpr
($=) = bindTo
infixr 2 $=
appendBindings :: [Binding NExpr] -> NExpr -> NExpr
appendBindings newBindings (Fix e) = case e of
NLet bindings e' -> Fix $ NLet (bindings <> newBindings) e'
NSet bindings -> Fix $ NSet (bindings <> newBindings)
NRecSet bindings -> Fix $ NRecSet (bindings <> newBindings)
_ -> error "Can only append bindings to a set or a let"
modifyFunctionBody :: (NExpr -> NExpr) -> NExpr -> NExpr
modifyFunctionBody f (Fix e) = case e of
NAbs params body -> Fix $ NAbs params (f body)
_ -> error "Not a function"
letsE :: [(Text, NExpr)] -> NExpr -> NExpr
letsE pairs = Fix . NLet (map (uncurry bindTo) pairs)
letE :: Text -> NExpr -> NExpr -> NExpr
letE varName varExpr = letsE [(varName, varExpr)]
attrsE :: [(Text, NExpr)] -> NExpr
attrsE pairs = Fix $ NSet (map (uncurry bindTo) pairs)
recAttrsE :: [(Text, NExpr)] -> NExpr
recAttrsE pairs = Fix $ NRecSet (map (uncurry bindTo) pairs)
mkNot :: NExpr -> NExpr
mkNot = Fix . NUnary NNot
mkBinop :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkBinop op e1 e2 = Fix (NBinary op e1 e2)
($==), ($!=), ($<), ($<=), ($>), ($>=), ($&&), ($||), ($->),
($//), ($+), ($-), ($*), ($/), ($++)
:: NExpr -> NExpr -> NExpr
e1 $== e2 = mkBinop NEq e1 e2
e1 $!= e2 = mkBinop NNEq e1 e2
e1 $< e2 = mkBinop NLt e1 e2
e1 $<= e2 = mkBinop NLte e1 e2
e1 $> e2 = mkBinop NGt e1 e2
e1 $>= e2 = mkBinop NGte e1 e2
e1 $&& e2 = mkBinop NAnd e1 e2
e1 $|| e2 = mkBinop NOr e1 e2
e1 $-> e2 = mkBinop NImpl e1 e2
e1 $// e2 = mkBinop NUpdate e1 e2
e1 $+ e2 = mkBinop NPlus e1 e2
e1 $- e2 = mkBinop NMinus e1 e2
e1 $* e2 = mkBinop NMult e1 e2
e1 $/ e2 = mkBinop NDiv e1 e2
e1 $++ e2 = mkBinop NConcat e1 e2
(@@) :: NExpr -> NExpr -> NExpr
f @@ arg = mkBinop NApp f arg
infixl 1 @@
(==>) :: Params NExpr -> NExpr -> NExpr
(==>) = mkFunction
infixr 1 ==>
(@.) :: NExpr -> Text -> NExpr
obj @. name = Fix (NSelect obj (StaticKey name :| []) Nothing)
infixl 2 @.