Import hs-plugins cvs
This commit is contained in:
17
examples/README
Normal file
17
examples/README
Normal file
@ -0,0 +1,17 @@
|
||||
These examples illustrate the various uses of hs-plugins.
|
||||
|
||||
conf a configuration file edsl using plugins
|
||||
dynload dynamically typed load
|
||||
eval runtime evaluation of haskell strings, from Haskell and C
|
||||
hmake the 'plugs' haskell interpreter
|
||||
iface test the interface file parser
|
||||
load load a plugin
|
||||
make build a Haskell file
|
||||
makewith merge and build a Haskell file
|
||||
multi load multiple plugins at once
|
||||
objc load Haskell plugins into object C programs
|
||||
pkgconf test package.conf parsing
|
||||
popen test popen
|
||||
reload reload a plugin when it changes
|
||||
shell a simple string filter
|
||||
unload test unloading of plugins
|
45
examples/TIMINGS
Normal file
45
examples/TIMINGS
Normal file
@ -0,0 +1,45 @@
|
||||
Method:
|
||||
* "pdynload"
|
||||
comes from pdynload/small
|
||||
* "load + ghc"
|
||||
comes from pdynload/null, with lines 13-14
|
||||
uncommented from prog/Main.hs
|
||||
* "dynload"
|
||||
from dynload/simple
|
||||
* "load, no check"
|
||||
from pdynload/null, with lines 13-14 of prog/Main.hs
|
||||
commented out
|
||||
|
||||
For example, to run the "pdynload" test:
|
||||
$ cd pdynload/small
|
||||
$ make
|
||||
$ make check # to prime caches, etc.
|
||||
$ time make check
|
||||
$ time make check
|
||||
$ time make check # run 'time make check' until value converges
|
||||
|
||||
The converged value is entered into the "Raw" timings, and then the
|
||||
scaled timing is calculated for each machine. These scaled values were
|
||||
then averaged over the number of machines, yielding the final
|
||||
"Average" scores -- the average over a number of machines and os.
|
||||
|
||||
Raw timing:
|
||||
pdynload load+ghc dynload load, no check
|
||||
|
||||
0.33 0.25 0.22 0.21 -- P4 2.6 , OpenBSD
|
||||
0.38 0.31 0.29 0.27 -- P4 2.66, Linux
|
||||
0.84 0.77 0.64 0.55 -- Quad P4 2.4, Linux
|
||||
0.76 0.60 0.52 0.50 -- AMD 1.1G, Linux
|
||||
0.95 0.83 0.75 0.72 -- G5 2.0G, Mac OS X
|
||||
-- Quad Itanium 1,Linux
|
||||
|
||||
Scaled:
|
||||
1.57 1.19 1.05 1
|
||||
1.40 1.15 1.07
|
||||
1.52 1.4 1.16
|
||||
1.52 1.2 1.04
|
||||
1.32 1.15 1.04
|
||||
|
||||
Average:
|
||||
=1.46 = 1.218 = 1.07
|
||||
|
41
examples/build.mk
Normal file
41
examples/build.mk
Normal file
@ -0,0 +1,41 @@
|
||||
# how to build the default projects
|
||||
|
||||
include $(TOP)/config.mk
|
||||
include $(TOP)/examples/check.mk
|
||||
|
||||
BIN= prog/a.out
|
||||
OBJ= prog/Main.o
|
||||
SRC= prog/Main.hs
|
||||
|
||||
BINDIR= prog
|
||||
REALBIN= ./a.out
|
||||
|
||||
API_OBJ= api/API.o
|
||||
|
||||
INCLUDES= -i$(TOP)/examples/$(TEST)/api
|
||||
PKGFLAGS= -package-conf $(TOP)/plugins.conf.inplace -package plugins
|
||||
GHCFLAGS= -Onot -cpp -fglasgow-exts
|
||||
|
||||
.SUFFIXES : .o .hs .hi .lhs .hc .s
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN) : $(PRIOR_OBJS) $(API_OBJ) $(SRC) $(EXTRA_OBJS)
|
||||
@rm -f $@
|
||||
@$(GHC) --make -o $@ $(INCLUDES) $(PKGFLAGS) $(GHCFLAGS) $(EXTRAFLAGS) $(API) $(SRC)
|
||||
|
||||
# Standard suffix rules
|
||||
.o.hi:
|
||||
@:
|
||||
.hs.o:
|
||||
@$(GHC) $(INCLUDES) $(PKGFLAGS) $(GHCFLAGS) $(EXTRAFLAGS) -c $<
|
||||
|
||||
clean:
|
||||
find . -name '*~' -exec rm {} \;
|
||||
rm -rf *.{o,hi,dep}
|
||||
rm -rf */*.{hi,o,old} */a.out
|
||||
rm -rf */*core
|
||||
rm -rf */*.a
|
||||
rm -rf */package.conf
|
||||
rm -rf *.a
|
||||
|
24
examples/check.mk
Normal file
24
examples/check.mk
Normal file
@ -0,0 +1,24 @@
|
||||
include $(TOP)/config.mk
|
||||
|
||||
check: $(BIN)
|
||||
@(cd $(BINDIR) ;\
|
||||
expected="expected" ;\
|
||||
if [ -f "expected" -o -f "expected.$(GLASGOW_HASKELL)" ] ;\
|
||||
then \
|
||||
actual_out="/tmp/hs-plugins-actual.out.$$$$" ;\
|
||||
diff_out="/tmp/hs-plugins.diff.$$$$" ;\
|
||||
$(REALBIN) > $$actual_out 2>&1 || true ;\
|
||||
if [ -f "expected.$(GLASGOW_HASKELL)" ] ; then \
|
||||
expected="expected.$(GLASGOW_HASKELL)" ;\
|
||||
fi ;\
|
||||
diff -u $$expected $$actual_out > $$diff_out || true ;\
|
||||
if [ -s "$$diff_out" ] ; then \
|
||||
echo "failed with:" ;\
|
||||
cat "$$diff_out" | sed '1,3d' ;\
|
||||
else \
|
||||
echo "ok." ;\
|
||||
fi ;\
|
||||
rm $$actual_out $$diff_out ;\
|
||||
else \
|
||||
$(REALBIN) 2>&1 || true ;\
|
||||
fi)
|
11
examples/conf/simple/Mailrc.conf
Normal file
11
examples/conf/simple/Mailrc.conf
Normal file
@ -0,0 +1,11 @@
|
||||
import System.Directory
|
||||
|
||||
resource = mail {
|
||||
-- editor = do b <- doesFileExist "/usr/bin/emacs"
|
||||
-- return $ if b then "emacs" else "vi" ,
|
||||
editor = do b <- doesFileExist "/bin/sh"
|
||||
return "sh",
|
||||
|
||||
attribution = \name -> "Today, "++name++" wrote :"
|
||||
}
|
||||
|
28
examples/conf/simple/Mailrc.stub
Normal file
28
examples/conf/simple/Mailrc.stub
Normal file
@ -0,0 +1,28 @@
|
||||
module Mailrc ( resource ) where
|
||||
|
||||
import API
|
||||
|
||||
resource :: Interface
|
||||
resource = mail
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
4
examples/conf/simple/Makefile
Normal file
4
examples/conf/simple/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
TEST= conf/simple
|
||||
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
27
examples/conf/simple/api/API.hs
Normal file
27
examples/conf/simple/api/API.hs
Normal file
@ -0,0 +1,27 @@
|
||||
--
|
||||
-- the configuration file interface.
|
||||
--
|
||||
|
||||
module API where
|
||||
|
||||
data Color = Black | Grey | Green | Cyan | Yellow | Magenta | Red
|
||||
|
||||
data Interface = Interface {
|
||||
editor :: IO String,
|
||||
attribution :: String -> String,
|
||||
header_color :: Color,
|
||||
colorize :: [String],
|
||||
include :: Bool
|
||||
}
|
||||
|
||||
-- Default settings
|
||||
mail :: Interface
|
||||
mail = Interface {
|
||||
editor = return "vi",
|
||||
|
||||
attribution = (\user -> user ++ " wrote:"),
|
||||
header_color = Grey,
|
||||
colorize = [],
|
||||
include = True
|
||||
}
|
||||
|
22
examples/conf/simple/prog/Main.hs
Normal file
22
examples/conf/simple/prog/Main.hs
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
conf = "../Mailrc.conf"
|
||||
stub = "../Mailrc.stub"
|
||||
apipath = "../api"
|
||||
|
||||
main = do
|
||||
status <- makeWith conf stub ["-i"++apipath]
|
||||
o <- case status of
|
||||
MakeFailure e -> mapM_ putStrLn e >> error "failed"
|
||||
MakeSuccess _ o -> return o
|
||||
status <- load o [apipath] [] "resource"
|
||||
v <- case status of
|
||||
LoadFailure err -> mapM_ putStrLn err >> error "no"
|
||||
LoadSuccess _ v -> return v
|
||||
|
||||
user_editor <- editor v
|
||||
putStrLn user_editor
|
||||
makeCleaner o
|
||||
|
1
examples/conf/simple/prog/expected
Normal file
1
examples/conf/simple/prog/expected
Normal file
@ -0,0 +1 @@
|
||||
sh
|
6
examples/dynload/io/Makefile
Normal file
6
examples/dynload/io/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
TEST=dynload/io
|
||||
|
||||
EXTRA_OBJS=TestIO.o
|
||||
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
86
examples/dynload/io/TestIO.hs
Normal file
86
examples/dynload/io/TestIO.hs
Normal file
@ -0,0 +1,86 @@
|
||||
{-# OPTIONS -fglasgow-exts -cpp #-}
|
||||
--
|
||||
-- Copyright (c) 2004 Don Stewart - http://www.cse.unsw.edu.au/~dons
|
||||
-- LGPL version 2.1 or later (see http://www.gnu.org/copyleft/lesser.html)
|
||||
--
|
||||
|
||||
module TestIO ( resource_dyn ) where
|
||||
|
||||
import API
|
||||
import AltData
|
||||
|
||||
import System.IO
|
||||
import System.Posix.Types ( ProcessID, Fd )
|
||||
import System.Posix.Process ( forkProcess, executeFile, getProcessID )
|
||||
import System.Posix.IO ( createPipe, stdInput,
|
||||
stdOutput, fdToHandle, closeFd, dupTo )
|
||||
|
||||
resource_dyn :: Dynamic
|
||||
resource_dyn = toDyn resource
|
||||
|
||||
resource :: TestIO
|
||||
resource = testio { field = date }
|
||||
|
||||
|
||||
--
|
||||
-- call a shell command , returning it's output
|
||||
--
|
||||
date :: IO String
|
||||
date = do (hdl,_,_) <- catch (popen "/bin/date") (\_->error "popen failed")
|
||||
hGetLine hdl
|
||||
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- my implementation of $val = `cmd`; (if this was perl)
|
||||
--
|
||||
-- provide similar functionality to popen(3),
|
||||
-- along with bidirectional ipc via pipes
|
||||
-- return's the pid of the child process
|
||||
--
|
||||
-- there are two different forkProcess functions. the pre-620 was a
|
||||
-- unix-fork style function, and the modern function has semantics more
|
||||
-- like the Awkward-Squad paper. We provide implementations of popen
|
||||
-- using both versions, depending on which GHC the user wants to try.
|
||||
--
|
||||
|
||||
popen :: FilePath -> IO (Handle, Handle, ProcessID)
|
||||
popen cmd = do
|
||||
(pr, pw) <- createPipe
|
||||
(cr, cw) <- createPipe
|
||||
|
||||
-- parent --
|
||||
let parent = do closeFd cw
|
||||
closeFd pr
|
||||
-- child --
|
||||
let child = do closeFd pw
|
||||
closeFd cr
|
||||
exec cmd (pr,cw)
|
||||
error "exec cmd failed!" -- typing only
|
||||
|
||||
-- if the parser front end understood cpp, this would work
|
||||
-- #if __GLASGOW_HASKELL__ >= 601
|
||||
pid <- forkProcess child -- fork child
|
||||
parent -- and run parent code
|
||||
-- #else
|
||||
-- p <- forkProcess
|
||||
-- pid <- case p of
|
||||
-- Just pid -> parent >> return pid
|
||||
-- Nothing -> child
|
||||
-- #endif
|
||||
|
||||
hcr <- fdToHandle cr
|
||||
hpw <- fdToHandle pw
|
||||
|
||||
return (hcr,hpw,pid)
|
||||
|
||||
--
|
||||
-- execve cmd in the child process, dup'ing the file descriptors passed
|
||||
-- as arguments to become the child's stdin and stdout.
|
||||
--
|
||||
exec :: FilePath -> (Fd,Fd) -> IO ()
|
||||
exec cmd (pr,cw) = do
|
||||
dupTo pr stdInput
|
||||
dupTo cw stdOutput
|
||||
executeFile cmd False [] Nothing
|
||||
|
||||
------------------------------------------------------------------------
|
19
examples/dynload/io/api/API.hs
Normal file
19
examples/dynload/io/api/API.hs
Normal file
@ -0,0 +1,19 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module API where
|
||||
|
||||
import AltData
|
||||
|
||||
data TestIO = TestIO {
|
||||
field :: IO String
|
||||
}
|
||||
|
||||
instance Typeable TestIO where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf i = mkTyConApp (mkTyCon "API.TestIO") []
|
||||
#else
|
||||
typeOf i = mkAppTy (mkTyCon "API.TestIO") []
|
||||
#endif
|
||||
|
||||
testio :: TestIO
|
||||
testio = TestIO { field = return "default value" }
|
12
examples/dynload/io/prog/Main.hs
Normal file
12
examples/dynload/io/prog/Main.hs
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
main = do
|
||||
m_v <- dynload "../TestIO.o" ["../api"]
|
||||
["../../../../plugins.conf.inplace"] "resource_dyn"
|
||||
case m_v of
|
||||
LoadFailure _ -> error "couldn't compile"
|
||||
LoadSuccess _ v -> do
|
||||
s <- field v
|
||||
if s /= [] then print True else print False
|
1
examples/dynload/io/prog/expected
Normal file
1
examples/dynload/io/prog/expected
Normal file
@ -0,0 +1 @@
|
||||
True
|
4
examples/dynload/poly/Makefile
Normal file
4
examples/dynload/poly/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
TEST=dynload/poly
|
||||
EXTRA_OBJS=Plugin.o
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
12
examples/dynload/poly/Plugin.hs
Normal file
12
examples/dynload/poly/Plugin.hs
Normal file
@ -0,0 +1,12 @@
|
||||
module Plugin where
|
||||
|
||||
import API
|
||||
import AltData
|
||||
|
||||
my_fun = plugin {
|
||||
equals = \x y -> (x /= y) -- a strange equals function :)
|
||||
}
|
||||
|
||||
resource_dyn :: Dynamic
|
||||
resource_dyn = toDyn my_fun
|
||||
|
24
examples/dynload/poly/api/API.hs
Normal file
24
examples/dynload/poly/api/API.hs
Normal file
@ -0,0 +1,24 @@
|
||||
{-# OPTIONS -cpp #-}
|
||||
|
||||
module API where
|
||||
|
||||
import AltData
|
||||
|
||||
data Interface = Interface {
|
||||
equals :: forall t. Eq t => t -> t -> Bool
|
||||
}
|
||||
|
||||
--
|
||||
-- see how it hides the internal type.. but to compile GHC still checks
|
||||
-- the type.
|
||||
--
|
||||
instance Typeable Interface where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf i = mkTyConApp (mkTyCon "API.Interface") []
|
||||
#else
|
||||
typeOf i = mkAppTy (mkTyCon "API.Interface") []
|
||||
#endif
|
||||
|
||||
plugin :: Interface
|
||||
plugin = Interface { equals = (==) }
|
||||
|
17
examples/dynload/poly/prog/Main.hs
Normal file
17
examples/dynload/poly/prog/Main.hs
Normal file
@ -0,0 +1,17 @@
|
||||
{-# OPTIONS -cpp #-}
|
||||
|
||||
#include "../../../../config.h"
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
main = do
|
||||
m_v <- dynload "../Plugin.o" ["../api"]
|
||||
["../../../../plugins.conf.inplace"]
|
||||
"resource_dyn"
|
||||
case m_v of
|
||||
LoadFailure _ -> error "didn't compile"
|
||||
LoadSuccess _ (Interface eq) -> do
|
||||
putStrLn $ show $ 1 `eq` 2
|
||||
putStrLn $ show $ 'a' `eq` 'b'
|
||||
|
2
examples/dynload/poly/prog/expected
Normal file
2
examples/dynload/poly/prog/expected
Normal file
@ -0,0 +1,2 @@
|
||||
True
|
||||
True
|
4
examples/dynload/should_fail/Makefile
Normal file
4
examples/dynload/should_fail/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
TEST= dynload/should_fail
|
||||
EXTRA_OBJS=Plugin.o
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
12
examples/dynload/should_fail/Plugin.hs
Normal file
12
examples/dynload/should_fail/Plugin.hs
Normal file
@ -0,0 +1,12 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
module Plugin where
|
||||
|
||||
import API
|
||||
import AltData
|
||||
|
||||
v :: Int
|
||||
v = 0xdeadbeef
|
||||
|
||||
resource_dyn :: Dynamic
|
||||
resource_dyn = toDyn v
|
||||
|
20
examples/dynload/should_fail/api/API.hs
Normal file
20
examples/dynload/should_fail/api/API.hs
Normal file
@ -0,0 +1,20 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module API where
|
||||
|
||||
import AltData
|
||||
|
||||
data Interface = Interface {
|
||||
function :: String
|
||||
}
|
||||
|
||||
instance Typeable Interface where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf i = mkTyConApp (mkTyCon "API.Interface") []
|
||||
#else
|
||||
typeOf i = mkAppTy (mkTyCon "API.Interface") []
|
||||
#endif
|
||||
|
||||
plugin :: Interface
|
||||
plugin = Interface { function = "goodbye" }
|
||||
|
14
examples/dynload/should_fail/prog/Main.hs
Normal file
14
examples/dynload/should_fail/prog/Main.hs
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
main = do
|
||||
m_v <- dynload "../Plugin.o"
|
||||
["../api"]
|
||||
["../../../../plugins.conf.inplace"]
|
||||
"resource_dyn"
|
||||
|
||||
case m_v of
|
||||
LoadFailure _ -> putStrLn "didn't compile"
|
||||
LoadSuccess _ v -> putStrLn $ function v
|
||||
|
4
examples/dynload/should_fail/prog/expected
Normal file
4
examples/dynload/should_fail/prog/expected
Normal file
@ -0,0 +1,4 @@
|
||||
Couldn't match `API.Interface' against `Int'
|
||||
Expected type: API.Interface
|
||||
Inferred type: Int
|
||||
didn't compile
|
4
examples/dynload/should_fail_1/Makefile
Normal file
4
examples/dynload/should_fail_1/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
TEST= dynload/should_fail_1
|
||||
EXTRA_OBJS=Plugin.o
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
15
examples/dynload/should_fail_1/Plugin.hs
Normal file
15
examples/dynload/should_fail_1/Plugin.hs
Normal file
@ -0,0 +1,15 @@
|
||||
--
|
||||
-- trying to be really mean.
|
||||
--
|
||||
|
||||
module Plugin where
|
||||
|
||||
import API
|
||||
import AltData
|
||||
|
||||
v :: Int -> Int
|
||||
v = \x -> 0xdeadbeef
|
||||
|
||||
resource_dyn :: Dynamic
|
||||
resource_dyn = toDyn v
|
||||
|
20
examples/dynload/should_fail_1/api/API.hs
Normal file
20
examples/dynload/should_fail_1/api/API.hs
Normal file
@ -0,0 +1,20 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module API where
|
||||
|
||||
import AltData
|
||||
|
||||
data Interface = Interface {
|
||||
function :: String
|
||||
}
|
||||
|
||||
instance Typeable Interface where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf i = mkTyConApp (mkTyCon "API.Interface") []
|
||||
#else
|
||||
typeOf i = mkAppTy (mkTyCon "API.Interface") []
|
||||
#endif
|
||||
|
||||
plugin :: Interface
|
||||
plugin = Interface { function = "goodbye" }
|
||||
|
11
examples/dynload/should_fail_1/prog/Main.hs
Normal file
11
examples/dynload/should_fail_1/prog/Main.hs
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
main = do
|
||||
m_v <- dynload "../Plugin.o" ["../api"]
|
||||
["../../../../plugins.conf.inplace"] "resource_dyn"
|
||||
case m_v of
|
||||
LoadFailure _ -> putStrLn "didn't compile"
|
||||
LoadSuccess _ v -> putStrLn $ (function v)
|
||||
|
4
examples/dynload/should_fail_1/prog/expected
Normal file
4
examples/dynload/should_fail_1/prog/expected
Normal file
@ -0,0 +1,4 @@
|
||||
Couldn't match `API.Interface' against `Int -> Int'
|
||||
Expected type: API.Interface
|
||||
Inferred type: Int -> Int
|
||||
didn't compile
|
4
examples/dynload/should_fail_2/Makefile
Normal file
4
examples/dynload/should_fail_2/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
TEST= dynload/should_fail_2
|
||||
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
19
examples/dynload/should_fail_2/Plugin.in
Normal file
19
examples/dynload/should_fail_2/Plugin.in
Normal file
@ -0,0 +1,19 @@
|
||||
--
|
||||
-- the plugin doesn't even make the resource_dyn a Dynamic.
|
||||
--
|
||||
-- let's hope that makeWith strips out the invalid declarations
|
||||
--
|
||||
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module Plugin where
|
||||
|
||||
import API
|
||||
import AltData
|
||||
import GHC.Base
|
||||
|
||||
v :: Int
|
||||
v = 0xdeadbeef
|
||||
|
||||
resource_dyn = (typeOf v, unsafeCoerce v)
|
||||
|
12
examples/dynload/should_fail_2/Plugin.stub
Normal file
12
examples/dynload/should_fail_2/Plugin.stub
Normal file
@ -0,0 +1,12 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module Plugin ( resource_dyn ) where
|
||||
|
||||
import API
|
||||
import AltData
|
||||
|
||||
resource = plugin
|
||||
|
||||
resource_dyn :: Dynamic
|
||||
resource_dyn = toDyn resource
|
||||
|
22
examples/dynload/should_fail_2/api/API.hs
Normal file
22
examples/dynload/should_fail_2/api/API.hs
Normal file
@ -0,0 +1,22 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module API where
|
||||
|
||||
import AltData
|
||||
import GHC.Base
|
||||
|
||||
data Interface = Interface {
|
||||
function :: String
|
||||
}
|
||||
|
||||
instance Typeable Interface where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf i = mkTyConApp (mkTyCon "API.Interface") []
|
||||
#else
|
||||
typeOf i = mkAppTy (mkTyCon "API.Interface") []
|
||||
#endif
|
||||
|
||||
plugin :: Interface
|
||||
plugin = Interface { function = "goodbye" }
|
||||
|
||||
unsafeCoerce = unsafeCoerce#
|
19
examples/dynload/should_fail_2/prog/Main.hs
Normal file
19
examples/dynload/should_fail_2/prog/Main.hs
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
conf = "../Plugin.in"
|
||||
stub = "../Plugin.stub"
|
||||
|
||||
main = do
|
||||
status <- makeWith conf stub ["-i../api", "-i../../../../src/altdata/"]
|
||||
case status of
|
||||
MakeFailure e -> mapM_ putStrLn e >> putStrLn "failed"
|
||||
MakeSuccess _ o -> do {
|
||||
; m_v <- dynload o ["../api"] [] "resource_dyn"
|
||||
; makeCleaner o
|
||||
; case m_v of
|
||||
LoadFailure _ -> putStrLn "didn't load"
|
||||
LoadSuccess _ v -> putStrLn $ (function v)
|
||||
}
|
||||
|
8
examples/dynload/should_fail_2/prog/expected
Normal file
8
examples/dynload/should_fail_2/prog/expected
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
../Plugin.in:18:
|
||||
Couldn't match `Dynamic' against `(t, t1)'
|
||||
Expected type: Dynamic
|
||||
Inferred type: (t, t1)
|
||||
In the definition of `resource_dyn':
|
||||
resource_dyn = (typeOf v, unsafeCoerce v)
|
||||
failed
|
7
examples/dynload/should_fail_2/prog/expected.604
Normal file
7
examples/dynload/should_fail_2/prog/expected.604
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
../Plugin.in:18:15:
|
||||
Couldn't match `Dynamic' against `(a, b)'
|
||||
Expected type: Dynamic
|
||||
Inferred type: (a, b)
|
||||
In the definition of `resource_dyn': resource_dyn = (typeOf v, unsafeCoerce v)
|
||||
failed
|
4
examples/dynload/should_fail_3/Makefile
Normal file
4
examples/dynload/should_fail_3/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
TEST= dynload/should_fail_3
|
||||
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
19
examples/dynload/should_fail_3/Plugin.in
Normal file
19
examples/dynload/should_fail_3/Plugin.in
Normal file
@ -0,0 +1,19 @@
|
||||
--
|
||||
-- the plugin doesn't even make the resource_dyn a Dynamic.
|
||||
-- let's hope that makeWith strips out the invalid declarations
|
||||
--
|
||||
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module Plugin where
|
||||
|
||||
import API
|
||||
|
||||
import AltData
|
||||
import GHC.Base
|
||||
|
||||
v :: Int
|
||||
v = 0xdeadbeef
|
||||
|
||||
resource_dyn = (typeOf plugin, unsafeCoerce v)
|
||||
|
12
examples/dynload/should_fail_3/Plugin.stub
Normal file
12
examples/dynload/should_fail_3/Plugin.stub
Normal file
@ -0,0 +1,12 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
|
||||
module Plugin ( resource_dyn ) where
|
||||
|
||||
import API
|
||||
import AltData.Dynamic
|
||||
|
||||
resource = plugin
|
||||
|
||||
resource_dyn :: Dynamic
|
||||
resource_dyn = toDyn resource
|
||||
|
22
examples/dynload/should_fail_3/api/API.hs
Normal file
22
examples/dynload/should_fail_3/api/API.hs
Normal file
@ -0,0 +1,22 @@
|
||||
{-# OPTIONS -cpp -fglasgow-exts #-}
|
||||
|
||||
module API where
|
||||
|
||||
import AltData
|
||||
import GHC.Base
|
||||
|
||||
data Interface = Interface {
|
||||
function :: String
|
||||
}
|
||||
|
||||
instance Typeable Interface where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf _ = mkTyConApp (mkTyCon "API.Interface") []
|
||||
#else
|
||||
typeOf _ = mkAppTy (mkTyCon "API.Interface") []
|
||||
#endif
|
||||
|
||||
plugin :: Interface
|
||||
plugin = Interface { function = "goodbye" }
|
||||
|
||||
unsafeCoerce = unsafeCoerce#
|
18
examples/dynload/should_fail_3/prog/Main.hs
Normal file
18
examples/dynload/should_fail_3/prog/Main.hs
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
conf = "../Plugin.in"
|
||||
stub = "../Plugin.stub"
|
||||
|
||||
main = do
|
||||
status <- makeWith conf stub ["-i../api", "-i../../../../src/altdata"]
|
||||
o <- case status of
|
||||
MakeFailure e -> mapM_ putStrLn e >> error "failed"
|
||||
MakeSuccess _ o -> return o
|
||||
m_v <- dynload o ["../api"] [] "resource_dyn"
|
||||
case m_v of
|
||||
LoadFailure _ -> error "didn't compile"
|
||||
LoadSuccess _ v -> do putStrLn $ (function v)
|
||||
makeCleaner o
|
||||
|
9
examples/dynload/should_fail_3/prog/expected
Normal file
9
examples/dynload/should_fail_3/prog/expected
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
../Plugin.in:18:
|
||||
Couldn't match `Dynamic' against `(t, t1)'
|
||||
Expected type: Dynamic
|
||||
Inferred type: (t, t1)
|
||||
In the definition of `resource_dyn':
|
||||
resource_dyn = (typeOf plugin, unsafeCoerce v)
|
||||
|
||||
Fail: failed
|
8
examples/dynload/should_fail_3/prog/expected.604
Normal file
8
examples/dynload/should_fail_3/prog/expected.604
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
../Plugin.in:18:15:
|
||||
Couldn't match `Dynamic' against `(a, b)'
|
||||
Expected type: Dynamic
|
||||
Inferred type: (a, b)
|
||||
In the definition of `resource_dyn':
|
||||
resource_dyn = (typeOf plugin, unsafeCoerce v)
|
||||
a.out: failed
|
4
examples/dynload/simple/Makefile
Normal file
4
examples/dynload/simple/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
TEST=dynload/simple
|
||||
EXTRA_OBJS=Plugin.o
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
11
examples/dynload/simple/Plugin.hs
Normal file
11
examples/dynload/simple/Plugin.hs
Normal file
@ -0,0 +1,11 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
module Plugin where
|
||||
|
||||
import API
|
||||
import AltData
|
||||
|
||||
my_fun = plugin { function = "plugin says \"hello\"" }
|
||||
|
||||
resource_dyn :: Dynamic
|
||||
resource_dyn = toDyn my_fun
|
||||
|
20
examples/dynload/simple/api/API.hs
Normal file
20
examples/dynload/simple/api/API.hs
Normal file
@ -0,0 +1,20 @@
|
||||
{-# OPTIONS -cpp #-}
|
||||
|
||||
module API where
|
||||
|
||||
import AltData
|
||||
|
||||
data Interface = Interface {
|
||||
function :: String
|
||||
}
|
||||
|
||||
instance Typeable Interface where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf i = mkTyConApp (mkTyCon "API.Interface") []
|
||||
#else
|
||||
typeOf i = mkAppTy (mkTyCon "API.Interface") []
|
||||
#endif
|
||||
|
||||
plugin :: Interface
|
||||
plugin = Interface { function = "goodbye" }
|
||||
|
15
examples/dynload/simple/prog/Main.hs
Normal file
15
examples/dynload/simple/prog/Main.hs
Normal file
@ -0,0 +1,15 @@
|
||||
{-# OPTIONS -cpp #-}
|
||||
|
||||
#include "../../../../config.h"
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
|
||||
main = do
|
||||
m_v <- dynload "../Plugin.o" ["../api"]
|
||||
["../../../../plugins.conf.inplace"]
|
||||
"resource_dyn"
|
||||
case m_v of
|
||||
LoadFailure _ -> error "didn't compile"
|
||||
LoadSuccess _ v -> putStrLn $ (function v)
|
||||
|
1
examples/dynload/simple/prog/expected
Normal file
1
examples/dynload/simple/prog/expected
Normal file
@ -0,0 +1 @@
|
||||
plugin says "hello"
|
27
examples/eval.mk
Normal file
27
examples/eval.mk
Normal file
@ -0,0 +1,27 @@
|
||||
include $(TOP)/config.mk
|
||||
include $(TOP)/examples/check.mk
|
||||
|
||||
PKGFLAGS= -package-conf $(TOP)/plugins.conf.inplace -package eval -package plugins -package printf
|
||||
|
||||
BIN=a.out
|
||||
SRC=Main.hs
|
||||
|
||||
BINDIR= "."
|
||||
REALBIN= ./$(BIN)
|
||||
|
||||
.SUFFIXES : .o .hs .hi .lhs .hc .s
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN): $(SRC) $(OBJS)
|
||||
@rm -f $@
|
||||
@$(GHC) --make -fglasgow-exts $(GHCFLAGS) $(PKGFLAGS) $(EXTRAFLAGS) $(SRC)
|
||||
|
||||
# Standard suffix rules
|
||||
.o.hi:
|
||||
@:
|
||||
.hs.o:
|
||||
@$(GHC) $(INCLUDES) $(PKGFLAGS) $(GHCFLAGS) $(EXTRAFLAGS) -c $<
|
||||
|
||||
clean:
|
||||
rm -rf *.hi *.o *~ $(BIN)
|
5
examples/eval/eval1/Main.hs
Normal file
5
examples/eval/eval1/Main.hs
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
import Eval.Haskell
|
||||
|
||||
main = do i <- eval "1 + 6 :: Int" [] :: IO (Maybe Int)
|
||||
if isJust i then putStrLn $ show (fromJust i) else return ()
|
2
examples/eval/eval1/Makefile
Normal file
2
examples/eval/eval1/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../eval.mk
|
1
examples/eval/eval1/expected
Normal file
1
examples/eval/eval1/expected
Normal file
@ -0,0 +1 @@
|
||||
7
|
6
examples/eval/eval2/Main.hs
Normal file
6
examples/eval/eval2/Main.hs
Normal file
@ -0,0 +1,6 @@
|
||||
import Eval.Haskell
|
||||
|
||||
main = do m_s <- eval "map toUpper \"haskell\"" ["Data.Char"]
|
||||
case m_s of
|
||||
Nothing -> putStrLn "typechecking failed"
|
||||
Just s -> putStrLn s
|
2
examples/eval/eval2/Makefile
Normal file
2
examples/eval/eval2/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../eval.mk
|
1
examples/eval/eval2/expected
Normal file
1
examples/eval/eval2/expected
Normal file
@ -0,0 +1 @@
|
||||
HASKELL
|
42
examples/eval/eval3/Main.hs
Normal file
42
examples/eval/eval3/Main.hs
Normal file
@ -0,0 +1,42 @@
|
||||
{-# OPTIONS -cpp #-}
|
||||
--
|
||||
-- Should evaluate to '3', unless something goes wrong.
|
||||
--
|
||||
-- Not so bad to use AltData, as it is already derived for all the basic
|
||||
-- types. Then, just replace deriving Typeable, with hand-derived
|
||||
-- instance of Typeable (see hs-plugins/examples/eval/eval_fn1/Poly.hs
|
||||
--
|
||||
--
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
import Eval.Haskell
|
||||
import AltData.Dynamic
|
||||
|
||||
-- import Data.Dynamic
|
||||
|
||||
pkgconf = TOP ++ "/plugins.conf.inplace"
|
||||
|
||||
main = do
|
||||
a <- return $ toDyn (3::Int)
|
||||
|
||||
m_b <- unsafeEval_ "\\dyn -> fromMaybe (7 :: Int) (fromDyn dyn)"
|
||||
["AltData.Dynamic","Data.Maybe"] -- imports
|
||||
|
||||
[ "-package-conf "++pkgconf , "-package altdata" ]
|
||||
|
||||
[ pkgconf ]
|
||||
[]
|
||||
|
||||
|
||||
{-
|
||||
-- should work, but doesn't. type check fails
|
||||
-- (due to static vs dynamic typing issue)
|
||||
|
||||
m_b <- unsafeEval_ "\\dyn -> fromMaybe (7 :: Int) (fromDynamic dyn)"
|
||||
["Data.Dynamic","Data.Maybe"] [] []
|
||||
-}
|
||||
|
||||
case m_b of
|
||||
Left s -> mapM_ putStrLn s
|
||||
Right b -> putStrLn $ show (b a :: Int)
|
2
examples/eval/eval3/Makefile
Normal file
2
examples/eval/eval3/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../eval.mk
|
1
examples/eval/eval3/expected
Normal file
1
examples/eval/eval3/expected
Normal file
@ -0,0 +1 @@
|
||||
3
|
9
examples/eval/eval_/Main.hs
Normal file
9
examples/eval/eval_/Main.hs
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
import Eval.Haskell
|
||||
|
||||
main = do i <- eval_ "Just (7 :: Int)"
|
||||
["Maybe"]
|
||||
["-fglasgow-exts"]
|
||||
[]
|
||||
[] :: IO (Either [String] (Maybe (Maybe Int)))
|
||||
print i
|
2
examples/eval/eval_/Makefile
Normal file
2
examples/eval/eval_/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../eval.mk
|
1
examples/eval/eval_/expected
Normal file
1
examples/eval/eval_/expected
Normal file
@ -0,0 +1 @@
|
||||
Right (Just (Just 7))
|
10
examples/eval/eval_fn/Main.hs
Normal file
10
examples/eval/eval_fn/Main.hs
Normal file
@ -0,0 +1,10 @@
|
||||
--
|
||||
-- lambda abstraction!
|
||||
--
|
||||
--
|
||||
-- needs unsafeEval because eval has a broken Dynamic check
|
||||
--
|
||||
import Eval.Haskell
|
||||
|
||||
main = do fn <- unsafeEval "(\\(x::Int) -> (x,x))" [] :: IO (Maybe (Int -> (Int,Int)))
|
||||
when (isJust fn) $ putStrLn $ show $ (fromJust fn) 7
|
2
examples/eval/eval_fn/Makefile
Normal file
2
examples/eval/eval_fn/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../eval.mk
|
1
examples/eval/eval_fn/expected
Normal file
1
examples/eval/eval_fn/expected
Normal file
@ -0,0 +1 @@
|
||||
(7,7)
|
15
examples/eval/eval_fn1/Main.hs
Normal file
15
examples/eval/eval_fn1/Main.hs
Normal file
@ -0,0 +1,15 @@
|
||||
{-# OPTIONS -fglasgow-exts #-}
|
||||
--
|
||||
-- polymorphic eval!
|
||||
--
|
||||
|
||||
module Main where
|
||||
|
||||
import Poly
|
||||
import Eval.Haskell
|
||||
|
||||
main = do m_f <- eval "Fn (\\x y -> x == y)" ["Poly"]
|
||||
when (isJust m_f) $ do
|
||||
let (Fn f) = fromJust m_f
|
||||
putStrLn $ show (f True True)
|
||||
putStrLn $ show (f 1 2)
|
2
examples/eval/eval_fn1/Makefile
Normal file
2
examples/eval/eval_fn1/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../eval.mk
|
16
examples/eval/eval_fn1/Poly.hs
Normal file
16
examples/eval/eval_fn1/Poly.hs
Normal file
@ -0,0 +1,16 @@
|
||||
{-# OPTIONS -cpp -fglasgow-exts #-}
|
||||
module Poly where
|
||||
|
||||
import AltData.Typeable
|
||||
|
||||
data Fn = Fn {fn :: forall t. Eq t => t -> t -> Bool}
|
||||
|
||||
--
|
||||
-- ignore type inside the Fn... is this correct?
|
||||
--
|
||||
instance Typeable Fn where
|
||||
#if __GLASGOW_HASKELL__ >= 603
|
||||
typeOf _ = mkTyConApp (mkTyCon "Poly.Fn") []
|
||||
#else
|
||||
typeOf _ = mkAppTy (mkTyCon "Poly.Fn") []
|
||||
#endif
|
2
examples/eval/eval_fn1/expected
Normal file
2
examples/eval/eval_fn1/expected
Normal file
@ -0,0 +1,2 @@
|
||||
True
|
||||
False
|
2
examples/eval/foreign_eval/Makefile
Normal file
2
examples/eval/foreign_eval/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../foreign.mk
|
1
examples/eval/foreign_eval/README
Normal file
1
examples/eval/foreign_eval/README
Normal file
@ -0,0 +1 @@
|
||||
run a string of Haskell code from a C program.
|
1
examples/eval/foreign_eval/expected
Normal file
1
examples/eval/foreign_eval/expected
Normal file
@ -0,0 +1 @@
|
||||
10946
|
16
examples/eval/foreign_eval/main.c
Normal file
16
examples/eval/foreign_eval/main.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "EvalHaskell.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int *p;
|
||||
hs_init(&argc, &argv);
|
||||
p = hs_eval_i("let fibs = 1:1:zipWith (+) fibs (tail fibs) in fibs !! 20 :: Int");
|
||||
if (p == NULL)
|
||||
printf("failed!\n");
|
||||
else
|
||||
printf("%d\n",*p);
|
||||
hs_exit();
|
||||
return 0;
|
||||
}
|
2
examples/eval/foreign_eval1/Makefile
Normal file
2
examples/eval/foreign_eval1/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../foreign.mk
|
1
examples/eval/foreign_eval1/expected
Normal file
1
examples/eval/foreign_eval1/expected
Normal file
@ -0,0 +1 @@
|
||||
10946
|
16
examples/eval/foreign_eval1/main.c
Normal file
16
examples/eval/foreign_eval1/main.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "EvalHaskell.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *p;
|
||||
hs_init(&argc, &argv);
|
||||
p = hs_eval_s("show $ let fibs = 1:1:zipWith (+) fibs (tail fibs) in fibs !! 20");
|
||||
if (p == NULL)
|
||||
printf("failed!\n");
|
||||
else
|
||||
printf("%s\n",p);
|
||||
hs_exit();
|
||||
return 0;
|
||||
}
|
2
examples/eval/foreign_should_fail/Makefile
Normal file
2
examples/eval/foreign_should_fail/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../foreign.mk
|
2
examples/eval/foreign_should_fail/expected
Normal file
2
examples/eval/foreign_should_fail/expected
Normal file
@ -0,0 +1,2 @@
|
||||
<eval>:1: parse error on input `in'
|
||||
failed!
|
1
examples/eval/foreign_should_fail/expected.604
Normal file
1
examples/eval/foreign_should_fail/expected.604
Normal file
@ -0,0 +1 @@
|
||||
failed!
|
16
examples/eval/foreign_should_fail/main.c
Normal file
16
examples/eval/foreign_should_fail/main.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "EvalHaskell.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int *p;
|
||||
hs_init(&argc, &argv);
|
||||
p = hs_eval_i("show $ case 1 + 2 in{-wrong-} x -> x");
|
||||
if (p == NULL)
|
||||
printf("failed!\n");
|
||||
else
|
||||
printf("%d\n",*p);
|
||||
hs_exit();
|
||||
return 0;
|
||||
}
|
2
examples/eval/foreign_should_fail_illtyped/Makefile
Normal file
2
examples/eval/foreign_should_fail_illtyped/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../foreign.mk
|
4
examples/eval/foreign_should_fail_illtyped/expected
Normal file
4
examples/eval/foreign_should_fail_illtyped/expected
Normal file
@ -0,0 +1,4 @@
|
||||
Couldn't match `Int' against `[Char]'
|
||||
Expected type: Int
|
||||
Inferred type: [Char]
|
||||
failed!
|
1
examples/eval/foreign_should_fail_illtyped/expected.604
Normal file
1
examples/eval/foreign_should_fail_illtyped/expected.604
Normal file
@ -0,0 +1 @@
|
||||
failed!
|
16
examples/eval/foreign_should_fail_illtyped/main.c
Normal file
16
examples/eval/foreign_should_fail_illtyped/main.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "EvalHaskell.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int *p;
|
||||
hs_init(&argc, &argv);
|
||||
p = hs_eval_i("\"an ill-typed string\"");
|
||||
if (p == NULL)
|
||||
printf("failed!\n");
|
||||
else
|
||||
printf("%d\n",*p);
|
||||
hs_exit();
|
||||
return 0;
|
||||
}
|
16
examples/eval/unsafeidir/Main.hs
Normal file
16
examples/eval/unsafeidir/Main.hs
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
import Plugins.Make
|
||||
import Eval.Haskell
|
||||
|
||||
main = do make "a/Extra.hs" []
|
||||
|
||||
i <- unsafeEval_ "show (Just (1 + 6 :: Int)) ++ extra"
|
||||
["Data.Maybe", "Extra"]
|
||||
["-ia"] -- no make flags
|
||||
[] -- no package.confs
|
||||
["a"] -- include paths to load from
|
||||
:: IO (Either [String] String)
|
||||
|
||||
case i of
|
||||
Right i -> putStrLn $ show i
|
||||
Left es -> mapM_ putStrLn es
|
2
examples/eval/unsafeidir/Makefile
Normal file
2
examples/eval/unsafeidir/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
TOP=../../..
|
||||
include ../../eval.mk
|
3
examples/eval/unsafeidir/a/Extra.hs
Normal file
3
examples/eval/unsafeidir/a/Extra.hs
Normal file
@ -0,0 +1,3 @@
|
||||
module Extra where
|
||||
|
||||
extra = "an extra value"
|
1
examples/eval/unsafeidir/expected
Normal file
1
examples/eval/unsafeidir/expected
Normal file
@ -0,0 +1 @@
|
||||
"Just 7an extra value"
|
23
examples/foreign.mk
Normal file
23
examples/foreign.mk
Normal file
@ -0,0 +1,23 @@
|
||||
include $(TOP)/config.mk
|
||||
include $(TOP)/examples/check.mk
|
||||
|
||||
|
||||
INCLUDES= -I$(TOP)
|
||||
PKGFLAGS= -package-conf $(TOP)/plugins.conf.inplace -package eval
|
||||
|
||||
# compile with GHC to save us setting all the necessary include and
|
||||
# lib flags. use ghc -v to find out what these are if you wish to go
|
||||
# via gcc.
|
||||
BIN=./a.out
|
||||
SRC=main.c
|
||||
|
||||
BINDIR= "."
|
||||
REALBIN= $(BIN)
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN): $(SRC)
|
||||
@$(GHC) $(INCLUDES) $(PKGFLAGS) $(SRC)
|
||||
|
||||
clean:
|
||||
rm -rf *.hi *.o *~ $(BIN)
|
8
examples/hier/hier1/Makefile
Normal file
8
examples/hier/hier1/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
TEST= hier/hier1
|
||||
|
||||
EXTRA_OBJS=Plugin.o
|
||||
PRIOR_OBJS=Modules/Flags.o
|
||||
EXTRAFLAGS=
|
||||
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
15
examples/hier/hier1/Modules/Flags.hs
Normal file
15
examples/hier/hier1/Modules/Flags.hs
Normal file
@ -0,0 +1,15 @@
|
||||
--
|
||||
-- A simple module
|
||||
--
|
||||
|
||||
module Modules.Flags where
|
||||
|
||||
|
||||
data FlagRec = FlagRec {
|
||||
f1 :: Int,
|
||||
f2 :: Int
|
||||
}
|
||||
|
||||
|
||||
foo :: FlagRec -> Int
|
||||
foo x = f1 x
|
6
examples/hier/hier1/Modules/Makefile
Normal file
6
examples/hier/hier1/Modules/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
all:
|
||||
ghc -O -c Flags.hs
|
||||
|
||||
clean:
|
||||
rm -f *.hi *.o
|
14
examples/hier/hier1/Plugin.hs
Normal file
14
examples/hier/hier1/Plugin.hs
Normal file
@ -0,0 +1,14 @@
|
||||
--
|
||||
-- Plugin
|
||||
--
|
||||
|
||||
module Plugin where
|
||||
|
||||
import API
|
||||
import Modules.Flags as Flags
|
||||
|
||||
|
||||
resource = plugin {
|
||||
dbFunc = (\x -> Flags.f1 x)
|
||||
}
|
||||
|
16
examples/hier/hier1/api/API.hs
Normal file
16
examples/hier/hier1/api/API.hs
Normal file
@ -0,0 +1,16 @@
|
||||
--
|
||||
-- API for plugin test
|
||||
--
|
||||
|
||||
module API where
|
||||
|
||||
import Modules.Flags as Flags
|
||||
|
||||
data Interface = Interface {
|
||||
dbFunc :: Flags.FlagRec -> Int
|
||||
}
|
||||
|
||||
|
||||
plugin :: Interface
|
||||
plugin = Interface { dbFunc = (\x -> 1) }
|
||||
|
21
examples/hier/hier1/prog/Main.hs
Normal file
21
examples/hier/hier1/prog/Main.hs
Normal file
@ -0,0 +1,21 @@
|
||||
--
|
||||
-- Test multiple plugins
|
||||
--
|
||||
|
||||
|
||||
module Main where
|
||||
|
||||
import Plugins
|
||||
import API
|
||||
import Modules.Flags as Flags
|
||||
|
||||
|
||||
rec = Flags.FlagRec { Flags.f1 = 4, Flags.f2 = 10 }
|
||||
|
||||
|
||||
main = do
|
||||
status <- load "../Plugin.o" ["../api",".."] [] "resource"
|
||||
case status of
|
||||
LoadFailure _ -> error "load failed"
|
||||
LoadSuccess _ v -> do let func = dbFunc v
|
||||
print (func rec)
|
1
examples/hier/hier1/prog/expected
Normal file
1
examples/hier/hier1/prog/expected
Normal file
@ -0,0 +1 @@
|
||||
4
|
8
examples/hier/hier2/A/B/C/Module.hs
Normal file
8
examples/hier/hier2/A/B/C/Module.hs
Normal file
@ -0,0 +1,8 @@
|
||||
--
|
||||
-- A simple module
|
||||
--
|
||||
|
||||
module A.B.C.Module where
|
||||
|
||||
symbol = "You found me"
|
||||
|
7
examples/hier/hier2/A/Makefile
Normal file
7
examples/hier/hier2/A/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
all:
|
||||
ghc -c B/C/Module.hs
|
||||
|
||||
|
||||
clean:
|
||||
rm -f B/C/*.hi B/C/*.o
|
7
examples/hier/hier2/Makefile
Normal file
7
examples/hier/hier2/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
TEST= hier/hier2
|
||||
|
||||
PRIOR_OBJS=A/B/C/Module.o
|
||||
EXTRAFLAGS=
|
||||
|
||||
TOP=../../..
|
||||
include ../../build.mk
|
4
examples/hier/hier2/api/API.hs
Normal file
4
examples/hier/hier2/api/API.hs
Normal file
@ -0,0 +1,4 @@
|
||||
module API where
|
||||
|
||||
-- just a dummy for the build system
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user