Add initial support for parsing operators

This commit is contained in:
John Wiegley 2014-07-01 01:12:28 -05:00
parent 52bfdd126b
commit be1434726a
6 changed files with 93 additions and 37 deletions

View File

@ -37,9 +37,9 @@ evalExpr = cata phi
phi (NList l) = \env -> phi (NList l) = \env ->
Fix . NVList <$> mapM ($ env) l Fix . NVList <$> mapM ($ env) l
phi (NConcat l) = \env -> -- phi (NConcat l) = \env ->
Fix . NVConstant . NStr . T.concat -- Fix . NVConstant . NStr . T.concat
<$> mapM (fmap valueText . ($ env)) l -- <$> mapM (fmap valueText . ($ env)) l
phi (NArgSet _xs) = error "Cannot evaluate an argument set" phi (NArgSet _xs) = error "Cannot evaluate an argument set"

View File

@ -1,5 +1,5 @@
module Nix.Internal (trace) where module Nix.Internal (trace) where
--import Debug.Trace import Debug.Trace
trace :: String -> b -> b --trace :: String -> b -> b
trace _ x = x --trace _ x = x

View File

@ -3,26 +3,47 @@
module Nix.Parser (parseNixFile, Result(..)) where module Nix.Parser (parseNixFile, Result(..)) where
import Control.Applicative import Control.Applicative
import Control.Monad hiding (forM_, mapM, sequence) import Control.Monad
import Control.Monad.IO.Class import Control.Monad.IO.Class
import Data.Char import Data.Char
import Data.Foldable import Data.Foldable
import Data.List (foldl1')
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Text hiding (concat, concatMap, head, map) import Data.Text hiding (head, map, foldl1')
import Nix.Types import Nix.Types
import Nix.Internal import Nix.Internal
import Nix.Parser.Library import Nix.Parser.Library
import qualified Prelude import qualified Prelude
import Prelude hiding (readFile, concat, concatMap, elem, mapM, import Prelude hiding (elem)
sequence)
nixApp :: Parser NExpr nixApp :: Parser NExpr
nixApp = go <$> some (whiteSpace *> nixTerm True) nixApp = go <$> some (whiteSpace *> nixExpr True)
where where
go [] = error "some has failed us" go [] = error "some has failed us"
go [x] = x go [x] = x
go (f:xs) = Fix (NApp f (go xs)) go (f:xs) = Fix (NApp f (go xs))
nixExpr :: Bool -> Parser NExpr
nixExpr allowLambdas =
buildExpressionParser table (nixTerm allowLambdas) <?> "expression"
where
table :: OperatorTable Parser NExpr
table =
[ [ prefix "-" NNeg ]
, [ binary "++" NConcat AssocRight ]
, [ binary "*" NMult AssocLeft,
binary "/" NDiv AssocLeft ]
, [ binary "+" NPlus AssocLeft,
binary "-" NMinus AssocLeft ]
]
binary name fun =
Infix (pure (\x y -> Fix (NOper (fun x y))) <* symbol name)
prefix name fun =
Prefix (pure (Fix . NOper . fun) <* symbol name)
-- postfix name fun =
-- Postfix (pure (Fix . NOper . fun) <* symbol name)
nixTerm :: Bool -> Parser NExpr nixTerm :: Bool -> Parser NExpr
nixTerm allowLambdas = choice nixTerm allowLambdas = choice
[ nixInt [ nixInt
@ -92,9 +113,11 @@ symName = do
stringish :: Parser NExpr stringish :: Parser NExpr
stringish stringish
= (char '"' *> = (char '"' *>
(Fix . NConcat <$> manyTill stringChar (char '"'))) (merge <$> manyTill stringChar (char '"')))
<|> (char '$' *> between (symbolic '{') (symbolic '}') nixApp) <|> (char '$' *> between (symbolic '{') (symbolic '}') nixApp)
where where
merge = foldl1' (\x y -> Fix (NOper (NConcat x y)))
stringChar :: Parser NExpr stringChar :: Parser NExpr
stringChar = char '\\' *> oneChar stringChar = char '\\' *> oneChar
<|> (string "${" *> nixApp <* char '}') <|> (string "${" *> nixApp <* char '}')
@ -111,8 +134,8 @@ argExpr = (Fix . NArgSet . Map.fromList <$> argList)
<?> "arglist" <?> "arglist"
argName = (,) <$> (symName <* whiteSpace) argName = (,) <$> (symName <* whiteSpace)
<*> optional (try (symbolic '?' *> nixApp)) <*> optional (symbolic '?' *> nixTerm False)
1
nvPair :: Parser (NExpr, NExpr) nvPair :: Parser (NExpr, NExpr)
nvPair = (,) <$> keyName <*> (symbolic '=' *> nixApp) nvPair = (,) <$> keyName <*> (symbolic '=' *> nixApp)

View File

@ -4,9 +4,11 @@ module Nix.Parser.Library
( (
#if USE_PARSEC #if USE_PARSEC
module Text.Parsec module Text.Parsec
, module Text.Parsec.Expr
, module Text.Parsec.Text , module Text.Parsec.Text
#else #else
module Text.Trifecta module Text.Trifecta
, module Text.Parser.Expression
, module Text.Parser.LookAhead , module Text.Parser.LookAhead
#endif #endif
) )
@ -17,6 +19,7 @@ module Nix.Parser.Library
import Control.Applicative import Control.Applicative
import Data.Text.IO import Data.Text.IO
import Text.Parsec hiding ((<|>), many, optional) import Text.Parsec hiding ((<|>), many, optional)
import Text.Parsec.Expr
import Text.Parsec.Text import Text.Parsec.Text
import Text.PrettyPrint.ANSI.Leijen (Doc, text) import Text.PrettyPrint.ANSI.Leijen (Doc, text)
@ -42,6 +45,7 @@ parseFromFileEx p path =
#else #else
import Text.Parser.Expression
import Text.Parser.LookAhead import Text.Parser.LookAhead
import Text.Trifecta import Text.Trifecta

View File

@ -43,12 +43,45 @@ atomText (NPath p) = pack p
atomText (NBool b) = if b then "true" else "false" atomText (NBool b) = if b then "true" else "false"
atomText (NSym s) = s atomText (NSym s) = s
atomText NNull = "null" atomText NNull = "null"
data NOperF r
= NNot r
| NNeg r
| NEq r r
| NNEq r r
| NLt r r
| NLte r r
| NGt r r
| NGte r r
| NAnd r r
| NOr r r
| NImpl r r
| NUpdate r r
| NHasAttr r r
| NPlus r r
| NMinus r r
| NMult r r
| NDiv r r
| NConcat r r
deriving (Eq, Ord, Generic, Typeable, Data, Functor)
-- show (NConcat l) = go l
-- where
-- go [] = ""
-- go [x] = show x
-- go (x:xs) = show x ++ " ++ " ++ go xs
-- phi (NConcat l) = "NConcat " ++ show l
data NExprF r data NExprF r
= NConstant NAtom = NConstant NAtom
| NOper (NOperF r)
| NList [r] | NList [r]
| NConcat [r]
-- ^ A "concat" is a list of things which must combine to form a string. -- ^ A "concat" is a list of things which must combine to form a string.
| NArgSet (Map Text (Maybe r)) | NArgSet (Map Text (Maybe r))
| NSet Bool [(r, r)] | NSet Bool [(r, r)]
@ -62,7 +95,7 @@ data NExprF r
| NApp r r | NApp r r
| NAbs r r | NAbs r r
-- ^ The untyped lambda calculus core -- ^ The untyped lambda calculus core
deriving (Ord, Eq, Generic, Typeable, Data) deriving (Ord, Eq, Generic, Typeable, Data, Functor)
type NExpr = Fix NExprF type NExpr = Fix NExprF
@ -70,23 +103,23 @@ instance Show (Fix NExprF) where show (Fix f) = show f
instance Eq (Fix NExprF) where Fix x == Fix y = x == y instance Eq (Fix NExprF) where Fix x == Fix y = x == y
instance Ord (Fix NExprF) where compare (Fix x) (Fix y) = compare x y instance Ord (Fix NExprF) where compare (Fix x) (Fix y) = compare x y
instance Functor NExprF where -- instance Functor NExprF where
fmap _ (NConstant a) = NConstant a -- fmap _ (NConstant a) = NConstant a
fmap f (NList r) = NList (fmap f r) -- fmap f (NList r) = NList (fmap f r)
fmap f (NConcat r) = NConcat (fmap f r) -- fmap f (NArgSet h) = NArgSet (fmap (fmap f) h)
fmap f (NArgSet h) = NArgSet (fmap (fmap f) h) -- fmap f (NSet b h) = NSet b $ map go h
fmap f (NSet b h) = NSet b $ map go h -- where go (k, v) = (f k, f v)
where go (k, v) = (f k, f v) -- fmap f (NLet r r1) = NLet (f r) (f r1)
fmap f (NLet r r1) = NLet (f r) (f r1) -- fmap f (NIf r r1 r2) = NIf (f r) (f r1) (f r2)
fmap f (NIf r r1 r2) = NIf (f r) (f r1) (f r2) -- fmap f (NWith r r1) = NWith (f r) (f r1)
fmap f (NWith r r1) = NWith (f r) (f r1) -- fmap f (NAssert r r1) = NAssert (f r) (f r1)
fmap f (NAssert r r1) = NAssert (f r) (f r1) -- fmap f (NVar r) = NVar (f r)
fmap f (NVar r) = NVar (f r) -- fmap f (NApp r r1) = NApp (f r) (f r1)
fmap f (NApp r r1) = NApp (f r) (f r1) -- fmap f (NAbs r r1) = NAbs (f r) (f r1)
fmap f (NAbs r r1) = NAbs (f r) (f r1)
instance Show f => Show (NExprF f) where instance Show f => Show (NExprF f) where
show (NConstant x) = show x show (NConstant x) = show x
-- show (NOper x) = show x
show (NList l) = "[ " ++ go l ++ " ]" show (NList l) = "[ " ++ go l ++ " ]"
where where
@ -94,12 +127,6 @@ instance Show f => Show (NExprF f) where
go [x] = show x go [x] = show x
go (x:xs) = show x ++ ", " ++ go xs go (x:xs) = show x ++ ", " ++ go xs
show (NConcat l) = go l
where
go [] = ""
go [x] = show x
go (x:xs) = show x ++ " ++ " ++ go xs
show (NArgSet h) = "{ " ++ go (Map.toList h) ++ " }" show (NArgSet h) = "{ " ++ go (Map.toList h) ++ " }"
where where
go [] = "" go [] = ""
@ -126,8 +153,8 @@ instance Show f => Show (NExprF f) where
dumpExpr :: NExpr -> String dumpExpr :: NExpr -> String
dumpExpr = cata phi where dumpExpr = cata phi where
phi (NConstant x) = "NConstant " ++ show x phi (NConstant x) = "NConstant " ++ show x
-- phi (NOper x) = "NOper " ++ show x
phi (NList l) = "NList [" ++ show l ++ "]" phi (NList l) = "NList [" ++ show l ++ "]"
phi (NConcat l) = "NConcat " ++ show l
phi (NArgSet xs) = "NArgSet " ++ show xs phi (NArgSet xs) = "NArgSet " ++ show xs
phi (NSet b xs) = "NSet " ++ show b ++ " " ++ show xs phi (NSet b xs) = "NSet " ++ show b ++ " " ++ show xs
phi (NLet v e) = "NLet " ++ v ++ " " ++ e phi (NLet v e) = "NLet " ++ v ++ " " ++ e

View File

@ -29,6 +29,7 @@ Library
Default-extensions: Default-extensions:
DataKinds DataKinds
DeriveDataTypeable DeriveDataTypeable
DeriveFunctor
DeriveGeneric DeriveGeneric
FlexibleContexts FlexibleContexts
FlexibleInstances FlexibleInstances
@ -62,6 +63,7 @@ executable hnix
Default-extensions: Default-extensions:
DataKinds DataKinds
DeriveDataTypeable DeriveDataTypeable
DeriveFunctor
DeriveGeneric DeriveGeneric
FlexibleContexts FlexibleContexts
FlexibleInstances FlexibleInstances