rserve-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,360 @@
1
+ module Rserve
2
+ module Protocol
3
+ # representation of R-eXpressions in Ruby
4
+ class REXPFactory
5
+ include Rserve::Protocol
6
+ # xpression type: NULL
7
+ XT_NULL=0;
8
+ # xpression type: integer
9
+ XT_INT=1;
10
+ # xpression type: double
11
+ XT_DOUBLE=2;
12
+ # xpression type: String
13
+ XT_STR=3;
14
+ # xpression type: language construct (currently content is same as list)
15
+ XT_LANG=4;
16
+ # xpression type: symbol (content is symbol name: String)
17
+ XT_SYM=5;
18
+ # xpression type: RBool
19
+ XT_BOOL=6;
20
+ # xpression type: S4 object
21
+ #@since Rserve 0.5
22
+ XT_S4=7;
23
+ # xpression type: generic vector (RList)
24
+ XT_VECTOR=16;
25
+ # xpression type: dotted-pair list (RList)
26
+ XT_LIST=17;
27
+ # xpression type: closure (there is no java class for that type (yet?). currently the body of the closure is stored in the content part of the REXP. Please note that this may change in the future!)
28
+ XT_CLOS=18;
29
+ # xpression type: symbol name
30
+ # @since Rserve 0.5
31
+ XT_SYMNAME=19;
32
+ # xpression type: dotted-pair list (w/o tags)
33
+ # @since Rserve 0.5
34
+ XT_LIST_NOTAG=20;
35
+ # xpression type: dotted-pair list (w tags)
36
+ # @since Rserve 0.5
37
+ XT_LIST_TAG=21;
38
+ # xpression type: language list (w/o tags)
39
+ # @since Rserve 0.5
40
+ XT_LANG_NOTAG=22;
41
+ # xpression type: language list (w tags)
42
+ # @since Rserve 0.5
43
+ XT_LANG_TAG=23;
44
+ # xpression type: expression vector
45
+ XT_VECTOR_EXP=26;
46
+ # xpression type: string vector
47
+ XT_VECTOR_STR=27;
48
+ # xpression type: int[]
49
+ XT_ARRAY_INT=32;
50
+ # xpression type: double[]
51
+ XT_ARRAY_DOUBLE=33;
52
+ # xpression type: String[] (currently not used, Vector is used instead)
53
+ XT_ARRAY_STR=34;
54
+ # internal use only! this constant should never appear in a REXP
55
+ XT_ARRAY_BOOL_UA=35;
56
+ # xpression type: RBool[]
57
+ XT_ARRAY_BOOL=36;
58
+ # xpression type: raw (byte[])
59
+ # @since Rserve 0.4-?
60
+ XT_RAW=37;
61
+ # xpression type: Complex[]
62
+ # @since Rserve 0.5
63
+ XT_ARRAY_CPLX=38;
64
+ # xpression type: unknown; no assumptions can be made about the content
65
+ XT_UNKNOWN=48;
66
+ # xpression type: RFactor; this XT is internally generated (ergo is does not come from Rsrv.h) to support RFactor class which is built from XT_ARRAY_INT
67
+ XT_FACTOR=127;
68
+ # used for transport only - has attribute
69
+ XT_HAS_ATTR=128;
70
+
71
+ attr_reader :type, :attr, :cont, :root_list
72
+ def get_REXP
73
+ @cont
74
+ end
75
+ def get_attr
76
+ attr.nil? ? nil : attr.cont
77
+ end
78
+ def initialize(*args)
79
+ if args.size==0
80
+
81
+ elsif
82
+ r=args[0]
83
+ r=Rserve::REXP::Null if r.nil?
84
+ a=r.attr
85
+ @attr=Factory.new(a) if !a.nil?
86
+ if r.is_a? REXP::Null
87
+ @type=XT_NULL
88
+ elsif r.is_a? REXP::List
89
+ l=r.as_list
90
+ @type=l.named? ? XT_LIST_TAG : XT_LIST_NOTAG
91
+ if r.is_a? REXPLanguage
92
+ @type = (@type==XT_LIST_TAG) ? XT_LANG_TAG : XT_LANG_NOTAG;
93
+ end
94
+ elsif r.is_a? REXP::GenericVector
95
+ @type = XT_VECTOR; # FIXME: may have to adjust names attr
96
+ elsif r.is_a? REXP::S4
97
+ @type = XT_S4
98
+ elsif r.is_a? REXP::Integer
99
+ @type = XT_ARRAY_INT
100
+ elsif r.is_a? REXP::Double
101
+ @type = XT_ARRAY_DOUBLE
102
+ elsif r.is_a? REXP::String
103
+ @type = XT_ARRAY_STRING
104
+ elsif r.is_a? REXP::Symbol
105
+ @type = XT_SYMNAME
106
+ elsif r.is_a? REXP::Raw
107
+ @type = XT_RAW
108
+ elsif r.is_a? REXP::Logical
109
+ @type = XT_ARRAY_BOOL
110
+ else
111
+ raise ArgumentError("***REXPFactory unable to interpret #{r}")
112
+ end
113
+ end
114
+ end
115
+ def parse_REXP(buf,o)
116
+ xl=get_len(buf,o)
117
+ #p "buffer:#{buf.to_s}"
118
+ has_at = (buf[o]&128)!=0
119
+ is_long = (buf[o]&64 )!=0
120
+ xt = buf[o]&63
121
+ o+=4 if is_long
122
+ o+=4
123
+ eox=o+xl
124
+ @type=xt
125
+
126
+ @attr=REXPFactory.new()
127
+ @cont=nil
128
+
129
+ o=attr.parse_REXP(buf,o) if has_at
130
+
131
+ if xt==XT_NULL
132
+ @cont=REXP::Null(get_attr)
133
+ return o
134
+ end
135
+ if xt==XT_DOUBLE
136
+ lr=get_long(buf,o)
137
+ d=[longBitsToDouble(lr)]
138
+ o+=8
139
+ if(o!=eox)
140
+ $STDERR.puts("Warning: double SEXP size mismatch\n");
141
+ o=eox
142
+ end
143
+ @cont=REXP::Double.new(d,get_attr)
144
+ return o
145
+ end
146
+ if xt==XT_ARRAY_DOUBLE
147
+ as=(eox-o).quo(8)
148
+ i=0
149
+ d=Array.new(as)
150
+ while(o<eox)
151
+ d[i]=longBitsToDouble(get_long(buf,o))
152
+ o+=8
153
+ i+=1
154
+ end
155
+ if(o!=eox)
156
+ $STDERR.puts("Warning: double SEXP size mismatch\n");
157
+ o=eox
158
+ end
159
+ @cont=REXP::Double.new(d,get_attr)
160
+ return o
161
+ end
162
+ if xt==XT_BOOL
163
+ b=[buf[o]]
164
+ if (b[0]!=0 && b[0]!=1)
165
+ b[0]=REXP::Logical::NA
166
+ end
167
+ @cont=REXP::Logical.new(b,get_attr)
168
+ o+=1
169
+ return o
170
+ end
171
+ if xt==XT_ARRAY_BOOL_UA
172
+ as=(eox-o)
173
+ i=0
174
+ d=Array.new(as)
175
+ (eox-i).times {|i| d[i]=buf[o+i]}
176
+ o=eox
177
+ d.length.each {|j|
178
+ if d[j]!=0 && d[j]!=1
179
+ d[j]==REXP::Logical::NA
180
+ end
181
+ }
182
+ @cont=REXP::Logical.new(d,get_attr)
183
+ return o
184
+ end
185
+ if xt==XT_ARRAY_BOOL
186
+ as=get_int(buf, o)
187
+ o+=4
188
+ d=Array.new(as)
189
+ as.times {|i| d[i]=buf[o+i]}
190
+ d.length.times {|j|
191
+ if d[j]!=0 && d[j]!=1
192
+ d[j]==REXP::Logical::NA
193
+ end
194
+ }
195
+ o=eox
196
+ @cont=REXP::Logical.new(d,get_attr)
197
+ return o
198
+ end
199
+ if xt==XT_INT
200
+ i=Array.new(get_int(buf,o))
201
+ @cont=REXP::Integer.new(i,get_attr)
202
+ o+=4
203
+ if o!=eox
204
+ $STDERR.puts "int SEXP size mismatch"
205
+ o=eox
206
+ end
207
+ return o
208
+ end
209
+
210
+ if xt==XT_ARRAY_INT
211
+ as=(eox-o).quo(4)
212
+ i=0
213
+ d=Array.new(as)
214
+ while(o<eox)
215
+ d[i]=get_int(buf,o)
216
+ o+=4
217
+ i+=1
218
+ end
219
+ if o!=eox
220
+ $STDERR.puts "int SEXP size mismatch"
221
+ o=eox
222
+ end
223
+ # hack for list. Not implemented yet!
224
+ @cont=nil
225
+ @cont=REXP::Integer(d,get_attr)
226
+ return o
227
+ end
228
+
229
+ # RAW not implemented yet
230
+ if xt==XT_LIST_NOTAG or xt==XT_LIST_TAG or xt==XT_LANG_NOTAG or xt==XT_LANG_TAG
231
+ lc=REXPFactory.new
232
+ nf=REXPFactory.new
233
+ l=Rlist.new
234
+ while(o<eox)
235
+ name=nil
236
+ o=lc.parse_REXP(buf,o)
237
+ if(xt==XT_LIST_TAG or xt==XT_LANG_TAG)
238
+ o=nf.parse_REXP(buf,o)
239
+ name=nf.cont.as_strings if(nf.cont.symbol? or nf.cont.string?)
240
+ end
241
+ if name.nil?
242
+ l.add(lc.cont)
243
+ else
244
+ l.put(name,lc.cont)
245
+ end
246
+ end
247
+
248
+ @cont=(xt==XT_LANG_NOTAG or xt==XT_LANG_TAG) ?
249
+ REXP::Language.new(l,get_attr) : REXP::List.new(l, get_attr)
250
+
251
+ if(o!=eox)
252
+ $STDERR.puts "Mismatch"
253
+ o=eox
254
+ end
255
+
256
+ return o
257
+
258
+ end
259
+
260
+
261
+ # XT_LIST and XT_LANG not implemented yet
262
+
263
+ if xt==XT_VECTOR or xt==XT_VECTOR_EXP
264
+ v=Array.new
265
+ while(o<eox)
266
+ xx=REXPFactory.new()
267
+ o = xx.parse_REXP(buf,o);
268
+ v.push(xx.cont);
269
+ end
270
+ if (o!=eox)
271
+ $STDERR.puts("Warning: int vector SEXP size mismatch\n");
272
+ o=eox;
273
+ end
274
+ # fixup for lists since they're stored as attributes of vectors
275
+ if !get_attr.nil? and !get_attr.as_list['names'].nil?
276
+ nam=get_attr.as_list['names']
277
+ names=nil
278
+ if nam.string?
279
+ names=nam.as_strings
280
+ elsif nam.vector?
281
+ l=nam.to_a
282
+ names=Array.new(aa.length)
283
+ aa.length.times {|i| names[i]=aa[i].as_string}
284
+ end
285
+ l=RList.new(v,names)
286
+ @cont=(xt==XT_VECTOR_EXP) ? REXP::ExpressionVector.new(l,get_attr) : REXP::GenericVector.new(l,get_attr)
287
+ else
288
+
289
+ @cont=(xt==XT_VECTOR_EXP) ? REXP::ExpressionVector.new(Rlist.new(v), get_attr) : REXP::GenericVector.new(Rlist.new(v), get_attr)
290
+ end
291
+ return o
292
+ end
293
+ if xt==XT_ARRAY_STR
294
+ c=0
295
+ i=o
296
+ while(i<eox)
297
+ c+=1 if buf[i]==0
298
+ i+=1
299
+ end
300
+ s=Array.new(c)
301
+ if c>0
302
+ c=0; i=o;
303
+ while(o < eox)
304
+ if buf[o]==0
305
+ begin
306
+ s[c]=buf[i,o-i].pack("C*")
307
+ rescue
308
+ s[c]=""
309
+ end
310
+ c+=1
311
+ i=o+1
312
+ end
313
+ o+=1
314
+ end
315
+
316
+ end
317
+ @cont=REXP::String.new(s, get_attr)
318
+ return o
319
+ end
320
+ if xt==XT_VECTOR_STR
321
+ v=Array.new
322
+ while(o<eox)
323
+ xx=REXP::Factory.new
324
+ o=xx.parse_REXP(buf,o)
325
+ v.push(xx.cont.as_string)
326
+ end
327
+ sa=Array.new(v.size)
328
+ i=0
329
+ while(i<sa.length)
330
+ sa[i]=v.get(i)
331
+ i+=1
332
+ end
333
+ @cont=REXP::String.new(sa,get_attr)
334
+ return o
335
+ end
336
+
337
+ if (xt==XT_STR||xt==XT_SYMNAME)
338
+ i = o;
339
+ while (buf[i]!=0 && i<eox) do
340
+ i+=1
341
+ end
342
+ if (xt==XT_STR)
343
+ @cont = REXP::String.new(buf[o,i-o].pack("C*"), get_attr);
344
+ else
345
+ @cont = REXP::Symbol.new(buf[o,i-o].pack("C*"))
346
+ end
347
+
348
+ o = eox;
349
+ return o;
350
+ end
351
+
352
+ #not implemented XT_SYM, XT_CLOSS, XT_UNKNOWN, XT_S4
353
+ @cont=nil
354
+ o=eox
355
+ raise "Unhandled type:#{xt}"
356
+ return o
357
+ end # def
358
+ end # Factory
359
+ end # end Protocol
360
+ end # end Rserve
@@ -0,0 +1,234 @@
1
+ module Rserve
2
+ # Basic class representing an object of any type in R. Each type in R in represented by a specific subclass.
3
+ #
4
+ # This class defines basic accessor methods (<tt>as</tt><i>XXX</i>), type check methods (<tt>is</tt><i>XXX</i>), gives access to attributes ({@link #getAttribute}, {@link #hasAttribute}) as well as several convenience methods. If a given method is not applicable to a particular type, it will throw the {@link MismatchException} exception.
5
+ #
6
+ # This root class will throw on any accessor call and returns <code>false</code> for all type methods. This allows subclasses to override accessor and type methods selectively.
7
+ #
8
+ class REXP
9
+ MismatchException= Class.new(Exception)
10
+ attr_reader :attr
11
+ def initialize(attr=nil)
12
+ @attr=attr
13
+ end
14
+ # specifies how many items of a vector or list will be displayed in {@link #toDebugString} */
15
+ MaxDebugItems = 32
16
+ # :section: type checks
17
+ # check whether the <code>REXP</code> object is a character vector (string)
18
+ # @return <code>true</code> if the receiver is a character vector, <code>false</code> otherwise */
19
+
20
+ def string?;return false;end
21
+
22
+ # # check whether the <code>REXP</code> object is a numeric vector
23
+ # @return <code>true</code> if the receiver is a numeric vector, <code>false</code> otherwise */
24
+
25
+ def numeric?;false;end
26
+ # check whether the <code>REXP</code> object is an integer vector
27
+ # @return <code>true</code> if the receiver is an integer vector, <code>false</code> otherwise */
28
+ def integer?;false;end
29
+ # check whether the <code>REXP</code> object is NULL
30
+ # @return <code>true</code> if the receiver is NULL, <code>false</code> otherwise */
31
+ def null?;false;end
32
+ # check whether the <code>REXP</code> object is a factor
33
+ # @return <code>true</code> if the receiver is a factor, <code>false</code> otherwise */
34
+ def factor?;false;end
35
+ # check whether the <code>REXP</code> object is a list (either generic vector or a pairlist - i.e. {@link #asList()} will succeed)
36
+ # @return <code>true</code> if the receiver is a generic vector or a pair-list, <code>false</code> otherwise */
37
+ def list?;false;end
38
+ # check whether the <code>REXP</code> object is a pair-list
39
+ # @return <code>true</code> if the receiver is a pair-list, <code>false</code> otherwise */
40
+ def pair_list?;false;end
41
+ # check whether the <code>REXP</code> object is a logical vector
42
+ # @return <code>true</code> if the receiver is a logical vector, <code>false</code> otherwise */
43
+ def logical?;false;end
44
+ # check whether the <code>REXP</code> object is an environment
45
+ # @return <code>true</code> if the receiver is an environment, <code>false</code> otherwise */
46
+ def environment?;false;end
47
+ # check whether the <code>REXP</code> object is a language object
48
+ # @return <code>true</code> if the receiver is a language object, <code>false</code> otherwise */
49
+ def language?;false;end
50
+ # check whether the <code>REXP</code> object is an expression vector
51
+ # @return <code>true</code> if the receiver is an expression vector, <code>false</code> otherwise */
52
+ def expression?;false;end
53
+ # check whether the <code>REXP</code> object is a symbol
54
+ # @return <code>true</code> if the receiver is a symbol, <code>false</code> otherwise */
55
+ def symbol?;false;end
56
+ # check whether the <code>REXP</code> object is a vector
57
+ # @return <code>true</code> if the receiver is a vector, <code>false</code> otherwise */
58
+ def vector?;false;end
59
+ # check whether the <code>REXP</code> object is a raw vector
60
+ # @return <code>true</code> if the receiver is a raw vector, <code>false</code> otherwise */
61
+ def raw?;false;end
62
+ # check whether the <code>REXP</code> object is a complex vector
63
+ # @return <code>true</code> if the receiver is a complex vector, <code>false</code> otherwise */
64
+ def complex?;false;end
65
+ # check whether the <code>REXP</code> object is a recursive obejct
66
+ # @return <code>true</code> if the receiver is a recursive object, <code>false</code> otherwise */
67
+ def recursive?;false;end
68
+ # check whether the <code>REXP</code> object is a reference to an R object
69
+ # @return <code>true</code> if the receiver is a reference, <code>false</code> otherwise */
70
+ def reference?;false;end
71
+
72
+ # :section: basic accessor methods
73
+ # returns the contents as an array of Strings (if supported by the represented object)
74
+ def as_strings;raise MismatchException, "String";end
75
+ # returns the contents as an array of integers (if supported by the represented object) */
76
+
77
+ def as_integers; raise MismatchException, "int";end;
78
+ # returns the contents as an array of doubles (if supported by the represented object) */
79
+ def as_doubles; raise MismatchException,"double";end;
80
+ # returns the contents as an array of bytes (if supported by the represented object) */
81
+ def as_bytes; raise MismatchException , "byte";end;
82
+ # returns the contents as a (named) list (if supported by the represented object) */
83
+ def as_list; raise MismatchException,"list";end;
84
+ # returns the contents as a factor (if supported by the represented object) */
85
+ def as_factor; raise MismatchException,"factor";end;
86
+
87
+ # returns the length of a vector object. Note that we use R semantics here, i.e. a matrix will have a length of <i>m * n</i> since it is represented by a single vector (see {@link #dim} for retrieving matrix and multidimentional-array dimensions).
88
+ # * @return length (number of elements) in a vector object
89
+ # * @throws MismatchException if this is not a vector object */
90
+ def length()
91
+ raise MismatchException, "vector";
92
+ end
93
+
94
+ # returns a boolean vector of the same length as this vector with <code>true</code> for NA values and <code>false</code> for any other values
95
+ # * @return a boolean vector of the same length as this vector with <code>true</code> for NA values and <code>false</code> for any other values
96
+ # * @throws MismatchException if this is not a vector object */
97
+ def na?
98
+ raise MismatchException, "vector"
99
+ end
100
+
101
+ # :section: convenience accessor methods
102
+ # convenience method corresponding to <code>as_integer()[0]</code>
103
+ # @return first entry returned by {@link #as_integer} */
104
+ def as_integer
105
+ as_integers[0]
106
+ end
107
+ # convenience method corresponding to <code>asDoubles()[0]</code>
108
+ # @return first entry returned by {@link #asDoubles} */
109
+ def as_double
110
+ as_doubles[0]
111
+ end
112
+ # convenience method corresponding to <code>asStrings()[0]</code>
113
+ # @return first entry returned by {@link #asStrings} */
114
+ def as_string
115
+ as_strings[0]
116
+ end
117
+ # // methods common to all REXPs
118
+
119
+ # retrieve an attribute of the given name from this object
120
+ # * @param name attribute name
121
+ # * @return attribute value or <code>null</code> if the attribute does not exist */
122
+
123
+ def get_attribute(name)
124
+ nil if @attr.nil? or !@attr.is_list?
125
+ @attr.as_list[name]
126
+ end
127
+
128
+ # checks whether this obejct has a given attribute
129
+ # * @param name attribute name
130
+ # * @return <code>true</code> if the attribute exists, <code>false</code> otherwise */
131
+ def has_attribute? (name)
132
+ return (!@attr.nil? and @attr.is_list and !@attr.as_list[name].nil?);
133
+ end
134
+
135
+
136
+ # :section: helper methods common to all REXPs
137
+
138
+ # returns dimensions of the object (as determined by the "<code>dim</code>" attribute)
139
+ # @return an array of integers with corresponding dimensions or <code>null</code> if the object has no dimension attribute */
140
+ def dim
141
+ begin
142
+ return has_attribute?("dim") ? @attr.as_list['dim'].as_integers : nil;
143
+ rescue MismatchException
144
+ # nothing to do
145
+ end
146
+ nil
147
+ end
148
+
149
+ # determines whether this object inherits from a given class in the same fashion as the <code>inherits()</code> function in R does (i.e. ignoring S4 inheritance)
150
+ # @param klass class name
151
+ # @return <code>true</code> if this object is of the class <code>klass</code>, <code>false</code> otherwise */
152
+ def inherits?(klass)
153
+ return false if (!has_attribute? "class")
154
+ begin
155
+ c = get_attribute("class").as_strings;
156
+ if (!c.nil?)
157
+ return c.any? {|v| v.equals klass}
158
+ end
159
+ rescue MismatchException
160
+ end
161
+ return false;
162
+ end
163
+
164
+
165
+
166
+ # returns a string description of the object
167
+ # @return string describing the object - it can be of an arbitrary form and used only for debugging (do not confuse with {@link #asString()} for accessing string REXPs) */
168
+ #def to_s
169
+ #return super+((!@attr.nil?) ? "+" : "");
170
+ # end
171
+
172
+ # returns representation that it useful for debugging (e.g. it includes attributes and may include vector values -- see {@link #maxDebugItems})
173
+ # @return extended description of the obejct -- it may include vector values
174
+ #def inspect {
175
+ # (!@attr.nil?) ? (("<"+@attr.inspect()+">")+to_s()) : to_s;
176
+ #}
177
+
178
+ #//======= complex convenience methods
179
+ # returns the content of the REXP as a ruby matrix of doubles (2D-array: m[rows][cols]). You could use Matrix.rows(result) to create
180
+ # a ruby dfeault library matrix.
181
+ # Matrix(c.eval("matrix(c(1,2,3,4,5,6),2,3)").asDoubleMatrix());</code>
182
+ # @return 2D array of doubles in the form double[rows][cols] or <code>null</code> if the contents is no 2-dimensional matrix of doubles */
183
+ def as_double_matrix()
184
+ ct = as_doubles()
185
+ dim =get_attribute "dim"
186
+ raise MismatchException, "matrix (dim attribute missing)" if dim.nil?
187
+ ds = dim.as_integers
188
+ raise MismatchException, "matrix (wrong dimensionality)" if (ds.length!=2)
189
+ m = ds[0], n = ds[1]
190
+ # R stores matrices as matrix(c(1,2,3,4),2,2) = col1:(1,2), col2:(3,4)
191
+ # we need to copy everything, since we create 2d array from 1d array
192
+ r=m.times.map {|i| n.times.map {|j| ct[j*n+i]}}
193
+ end
194
+ def to_s
195
+ (@attr.nil? ? "" : "+")
196
+ end
197
+ def to_debug_string
198
+ (@attr.nil? ? "" : "<"+@attr.to_debug_string+">")
199
+ end
200
+
201
+ # :section: tools
202
+
203
+ # creates a data frame object from a list object using integer row names
204
+ # * @param l a (named) list of vectors ({@link REXPVector} subclasses), each element corresponds to a column and all elements must have the same length
205
+ # * @return a data frame object
206
+ # * @throws MismatchException if the list is empty or any of the elements is not a vector */
207
+ def create_data_frame(l)
208
+ raise(MismatchException, "data frame (must have dim>0)") if l.nil? or l.size<1
209
+ raise MismatchException, "data frame (contents must be vectors)" if (!(l[0].is_a? REXP::Vector))
210
+ fe = l[0]
211
+ return REXP::GenericVector.new(l,
212
+ REXP::List.new(
213
+ RList.new(
214
+ [
215
+ REXP::String.new("data.frame"),
216
+ REXP::String.new(l.keys()),
217
+ REXP::Integer.new([REXP::Integer.NA, -fe.length()])
218
+ ],
219
+ ["class", "names", "row.names" ])
220
+ )
221
+ )
222
+ end
223
+ end
224
+ end
225
+
226
+ require 'rserve/rexp/vector'
227
+ require 'rserve/rexp/genericvector'
228
+ require 'rserve/rexp/integer'
229
+ require 'rserve/rexp/double'
230
+ require 'rserve/rexp/list'
231
+ require 'rserve/rexp/logical'
232
+ require 'rserve/rexp/string'
233
+ require 'rserve/rexp/symbol'
234
+