diff --git a/LambdaPrettyQuote.cabal b/LambdaPrettyQuote.cabal
--- a/LambdaPrettyQuote.cabal
+++ b/LambdaPrettyQuote.cabal
@@ -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.0.0.2
+Version:             0.0.0.6
 
 -- A short (one-line) description of the package.
 Synopsis:            Parser, pretty printer, quasiquoter, and Arbitrary helpers for the untyped lambda calculus.
@@ -16,7 +16,10 @@
 
 -- A longer description of the package.
 Description:  
-       CHANGES -- 0.0.0.2 added \"anti\" expressions for the quasiquoter to capture variables from the environment. Also added a pattern quasiquoter. 
+       CHANGES -- 0.0.0.2 added \"anti\" expressions for the quasiquoter to capture variables from the environment. Also added a pattern quasiquoter.
+       
+       
+
 
 -- The license under which the package is released.
 License:             BSD3
diff --git a/src/Language/Lambda/Parser.hs b/src/Language/Lambda/Parser.hs
--- a/src/Language/Lambda/Parser.hs
+++ b/src/Language/Lambda/Parser.hs
@@ -11,65 +11,89 @@
 
 type M = Identity
 
-data MetaExpr = MVar Sym
-              | MApp MetaExpr MetaExpr
-              | MLam Sym MetaExpr
+data MetaExpr s = MVar (MetaSym s)
+              | MApp (MetaExpr s) (MetaExpr s)
+              | MLam (MetaSym s) (MetaExpr s)
               | AntiExpr String
+              | AntiVar  String
               deriving(Show, Eq, Data, Typeable)
+              
+data MetaSym s = S s
+               | AntiSym String
+              deriving(Show, Eq, Data, Typeable)
 
-type Output = MetaExpr
+type Output s = MetaExpr s
 
-top_expr :: ParsecT String u M Output
-top_expr = do 
+type SymParser u s = ParsecT String u M s
+
+top_expr :: SymParser u s -> ParsecT String u M (Output s)
+top_expr sp = do 
     spaces
-    e <- parse_expr
+    e <- parse_expr sp
     spaces
     eof
     return e
     
-parse_expr :: ParsecT String u M Output
-parse_expr =  try parse_aexpr 
-          <|> try parse_lambda
+parse_expr :: SymParser u s -> ParsecT String u M (Output s)
+parse_expr sp = try (parse_aexpr sp)
+          <|> try (parse_lambda sp)
           <|> try parse_anti_expr
  
-parse_aexpr :: ParsecT String u M Output
-parse_aexpr =  try parse_app 
-           <|> try parse_atom
+parse_aexpr :: SymParser u s -> ParsecT String u M (Output s)
+parse_aexpr sp =  try (parse_app sp)
+              <|> try (parse_atom sp)
            
-parse_anti_expr :: ParsecT String u M Output
+parse_anti_expr :: ParsecT String u M (Output s)
 parse_anti_expr = do
     _ <- string "$"
     i <- (identifier haskell)
     return $ AntiExpr i
 
-parse_lambda :: ParsecT String u M Output
-parse_lambda = do
+parse_lambda :: SymParser u s -> ParsecT String u M (Output s)
+parse_lambda sp = do
     _ <- char '\\'
     spaces
-    sym  <- parse_sym <?> "lambda argument"
+    sym  <- (p_sym sp) <?> "lambda argument"
     _ <- char '.'
     spaces
-    expr <- parse_expr <?> "lambda expression"
+    expr <- (parse_expr sp) <?> "lambda expression"
     return $ MLam sym expr
 
-parse_app :: ParsecT String u M Output
-parse_app = do
-    expr_0 <- parse_atom <?> "first apply argument"
+parse_app :: SymParser u s -> ParsecT String u M (Output s)
+parse_app sp = do
+    expr_0 <- (parse_atom sp) <?> "first apply argument"
     spaces
-    as <-  sepBy1 parse_atom spaces <?> "other apply arguments"
+    as <-  sepBy1 (parse_atom sp) spaces <?> "other apply arguments"
     return $ foldl' MApp expr_0 as
 
-parse_atom :: ParsecT String u M Output
-parse_atom =  try  (parens'  parse_expr)
-          <|> try parse_var 
+parse_atom :: SymParser u s -> ParsecT String u M (Output s)
+parse_atom sp =  try  (parens'  (parse_expr sp))
+          <|> try (parse_var sp)
           <|> try parse_anti_expr
           
-parse_var :: ParsecT String u M Output
-parse_var = do
+parse_var sp = try (parse_var' sp) <|> parse_anti_var 
+          
+parse_var' :: SymParser u s -> ParsecT String u M (Output s)
+parse_var' sp = do
     spaces
-    sym <- parse_sym <?> "Var symbol"
-    return $ MVar sym 
+    sym <- (p_sym sp) <?> "Var symbol"
+    return $ MVar sym  
+ 
+parse_anti_var = do 
+    spaces 
+    _ <- string "*"
+    i <- (identifier haskell)
+    return $ AntiVar i
     
+p_sym :: SymParser u s -> ParsecT String u M (MetaSym s)
+p_sym sp = try (S `fmap` sp) <|> try parse_anti_sym
+
+parse_anti_sym :: ParsecT String u M (MetaSym s)
+parse_anti_sym = do
+    _ <- string "^"
+    i <- (identifier haskell)
+    return $ AntiSym i
+    
 parse_sym :: ParsecT String u M Sym
 parse_sym = many1 (alphaNum <|> char '_') <?> "symbol"
 
@@ -80,16 +104,16 @@
     _ <- char ')'
     return e
 
-meta_to_expr :: MetaExpr -> Expr
-meta_to_expr (MVar x)     = Var x
+meta_to_expr :: MetaExpr s -> GExpr s
+meta_to_expr (MVar (S x))     = Var x
 meta_to_expr (MApp x y)   = App (meta_to_expr x) (meta_to_expr y)
-meta_to_expr (MLam x y)   = Lam x (meta_to_expr y)
-meta_to_expr (AntiExpr _) = error "meta_to_expr should not be used if the MetaExpr tree has AntiExpr"
+meta_to_expr (MLam (S x) y)   = Lam x (meta_to_expr y)
+meta_to_expr _ = error "meta_to_expr should not be used if the MetaExpr tree has AntiExpr"
 
-to_meta :: Expr -> MetaExpr
-to_meta (Var x)   = MVar x
+to_meta :: GExpr s -> MetaExpr s
+to_meta (Var x)   = MVar (S x)
 to_meta (App x y) = MApp (to_meta x) (to_meta y)
-to_meta (Lam x y) = MLam x (to_meta y)
+to_meta (Lam x y) = MLam (S x) (to_meta y)
 
 
 
diff --git a/src/Language/Lambda/Quote.hs b/src/Language/Lambda/Quote.hs
--- a/src/Language/Lambda/Quote.hs
+++ b/src/Language/Lambda/Quote.hs
@@ -1,58 +1,80 @@
-{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
-module Language.Lambda.Quote (lam) where
+{-# LANGUAGE TemplateHaskell, QuasiQuotes, RankNTypes #-}
+module Language.Lambda.Quote (lam, g_lam) where
 import Language.Haskell.TH.Quote
 import Language.Haskell.TH
 import Language.Lambda.Parser
 import Text.Parsec (runParser)
 import Data.Generics.Aliases
 import Data.Generics.Uniplate.Data
+import Language.Lambda.AST
+import Data.Data
+import Debug.Trace.Helpers
  
 lam :: QuasiQuoter
-lam = QuasiQuoter quoteExprExp quoteExprPat undefined undefined
+lam = g_lam parse_sym
 
-parseExpr :: Monad m => (String, Int, Int) -> String -> m Output
-parseExpr (file, line, col) s = result where
-    result = case runParser top_expr () file s of
+g_lam :: (Data s, Show s) => SymParser () s -> QuasiQuoter
+g_lam sp = QuasiQuoter (g_quoteExprExp sp) (g_quoteExprPat sp) undefined undefined
+
+
+parseExpr :: Monad m => SymParser () s -> (String, Int, Int) -> String -> m (Output s)
+parseExpr sp (file, line, col) s = result where
+    result = case runParser (top_expr sp) () 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  
+
+    
+g_quoteExprExp :: (Data s, Show s,  Typeable s) => SymParser () s -> String -> ExpQ
+g_quoteExprExp sp r =  do  
     loc <- location
     let pos =  (loc_filename loc,
              fst (loc_start loc),
              snd (loc_start loc))
-    parsed_expr <- parseExpr pos s
-    appE (varE $ mkName "meta_to_expr") $ dataToExpQ (const Nothing `extQ` antiExprExp) parsed_expr
+    parsed_expr <- (parseExpr sp) pos r
+    appE (varE $ mkName "meta_to_expr") $ dataToExpQ (const Nothing `extQ` 
+        (antiExprExp sp)) $ parsed_expr
              
-antiExprExp :: MetaExpr -> Maybe (Q Exp)
-antiExprExp  (AntiExpr v)     = Just $ appE (varE $ mkName "to_meta") $ varE (mkName v)
-antiExprExp  _                = Nothing
-
+antiExprExp :: (Data s, Typeable s) => SymParser () s -> MetaExpr s -> Maybe (Q Exp)
+antiExprExp d (MLam (AntiSym v) x) = Just $ appE (appE (conE $ mkName "MLam") $ appE (conE $ mkName "S") $ varE (mkName v))
+                                         $ dataToExpQ (const Nothing `extQ` (antiExprExp d)) x
+antiExprExp d (MVar (AntiSym v))   = Just $ appE (conE $ mkName "MVar") $ appE (conE $ mkName "S") $ varE (mkName v)
+antiExprExp d (AntiExpr v)         = Just $ appE (varE $ mkName "to_meta") $ varE (mkName v)
+antiExprExp d (AntiVar v)          = Just $ [| MVar (S $(varE $ mkName v)) |]
+antiExprExp _ _                    = Nothing
 
-quoteExprPat :: String -> PatQ
-quoteExprPat s =  do  
+g_quoteExprPat :: (Data s, Show s, Typeable s) => SymParser () s ->  String -> PatQ
+g_quoteExprPat sp r =  do  
     loc <- location
     let pos =  (loc_filename loc,
              fst (loc_start loc),
              snd (loc_start loc))
-    parsed_expr <- parseExpr pos s
-    th_pat <- dataToPatQ (const Nothing `extQ` antiExprPat) parsed_expr
+    parsed_expr <- (parseExpr sp) pos r
+    th_pat <- dataToPatQ (const Nothing `extQ` (antiExprPat sp)) parsed_expr
     return $ to_e th_pat where
         to_e p = transform to_e' p
 
-        to_e' (ConP n xs) = ConP (to_expr_name n) xs
+        to_e' (ConP n xs) | show n == "MVar" = ConP (to_expr_name n) [collapse_meta_sym $ head xs]
+        to_e' (ConP n xs) | show n == "MLam" = ConP (to_expr_name n) ((collapse_meta_sym $ head xs):(tail xs))
+        to_e' (ConP n xs) | otherwise        = ConP (to_expr_name n) xs
         to_e' x = x
 
         to_expr_name name | show name == "MVar" = mkName "Var" 
         to_expr_name name | show name == "MApp" = mkName "App" 
         to_expr_name name | show name == "MLam" = mkName "Lam"
         to_expr_name name | otherwise           = name
+        
+        collapse_meta_sym (ConP n xs) | nameBase n == "S" = head xs
+        collapse_meta_sym p@(ConP n xs) | otherwise = error ("collapse_meta_sym not used on a S " ++ show p)
              
-antiExprPat :: MetaExpr -> Maybe (Q Pat)
-antiExprPat  (AntiExpr v)     = Just $ varP (mkName v)
-antiExprPat  _                = Nothing
+antiExprPat :: (Data s, Typeable s) => SymParser () s -> MetaExpr s -> Maybe (Q Pat)
+antiExprPat d (MLam (AntiSym v) x) = Just $ conP (mkName "MLam") [conP (mkName "S") [varP (mkName v)], 
+                                        dataToPatQ (const Nothing `extQ` (antiExprPat d)) x]
+antiExprPat d (MVar (AntiSym v))   = Just $ conP (mkName "MVar") [conP (mkName "S") [varP (mkName v)]]
+antiExprPat d (AntiExpr v)         = Just $ varP (mkName v)
+antiExprPat d (AntiVar v)          = Just $ conP (mkName "MVar") [conP (mkName "S") [varP $ mkName v]]
+antiExprPat _ _                    = Nothing
 
 
 
