{-# OPTIONS -fno-warn-name-shadowing #-} module Atomo.Haskell ( module Control.Concurrent , module Control.Monad , module Control.Monad.Cont , module Control.Monad.Error , module Control.Monad.State , module Control.Monad.Trans , module Atomo.Types , p , e , es ) where import Control.Concurrent import Control.Monad import "monads-fd" Control.Monad.Cont (MonadCont(..), ContT(..)) import "monads-fd" Control.Monad.Error (MonadError(..), ErrorT(..)) import "monads-fd" Control.Monad.State (MonadState(..), gets, modify) import "monads-fd" Control.Monad.Trans import Language.Haskell.TH.Quote import Language.Haskell.TH.Syntax import Text.Parsec import qualified Language.Haskell.TH as TH import qualified Data.Text as T import Atomo.Parser import Atomo.Parser.Pattern import Atomo.Parser.Base import Atomo.Types p :: QuasiQuoter p = QuasiQuoter quotePatternExp undefined e :: QuasiQuoter e = QuasiQuoter quoteExprExp undefined es :: QuasiQuoter es = QuasiQuoter quoteExprsExp undefined withLocation :: (String -> (String, Int, Int) -> Q a) -> (a -> Exp) -> String -> TH.ExpQ withLocation p c s = do l <- TH.location r <- p s ( TH.loc_filename l , fst $ TH.loc_start l , snd $ TH.loc_start l ) return (c r) parsing :: Monad m => Parser a -> String -> (String, Int, Int) -> m a parsing p s (file, line, col) = case runParser pp [] "" s of Left e -> fail (show e) Right e -> return e where pp = do pos <- getPosition setPosition $ (flip setSourceName) file $ (flip setSourceLine) line $ (flip setSourceColumn) col $ pos whiteSpace e <- p whiteSpace eof return e parsePattern :: Monad m => String -> (String, Int, Int) -> m Pattern parsePattern = parsing ppDefine quotePatternExp :: String -> TH.ExpQ quotePatternExp = withLocation parsePattern patternToExp parseExpr :: Monad m => String -> (String, Int, Int) -> m Expr parseExpr = parsing pExpr quoteExprExp :: String -> TH.ExpQ quoteExprExp = withLocation parseExpr exprToExp parseExprs :: Monad m => String -> (String, Int, Int) -> m [Expr] parseExprs = parsing (wsBlock pExpr) quoteExprsExp :: String -> TH.ExpQ quoteExprsExp = withLocation parseExprs (ListE . map exprToExp) exprToExp :: Expr -> Exp exprToExp (Define l p e) = AppE (AppE (expr "Define" l) (patternToExp p)) (exprToExp e) exprToExp (Set l p e) = AppE (AppE (expr "Set" l) (patternToExp p)) (exprToExp e) exprToExp (Dispatch l m) = AppE (expr "Dispatch" l) (emessageToExp m) exprToExp (Operator l ns a p) = AppE (AppE (AppE (expr "Operator" l) (ListE (map (LitE . StringL) ns))) (assocToExp a)) (LitE (IntegerL p)) exprToExp (Primitive l v) = AppE (expr "Primitive" l) (valueToExp v) exprToExp (EBlock l as es) = AppE (AppE (expr "EBlock" l) (ListE (map patternToExp as))) (ListE (map exprToExp es)) exprToExp (EDispatchObject l) = expr "EDispatchObject" l exprToExp (EVM _ _) = error "cannot exprToExp EVM" exprToExp (EList l es) = AppE (expr "EList" l) (ListE (map exprToExp es)) exprToExp (ETop l) = expr "ETop" l exprToExp (EParticle l p) = AppE (expr "EParticle" l) (eparticleToExp p) assocToExp :: Assoc -> Exp assocToExp ALeft = ConE (mkName "ALeft") assocToExp ARight = ConE (mkName "ARight") messageToExp :: Message -> Exp messageToExp (Keyword i ns vs) = AppE (AppE (AppE (ConE (mkName "Keyword")) (LitE (IntegerL (fromIntegral i)))) (ListE (map (LitE . StringL) ns))) (ListE (map valueToExp vs)) messageToExp (Single i n v) = AppE (AppE (AppE (ConE (mkName "Single")) (LitE (IntegerL (fromIntegral i)))) (LitE (StringL n))) (valueToExp v) particleToExp :: Particle -> Exp particleToExp (PMSingle n) = AppE (ConE (mkName "PMSingle")) (LitE (StringL n)) particleToExp (PMKeyword ns vs) = AppE (AppE (ConE (mkName "PMKeyword")) (ListE (map (LitE . StringL) ns))) (ListE (map maybeValue vs)) where maybeValue Nothing = ConE (mkName "Nothing") maybeValue (Just v) = AppE (ConE (mkName "Just")) (valueToExp v) emessageToExp :: EMessage -> Exp emessageToExp (EKeyword i ns es) = AppE (AppE (AppE (ConE (mkName "EKeyword")) (LitE (IntegerL (fromIntegral i)))) (ListE (map (LitE . StringL) ns))) (ListE (map exprToExp es)) emessageToExp (ESingle i n e) = AppE (AppE (AppE (ConE (mkName "ESingle")) (LitE (IntegerL (fromIntegral i)))) (LitE (StringL n))) (exprToExp e) eparticleToExp :: EParticle -> Exp eparticleToExp (EPMSingle n) = AppE (ConE (mkName "EPMSingle")) (LitE (StringL n)) eparticleToExp (EPMKeyword ns es) = AppE (AppE (ConE (mkName "EPMKeyword")) (ListE (map (LitE . StringL) ns))) (ListE (map maybeExpr es)) where maybeExpr Nothing = ConE (mkName "Nothing") maybeExpr (Just e) = AppE (ConE (mkName "Just")) (exprToExp e) expr :: String -> Maybe SourcePos -> Exp expr n _ = AppE (ConE (mkName n)) (ConE (mkName "Nothing")) valueToExp :: Value -> Exp valueToExp (Block s as es) = AppE (AppE (AppE (ConE (mkName "Block")) (valueToExp s)) (ListE (map patternToExp as))) (ListE (map exprToExp es)) valueToExp (Char c) = AppE (ConE (mkName "Char")) (LitE (CharL c)) valueToExp (Double d) = AppE (ConE (mkName "Double")) (LitE (RationalL (toRational d))) valueToExp (Expression e) = AppE (ConE (mkName "Expression")) (exprToExp e) valueToExp (Integer i) = AppE (ConE (mkName "Integer")) (LitE (IntegerL i)) valueToExp (Message m) = AppE (ConE (mkName "Message")) (messageToExp m) valueToExp (Particle p) = AppE (ConE (mkName "Particle")) (particleToExp p) valueToExp (Pattern p) = AppE (ConE (mkName "Pattern")) (patternToExp p) valueToExp (String s) = AppE (VarE (mkName "string")) (LitE (StringL (T.unpack s))) valueToExp v = error $ "no valueToExp for: " ++ show v patternToExp :: Pattern -> Exp patternToExp PAny = ConE (mkName "PAny") patternToExp (PHeadTail h t) = AppE (AppE (ConE (mkName "PHeadTail")) (patternToExp h)) (patternToExp t) patternToExp (PKeyword i ns ts) = AppE (AppE (AppE (ConE (mkName "PKeyword")) (LitE (IntegerL (fromIntegral i)))) (ListE (map (LitE . StringL) ns))) (ListE (map patternToExp ts)) patternToExp (PList ps) = AppE (ConE (mkName "PList")) (ListE (map patternToExp ps)) patternToExp (PMatch v) = AppE (ConE (mkName "PMatch")) (valueToExp v) patternToExp (PNamed n p) = AppE (AppE (ConE (mkName "PNamed")) (LitE (StringL n))) (patternToExp p) patternToExp (PObject e) = AppE (ConE (mkName "PObject")) (exprToExp e) patternToExp (PPMSingle n) = AppE (ConE (mkName "PPMSingle")) (LitE (StringL n)) patternToExp (PPMKeyword ns ts) = AppE (AppE (ConE (mkName "PPMKeyword")) (ListE (map (LitE . StringL) ns))) (ListE (map patternToExp ts)) patternToExp PSelf = ConE (mkName "PSelf") patternToExp (PSingle i n t) = AppE (AppE (AppE (ConE (mkName "PSingle")) (LitE (IntegerL (fromIntegral i)))) (LitE (StringL n))) (patternToExp t)