Eq-1.1.1: Language/Eq/QuasiQuote.hs
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Language.Eq.Quasiquote( eqDefs ) where
import Language.Eq.Algorithm.Eval
import Language.Eq.Types
import Language.Eq.EvaluationContext
import Language.Eq.InputParser.EqCode
import qualified Data.Map as M
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax
-- | Quasi quote transforming Eq code into a symbol list
-- of type :: (String, Formula ListForm)
-- Usefull to prepare a pre-feed symbol table.
-- To use it, yout must use the following :
--
-- @
-- -- at the top of the file.
-- {-# LANGUAGE QuasiQuotes #-}
-- ...
-- -- in any expression
-- [eqDefs| myFunc(a,b) :> a ^ 2 + if(b < 0, 2, 3) |]
--
-- -- you can put several definitions
-- [eqDefs| myFunc(a,b) :> a ^ 2 + if(b < 0, 2, 3);
-- myOtherFunc(a) :> listFromTo(0, a) |]
-- @
--
-- Compilation will fail if an error is found in the eq
-- syntax, giving you a (rather succint) error message
-- with some position information in the quotation.
eqDefs :: QuasiQuoter
eqDefs = QuasiQuoter { quoteExp = symbolTableExtractor
, quotePat = undefined
, quoteType = undefined
, quoteDec = undefined
}
symbolTableExtractor :: String -> Q Exp
symbolTableExtractor str = case parseProgramm str of
Left err -> fail $ "Cannot parse the quasi quoted 'Eq' expression"
++ show err
Right flist -> [e| elemList |]
where elemList = M.assocs $ context info
info = performLastTransformationWithContext M.empty
$ mapM evalGlobalLosslessStatement flist
instance Lift Double where
lift d = return . LitE . DoublePrimL $ toRational d
instance Lift BinOperator where
lift = return . ConE . mkName . show
instance Lift UnOperator where
lift = return . ConE . mkName . show
instance Lift MetaOperation where
lift = return . ConE . mkName . show
instance Lift Entity where
lift = return . ConE . mkName . show
instance Lift (Formula ListForm) where
lift (Formula f) = [| Formula f |]
instance Lift (Formula TreeForm) where
lift (Formula f) = [| Formula f |]
instance Lift Rational where
lift = return . LitE . RationalL
instance Lift PolyCoeff where
lift (CoeffFloat f) = [| CoeffFloat f |]
lift (CoeffInt i) = [| CoeffInt i |]
lift (CoeffRatio r) = [| CoeffRatio r |]
instance Lift Polynome where
lift (Polynome s lst) = [| Polynome s lst |]
lift (PolyRest c) = [| PolyRest c |]
instance Lift FormulaPrim where
lift (Variable str) = [| Variable str |]
lift (NumEntity entity) = [| NumEntity entity |]
lift (Truth b) = [| Truth b |]
lift (CInteger i) = [| CInteger i |]
lift (CFloat f) = [| CFloat f |]
lift (Fraction r) = [| Fraction r |]
lift (Complex i (e1, e2)) = [| Complex i (e1, e2) |]
lift (Indexes i e el) = [| Indexes i e el |]
lift (List i el) = [| List i el |]
lift (App i e el) = [| App i e el |]
lift (Sum i e1 e2 e3) = [| Sum i e1 e2 e3 |]
lift (Product i e1 e2 e3) = [| Product i e1 e2 e3 |]
lift (Derivate i e1 e2) = [| Derivate i e1 e2 |]
lift (Integrate i e1 e2 e3 e4) = [| Integrate i e1 e2 e3 e4 |]
lift (UnOp i op e) = [| UnOp i op e |]
lift (Lambda i lst) = [| Lambda i lst |]
lift (BinOp i op el) = [| BinOp i op el |]
lift (Matrix i n m el) = [| Matrix i n m el |]
lift (Poly i p) = [| Poly i p |]
lift (Block i1 i2 i3) = [| Block i1 i2 i3 |]
lift (Meta i op sub) = [| Meta i op sub |]