mwotton-hubris 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+