rawstring-qm (empty) → 0.1.5
raw patch · 6 files changed
+216/−0 lines, 6 filesdep +basedep +bytestringdep +haskell-src-metasetup-changed
Dependencies added: base, bytestring, haskell-src-meta, template-haskell, text
Files
- CHANGES +3/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- rawstring-qm.cabal +39/−0
- src/Data/String/QM.hs +113/−0
- src/Data/Text/ToText.hs +29/−0
+ CHANGES view
@@ -0,0 +1,3 @@++0.1.4+* Initial public version
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Marcin Tolysz++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Marcin Tolysz nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ rawstring-qm.cabal view
@@ -0,0 +1,39 @@+-- Initial rawstring-qm.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: rawstring-qm+version: 0.1.5+cabal-version: >=1.10+synopsis: Simple raw string quotation and dictionary interpolation+description: Supply a couple of usefull QuasiQuotes so we can use functions to lookup values+ This is an initial, and unstable package.+homepage: https://github.com/tolysz/rawstring-qm+license: BSD3+license-file: LICENSE+author: Marcin Tolysz+maintainer: tolysz@gmail.com+-- copyright: +category: Text+build-type: Simple+extra-source-files: CHANGES++Source-Repository head+ type: git+ location: https://github.com/tolysz/rawstring-qm.git++++library+ exposed-modules: Data.String.QM+ , Data.Text.ToText+ + -- other-modules: + -- other-extensions: + build-depends: base >=4.7 && <4.8+ , text+ , template-haskell+ , bytestring+ , haskell-src-meta++ hs-source-dirs: src+ default-language: Haskell2010
+ src/Data/String/QM.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE OverloadedStrings #-}++{-# LANGUAGE TemplateHaskell, TypeSynonymInstances, FlexibleInstances, + UndecidableInstances, OverlappingInstances, MultiParamTypeClasses,+ IncoherentInstances+ #-}+++module Data.String.QM+ (qq, qm)+where++import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Language.Haskell.TH.Syntax++import Prelude ((.), ($), fail, map, return, foldl,foldl1, foldr)++import qualified Language.Haskell.TH as TH+import Language.Haskell.TH.Quote+import Language.Haskell.Meta.Parse+import GHC.Exts (IsString(..))+import Data.Monoid (Monoid(..))+import Data.ByteString.Char8 as Strict (ByteString, unpack)+import Data.ByteString.Lazy.Char8 as Lazy (ByteString, unpack)+import Data.Text as T (Text, unpack)+import Data.Text.Lazy as LazyT(Text, unpack)+import Data.Char (isAlpha, isAlphaNum)+import Prelude+import Data.Maybe++data StringPart = Literal String | AntiQuote String | Lookup String deriving Show+++qq :: QuasiQuoter+qq = QuasiQuoter + { quoteExp = return . LitE . StringL+ -- , quotePat = return . ListP . map (LitP . CharL)+ , quotePat = return . bla+ , quoteType = \_ -> fail "illegal raw string QuasiQuote (allowed as expression only, used as a type)"+ , quoteDec = \_ -> fail "illegal raw string QuasiQuote (allowed as expression only, used as a declaration)"+}++-- lets have++bla [c] = LitP (CharL c)+bla (c:cs) = InfixP (LitP (CharL c)) '(:) (bla cs)+++unQM a [] = [Literal (reverse a)]+unQM a ('\\':x:xs) = unQM (x:a) xs+unQM a ('\\':[]) = unQM ('\\':a) []+unQM a ('}':xs) = Lookup (reverse a) : parseQM [] xs+unQM a (x:xs) = unQM (x:a) xs++parseQM a [] = [Literal (reverse a)]+parseQM a ('\\':x:xs) = parseQM (x:a) xs+parseQM a ('\\':[]) = parseQM ('\\':a) []+parseQM a ('$':x:xs) | x == '_' || isAlpha x =+ Literal (reverse a) : AntiQuote (x:pre) : parseQM [] post+ where+ (pre, post) = span isIdent xs+parseQM a ('{':xs) = Literal (reverse a) : unQM [] xs+parseQM a (x:xs) = parseQM (x:a) xs+++isIdent '_' = True+isIdent '\'' = True+isIdent x = isAlphaNum x++makeExpr [] = ls ""+makeExpr ((Literal a):xs) = TH.appE [| (++) a |] + $ makeExpr xs+makeExpr ((AntiQuote a):xs) = TH.appE [| (++) $(reifyM a) |]+ $ makeExpr xs++ls = return . TH.LitE . TH.StringL++makeExprF1 a = + if (hasLookup a)+ then+ do+ l <- TH.newName "lookup" -- string -> value+ x <- TH.appE [| fromString |] $ makeExprF l a+ return $ TH.LamE [TH.VarP l ] $ x+ else+ TH.appE [| fromString |] $ makeExpr a++makeExprF l [] = ls ""+makeExprF l ((Literal a):xs) = TH.appE [| (++) a |] + $ makeExprF l xs+makeExprF l ((AntiQuote a):xs) = TH.appE [| (++) $(reifyM a) |] + $ makeExprF l xs+makeExprF l ((Lookup a):xs) = TH.appE [| (++) ((fromMaybe "" $( return $ TH.AppE (TH.VarE l) (TH.LitE (TH.StringL a)) )) ) |] + $ makeExprF l xs++hasLookup [] = False+hasLookup ((Lookup _ ):as) = True+hasLookup (_:as) = hasLookup as+++-- | QuasiQuoter for interpolating '$var' and '{expr}' into a string literal. The pattern portion is undefined.+qm :: QuasiQuoter+qm = QuasiQuoter (makeExprF1 . parseQM [])+ (error "Cannot use qm as a pattern")+ (error "Cannot use qm as a type")+ (error "Cannot use qm as a dec")++reifyM s = + case parseExp s of+ Left s -> TH.reportWarning s >> ls ""+ Right e -> return e+
+ src/Data/Text/ToText.hs view
@@ -0,0 +1,29 @@++{-# Language TypeSynonymInstances+ , FlexibleInstances #-}++module Data.Text.ToText where++import Prelude+import Data.Text+import Data.Text.Lazy (toStrict)+import Data.Text.Lazy.Builder (toLazyText)+import Data.Text.Lazy.Builder.Int (decimal)+import Data.Text.Lazy.Builder.RealFloat (realFloat)++class ToText a where+ toText :: a -> Text++instance ToText Int where+ toText = toStrict . toLazyText . decimal+instance ToText Integer where+ toText = toStrict . toLazyText . decimal++instance ToText Float where+ toText = toStrict . toLazyText . realFloat++instance ToText Text where+ toText = id++instance ToText String where+ toText = pack