aboutsummaryrefslogtreecommitdiffstats
path: root/src/Verismith/Verilog/Quote.hs
blob: 5e1e5dcf9bee4bb9dfc0000cf437750cc952206e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
{-|
Module      : Verismith.Verilog.Quote
Description : QuasiQuotation for verilog code in Haskell.
Copyright   : (c) 2019, Yann Herklotz Grave
License     : GPL-3
Maintainer  : yann [at] yannherklotz [dot] com
Stability   : experimental
Portability : POSIX

QuasiQuotation for verilog code in Haskell.
-}

{-# LANGUAGE TemplateHaskell #-}

module Verismith.Verilog.Quote
    ( verilog
    )
where

import           Data.Data
import qualified Data.Text                  as T
import qualified Language.Haskell.TH        as TH
import           Language.Haskell.TH.Quote
import           Language.Haskell.TH.Syntax
import           Verismith.Verilog.Parser
import Verismith.Verilog.AST (Verilog)

liftDataWithText :: Data a => a -> Q Exp
liftDataWithText = dataToExpQ $ fmap liftText . cast

liftText :: T.Text -> Q Exp
liftText txt = AppE (VarE 'T.pack) <$> lift (T.unpack txt)

-- | Quasiquoter for verilog, so that verilog can be written inline and be
-- parsed to an AST at compile time.
verilog :: QuasiQuoter
verilog = QuasiQuoter
    { quoteExp  = quoteVerilog
    , quotePat  = undefined
    , quoteType = undefined
    , quoteDec  = undefined
    }

quoteVerilog :: String -> TH.Q TH.Exp
quoteVerilog s = do
    loc <- TH.location
    let pos = T.pack $ TH.loc_filename loc
    v <- case parseVerilog pos (T.pack s) of
        Right e -> return e
        Left  e -> fail $ show e
    liftDataWithText (v :: Verilog ())