Haskell bindings for duktape, a very compact embedded ECMAScript (JavaScript) engine.
Here's a simple REPL example:
module Main where
import Scripting.Duktape
import Control.Monad (forever)
import Data.ByteString.Char8 (pack)
import System.IO (hFlush, stdout)
main :: IO ()
main = do
dukm <- createDuktapeCtx
case dukm of
Nothing -> putStrLn "I can't even (start Duktape)"
Just duk -> forever $ do
putStr "duktape> "
hFlush stdout
retVal <- evalDuktape duk =<< return . pack =<< getLine
case retVal of
Left e -> putStrLn $ "Duktape error: " ++ e
Right Nothing -> putStrLn "No result"
Right (Just v) -> print v
Aeson's Value
type is used for exchanging values between Haskell and ECMAScript.
lens-aeson is a good library for working with Value
, um, values.
You can also call functions that are on the global object (or any object that's on the global object):
dukm <- createDuktapeCtx
bresult <- callDuktape (fromJust dukm) Nothing "boolTest" [Bool True, Bool True, Bool False] -- boolTest(true, true, false)
aresult <- callDuktape (fromJust dukm) (Just "NumFuns") "sum" [Number 1, Number 2] -- NumFuns.sum(1, 2)
And expose Haskell functions (same as with calls: set on global or a property of global):
dukm <- createDuktapeCtx
let dbl (Number x) = return $ Number $ x * 2 ∷ IO Value
dbl _ = return $ String "wtf"
reD ← exposeFnDuktape (fromJust ctx) Nothing "double" dbl
The functions must be of type IO ()
, IO Value
, Value -> IO Value
, Value -> Value -> IO Value
... and so on, up to 5 arguments.
If you need more, use an Object
Value
, seriously.
Use stack to build.
$ stack build
$ stack test && rm tests.tix
Please feel free to submit pull requests!
By participating in this project you agree to follow the Contributor Code of Conduct.
The list of contributors is available on GitHub.
Licensed under the MIT license (see to the LICENSE
file).
Haskell bindings: Copyright (c) 2015-2016 Greg V [email protected]
Duktape: Copyright (c) 2013-2016 by Duktape authors (see duktape/AUTHORS.rst)