r_bridge 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,202 @@
1
+ require "r_bridge/r_bridge_ffi"
2
+
3
+ module RBridge
4
+ def self.create_lazy_function( fname, hash , param_manager)
5
+ raise "create_lazy_function should take String for function name" if(fname.class != String)
6
+ raise "create_lazy_function should take Hash for function arguments" if(hash.class != Hash)
7
+ return LazyFunc.new( fname, hash , param_manager)
8
+ end
9
+
10
+ def self.create_function_call_from_lazy_function ( fname, fargs, param_manager, result_manager)
11
+ farg_keys = fargs.keys
12
+
13
+ new_arg_hash = {}
14
+ farg_keys.each(){|key|
15
+ val = fargs[key]
16
+ case val
17
+ when LazyFunc then
18
+ new_arg_hash[key] = create_function_call_from_lazy_function( val.fname, val.args , param_manager, result_manager )
19
+ when RResultName , RResultNameArray then
20
+ new_arg_hash[key] = result_manager.get_last_for( val )
21
+ when RParamName then
22
+ new_arg_hash[key] = param_manager.get_r_object( val )
23
+ when RNameContainer then
24
+ idx = 0
25
+ while idx < val.elems.size do
26
+ elem = val.elems[idx]
27
+ case elem
28
+ when RResultName, RResultNameArray then
29
+ result = result_manager.get_last_for( elem )
30
+ if( ! result.nil? )
31
+ new_arg_hash[key] = result
32
+ break
33
+ end
34
+ when RParamName then
35
+ result = param_manager.get_r_object( elem )
36
+ if( ! result.nil? )
37
+ new_arg_hash[key] = result
38
+ break
39
+ end
40
+ else # R object
41
+ new_arg_hash[key] = val
42
+ break
43
+ end
44
+ idx = idx + 1
45
+ end
46
+ if(idx == val.elems.size ) # Not found
47
+ new_arg_hash[key] = nil
48
+ end
49
+ else # R object
50
+ new_arg_hash[key] = val
51
+ end
52
+ }
53
+ return create_function_call( fname, new_arg_hash )
54
+ end
55
+
56
+ def self.exec_lazy_function( lazy_func , result_manager , allow_nil_result: false )
57
+ raise "exec_lazy_function should take LazyFunc object" if(lazy_func.class != LazyFunc)
58
+ raise "exec_lazy_function should take RResultManager or Nil for 2nd argment: " + result_manager.class.to_s if(! [RResultManager, NilClass].include?(result_manager.class) )
59
+ fname = lazy_func.fname
60
+ arg_hash = lazy_func.args
61
+ param_manager = lazy_func.param_manager
62
+
63
+ func = create_function_call_from_lazy_function(fname, arg_hash, param_manager, result_manager)
64
+ result = exec_function( func , allow_nil_result: allow_nil_result )
65
+ return result
66
+ end
67
+
68
+ class LazyFunc
69
+ attr :fname
70
+ attr :args
71
+ attr :param_manager
72
+
73
+ def initialize( fname, arg_hash, param_manager)
74
+ raise "LazyFunc requires RParamManager object for param_manager argument " if ! param_manager.is_a?(RParamManager)
75
+ @fname = fname
76
+ @args = arg_hash
77
+ @param_manager = param_manager
78
+ end
79
+ end
80
+
81
+ class RParamName
82
+ attr :name
83
+ def initialize(name)
84
+ @name = name
85
+ end
86
+ end
87
+
88
+ class RParamManager
89
+ def initialize(hash)
90
+ @param_hash = hash
91
+ end
92
+
93
+ def get_r_object(r_param)
94
+ raise "argument of get_r_object needs to be RParamName" if ! r_param.is_a?(RParamName)
95
+ stored_value = @param_hash[r_param.name]
96
+ return RBridge::convert_to_r_object(stored_value)
97
+ end
98
+ end
99
+
100
+ class RResultName
101
+ attr :name
102
+ def initialize(name)
103
+ @name = name
104
+ end
105
+ end
106
+
107
+ class RResultNameArray
108
+ attr :elems
109
+ def initialize(ary)
110
+ raise if(! ary.all? {|i| i.is_a?(RResultName) })
111
+ @elems = ary
112
+ end
113
+ end
114
+
115
+ class RResultManager
116
+ def initialize
117
+ @results = []
118
+ end
119
+
120
+ def add_inst( inst_name )
121
+ @results << [inst_name, RBridge::r_lang_nil() ]
122
+ end
123
+
124
+ def add_inst_r_obj( inst_name, r_obj )
125
+ @results << [inst_name, r_obj ]
126
+ end
127
+
128
+ def get_last_index_for( result_name )
129
+ name = result_name.name
130
+
131
+ idx = @results.size - 1
132
+ @results.reverse.each{|inst_name, r_obj|
133
+ if inst_name == name
134
+ break
135
+ else
136
+ idx = idx - 1
137
+ end
138
+ }
139
+ if idx < 0
140
+ return nil
141
+ else
142
+ return idx
143
+ end
144
+ end
145
+
146
+ def get_last_for( r_result ) # If corresponding result name is not found, return nil.
147
+ raise "get_last_for method requires RResultName or RResultNameArray for its argument." if ! ( r_result.is_a?(RResultName) || r_result.is_a?(RResultNameArray) )
148
+ if( r_result.is_a? RResultName)
149
+ inst_name = r_result.name
150
+
151
+ elem_to_match = @results.reverse.find{|elem| elem[0] == inst_name }
152
+ if elem_to_match.nil?
153
+ return nil
154
+ else
155
+ r_obj = elem_to_match[1]
156
+ if RBridge::is_r_nil?( r_obj )
157
+ return nil
158
+ else
159
+ return r_obj
160
+ end
161
+ end
162
+ elsif( r_result.is_a? RResultNameArray)
163
+ index_array = r_result.elems.map(){|result_name|
164
+ if result_name.is_a? RResultName
165
+ get_last_index_for( result_name )
166
+ else
167
+ p result_name
168
+ raise "RResultNameArray should hold only RResultName objects"
169
+ end
170
+ }
171
+
172
+ if( index_array.all?(nil) )
173
+ return nil
174
+ else
175
+ index_array.delete(nil)
176
+ if ! index_array.empty?
177
+ last_idx = index_array.max
178
+ r_obj = @results[last_idx][1]
179
+ return r_obj
180
+ else
181
+ return nil
182
+ end
183
+ end
184
+ else
185
+ raise "get_last_for() takes unexpected object"
186
+ end
187
+ end
188
+ end
189
+
190
+ class RNameContainer
191
+ attr :elems
192
+ def initialize(ary)
193
+ raise "RNameContainer constructor requires Array" if ! ary.is_a?(Array)
194
+ if(! ary.all? {|i| i.is_a?(RResultName) || i.is_a?(RResultNameArray) || i.is_a?(RParamName) || ::RBridge.is_pointer?( i ) })
195
+ p ary
196
+ raise "RNameContainer's elemet needs to be RResultName, RResultNameArray, RParamName or R object"
197
+ end
198
+ @elems = ary
199
+ end
200
+ end
201
+
202
+ end
@@ -0,0 +1,3 @@
1
+ module RBridge
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'lib/r_bridge/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "r_bridge"
5
+ spec.version = RBridge::VERSION
6
+ spec.authors = ["Toshihiro Umehara"]
7
+ spec.email = ["toshi@niceume.com"]
8
+
9
+ spec.summary = %q{Enables Ruby to access and construct R internal objects}
10
+ spec.description = %q{R (language) provides C interface. This package utilize the interface and allow Ruby to manipulate and evaluate R's internal S expressions }
11
+ spec.homepage = "https://github.com/niceume/r_bridge"
12
+ spec.license = "GPL-3.0"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+
15
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+ spec.metadata["changelog_uri"] = spec.homepage
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.extensions = %w[ext/r_bridge/extconf.rb]
31
+ spec.add_dependency "ffi" , '~> 1.13', '>= 1.13.0'
32
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: r_bridge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Toshihiro Umehara
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.13.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.13'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.13.0
33
+ description: 'R (language) provides C interface. This package utilize the interface
34
+ and allow Ruby to manipulate and evaluate R''s internal S expressions '
35
+ email:
36
+ - toshi@niceume.com
37
+ executables: []
38
+ extensions:
39
+ - ext/r_bridge/extconf.rb
40
+ extra_rdoc_files: []
41
+ files:
42
+ - ".gitignore"
43
+ - ".travis.yml"
44
+ - Gemfile
45
+ - LICENSE.txt
46
+ - README.md
47
+ - Rakefile
48
+ - bin/console
49
+ - bin/setup
50
+ - ext/r_bridge/extconf.rb
51
+ - ext/r_bridge/r_bridge.c
52
+ - ext/r_bridge/r_embed.c
53
+ - ext/r_bridge/r_eval.c
54
+ - ext/r_bridge/r_lang.c
55
+ - ext/r_bridge/r_list.c
56
+ - ext/r_bridge/r_mysum.c
57
+ - ext/r_bridge/r_ptr.c
58
+ - ext/r_bridge/r_vec.c
59
+ - ext/r_bridge/win_compat.h
60
+ - lib/r_bridge.rb
61
+ - lib/r_bridge/r_bridge_ffi.rb
62
+ - lib/r_bridge/r_bridge_lazyfunc_ext.rb
63
+ - lib/r_bridge/version.rb
64
+ - r_bridge.gemspec
65
+ homepage: https://github.com/niceume/r_bridge
66
+ licenses:
67
+ - GPL-3.0
68
+ metadata:
69
+ homepage_uri: https://github.com/niceume/r_bridge
70
+ source_code_uri: https://github.com/niceume/r_bridge
71
+ changelog_uri: https://github.com/niceume/r_bridge
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 2.3.0
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.1.2
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Enables Ruby to access and construct R internal objects
91
+ test_files: []