rucy 0.1.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.
data/src/value.cpp.erb ADDED
@@ -0,0 +1,409 @@
1
+ // -*- c++ -*-
2
+ % require 'support'
3
+ #include "rucy/value.h"
4
+
5
+
6
+ #include <rucy/rucy.h>
7
+ #include <rucy/function.h>
8
+ #include <rucy/exception.h>
9
+
10
+
11
+ namespace Rucy
12
+ {
13
+
14
+
15
+ Value::Value ()
16
+ : v(Qnil)
17
+ {
18
+ }
19
+
20
+ Value::Value (bool b)
21
+ : v(b ? Qtrue : Qfalse)
22
+ {
23
+ }
24
+
25
+ Value::Value (int n)
26
+ : v(INT2FIX(n))
27
+ {
28
+ }
29
+
30
+ Value::Value (float f)
31
+ : v(rb_float_new(f))
32
+ {
33
+ }
34
+
35
+ Value::Value (double d)
36
+ : v(rb_float_new(d))
37
+ {
38
+ }
39
+
40
+ Value::Value (const char* s, bool tainted)
41
+ : v(tainted ? rb_tainted_str_new2(s) : rb_str_new2(s))
42
+ {
43
+ }
44
+
45
+ Value::Value (const char* s, size_t len, bool tainted)
46
+ : v(tainted ? rb_tainted_str_new(s, len) : rb_str_new(s, len))
47
+ {
48
+ }
49
+
50
+ Value::Value (size_t size, const Value* values)
51
+ : v(size > 0 ? rb_ary_new2(size) : rb_ary_new())
52
+ {
53
+ if (!values) return;
54
+ for (size_t i = 0; i < size; ++i)
55
+ push(values[i]);
56
+ }
57
+
58
+ Value::Value (VALUE v)
59
+ : v(v)
60
+ {
61
+ }
62
+
63
+ VALUE
64
+ Value::value () const
65
+ {
66
+ return v;
67
+ }
68
+
69
+ void
70
+ Value::mark () const
71
+ {
72
+ rb_gc_mark(v);
73
+ }
74
+
75
+ int
76
+ Value::type () const
77
+ {
78
+ return TYPE(v);
79
+ }
80
+
81
+ Value
82
+ Value::klass () const
83
+ {
84
+ return RBASIC(v)->klass;
85
+ }
86
+
87
+ bool
88
+ Value::is_kind_of (Value klass) const
89
+ {
90
+ SYM_Q(kind_of);
91
+ return call(kind_of, klass);
92
+ }
93
+
94
+ static int
95
+ get_object_size (Value obj, Symbol method)
96
+ {
97
+ if (obj.type() == T_STRING)
98
+ return RSTRING_LEN(obj.value());
99
+ else if (obj.type() == T_ARRAY)
100
+ return RARRAY_LEN(obj.value());
101
+ else
102
+ return obj.call(method);
103
+ }
104
+
105
+ int
106
+ Value::size () const
107
+ {
108
+ SYM(size);
109
+ return get_object_size(v, size);
110
+ }
111
+
112
+ int
113
+ Value::length () const
114
+ {
115
+ SYM(length);
116
+ return get_object_size(v, length);
117
+ }
118
+
119
+ Value
120
+ Value::to_i () const
121
+ {
122
+ if (FIXNUM_P(v) || TYPE(v) == T_BIGNUM) return *this;
123
+ SYM(to_i);
124
+ return call(to_i);
125
+ }
126
+
127
+ Value
128
+ Value::to_f () const
129
+ {
130
+ if (TYPE(v) == T_FLOAT) return *this;
131
+ SYM(to_f);
132
+ return call(to_f);
133
+ }
134
+
135
+ Value
136
+ Value::to_s () const
137
+ {
138
+ if (TYPE(v) == T_STRING) return *this;
139
+ SYM(to_s);
140
+ return call(to_s);
141
+ }
142
+
143
+ Value
144
+ Value::to_sym () const
145
+ {
146
+ if (TYPE(v) == T_SYMBOL) return *this;
147
+ SYM(to_sym);
148
+ return call(to_sym);
149
+ }
150
+
151
+ bool
152
+ Value::is_i () const
153
+ {
154
+ return is_kind_of(rb_cFixnum);
155
+ }
156
+
157
+ bool
158
+ Value::is_f () const
159
+ {
160
+ return is_kind_of(rb_cFloat);
161
+ }
162
+
163
+ bool
164
+ Value::is_s () const
165
+ {
166
+ return is_kind_of(rb_cString);
167
+ }
168
+
169
+ bool
170
+ Value::is_sym () const
171
+ {
172
+ return is_kind_of(rb_cSymbol);
173
+ }
174
+
175
+ bool
176
+ Value::is_a () const
177
+ {
178
+ return is_kind_of(rb_cArray);
179
+ }
180
+
181
+ int
182
+ Value::as_i (bool convert) const
183
+ {
184
+ return to<int>(*this, convert);
185
+ }
186
+
187
+ double
188
+ Value::as_f (bool convert) const
189
+ {
190
+ return to<double>(*this, convert);
191
+ }
192
+
193
+ const char*
194
+ Value::as_s (bool convert) const
195
+ {
196
+ return to<const char*>(*this, convert);
197
+ }
198
+
199
+ Symbol
200
+ Value::as_sym (bool convert) const
201
+ {
202
+ return to<Symbol>(*this, convert);
203
+ }
204
+
205
+ % ["call", "operator ()"].each do |op|
206
+ Value
207
+ Value::<%= op %> (Symbol name, int argc, const Value* argv) const
208
+ {
209
+ return protect(rb_funcall2, value(), name.id(), argc, (const VALUE*) argv);
210
+ }
211
+ % NTIMES.each do |n|
212
+ Value
213
+ Value::<%= op %> (Symbol name<%= params(n) {|i| ", Value v#{i}"} %>) const
214
+ {
215
+ const VALUE args[] = {<%= params(n, ", ") {|i| "v#{i}"} %>};
216
+ return protect(rb_funcall2, value(), name.id(), <%= n %>, args);
217
+ }
218
+ % end
219
+ % end
220
+
221
+ Value
222
+ Value::inspect () const
223
+ {
224
+ SYM(inspect);
225
+ return call(inspect);
226
+ }
227
+
228
+ const char*
229
+ Value::c_str () const
230
+ {
231
+ return value_to<const char*>(*this);
232
+ }
233
+
234
+ Value&
235
+ Value::operator [] (int i)
236
+ {
237
+ if (type() != T_ARRAY) type_error();
238
+ return *(Value*) &RARRAY_PTR(v)[i];
239
+ }
240
+
241
+ const Value&
242
+ Value::operator [] (int i) const
243
+ {
244
+ return const_cast<Value*>(this)->operator[](i);
245
+ }
246
+
247
+ Value::operator VALUE () const
248
+ {
249
+ return value();
250
+ }
251
+
252
+ static bool
253
+ test_value (VALUE v)
254
+ {
255
+ return !NIL_P(v) && v != Qfalse;// RTEST(v);
256
+ }
257
+
258
+ Value::operator bool () const
259
+ {
260
+ return test_value(v);
261
+ }
262
+
263
+ bool
264
+ Value::operator ! () const
265
+ {
266
+ return !operator bool();
267
+ }
268
+
269
+ bool
270
+ Value::operator == (const Value& rhs) const
271
+ {
272
+ return v == rhs.v;// test_value(rb_obj_equal(v, rhs.v);
273
+ }
274
+
275
+ bool
276
+ Value::operator != (const Value& rhs) const
277
+ {
278
+ return !operator==(rhs);
279
+ }
280
+
281
+ Value
282
+ Value::push (Value obj)
283
+ {
284
+ return rb_ary_push(value(), obj.value());
285
+ }
286
+
287
+ Value
288
+ Value::pop ()
289
+ {
290
+ return rb_ary_pop(value());
291
+ }
292
+
293
+ Value
294
+ Value::shift ()
295
+ {
296
+ return rb_ary_shift(value());
297
+ }
298
+
299
+ Value
300
+ Value::unshift (Value obj)
301
+ {
302
+ return rb_ary_unshift(value(), obj.value());
303
+ }
304
+
305
+
306
+ Value
307
+ value (bool b)
308
+ {
309
+ return b;
310
+ }
311
+
312
+ Value
313
+ value (char n)
314
+ {
315
+ return (int) n;
316
+ }
317
+
318
+ Value
319
+ value (unsigned char n)
320
+ {
321
+ return (int) n;
322
+ }
323
+
324
+ Value
325
+ value (short n)
326
+ {
327
+ return (int) n;
328
+ }
329
+
330
+ Value
331
+ value (unsigned short n)
332
+ {
333
+ return (int) n;
334
+ }
335
+
336
+ Value
337
+ value (int n)
338
+ {
339
+ return n;
340
+ }
341
+
342
+ Value
343
+ value (unsigned int n)
344
+ {
345
+ return UINT2NUM(n);
346
+ }
347
+
348
+ Value
349
+ value (long n)
350
+ {
351
+ return LONG2NUM(n);
352
+ }
353
+
354
+ Value
355
+ value (unsigned long n)
356
+ {
357
+ return ULONG2NUM(n);
358
+ }
359
+
360
+ Value
361
+ value (long long n)
362
+ {
363
+ return LL2NUM(n);
364
+ }
365
+
366
+ Value
367
+ value (unsigned long long n)
368
+ {
369
+ return ULL2NUM(n);
370
+ }
371
+
372
+ Value
373
+ value (float f)
374
+ {
375
+ return f;
376
+ }
377
+
378
+ Value
379
+ value (double d)
380
+ {
381
+ return d;
382
+ }
383
+
384
+ Value
385
+ value (const char* s, bool tainted)
386
+ {
387
+ return Value(s, tainted);
388
+ }
389
+
390
+ Value
391
+ value (const char* s, size_t len, bool tainted)
392
+ {
393
+ return Value(s, len, tainted);
394
+ }
395
+
396
+ Value
397
+ value (size_t size, const Value* values)
398
+ {
399
+ return Value(size, values);
400
+ }
401
+
402
+ Value
403
+ value (Symbol sym)
404
+ {
405
+ return ID2SYM(sym.id());
406
+ }
407
+
408
+
409
+ }// Rucy
data/support.rb ADDED
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'erb'
3
+ require 'pp'
4
+
5
+
6
+ NPARAM_MAX = 8
7
+ NTIMES = (0..NPARAM_MAX)
8
+
9
+
10
+ def version ()
11
+ open("VERSION") {|f| f.readline.chomp}
12
+ end
13
+
14
+ def glob (*patterns)
15
+ paths = []
16
+ patterns.each do |pattern|
17
+ paths.concat Dir.glob(pattern)
18
+ end
19
+ paths
20
+ end
21
+
22
+ def erb (str)
23
+ ERB.new(str, nil, "%").result binding
24
+ end
25
+
26
+ def compile (path, out)
27
+ open(path) do |input|
28
+ open(out, "w") do |output|
29
+ output.write erb(input.read)
30
+ end
31
+ end
32
+ #rescue
33
+ end
34
+
35
+ def params (n, sep = "", &block)
36
+ raise "block not given." unless block
37
+ return "" if n == 0
38
+ (1..n).map(&block).join(sep)
39
+ end
40
+
41
+ def convertions (paths, convs)
42
+ raise "empty conversion." if convs.empty?
43
+ paths.map! do |path|
44
+ convpath = path
45
+ convs.each do |from, to|
46
+ convpath = convpath.sub(/#{from.gsub('.', '\.')}$/, to)
47
+ end
48
+ [path, convpath]
49
+ end
50
+ Hash[*paths.flatten]
51
+ end
52
+
53
+ alias sh_original sh
54
+
55
+ def sh (s)
56
+ sh_original s
57
+ #rescue
58
+ end
data/task/ext.rake ADDED
@@ -0,0 +1,36 @@
1
+ # -*- mode: ruby; coding: utf-8 -*-
2
+
3
+
4
+ namespace :ext do
5
+
6
+ dir = "#{EXTDIR}/#{NAME}"
7
+ name = "#{NAME}/tester"
8
+ outname = "#{name}.#{EXTEXT}"
9
+ out = File.join EXTDIR, outname
10
+
11
+ extconf = File.join dir, "extconf.rb"
12
+ makefile = File.join dir, "Makefile"
13
+ depends = File.join dir, "depends"
14
+
15
+ cpps = Dir.glob("#{dir}/**/*.cpp")
16
+
17
+ task :build => out
18
+
19
+ task :clean do
20
+ sh %( cd #{dir} && #{MAKE} clean ) if File.exist? makefile
21
+ sh %( rm -f #{makefile} #{depends} )
22
+ end
23
+
24
+ file out => makefile do
25
+ sh %( cd #{dir} && #{MAKE} )
26
+ end
27
+
28
+ file makefile => [extconf, "lib:build"] do #, depends] do
29
+ sh %( cd #{dir} && #{RUBY} #{File.basename extconf} )
30
+ end
31
+
32
+ file depends => cpps do
33
+ sh %( cd #{dir} && touch #{depends} )
34
+ end
35
+
36
+ end# :ext
data/task/gem.rake ADDED
@@ -0,0 +1,33 @@
1
+ # -*- mode: ruby; coding: utf-8 -*-
2
+
3
+
4
+ namespace :gem do
5
+
6
+ name = NAME
7
+
8
+ gemspec = "#{name}.gemspec"
9
+ gem = "#{name}-#{version}.gem"
10
+
11
+ task :build => gem
12
+
13
+ task :install => gem do
14
+ sh %( #{GEM} install #{gem} )
15
+ end
16
+
17
+ task :uninstall do
18
+ sh %( #{GEM} uninstall #{name} )
19
+ end
20
+
21
+ task :clean do
22
+ sh %( rm -f #{gem} )
23
+ end
24
+
25
+ task :upload => gem do
26
+ sh %( #{GEM} push #{gem} )
27
+ end
28
+
29
+ file gem => "lib:build" do
30
+ sh %( #{GEM} build #{gemspec} )
31
+ end
32
+
33
+ end# :gem
data/task/lib.rake ADDED
@@ -0,0 +1,47 @@
1
+ # -*- mode: ruby; coding: utf-8 -*-
2
+
3
+
4
+ namespace :lib do
5
+
6
+ name = NAME
7
+ outname = "lib#{name}.a"
8
+ out = File.join LIBDIR, outname
9
+
10
+ erbs = convertions glob("**/*.erb"), {".erb" => ""}
11
+ headers = glob("include/**/*.h") | erbs.values.grep(/\.h$/)
12
+ srcs = glob("src/**/*.cpp") | erbs.values.grep(/\.cpp$/)
13
+
14
+ objs = convertions srcs, {".cpp" => ".o"}
15
+ tmps = objs.values | erbs.values
16
+
17
+ task :build => out
18
+
19
+ task :compile => objs.values
20
+
21
+ task :erb => erbs.values
22
+
23
+ task :clean do
24
+ sh %( rm -rf #{tmps.join " "} #{out} )
25
+ end
26
+
27
+ file out => objs.values do
28
+ sh %( #{AR} #{ARFLAGS} #{out} #{objs.values.join " "} )
29
+ end
30
+
31
+ objs.each do |(src, obj)|
32
+ incdirs = INCDIRS.map{|s| " -I#{s}"}.join
33
+
34
+ file obj => [src] + erbs.values do
35
+ sh %( #{CC} -c #{CFLAGS} #{incdirs} -o #{obj} #{src} )
36
+ end
37
+ end
38
+
39
+ erbs.each do |(erb, out)|
40
+ file out => [erb] + RBS do
41
+ print "#{erb}: compiling to #{out}..."
42
+ compile erb, out
43
+ puts "ok"
44
+ end
45
+ end
46
+
47
+ end# :lib
data/test/test_rucy.rb ADDED
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ $: << File.expand_path(File.join File.dirname(__FILE__), "..", "ext")
3
+ require 'test/unit'
4
+ require 'rucy/tester'
5
+
6
+
7
+ class TestTester < Test::Unit::TestCase
8
+
9
+ def setup ()
10
+ @t = Rucy::Tester.new
11
+ end
12
+
13
+ def test_no_return_returns_nil ()
14
+ assert_equal nil, @t.do_nothing
15
+ end
16
+
17
+ def test_returns_nil ()
18
+ assert_equal nil, @t.return_nil
19
+ end
20
+
21
+ def test_return_int ()
22
+ assert_kind_of Integer, @t.return_int
23
+ end
24
+
25
+ def test_return_float ()
26
+ assert_kind_of Float, @t.return_float
27
+ end
28
+
29
+ def test_return_string ()
30
+ assert_kind_of String, @t.return_string
31
+ end
32
+
33
+ def test_raise_ruby_exception ()
34
+ assert_raise(StandardError) {@t.raise_ruby_exception}
35
+ end
36
+
37
+ def test_raise_in_eval ()
38
+ assert_raise(RuntimeError) {@t.raise_in_eval}
39
+ end
40
+
41
+ def test_throw_std_exception ()
42
+ assert_raise(Rucy::NativeError) {@t.throw_std_exception}
43
+ end
44
+
45
+ def test_throw_std_runtime_error ()
46
+ assert_raise(Rucy::NativeError) {@t.throw_std_runtime_error}
47
+ end
48
+
49
+ def test_throw_std_string ()
50
+ assert_raise(Rucy::NativeError) {@t.throw_std_string}
51
+ end
52
+
53
+ def test_throw_cstring ()
54
+ assert_raise(Rucy::NativeError) {@t.throw_cstring}
55
+ end
56
+
57
+ end # TestTester