LambdaPrettyQuote (empty) → 0.0.0.1
raw patch · 7 files changed
+294/−0 lines, 7 filesdep +DebugTraceHelpersdep +HUnitdep +QuickChecksetup-changed
Dependencies added: DebugTraceHelpers, HUnit, QuickCheck, base, lambda-ast, parsec, template-haskell, test-framework, test-framework-hunit, test-framework-quickcheck2, transformers
Files
- LICENSE +30/−0
- LambdaPrettyQuote.cabal +81/−0
- Setup.hs +2/−0
- src/Language/Lambda/Arbitrary.hs +47/−0
- src/Language/Lambda/Parser.hs +88/−0
- src/Language/Lambda/Pretty.hs +15/−0
- src/Language/Lambda/Quote.hs +31/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2012, Jonathan Fischoff++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 Jonathan Fischoff 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.
+ LambdaPrettyQuote.cabal view
@@ -0,0 +1,81 @@+-- LambdaPrettyQuote.cabal auto-generated by cabal init. For+-- additional options, see+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.+-- The name of the package.+Name: LambdaPrettyQuote++-- 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.0.0.1++-- A short (one-line) description of the package.+Synopsis: Parser, pretty printer, quasiquoter, and Arbitrary helpers for the untyped lambda calculus.++homepage: http://github.com/jfischoff/LambdaPrettyQuote++-- A longer description of the package.+-- Description: ++-- The license under which the package is released.+License: BSD3++-- The file containing the license text.+License-file: LICENSE++-- The package author(s).+Author: Jonathan Fischoff++-- An email address to which users can send suggestions, bug reports,+-- and patches.+Maintainer: jonathangfischoff@gmail.com++-- A copyright notice.+-- Copyright: ++Category: Language++Build-type: Simple++-- Extra files to be distributed with the package, such as examples or+-- a README.+-- Extra-source-files: ++-- Constraint on the version of Cabal needed to build this package.+Cabal-version: >=1.8+++Library+ -- Modules exported by the library.+ Exposed-modules: Language.Lambda.Arbitrary, Language.Lambda.Parser, Language.Lambda.Pretty, Language.Lambda.Quote+ Hs-Source-Dirs: src+ -- Packages needed in order to build this package.+ Build-depends: base >= 4.0 && <= 6.0,+ QuickCheck >= 2.4.1.1,+ test-framework-quickcheck2 >= 0.2.10,+ test-framework-hunit >= 0.2.7,+ test-framework >= 0.4.1.1,+ lambda-ast,+ HUnit >= 1.2.4.2,+ DebugTraceHelpers >= 0.12,+ template-haskell >= 2.6.0.0,+ transformers >= 0.2.2.0,+ parsec >= 3.1.2+ ghc-options: -Wall++Test-Suite tests+ Hs-Source-Dirs: src, tests+ type: exitcode-stdio-1.0+ main-is: Main.hs+ build-depends: base >= 4.0 && <= 6.0,+ QuickCheck >= 2.4.1.1,+ test-framework-quickcheck2 >= 0.2.10,+ test-framework-hunit >= 0.2.7,+ test-framework >= 0.4.1.1,+ lambda-ast,+ HUnit >= 1.2.4.2,+ DebugTraceHelpers >= 0.12,+ template-haskell >= 2.6.0.0,+ transformers >= 0.2.2.0,+ parsec >= 3.1.2 +
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Language/Lambda/Arbitrary.hs view
@@ -0,0 +1,47 @@+{- | This module provides the code of QuickCheck instances, but doesn't declare the instances+ Of the whole orphan deal, oh well. + + Anyway, to use you will need to copy the following code somewhere+> Instance Arbitrary Expr where+> arbitrary = expr_arb +> shrink = gexpr_shrink+ There is also a gexpr_arb that takes in a generator for the symbol type+-}+module Language.Lambda.Arbitrary where+import Test.QuickCheck+import Control.Applicative ((<*>), (<$>))+import Data.List+import Language.Lambda.AST++-- | An arbitrary function for Expr. See the example above.+expr_arb :: Gen Expr+expr_arb = gexpr_arb sym_arbitrary++-- | Generates a string like "x_{n}" where n is positive integer+sym_arbitrary :: Gen String +sym_arbitrary = do+ index <- suchThat (arbitrary :: Gen Int) (>0)+ return $ ("x_" ++ (show index))+ +-- | Shrink function for an GExpr. See the example at the top of the module +gexpr_shrink :: GExpr a -> [GExpr a]+gexpr_shrink x@(Var _) = [x]+gexpr_shrink (App x y) = [x, y]+gexpr_shrink (Lam _ y) = [y]+ +-- | Helper function for creating generators for GExpr. Takes in a generator for the symbol type+gexpr_arb :: Gen a -> Gen (GExpr a) +gexpr_arb sym_gen = sized $ \x -> gexpr_arb' x sym_gen++-- | Helper function for creating generators for GExpr. Takes in a generator for the symbol type and the+-- "depth" of the expression tree+gexpr_arb' :: Int -> Gen s -> Gen (GExpr s)+gexpr_arb' 0 s_arb = Var <$> s_arb+gexpr_arb' n s_arb = do+ option <- choose(0, 2) :: Gen Int+ case option of+ 0 -> Var <$> s_arb+ 1 -> App <$> gexpr_arb' (n - 1) s_arb <*> gexpr_arb' (n - 1) s_arb+ 2 -> Lam <$> s_arb <*> gexpr_arb' (n - 1) s_arb+ _ -> error "choose messed up!"+
+ src/Language/Lambda/Parser.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE FlexibleContexts #-}+{-- | Parser for the lambda AST built of parsec. No Support for AntiExpr yet. Probably not efficent -}+module Language.Lambda.Parser where+import Text.Parsec +import Language.Lambda.AST+import Data.Functor.Identity+import Data.List++type M = Identity++{-+data AntiExpr = AntiVar String+ | AntiLam String+ | AntiApp String+ +type Output = (Expr, Maybe AntiExpr)+-}++type Output = Expr++top_expr :: ParsecT String u M Output+top_expr = do + spaces+ e <- parse_expr+ spaces+ eof+ return e+ +parse_expr :: ParsecT String u M Output+parse_expr = try parse_aexpr + <|> try parse_lambda+ +parse_aexpr :: ParsecT String u M Output+parse_aexpr = try parse_app + <|> try parse_atom++parse_lambda :: ParsecT String u M Output+parse_lambda = do+ _ <- char '\\'+ sym <- parse_sym <?> "lambda argument"+ _ <- char '.'+ expr <- parse_expr <?> "lambda expression"+ return $ Lam sym expr++parse_app :: ParsecT String u M Output+parse_app = do+ expr_0 <- parse_atom <?> "first apply argument"+ spaces+ as <- sepBy1 parse_atom spaces <?> "other apply arguments"+ return $ foldl' App expr_0 as++parse_atom :: ParsecT String u M Output+parse_atom = try (parens' parse_expr)+ <|> try parse_var ++parse_var :: ParsecT String u M Output+parse_var = do+ spaces+ sym <- parse_sym <?> "Var symbol"+ return $ Var sym ++parse_sym :: ParsecT String u M String+parse_sym = many1 (alphaNum <|> char '_') <?> "symbol"++parens' :: Stream s m Char => ParsecT s u m b -> ParsecT s u m b+parens' p = do + _ <- char '('+ e <- p+ _ <- char ')'+ return e++++++++++++++++++
+ src/Language/Lambda/Pretty.hs view
@@ -0,0 +1,15 @@+{-- | Pretty printers for lambda expression -}+module Language.Lambda.Pretty where+import Language.Lambda.AST++-- | Pretty prints a Expr+ppr :: Expr -> String+ppr (Var x) = x+ppr (App x y) = "(" ++ ppr x ++ " " ++ ppr y ++ ")" +ppr (Lam x y) = "(\\" ++ x ++ "." ++ ppr y ++ ")"++-- | Pretty prints a GExpr +g_ppr :: (Show a) => GExpr a -> String+g_ppr (Var x) = show x+g_ppr (App x y) = "(" ++ g_ppr x ++ " " ++ g_ppr y ++ ")" +g_ppr (Lam x y) = "(\\" ++ show x ++ "." ++ g_ppr y ++ ")"
+ src/Language/Lambda/Quote.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, StandaloneDeriving #-}+module Language.Lambda.Quote where+import Language.Haskell.TH.Quote+import Language.Haskell.TH+import Language.Lambda.Parser+import Language.Lambda.AST+import Text.Parsec (runParser)+import Data.Data++deriving instance Typeable1 GExpr+deriving instance (Data a) => Data (GExpr a) ++--TODO make the pattern quoter and the anti expr+lam :: QuasiQuoter+lam = QuasiQuoter quoteExprExp undefined undefined undefined++parseExpr :: Monad m => (String, Int, Int) -> String -> m Expr+parseExpr (file, line, col) s = result where+ result = case runParser top_expr () file s of+ Left err -> fail $ (show err ++ " at file " ++ file ++ " at line " ++ + show line ++ " at col " ++ show col)+ Right e -> return e+ +quoteExprExp :: String -> ExpQ+quoteExprExp s = do loc <- location+ let pos = (loc_filename loc,+ fst (loc_start loc),+ snd (loc_start loc))+ parsed_expr <- parseExpr pos s+ dataToExpQ (const Nothing) parsed_expr+