r_bridge 0.5.0

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.
@@ -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: []