mwotton-hubris 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2009-08-10
2
+
3
+ * 1 major enhancement:
4
+ * Initial release - allows calls to haskell from ruby.
data/README.markdown ADDED
@@ -0,0 +1,117 @@
1
+ # Hubris
2
+
3
+ ## Description
4
+
5
+ This is a quick and dirty way to call Haskell functions from ruby.
6
+
7
+ Hubris will wash your car, lie to your boss, and salvage your love life.
8
+ If you are very, very lucky, it might also let you get some uber-fast
9
+ functional goodness into your ruby programs through the back door.
10
+
11
+ ## Synopsis
12
+
13
+ Eventually, we'll integrate with RubyInline or something similar,
14
+ so we can write inline Haskell. Until that happy day:
15
+
16
+ * write a haskell file (say sample/foo.hs) with some ccall exports declared
17
+ * call "jhc_builder.sh foo.hs". This will build "libfoo.so".
18
+ * write a ruby file similar to sample/hsload.rb in order to call the functions from ruby
19
+
20
+ If all else fails, mail mwotton@gmail.com with tales of woe.
21
+
22
+ ## Requirements
23
+
24
+
25
+ * jhc (John's Haskell Compiler)
26
+ * gcc (oh, come on. don't tell me you don't have it)
27
+ * ruby 1.8.6 or higher
28
+ * Mac OSX or Linux
29
+ * bash
30
+
31
+ ## Install
32
+
33
+ - Install the Hubris gem from RubyForge
34
+
35
+ <pre>
36
+ sudo gem install hubris
37
+ </pre>
38
+
39
+ - Or live on the bleeding edge and install the latest from Github
40
+
41
+ <pre>
42
+ gem source --add http://gems.github.com
43
+ sudo gem install mwotton-hubris
44
+ </pre>
45
+
46
+ - Get the [Haskell Platform][haskell_platform] and install this for your platform (now we have GHC for building JHC)
47
+
48
+ - Install Darcs (so we can access the JHC repository)
49
+
50
+ <pre>
51
+ sudo cabal update
52
+ sudo cabal install --global darcs
53
+ </pre>
54
+
55
+ Don't worry too much about any warnings that you may see while this builds.
56
+
57
+ - Install [JHC][jhc] (the instructions there are slightly out of date so use the following instead). Before you start get a cup of tea, and get comfy. This may take a while...
58
+
59
+ <pre>
60
+ darcs get --partial http://repetae.net/repos/jhc
61
+ cd jhc/src
62
+ darcs get --partial http://repetae.net/repos/Doc
63
+ cd ../lib
64
+ darcs get --partial http://darcs.haskell.org/packages/haskell98
65
+ darcs get --partial http://darcs.haskell.org/packages/containers
66
+ </pre>
67
+
68
+ - Copy the jhc binary in the root jhc directory to somewhere in your $PATH
69
+
70
+ ## Troubleshooting installation
71
+
72
+ JHC doesn't have a heap of mac users, so there were a few problems I had in installing.
73
+
74
+ in ./src/data/rts/jhc_rts_header.h:
75
+
76
+ -#include <endian.h>
77
+ +#include <sys/types.h>
78
+ +#include <sys/param.h>
79
+
80
+ make libs doesn't always seem to work off the bat. so long as jhc builds, it's probably ok
81
+ for the moment - copy the jhc binary in the root jhc directory to somewhere in your $PATH.
82
+
83
+ ## Contributors
84
+
85
+
86
+ * Mark Wotton
87
+ * James Britt
88
+ * Josh Price
89
+
90
+ ## License
91
+
92
+ (The MIT License)
93
+
94
+ Copyright (c) 2009 Mark Wotton
95
+
96
+ Permission is hereby granted, free of charge, to any person obtaining
97
+ a copy of this software and associated documentation files (the
98
+ 'Software'), to deal in the Software without restriction, including
99
+ without limitation the rights to use, copy, modify, merge, publish,
100
+ distribute, sublicense, and/or sell copies of the Software, and to
101
+ permit persons to whom the Software is furnished to do so, subject to
102
+ the following conditions:
103
+
104
+ The above copyright notice and this permission notice shall be
105
+ included in all copies or substantial portions of the Software.
106
+
107
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
108
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
109
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
110
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
111
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
112
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
113
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
114
+
115
+
116
+ [haskell_platform]: http://hackage.haskell.org/platform/
117
+ [jhc]: http://repetae.net/computer/jhc/
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ # TODO - want other tests/tasks run by default? Add them to the list
2
+
3
+ # remove_task :default
4
+
5
+ # task :default => [:spec, :features]
6
+
7
+ require 'rubygems'
8
+ gem 'hoe', '>= 2.1.0'
9
+ require 'hoe'
10
+ require 'fileutils'
11
+ require './lib/hubris'
12
+
13
+ Hoe.plugin :newgem
14
+ # Hoe.plugin :website
15
+ # Hoe.plugin :cucumberfeatures
16
+
17
+ # Generate all the Rake tasks
18
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
19
+ $hoe = Hoe.spec 'hubris' do
20
+ self.developer 'Mark Wotton', 'mwotton@gmail.com'
21
+ self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
22
+ self.rubyforge_name = "hubris"
23
+ self.summary = 'tool to help build .so files from haskell code for use in Ruby via dl'
24
+ end
25
+
26
+ require 'newgem/tasks'
27
+ Dir['tasks/**/*.rake'].each { |t| load t }
28
+
29
+ # TODO - want other tests/tasks run by default? Add them to the list
30
+ # remove_task :default
31
+ # task :default => [:spec, :features]
data/bin/jhc_builder ADDED
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+
3
+ # $1 is our source haskell
4
+ rm -rf tmp.old
5
+ mv tmp tmp.old
6
+ mkdir tmp
7
+ tmp="tmp/$1"
8
+ cat $1 >> $tmp
9
+ echo "main :: IO ()" >> $tmp
10
+ echo "main = return ()" >> $tmp
11
+
12
+ cd tmp
13
+ jhc "$1"
14
+ sed -i 's/^main(/disregard_main(/' hs.out_code.c
15
+ gcc '-std=gnu99' -D_GNU_SOURCE '-falign-functions=4' -ffast-math -Wshadow -Wextra -Wall -Wno-unused-parameter -o libdynhs.so \
16
+ hs.out_code.c -DNDEBUG -O3 -fPIC -shared
17
+ mv libdynhs.so ..
data/lib/Mapper.hs ADDED
@@ -0,0 +1,93 @@
1
+ {-# LANGUAGE FlexibleInstances, ForeignFunctionInterface #-}
2
+ {-# INCLUDE <ruby.h> #-}
3
+
4
+ module Mapper where
5
+ import qualified Data.ByteString.Char8 as B -- do we need Unicode?
6
+ import Data.Array.CArray as CArray
7
+ import Data.Word
8
+ import Foreign.C.String
9
+ import Foreign.Ptr
10
+ import Foreign.Storable
11
+ import RubyMap
12
+ import System.IO.Unsafe
13
+ newtype RString = RString CString
14
+ newtype RSymbol = RSymbol Word
15
+
16
+
17
+
18
+ class Rubyable a where
19
+ toRuby :: a -> RValue
20
+ fromRuby :: RValue -> a
21
+
22
+ instance Rubyable Int where
23
+ toRuby a = T_FIXNUM a
24
+ fromRuby (T_FIXNUM a) = a
25
+
26
+ instance Rubyable Integer where
27
+ toRuby a = T_ a
28
+ fromRuby (T_FIXNUM a) = a
29
+
30
+ instance Rubyable Bool where
31
+ toRuby False = T_FALSE
32
+ toRuby True = T_TRUE
33
+ fromRuby T_FALSE = False
34
+ fromRuby T_TRUE = True
35
+
36
+ instance Rubyable (CArray Word RValue) where
37
+ toRuby arr = T_ARRAY arr
38
+ fromRuby (T_ARRAY arr) = arr
39
+
40
+ instance Rubyable a => Rubyable [a] where
41
+ toRuby l = unsafePerformIO $ do
42
+ arr <- rb_ary_new2 (length l)
43
+ mapM_ (\(i,x) -> rb_ary_store i arr x) l
44
+ return $ T_ARRAY arr
45
+ fromRuby (T_ARRAY arr) = map fromRuby $ CArray.elems arr
46
+
47
+ instance Rubyable RString where
48
+ toRuby (RString cstr) = T_STRING cstr
49
+ fromRuby (T_STRING cstr) = RString cstr
50
+
51
+ instance Rubyable RSymbol where
52
+ toRuby (RSymbol index) = T_SYMBOL index
53
+ fromRuby (T_SYMBOL index) = RSymbol index
54
+
55
+
56
+ -- -- | T_REGEXP
57
+ -- -- the array needs to be managed by ruby
58
+ -- | T_ARRAY (CArray Word RValue)
59
+ -- | T_FIXNUM Int --fixme, probably
60
+ -- -- the hash needs to be managed by ruby
61
+ -- | T_HASH Int -- definitely FIXME - native ruby hashes, or going to translitrate?
62
+ -- -- | T_STRUCT
63
+ -- | T_BIGNUM Integer
64
+ -- -- | T_FILE
65
+ -- | T_TRUE
66
+ -- | T_FALSE
67
+ -- -- | T_DATA
68
+ -- | T_SYMBOL Word -- interned string
69
+
70
+ instance Storable RValue where
71
+ sizeOf _ = 8 -- urgh, fixme. it's just a pointer, basically.
72
+ alignment _ = 8
73
+
74
+ -- so here's the problem - TYPE(...) is a macro, so we can't call it from haskell.
75
+ -- peek ptr = case toEnum $ rb_type ptr of
76
+ -- RT_FLOAT -> T_FLOAT (rb_num2dbl ptr)
77
+ -- RT_STRING -> T_STRING (rb_str_to_str ptr)
78
+
79
+ -- otherwise -> undefined
80
+
81
+
82
+ -- undefined -- insert definition of loadruby
83
+ -- poke ptr a = undefined
84
+
85
+
86
+
87
+
88
+
89
+ loadRuby :: Ptr RValue -> IO RValue
90
+ loadRuby ptr = undefined
91
+
92
+ dumpRuby :: RValue -> IO (Ptr RValue)
93
+ dumpRuby rval = undefined
data/lib/RubyMap.chs ADDED
@@ -0,0 +1,49 @@
1
+ {-# LANGUAGE ForeignFunctionInterface #-}
2
+ {-# LANGUAGE TypeSynonymInstances #-}
3
+ module RubyMap where
4
+ #include "rshim.h"
5
+ #include <ruby.h>
6
+
7
+ -- import Data.Array.CArray as CArray
8
+ import Data.Word
9
+ import Foreign.Ptr
10
+ import Foreign.C.Types
11
+ import Foreign.C.String
12
+
13
+ {# context lib="rshim" #}
14
+ {# enum RubyType {} deriving (Eq) #} -- maybe Ord?
15
+
16
+ -- can we have a type for Value, plz?
17
+ type Value = Ptr () -- fixme
18
+
19
+ -- we're being a bit filthy here - the interface is all macros, so we're digging in to find what it actually is
20
+ foreign import ccall unsafe "rshim.h rtype" rb_type :: Value -> CInt
21
+ -- FIXME jhc doesn't like importing floating point numbers, for some reason.
22
+ -- foreign import ccall unsafe "ruby.h rb_num2dbl" rb_num2dbl :: Value -> CDouble
23
+ foreign import ccall unsafe "ruby.h rb_str_to_str" rb_str_to_str :: Value -> CString
24
+ foreign import ccall unsafe "ruby.h rb_ary_new2" rb_ary_new :: Int -> IO Value
25
+ foreign import ccall unsafe "ruby.h rb_ary_store" rb_ary_store :: Value -> Int -> Value -> IO ()
26
+
27
+
28
+ -- all values in here need to be allocated and tracked by ruby.
29
+ -- ByteStrings... hm. Probably better to keep them as C-side ruby strings.
30
+ -- better come back and expand this later
31
+ data RValue = T_NIL
32
+ -- | T_OBJECT
33
+ -- | T_CLASS
34
+ -- | T_MODULE
35
+ | T_FLOAT Double
36
+ | T_STRING CString
37
+ -- | T_REGEXP
38
+ -- the array needs to be managed by ruby
39
+ -- | T_ARRAY (CArray Word RValue)
40
+ | T_FIXNUM Int --fixme, probably
41
+ -- the hash needs to be managed by ruby
42
+ | T_HASH Int -- definitely FIXME - native ruby hashes, or going to translitrate?
43
+ -- | T_STRUCT
44
+ | T_BIGNUM Integer
45
+ -- | T_FILE
46
+ | T_TRUE
47
+ | T_FALSE
48
+ -- | T_DATA
49
+ | T_SYMBOL Word -- interned string
data/lib/extconf.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+ create_makefile("rshim")
3
+
data/lib/hubris.rb ADDED
@@ -0,0 +1,70 @@
1
+ require 'dl/import'
2
+ require 'tempfile'
3
+
4
+ module Hubris
5
+ VERSION = '0.0.1'
6
+ class Hubris
7
+ extend DL::Importer # Importable in 1.8, FIXME
8
+
9
+ def initialize(haskell_str)
10
+ build_jhc(haskell_str)
11
+ end
12
+
13
+ def noisy(str)
14
+ print "Noisy: #{str}\n"
15
+ system(str)
16
+ end
17
+
18
+ def build_jhc(haskell_str)
19
+ file=Tempfile.new("TempHs.hs")
20
+ # cheap way: assert type sigs binding to RValue. Might be able to do better after,
21
+ # but this'll do for the moment
22
+ file.print(<<EOF
23
+ import RubyMap
24
+ import Mapper
25
+ main :: IO ()
26
+ main = return ()
27
+ EOF
28
+ )
29
+ file.print(haskell_str)
30
+ # TODO add foreign export calls immediately for each toplevel func
31
+ # cheap hacky way: first word on each line, nub it to get rid of
32
+ # function types.
33
+ # tricky bit: generating interface for each
34
+ functions={}
35
+ haskell_str.each_line do |line|
36
+ # if line ~= /^[^ ]/ then
37
+ functions[line.split(/ /)[0]]=1
38
+ end
39
+ functions.keys.each do |fname|
40
+ file.print "#{fname} :: RValue -> IO RValue\n"
41
+ # end
42
+ end
43
+
44
+ file.flush
45
+ # this is so dumb
46
+ system("cat #{file.path}; cp #{file.path} #{file.path}.hs")
47
+ if(0!=noisy("jhc #{file.path}.hs -ilib")) then
48
+ raise SyntaxError, "JHC build failed"
49
+ end
50
+ # output goes to hs_out.code.c
51
+ # don't need to grep out main any more
52
+ # FIXME unique name for dynamic lib
53
+ lib = Tempfile.new("libDyn.so")
54
+ if(0!=noisy("gcc '-std=gnu99' -D_GNU_SOURCE -D'-falign-functions=4' '-D_JHC_STANDALONE=0' -ffast-math -Wshadow -Wextra -Wall -Wno-unused-parameter -o libdynhs.so \
55
+ -DNDEBUG -D_JHC_STANDALONE=0 -O3 -fPIC -shared #{file.dirname}/hs.out_code.c -o {lib.name}")) then
56
+ raise SyntaxError, "C build failed"
57
+ end
58
+ dlload lib.name
59
+ # get all the headers from ... somewhere
60
+ headers = []
61
+ headers.each do |header|
62
+ extern header
63
+ end
64
+ extern "hs_init"
65
+ hs_init
66
+ # TODO load all the object headers into the lib
67
+ end
68
+ end
69
+
70
+ end
data/lib/rshim.c ADDED
@@ -0,0 +1,11 @@
1
+ #include "rshim.h"
2
+ #include <stdio.h>
3
+
4
+ void Init_rshim() {
5
+ printf("loaded, bitches\n");
6
+ }
7
+
8
+ // did this really have to be a macro? BAD MATZ
9
+ unsigned int rtype(VALUE obj) {
10
+ return TYPE(obj);
11
+ }
data/lib/rshim.h ADDED
@@ -0,0 +1,65 @@
1
+ #ifndef __rshim_h__
2
+ #define __rshim_h__
3
+ #define HAVE_STRUCT_TIMESPEC 1
4
+ // this is about as filthy as it looks, but c2hs chokes otherwise.
5
+
6
+ #include <ruby.h>
7
+
8
+ #ifdef HAVE_RUBY_ENCODING_H
9
+
10
+ #include <ruby/encoding.h>
11
+
12
+ #define ENCODED_STR_NEW2(str, encoding) \
13
+ ({ \
14
+ VALUE _string = rb_str_new2((const char *)str); \
15
+ int _enc = rb_enc_find_index(encoding); \
16
+ rb_enc_associate_index(_string, _enc); \
17
+ _string; \
18
+ })
19
+
20
+ #else
21
+
22
+ #define ENCODED_STR_NEW2(str, encoding) \
23
+ rb_str_new2((const char *)str)
24
+
25
+ #endif
26
+
27
+ // did this really have to be a macro? BAD MATZ
28
+ unsigned int rtype(VALUE obj);
29
+
30
+
31
+ // argh, and again
32
+ enum RubyType {
33
+ RT_NONE = T_NONE,
34
+
35
+ RT_NIL = T_NIL ,
36
+ RT_OBJECT = T_OBJECT ,
37
+ RT_CLASS = T_CLASS ,
38
+ RT_ICLASS = T_ICLASS ,
39
+ RT_MODULE = T_MODULE ,
40
+ RT_FLOAT = T_FLOAT ,
41
+ RT_STRING = T_STRING ,
42
+ RT_REGEXP = T_REGEXP ,
43
+ RT_ARRAY = T_ARRAY ,
44
+ RT_FIXNUM = T_FIXNUM ,
45
+ RT_HASH = T_HASH ,
46
+ RT_STRUCT = T_STRUCT ,
47
+ RT_BIGNUM = T_BIGNUM ,
48
+ RT_FILE = T_FILE ,
49
+
50
+ RT_TRUE = T_TRUE ,
51
+ RT_FALSE = T_FALSE ,
52
+ RT_DATA = T_DATA ,
53
+ RT_MATCH = T_MATCH ,
54
+ RT_SYMBOL = T_SYMBOL ,
55
+
56
+ // t_BLKTAG = T_BLKTAG , // this one is broken in ruby 1.9
57
+
58
+ RT_UNDEF = T_UNDEF ,
59
+ // t_VARMAP = T_VARMAP , // this one is broken in ruby 1.9
60
+ // t_SCOPE = T_SCOPE , // this one is broken in ruby 1.9
61
+ RT_NODE = T_NODE ,
62
+
63
+ RT_MASK = T_MASK ,
64
+ };
65
+ #endif
data/sample/Makefile ADDED
@@ -0,0 +1,6 @@
1
+ all: libdynhs.so
2
+ libdynhs.so: Test.hs
3
+ ../bin/jhc_builder.sh Test.hs
4
+
5
+ clean:
6
+ rm -rf tmp/ libdynhs.so
data/sample/Test.hs ADDED
@@ -0,0 +1,28 @@
1
+ {-# LANGUAGE ForeignFunctionInterface #-}
2
+
3
+ -- module Test where
4
+
5
+ import Foreign.C.Types
6
+ -- import Data.Map
7
+ import Maybe
8
+
9
+ -- main = putStrLn "11"
10
+
11
+ fibonacci :: Int -> Int
12
+ fibonacci n = fibs !! n
13
+ where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
14
+
15
+ -- local_map = Data.Map.fromList [(1,2), (3,4)]
16
+
17
+
18
+
19
+ -- lookup_hs ::CInt -> CInt
20
+ -- lookup_hs = fromIntegral . Maybe.fromJust . ((flip Data.Map.lookup) local_map) . fromIntegral
21
+ -- foreign export ccall lookup_hs :: CInt -> CInt
22
+
23
+ fibonacci_hs :: CInt -> CInt
24
+ fibonacci_hs = fromIntegral . fibonacci . fromIntegral
25
+
26
+ foreign export ccall fibonacci_hs :: CInt -> CInt
27
+
28
+ -- main = putStrLn "foo"
data/sample/hsload.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'dl/import'
2
+
3
+ module HaskyPants
4
+ extend DL::Importable
5
+ dlload "./libdynhs.so"
6
+ extern "int fibonacci_hs(int)"
7
+ end
8
+
9
+ puts HaskyPants.fibonacci_hs(12)
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ # Time to add your specs!
4
+ # http://rspec.info/
5
+ describe "Hubris" do
6
+
7
+ it "can whine like a little baby when you pass it bad haskell" do
8
+ lambda {Hubris::Hubris.new("broken _ = return (1 + \"a string\")")}.should raise_error(SyntaxError)
9
+ end
10
+
11
+ it "can sing like a golden bird when you treat it right, aw yeah" do
12
+ lambda {Hubris::Hubris.new("working _ = return (toRuby $ 1 + 2)")}.should_not raise_error
13
+ end
14
+
15
+ it "can double an int in Haskell-land" do
16
+ haskell = Hubris::Hubris.new(<<EOF
17
+ -- partial function, will probably crash and burn
18
+ double i = let j = fromRuby i in return (toRuby $ j + j)
19
+ EOF
20
+ )
21
+ haskell.double(1).should eql(2)
22
+ haskell.double("foo").should raise_error(RuntimeError)
23
+ end
24
+
25
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'hubris'
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mwotton-hubris
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Mark Wotton
8
+ - James Britt
9
+ - Josh Price
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-08-16 00:00:00 -07:00
15
+ default_executable:
16
+ dependencies: []
17
+
18
+ description: A Ruby Haskell bridge
19
+ email: mwotton@gmail.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - README.markdown
26
+ files:
27
+ - bin/jhc_builder
28
+ - History.txt
29
+ - lib/extconf.rb
30
+ - lib/hubris.rb
31
+ - lib/Mapper.hs
32
+ - lib/rshim.c
33
+ - lib/rshim.h
34
+ - lib/RubyMap.chs
35
+ - Rakefile
36
+ - README.markdown
37
+ - sample/hsload.rb
38
+ - sample/Makefile
39
+ - sample/Test.hs
40
+ - spec/hubris_spec.rb
41
+ - spec/spec.opts
42
+ - spec/spec_helper.rb
43
+ - tasks/rspec.rake
44
+ has_rdoc: false
45
+ homepage: http://github.com/mwotton/hubris
46
+ licenses:
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --inline-source
50
+ - --charset=UTF-8
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project: hubris
68
+ rubygems_version: 1.3.5
69
+ signing_key:
70
+ specification_version: 2
71
+ summary: Hubris is a Ruby Haskell bridge allowing you to call Haskell functions from your Ruby code.
72
+ test_files: []
73
+