rucy 0.1.0

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