{-# LANGUAGE DeriveDataTypeable #-}
module Expr where
import Data.Generics
import Language.Haskell.TH as TH
import Language.Haskell.TH.Quote
-- import Text.ParserCombinators.Parsec
-- import Text.ParserCombinators.Parsec.Char
data Expr = IntExpr Integer
| AntiIntExpr String
| BinopExpr BinOp Expr Expr
| AntiExpr String
deriving(Typeable, Data,Show)
data BinOp = AddOp
| SubOp
| MulOp
| DivOp
deriving(Typeable, Data,Show)
eval :: Expr -> Integer
eval (IntExpr n) = n
eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y)
where
opToFun AddOp = (+)
opToFun SubOp = (-)
opToFun MulOp = (*)
opToFun DivOp = (div)
small = lower <|> char '_'
large = upper
idchar = small <|> large <|> digit <|> char '\''
lexeme p = do{ x <- p; spaces; return x }
symbol name = lexeme (string name)
parens p = undefined -- between (symbol "(") (symbol ")") p
_expr :: CharParser st Expr
_expr = term `chainl1` mulop
term :: CharParser st Expr
term = factor `chainl1` addop
factor :: CharParser st Expr
factor = parens _expr <|> integer <|> anti
mulop = undefined
{-
do{ symbol "*"; return $ BinopExpr MulOp }
<|> do{ symbol "/"; return $ BinopExpr DivOp }
-}
addop = undefined
{-
do{ symbol "+"; return $ BinopExpr AddOp }
<|> do{ symbol "-"; return $ BinopExpr SubOp }
-}
integer :: CharParser st Expr
integer = lexeme $ do{ ds <- many1 digit ; return $ IntExpr (read ds) }
anti = undefined
{-
lexeme $
do symbol "$"
c <- small
cs <- many idchar
return $ AntiIntExpr (c : cs)
-}
parseExpr :: Monad m => TH.Loc -> String -> m Expr
parseExpr (Loc {loc_filename = file, loc_start = (line,col)}) s =
case runParser p () "" s of
Left err -> fail $ "baz"
Right e -> return e
where
p = do pos <- getPosition
setPosition $ setSourceName (setSourceLine (setSourceColumn pos col) line) file
spaces
e <- _expr
eof
return e
expr = QuasiQuoter { quoteExp = parseExprExp, quotePat = parseExprPat }
parseExprExp :: String -> Q Exp
parseExprExp s = do loc <- location
expr <- parseExpr loc s
dataToExpQ (const Nothing `extQ` antiExprExp) expr
antiExprExp :: Expr -> Maybe (Q Exp)
antiExprExp (AntiIntExpr v) = Just $ appE (conE (mkName "IntExpr"))
(varE (mkName v))
antiExprExp (AntiExpr v) = Just $ varE (mkName v)
antiExprExp _ = Nothing
parseExprPat :: String -> Q Pat
parseExprPat s = do loc <- location
expr <- parseExpr loc s
dataToPatQ (const Nothing `extQ` antiExprPat) expr
antiExprPat :: Expr -> Maybe (Q Pat)
antiExprPat (AntiIntExpr v) = Just $ conP (mkName "IntExpr")
[varP (mkName v)]
antiExprPat (AntiExpr v) = Just $ varP (mkName v)
antiExprPat _ = Nothing
-- keep parser happy
runParser = undefined
getPosition = undefined
setPosition = undefined
setSourceName = undefined
setSourceLine = undefined
setSourceColumn = undefined
spaces = undefined
eof = undefined
many = undefined
digit = undefined
many1 = undefined
data CharParser a b = F a b
(<|>) = undefined
chainl1 = undefined
string = undefined
char = undefined
lower = undefined
upper = undefined
between = undefined
instance Monad (CharParser a) where
instance Applicative (CharParser a) where
instance Functor (CharParser a) where