Přemysl Šťastný
Přemysl Šťastný

Reputation: 1832

How to compile QuasiQuoter during runtime?

I have a 'QuasiQuoter' which is useful in source code in Haskell, but also as a standalone application. So, I need to be able to run QuasiQuoter

  1. During the compile time in Haskell - [myGrammar|someCommand|]
  2. In runtime (runtime compilation) in shell - mygrammar 'someCommand'

The first part is easy but the second part might be a little clumsy if solved as calling the compiler with some generated code from the runtime.

I would like to solve a second part of the problem using some nice method in Haskell which doesn't accept only the source code, but accepts QuasyQuoter datatype instead so the code is less clumsy. But I can't find any compilation method like that.

Do you know any? Thanks.

Example of usage

Haskell

The function takes tuple [(a,b,c,d,e)] and returns a list of the strings with the products.

function = [lsql| {1..5}, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"|]

Bash

The command reads from stdin csv with at least 5 numerical columns and returns a list of their products (one per line).

lsql-csv '-, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"'

Upvotes: 1

Views: 159

Answers (1)

Daniel Wagner
Daniel Wagner

Reputation: 152682

I think the question is how to parse and process a string in a uniform way between a quasiquoter and some other chunk of code. If this interpretation is right, then you just... do that. For example:

-- implementation of these is left to the reader, but can use standard Haskell
-- programming techniques and libraries, like parsec and ADTs and stuff
command :: Parser Command
interpret :: Command -> IO ()
jit :: Command -> Exp -- or Q Exp

Then, in your lsql-csv.hs, you would write something like

main = do
    [s] <- getArgs
    case parse command s of
        Left err -> die (show err)
        Right com -> interpret com

and in your LSql/CSV/QQ.hs, you would write something like

lsql = QuasiQuoter { quoteExp = \s -> case parse command s of
    Left err -> qReport True (show err) >> fail ""
    Right com -> return (jit com) -- or just jit com if that's already a Q Exp
    }

Upvotes: 1

Related Questions