From 3c7025f9f3b72046cef1cb85abea7ebe99e29a0e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 4 Jul 2014 02:06:56 -0500 Subject: [PATCH] Preliminary support for "let" syntax --- Nix/Parser.hs | 15 ++++++++++++--- Nix/Types.hs | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Nix/Parser.hs b/Nix/Parser.hs index a578748..1055540 100644 --- a/Nix/Parser.hs +++ b/Nix/Parser.hs @@ -14,6 +14,7 @@ import Nix.Internal import Nix.Parser.Library import Prelude hiding (elem) +-- | The lexer for this parser is defined in 'Nix.Parser.Library'. nixApp :: Parser NExpr nixApp = go <$> someTill (whiteSpace *> nixExpr True) @@ -55,6 +56,7 @@ nixTerm allowLambdas = choice , nixParens , nixList , nixPath + , nixLet , setLambdaStringOrSym allowLambdas ] @@ -76,6 +78,11 @@ nixList = brackets (Fix . NList <$> many (nixTerm False)) "list" nixPath :: Parser NExpr nixPath = try $ fmap mkPath $ mfilter ('/' `elem`) $ some (oneOf "A-Za-z_0-9.:/") +nixLet :: Parser NExpr +nixLet = (Fix .) . NLet + <$> (symbol "let" *> nixBinders) + <*> (whiteSpace *> symbol "in" *> nixApp) + -- | This is a bit tricky because we don't know whether we're looking at a set -- or a lambda until we've looked ahead a bit. And then it may be neither, -- in which case we fall back to expected a plain string or identifier. @@ -99,7 +106,7 @@ setLambdaStringOrSym allowLambdas = do else keyName "string" symName :: Parser Text -symName = pack <$> ((:) <$> letter <*> many (alphaNum <|> char '.')) +symName = pack <$> ((:) <$> letter <*> many (alphaNum <|> oneOf "._")) stringish :: Parser NExpr stringish = (char '"' *> (merge <$> manyTill stringChar (char '"'))) @@ -124,6 +131,9 @@ argExpr = (Fix . NArgSet . Map.fromList <$> argList) nvPair :: Parser (NExpr, NExpr) nvPair = (,) <$> keyName <*> (symbolic '=' *> nixApp) +nixBinders :: Parser [(NExpr, NExpr)] +nixBinders = nvPair `endBy` symbolic ';' + keyName :: Parser NExpr keyName = (stringish <|> (mkSym <$> symName)) <* whiteSpace @@ -138,8 +148,7 @@ setOrArgs = do else try (lookAhead lookaheadForSet) trace ("Do we have a set: " ++ show haveSet) $ return () if haveSet - then braces (Fix . NSet sawRec <$> nvPair `endBy` symbolic ';') - "set" + then braces (Fix . NSet sawRec <$> nixBinders) "set" else do trace "parsing arguments" $ return () args <- argExpr "arguments" diff --git a/Nix/Types.hs b/Nix/Types.hs index c71cfbe..75d4bb1 100644 --- a/Nix/Types.hs +++ b/Nix/Types.hs @@ -100,7 +100,7 @@ data NExprF r | NArgSet (Map Text (Maybe r)) | NSet Bool [(r, r)] - | NLet r r + | NLet [(r, r)] r | NIf r r r | NWith r r | NAssert r r @@ -157,7 +157,7 @@ dumpExpr = cata phi where phi (NList l) = "NList [" ++ show l ++ "]" phi (NArgSet xs) = "NArgSet " ++ show xs phi (NSet b xs) = "NSet " ++ show b ++ " " ++ show xs - phi (NLet v e) = "NLet " ++ v ++ " " ++ e + phi (NLet v e) = "NLet " ++ show v ++ " " ++ e phi (NIf i t e) = "NIf " ++ i ++ " " ++ t ++ " " ++ e phi (NWith c v) = "NWith " ++ c ++ " " ++ v phi (NAssert e v) = "NAssert " ++ e ++ " " ++ v