packages feed

egison-quote 0.1.0 → 0.1.1

raw patch · 2 files changed

+109/−23 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Language.Egison.Quote: instance [incoherent] Integral i => IsEgisonExpr i
+ Language.Egison.Quote: evalEgisonTopLevel :: EgisonExpr -> [String] -> (Name -> [StmtQ]) -> ExpQ
+ Language.Egison.Quote: instance [incoherent] IsEgisonExpr Int
+ Language.Egison.Quote: instance [incoherent] IsEgisonExpr Integer
+ Language.Egison.Quote: parseAntiquote :: Parser ([String], String)
+ Language.Egison.Quote: pickupAntiquote :: String -> ([String], String)
- Language.Egison.Quote: toHaskellExp :: EgisonExpr -> TypeSignature -> ExpQ
+ Language.Egison.Quote: toHaskellExp :: EgisonExpr -> [String] -> TypeSignature -> ExpQ

Files

Language/Egison/Quote.hs view
@@ -12,14 +12,17 @@ --  -----------------------------------------------------------------------------    -{-# Language TemplateHaskell, QuasiQuotes, TypeSynonymInstances, FlexibleInstances, UndecidableInstances, OverlappingInstances, IncoherentInstances #-}+{-# Language TemplateHaskell, QuasiQuotes, TypeSynonymInstances, FlexibleInstances, UndecidableInstances, ViewPatterns, OverlappingInstances, IncoherentInstances #-}  module Language.Egison.Quote(egison,                              TypeSignature,-                             parseQuote,                              parseType,+                             pickupAntiquote,+                             parseAntiquote,+                             parseQuote,                              readQuote,-                             toHaskellExp) where+                             toHaskellExp,+                             evalEgisonTopLevel) where  import Language.Haskell.TH import Language.Haskell.TH.Syntax@@ -35,6 +38,9 @@  import Data.Either import Data.Ratio+import Data.Maybe+import Data.List+ import Control.Monad.Error hiding (lift) import Control.Monad.Trans hiding (lift) import Control.Arrow@@ -45,12 +51,13 @@ class IsEgisonExpr a where     toEgisonExpr :: a -> EgisonExpr -instance Integral i => IsEgisonExpr i where toEgisonExpr = NumberExpr . fromIntegral+instance IsEgisonExpr Int where toEgisonExpr = NumberExpr . fromIntegral+instance IsEgisonExpr Integer where toEgisonExpr = NumberExpr . fromIntegral instance IsEgisonExpr Char where toEgisonExpr = CharExpr-instance IsEgisonExpr String where toEgisonExpr = StringExpr instance IsEgisonExpr Bool where toEgisonExpr = BoolExpr instance IsEgisonExpr Float where toEgisonExpr = FloatExpr . realToFrac instance IsEgisonExpr Double where toEgisonExpr = FloatExpr+instance IsEgisonExpr String where toEgisonExpr = StringExpr instance IsEgisonExpr a => IsEgisonExpr [a] where toEgisonExpr = CollectionExpr . map (ElementExpr . toEgisonExpr) instance (IsEgisonExpr a, IsEgisonExpr b) => IsEgisonExpr (a, b) where   toEgisonExpr (x, y) = TupleExpr $ [toEgisonExpr $ x, toEgisonExpr $ y]@@ -67,19 +74,29 @@  -- |  -- QuasiQuoter for egison expression+-- -- The format is: -- -- > expr := [egison | <egison-expression> :: <type-signature> |] --+-- For example, with Egison pattern matching, /powerset function/ can be expressed easily as follows.+--+-- >>> [egison|(lambda [$l] (match-all l (Multiset Integer) [<join $l _> l])) :: [Int] -> [[Int]]|] [1..3]+-- [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]+-- -- Type signature is defined as follows -- -- > <Typ> = Bool | Int | Double | Float | Char | String | [<Typ>] | (<Typ>, <Typ>, ..., <Typ>) | <Typ> -> <Typ> -> ... <Typ> -- -- Embedded Egison expression is run-time evaluated by using 'Language.Egison.Core.eval' and 'System.Unsafe.unsafePerformIO'.--- For more detailed usage, please refer to <https://github.com/xenophobia/Egison-Quote>. +-- For more detailed usage, please refer to <https://github.com/xenophobia/Egison-Quote>. egison :: QuasiQuoter egison = QuasiQuoter {-           quoteExp = uncurry toHaskellExp . extractValue . readQuote,+           quoteExp = \input ->+                      let (antiquotes, input') = pickupAntiquote input+                          (expr, typ) = extractValue . readQuote $ input'+                      in+                        toHaskellExp expr antiquotes typ,            quotePat = error "Not implemented pat-quote.",            quoteType = error "Not implemented type-quote.",            quoteDec = error "Not implemented dec-quote."@@ -143,6 +160,25 @@                             return $ if null ttl then thd else TupleTS (thd:ttl))              <|> brackets (ListTS <$> lexeme parseType') +-- | Pick up antiquoted variables and delete notation @#{~}@+-- +-- > "(+ #{x} y)"  ---> ([x], "(+ x y)")+pickupAntiquote :: String -> ([String], String)+pickupAntiquote input = either (error.show) id $ parse parseAntiquote "Antiquote" input++-- | Parser for 'pickupAntiquote'+parseAntiquote :: Parser ([String], String)+parseAntiquote = (try $ do lexeme (char '#')+                           lexeme (char '{')+                           antiquote <- identifier+                           lexeme (char '}')+                           (antiquotes, rest) <- parseAntiquote+                           return $ (antiquote:antiquotes, ' ':antiquote++" "++rest))+                 <|> (try $ do c <- anyChar+                               (antiquotes, rest) <- parseAntiquote+                               return $ (antiquotes, c:rest))+                 <|> (eof >> return ([], ""))+ -- | Parser for egison-quote parseQuote :: Parser (EgisonExpr, TypeSignature) parseQuote = do@@ -214,20 +250,60 @@ -- * Construction Exp  -- | construct Exp from Egison-expression and type signature-toHaskellExp :: EgisonExpr -> TypeSignature -> ExpQ-toHaskellExp (FuncExpr (TupleExpr args) expr) (ArrowTS t1 t2) | length args == length t1 = do-  env <- newName "env"+toHaskellExp :: EgisonExpr -> [String] -> TypeSignature -> ExpQ+toHaskellExp (FuncExpr (TupleExpr args) expr) antiquotes (ArrowTS t1 t2) | length args == length t1 = do   let (argsName, argsType) = unzip . concat $ zipWith argsExpand args t1       argsExpr = zipWith (\aname atype -> sigE (varE (mkName aname)) atype) argsName argsType-      bindEnv = bindS (varP env) [|liftIO primitiveBindings|]-      loadEnv = noBindS [|liftIO (loadLibraries $(varE env))|]-      bindExprs = zipWith (\aname aexpr -> noBindS [|defineVar $(varE env) (aname, []) =<< (liftIO $ makeClosure $(varE env) (toEgisonExpr $(aexpr)))|]) argsName argsExpr+      bindExprs envName = zipWith (\aname aexpr -> noBindS [|runIOThrowsError $ defineVar $(varE envName) (aname, []) =<< (liftIO $ makeClosure $(varE envName) (toEgisonExpr $(aexpr)))|]) argsName argsExpr   (lamE (map toHaskellArgsPat args)-   (appE (varE 'unsafePerformIO) -    (appE (varE 'runIOThrowsError)-     (doE $ bindEnv : loadEnv : (bindExprs ++ [noBindS (appE (appE (varE 'fmap) (converter t2)) [|eval $(varE env) expr|])])))))-toHaskellExp expr typ = appE (converter typ) (appE (varE 'evalEgison) (lift expr))+        (appE (converter t2) (evalEgisonTopLevel expr antiquotes bindExprs)))+toHaskellExp expr antiquotes typ = appE (converter typ) (evalEgisonTopLevel expr antiquotes (const [])) +childExpr :: EgisonExpr -> [EgisonExpr]+childExpr (CharExpr _) = []+childExpr (StringExpr _) = []+childExpr (BoolExpr _) = []+childExpr (NumberExpr _) = []+childExpr (FloatExpr _) = []+childExpr (VarExpr _ cs) = cs+childExpr (MacroVarExpr _ cs) = cs+childExpr (PatVarOmitExpr c) = [c]+childExpr (VarOmitExpr c) = [c]+childExpr (PatVarExpr _ cs) = cs+childExpr WildCardExpr = []+childExpr (ValuePatExpr c) = [c]+childExpr (CutPatExpr c) = [c]+childExpr (NotPatExpr c) = [c]+childExpr (AndPatExpr cs) = cs+childExpr (OrPatExpr cs) = cs+childExpr (PredPatExpr c cs) = c:cs+childExpr (InductiveDataExpr _ cs) = cs+childExpr (TupleExpr cs) = cs+childExpr (CollectionExpr cs) = map go cs+    where go (ElementExpr x) = x+          go (SubCollectionExpr x) = x+childExpr (ArrayExpr cs) = concatMap go cs+    where go (AElementExpr x) = [x]+          go (AInnerArrayExpr xs) = concatMap go xs+childExpr (FuncExpr c1 c2) = [c1, c2]+childExpr (MacroExpr _ c) = [c]+childExpr (LoopExpr _ _ c1 c2 c3) = [c1, c2, c3]+childExpr (ParamsExpr _ c1 c2) = [c1, c2]+childExpr (IfExpr c1 c2 c3) = [c1, c2, c3]+childExpr (LetExpr bs c) = c:concatMap go bs+    where go (x, y) = [x, y]+childExpr (LetRecExpr bs c) = c:map snd bs+childExpr (DoExpr bs c) = c:concatMap go bs+    where go (x, y) = [x, y]+-- childExpr (TypeExpr DestructInfoExpr)+childExpr (MatchExpr c1 c2 ms) = c1:c2:concatMap go ms+    where go (x, y) = [x, y]+childExpr (MatchAllExpr c1 c2 (c3, c4)) = [c1, c2, c3, c4]+childExpr (GenerateArrayExpr c1 c2) = [c1, c2]+childExpr (ApplyExpr c1 c2) = [c1, c2]+childExpr SomethingExpr = []+childExpr UndefinedExpr = []+ argsExpand :: EgisonExpr -> TypeSignature -> [(String, TypeQ)] argsExpand (PatVarExpr a _) t = [(a, tsToType t)] argsExpand (TupleExpr as) (TupleTS ts) = concat $ zipWith argsExpand as ts@@ -237,8 +313,18 @@ toHaskellArgsPat (PatVarExpr a _) = varP (mkName a) toHaskellArgsPat (TupleExpr as) = tupP $ map toHaskellArgsPat as -evalEgison :: EgisonExpr -> EgisonVal-evalEgison expr = unsafePerformIO $ do-  env <- primitiveBindings-  loadLibraries env-  runIOThrowsError $ eval env expr+evalEgison :: EgisonExpr -> Env -> EgisonVal+evalEgison expr env = unsafePerformIO $ runIOThrowsError $ eval env expr++evalEgisonTopLevel :: EgisonExpr -> [String] -> (Name -> [StmtQ]) -> ExpQ+evalEgisonTopLevel expr vars binds = do+  env <- newName "env"+  let exprs = map (varE . mkName) vars+  (appE (varE 'unsafePerformIO)+   (doE (+     [(varP env) `bindS` (varE 'primitiveBindings),+      noBindS (appE (varE 'loadLibraries) (varE env))] ++ +     zipWith (\vname vexpr -> noBindS [|runIOThrowsError $ defineVar $(varE env) (vname, []) =<< (liftIO $ makeClosure $(varE env) (toEgisonExpr $(vexpr)))|]) vars exprs +++     binds env +++     [noBindS (appE (varE 'runIOThrowsError) (appsE [varE 'eval, varE env, [|expr|]]))]+    )))
egison-quote.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version:             0.1.0+Version:             0.1.1  -- A short (one-line) description of the package. Synopsis:            A quasi quotes for using Egison expression in Haskell code