hruby 0.2.8 → 0.2.9
raw patch · 5 files changed
+94/−97 lines, 5 filesdep ~basesetup-changed
Dependency ranges changed: base
Files
- Foreign/Ruby/Bindings.hsc +24/−63
- Setup.hs +15/−8
- cbits/shim.h +25/−0
- hruby.cabal +5/−5
- test/roundtrip.hs +25/−21
Foreign/Ruby/Bindings.hsc view
@@ -1,6 +1,7 @@ {-# LANGUAGE ForeignFunctionInterface, FlexibleInstances, CPP #-} #include "shim.h"+#include <ruby.h> module Foreign.Ruby.Bindings where @@ -52,15 +53,6 @@ | RSYMBOL | RUNDEF | RNODE-#ifdef RUBY2- | RCOMPLEX- | RRATIONAL- | RZOMBIE-#else- | RBLKTAG- | RVARMAP- | RSCOPE-#endif deriving (Show) -- | Ruby native types, as encoded in the Value type.@@ -157,60 +149,29 @@ rtype :: RValue -> IO RType rtype v = rubyType v >>= \x -> case x of-#ifdef RUBY2- 0x00 -> return RUndef- 0x01 -> return (RBuiltin ROBJECT)- 0x02 -> return (RBuiltin RCLASS)- 0x03 -> return (RBuiltin RMODULE)- 0x04 -> return (RBuiltin RFLOAT)- 0x05 -> return (RBuiltin RSTRING)- 0x06 -> return (RBuiltin RREGEXP)- 0x07 -> return (RBuiltin RARRAY)- 0x08 -> return (RBuiltin RHASH)- 0x09 -> return (RBuiltin RSTRUCT)- 0x0a -> return (RBuiltin RBIGNUM)- 0x0b -> return (RBuiltin RFILE)- 0x0c -> return (RBuiltin RDATA)- 0x0d -> return (RBuiltin RMATCH)- 0x0e -> return (RBuiltin RCOMPLEX)- 0x0f -> return (RBuiltin RRATIONAL)- 0x11 -> return RNil- 0x12 -> return RTrue- 0x13 -> return RFalse- 0x14 -> return RSymbol- 0x15 -> return RFixNum- 0x1b -> return (RBuiltin RUNDEF)- 0x1c -> return (RBuiltin RNODE)- 0x1d -> return (RBuiltin RICLASS)- 0x1e -> return (RBuiltin RZOMBIE)-#else- 0x00 -> return RUndef- 0x01 -> return RNil- 0x02 -> return (RBuiltin ROBJECT)- 0x03 -> return (RBuiltin RCLASS)- 0x04 -> return (RBuiltin RICLASS)- 0x05 -> return (RBuiltin RMODULE)- 0x06 -> return (RBuiltin RFLOAT)- 0x07 -> return (RBuiltin RSTRING)- 0x08 -> return (RBuiltin RREGEXP)- 0x09 -> return (RBuiltin RARRAY)- 0x0a -> return RFixNum- 0x0b -> return (RBuiltin RHASH)- 0x0c -> return (RBuiltin RSTRUCT)- 0x0d -> return (RBuiltin RBIGNUM)- 0x0e -> return (RBuiltin RFILE)- 0x20 -> return RTrue- 0x21 -> return RFalse- 0x22 -> return (RBuiltin RDATA)- 0x23 -> return (RBuiltin RMATCH)- 0x24 -> return RSymbol- 0x3b -> return (RBuiltin RBLKTAG)- 0x3c -> return RUndef- 0x3d -> return (RBuiltin RVARMAP)- 0x3e -> return (RBuiltin RSCOPE)- 0x3f -> return (RBuiltin RNODE)-#endif- _ -> return RUndef+ (#const RUBY_T_NONE) -> return RUndef+ (#const RUBY_T_OBJECT) -> return (RBuiltin ROBJECT)+ (#const RUBY_T_CLASS) -> return (RBuiltin RCLASS)+ (#const RUBY_T_MODULE) -> return (RBuiltin RMODULE)+ (#const RUBY_T_FLOAT) -> return (RBuiltin RFLOAT)+ (#const RUBY_T_STRING) -> return (RBuiltin RSTRING)+ (#const RUBY_T_REGEXP) -> return (RBuiltin RREGEXP)+ (#const RUBY_T_ARRAY) -> return (RBuiltin RARRAY)+ (#const RUBY_T_HASH) -> return (RBuiltin RHASH)+ (#const RUBY_T_STRUCT) -> return (RBuiltin RSTRUCT)+ (#const RUBY_T_BIGNUM) -> return (RBuiltin RBIGNUM)+ (#const RUBY_T_FILE) -> return (RBuiltin RFILE)+ (#const RUBY_T_DATA) -> return (RBuiltin RDATA)+ (#const RUBY_T_MATCH) -> return (RBuiltin RMATCH)+ (#const RUBY_T_NIL) -> return RNil+ (#const RUBY_T_TRUE) -> return RTrue+ (#const RUBY_T_FALSE) -> return RFalse+ (#const RUBY_T_SYMBOL) -> return RSymbol+ (#const RUBY_T_FIXNUM) -> return RFixNum+ (#const RUBY_T_UNDEF) -> return (RBuiltin RUNDEF)+ (#const RUBY_T_NODE) -> return (RBuiltin RNODE)+ (#const RUBY_T_ICLASS) -> return (RBuiltin RICLASS)+ _ -> return RUndef rb_string_value_cstr :: RValue -> IO String rb_string_value_cstr v = do
Setup.hs view
@@ -36,6 +36,11 @@ version <- evalRuby "print '('+RUBY_VERSION.gsub('.', ',')+')'" >>= (return . fmap read) case version of Nothing -> return Nothing+ Just (1,9,_) -> error $ unlines [ "Ruby 1.9 cannot be integrated with the GHC runtime. Tough luck :("+ , "On Ubuntu 14.04, you can try this:"+ , " apt-get install libruby2.0 ruby2.0-dev"+ , " cabal install hrupy -p --configure-option=\"--rubyversion=20 --rubylib=ruby-2.0 --rubyinc=/usr/include/ruby-2.0.0 --rubyinc=/usr/include/x86_64-linux-gnu/ruby-2.0.0\""+ ] Just v@(1,8,_) -> return $ Just $ RubyInfo v "/usr/lib/ruby/1.8" ["/usr/lib/ruby/1.8/x86_64-linux","/usr/lib64/ruby/1.8/x86_64-linux"]@@ -56,9 +61,9 @@ defsFor :: RubyInfo -> [String] defsFor info = case rbVersion info of- (1, _, _) -> [] (2, 0, _) -> ["-DRUBY2"] (2, _, _) -> ["-DRUBY2", "-DRUBY21"]+ (a, b, _) -> ["-DRUBY" ++ show a ++ show b] can'tFindRuby :: String can'tFindRuby = unlines $ [ "Could not find the ruby library. Ensure that it is present on your system (on Debian/Ubuntu, make sure you installed the ruby1.8-dev package)."@@ -95,19 +100,21 @@ , includeDirs = includeDirs buildinfos ++ rbIncludes info , ccOptions = ccOptions buildinfos ++ defsFor info }- in putStrLn ("Detected ruby: " ++ show info) >> return (setBuildInfo h bi)+ in putStrLn ("Detected ruby: " ++ show info ++ " cc:" ++ show (ccOptions bi)) >> return (setBuildInfo h bi) _ -> warn normal can'tFindRuby >> return h parseFlags :: [String] -> LocalBuildInfo -> IO LocalBuildInfo parseFlags flags h = return $ setBuildInfo h $ foldl' parseFlags' bbi flags where bbi = getBuildInfo h- parseFlags' bi fl = case (stripPrefix "--rubylib=" fl, stripPrefix "--rubyinc=" fl, stripPrefix "--rubyversion=" fl) of- (Just l, _, _) -> bi { extraLibs = l : extraLibs bi }- (_, Just l, _) -> bi { includeDirs = l : includeDirs bi }- (_, _, Just "20") -> bi { ccOptions = "-DRUBY2" : ccOptions bi }- (_, _, Just "21") -> bi { ccOptions = "-DRUBY2" : "-DRUBY21" : ccOptions bi }- _ -> bi+ addOptions (Just "20") bi = bi { ccOptions = "-DRUBY2" : ccOptions bi }+ addOptions (Just "21") bi = bi { ccOptions = "-DRUBY2" : "-DRUBY21" : ccOptions bi }+ addOptions (Just x) bi = bi { ccOptions = ("-DRUBY" ++ take 2 x) : ccOptions bi }+ addOptions Nothing bi = bi+ parseFlags' bi fl = addOptions (stripPrefix "--rubyversion=" fl) $ case (stripPrefix "--rubylib=" fl, stripPrefix "--rubyinc=" fl) of+ (Just l, _) -> bi { extraLibs = l : extraLibs bi }+ (_, Just l) -> bi { includeDirs = l : includeDirs bi }+ _ -> bi main :: IO () main = do
cbits/shim.h view
@@ -18,3 +18,28 @@ VALUE int2num(long x); long num2long(VALUE v); double num2dbl(VALUE v);++#ifdef RUBY18+#define RUBY_T_NONE T_NONE+#define RUBY_T_OBJECT T_OBJECT+#define RUBY_T_CLASS T_CLASS+#define RUBY_T_MODULE T_MODULE+#define RUBY_T_FLOAT T_FLOAT+#define RUBY_T_STRING T_STRING+#define RUBY_T_REGEXP T_REGEXP+#define RUBY_T_ARRAY T_ARRAY+#define RUBY_T_HASH T_HASH+#define RUBY_T_STRUCT T_STRUCT+#define RUBY_T_BIGNUM T_BIGNUM+#define RUBY_T_FILE T_FILE+#define RUBY_T_DATA T_DATA+#define RUBY_T_MATCH T_MATCH+#define RUBY_T_NIL T_NIL+#define RUBY_T_TRUE T_TRUE+#define RUBY_T_FALSE T_FALSE+#define RUBY_T_SYMBOL T_SYMBOL+#define RUBY_T_FIXNUM T_FIXNUM+#define RUBY_T_UNDEF T_UNDEF+#define RUBY_T_NODE T_NODE+#define RUBY_T_ICLASS T_ICLASS+#endif
hruby.cabal view
@@ -2,9 +2,9 @@ -- see http://haskell.org/cabal/users-guide/ name: hruby-version: 0.2.8-synopsis: Embed Ruby in your Haskell program.-description: Warning: this is completely experimental. Everything you need should be in "Foreign.Ruby".+version: 0.2.9+synopsis: Embed a Ruby intepreter in your Haskell program !+description: This doesn't work with Ruby 1.9. Everything you need should be in Foreign.Ruby.Safe. license: BSD3 license-file: LICENSE author: Simon Marechal@@ -39,9 +39,9 @@ Test-Suite test-roundtrip hs-source-dirs: test type: exitcode-stdio-1.0- ghc-options: -Wall+ ghc-options: -Wall -threaded extensions: OverloadedStrings- build-depends: base,hruby,aeson,QuickCheck,text,attoparsec,vector+ build-depends: base >= 4.6 && < 4.8,hruby,aeson,QuickCheck,text,attoparsec,vector main-is: roundtrip.hs
test/roundtrip.hs view
@@ -1,7 +1,8 @@ module Main where -import Foreign.Ruby.Helpers+import Foreign.Ruby.Helpers(toRuby,fromRuby,freezeGC) import Foreign.Ruby.Bindings+import Foreign.Ruby.Safe import Data.Aeson import Control.Monad import Test.QuickCheck@@ -40,27 +41,30 @@ instance Arbitrary Value where arbitrary = frequency [(1,s),(5,a),(1,b),(1,n),(5,h)] -roundTrip :: Property-roundTrip = monadicIO $ do+roundTrip :: RubyInterpreter -> Property+roundTrip i = monadicIO $ do v <- pick (arbitrary :: Gen Value)- void (run (setGC False))- rub <- run (toRuby v)- nxt <- run (safeMethodCall "TestClass" "testfunc" [rub])- case nxt of- Right x -> do- out <- run (fromRuby x)- void (run (setGC True))- run startGC- when (out /= Just v) (run (print out))- assert (Just v == out)- Left (rr,_) -> run (print rr) >> assert False+ ex <- run $ freezeGC $ do+ rub <- makeSafe i (toRuby v) >>= \r -> case r of+ Right r' -> return r'+ Left rr -> error (show rr)+ nxt <- safeMethodCall i "TestClass" "testfunc" [rub]+ case nxt of+ Right x -> do+ out <- makeSafe i (fromRuby x) >>= \r -> case r of+ Right r' -> return r'+ Left rr -> error (show rr)+ when (out /= Just v) (print out)+ return (Just v == out)+ Left rr -> print rr >> return False+ assert ex main :: IO () main = do- ruby_init- ruby_init_loadpath- rb_define_module "test"- st <- rb_load_protect "./test/test.rb" 0- unless (st == 0) (showErrorStack >>= error)- quickCheckWith (stdArgs { maxSuccess = 1000 } ) roundTrip- ruby_finalize+ i <- startRubyInterpreter+ putStrLn "loading"+ loadFile i "./test/test.rb" >>= \o -> case o of+ Right () -> return ()+ Left rr -> error (show rr)+ quickCheckWith (stdArgs { maxSuccess = 1000 } ) (roundTrip i)+ closeRubyInterpreter i