rucy 0.1.3 → 0.1.4

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.
Files changed (50) hide show
  1. data/.doc/ext/rucy/class.cpp +244 -0
  2. data/.doc/ext/rucy/exception.cpp +99 -0
  3. data/.doc/ext/rucy/function.cpp +63 -0
  4. data/.doc/ext/rucy/struct.cpp +80 -0
  5. data/.doc/ext/rucy/tester.cpp +41 -184
  6. data/.doc/ext/rucy/value.cpp +42 -0
  7. data/.gitignore +22 -0
  8. data/Rakefile +4 -29
  9. data/VERSION +1 -1
  10. data/ext/rucy/class.cpp +262 -0
  11. data/ext/rucy/class.h +96 -0
  12. data/ext/rucy/exception.cpp +107 -0
  13. data/ext/rucy/extconf.rb +9 -8
  14. data/ext/rucy/function.cpp +68 -0
  15. data/ext/rucy/struct.cpp +83 -0
  16. data/ext/rucy/tester.cpp +41 -197
  17. data/ext/rucy/tester.h +10 -0
  18. data/ext/rucy/value.cpp +46 -0
  19. data/include/rucy/defs.h.erb +17 -0
  20. data/include/rucy/exception.h +2 -0
  21. data/include/rucy/extension.h +206 -0
  22. data/include/rucy/rucy.h +25 -2
  23. data/include/rucy/symbol.h +11 -0
  24. data/include/rucy/value.h.erb +66 -14
  25. data/include/rucy.h +1 -1
  26. data/lib/rucy/module.rb +9 -2
  27. data/rucy.gemspec +16 -40
  28. data/src/exception.cpp +17 -25
  29. data/src/rucy.cpp +2 -2
  30. data/src/symbol.cpp +24 -0
  31. data/src/value.cpp.erb +161 -25
  32. data/task/doc.rake +50 -0
  33. data/test/helpers.rb +7 -0
  34. data/test/test_class.rb +161 -0
  35. data/test/test_exception.rb +39 -0
  36. data/test/test_function.rb +31 -0
  37. data/test/test_struct.rb +30 -0
  38. data/test/test_value.rb +18 -0
  39. metadata +123 -74
  40. data/include/rucy/defs.h +0 -101
  41. data/include/rucy/function.h +0 -245
  42. data/include/rucy/gc.h +0 -59
  43. data/include/rucy/module.h +0 -98
  44. data/include/rucy/value.h +0 -291
  45. data/src/function.cpp +0 -158
  46. data/src/gc.cpp +0 -63
  47. data/src/module.cpp +0 -325
  48. data/src/value.cpp +0 -511
  49. data/task/ext.rake +0 -96
  50. data/test/test_rucy.rb +0 -73
data/src/rucy.cpp CHANGED
@@ -33,10 +33,10 @@ namespace Rucy
33
33
  SYMBOL(klass, "class");
34
34
  SYM(name);
35
35
  String message = stringf(
36
- "object is instance of %s, bug %s is expected.",
36
+ "object is instance of %s, but %s is expected.",
37
37
  obj(klass)(name).c_str(), class_(name).c_str());
38
38
 
39
- throw RubyException(rb_eTypeError, message);
39
+ type_error(message.c_str());
40
40
  #endif
41
41
  }
42
42
 
data/src/symbol.cpp CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
 
5
5
  #include <rucy/rucy.h>
6
+ #include <rucy/value.h>
6
7
 
7
8
 
8
9
  namespace Rucy
@@ -19,6 +20,11 @@ namespace Rucy
19
20
  {
20
21
  }
21
22
 
23
+ Symbol::Symbol (const Value& value)
24
+ : id_(value.as_sym().id())
25
+ {
26
+ }
27
+
22
28
  Symbol::Symbol (const char* str)
23
29
  : id_(rb_intern(str))
24
30
  {
@@ -30,6 +36,12 @@ namespace Rucy
30
36
  return id_;
31
37
  }
32
38
 
39
+ VALUE
40
+ Symbol::value () const
41
+ {
42
+ return id_ != 0 ? ID2SYM(id_) : Qnil;
43
+ }
44
+
33
45
  const char*
34
46
  Symbol::c_str () const
35
47
  {
@@ -47,5 +59,17 @@ namespace Rucy
47
59
  return !operator bool();
48
60
  }
49
61
 
62
+ bool
63
+ operator == (const Symbol& lhs, const Symbol& rhs)
64
+ {
65
+ return lhs.id_ == rhs.id_;
66
+ }
67
+
68
+ bool
69
+ operator != (const Symbol& lhs, const Symbol& rhs)
70
+ {
71
+ return !operator==(lhs, rhs);
72
+ }
73
+
50
74
 
51
75
  }// Rucy
data/src/value.cpp.erb CHANGED
@@ -2,6 +2,7 @@
2
2
  #include "rucy/value.h"
3
3
 
4
4
 
5
+ #include <assert.h>
5
6
  #include <rucy/rucy.h>
6
7
  #include <rucy/function.h>
7
8
  #include <rucy/exception.h>
@@ -37,12 +38,12 @@ namespace Rucy
37
38
  }
38
39
 
39
40
  Value::Value (const char* s, bool tainted)
40
- : v(tainted ? rb_tainted_str_new2(s) : rb_str_new2(s))
41
+ : v(!s ? Qnil : tainted ? rb_tainted_str_new2(s) : rb_str_new2(s))
41
42
  {
42
43
  }
43
44
 
44
45
  Value::Value (const char* s, size_t len, bool tainted)
45
- : v(tainted ? rb_tainted_str_new(s, len) : rb_str_new(s, len))
46
+ : v(!s ? Qnil : tainted ? rb_tainted_str_new(s, len) : rb_str_new(s, len))
46
47
  {
47
48
  }
48
49
 
@@ -94,9 +95,9 @@ namespace Rucy
94
95
  get_object_size (Value obj, Symbol method)
95
96
  {
96
97
  if (obj.type() == T_STRING)
97
- return RSTRING_LEN(obj.value());
98
+ return (int) RSTRING_LEN(obj.value());
98
99
  else if (obj.type() == T_ARRAY)
99
- return RARRAY_LEN(obj.value());
100
+ return (int) RARRAY_LEN(obj.value());
100
101
  else
101
102
  return obj.call(method);
102
103
  }
@@ -147,6 +148,30 @@ namespace Rucy
147
148
  return call(to_sym);
148
149
  }
149
150
 
151
+ int
152
+ Value::as_i (bool convert) const
153
+ {
154
+ return to<int>(*this, convert);
155
+ }
156
+
157
+ double
158
+ Value::as_f (bool convert) const
159
+ {
160
+ return to<double>(*this, convert);
161
+ }
162
+
163
+ const char*
164
+ Value::as_s (bool convert) const
165
+ {
166
+ return to<const char*>(*this, convert);
167
+ }
168
+
169
+ Symbol
170
+ Value::as_sym (bool convert) const
171
+ {
172
+ return to<Symbol>(*this, convert);
173
+ }
174
+
150
175
  bool
151
176
  Value::is_i () const
152
177
  {
@@ -177,28 +202,10 @@ namespace Rucy
177
202
  return is_kind_of(rb_cArray);
178
203
  }
179
204
 
180
- int
181
- Value::as_i (bool convert) const
182
- {
183
- return to<int>(*this, convert);
184
- }
185
-
186
- double
187
- Value::as_f (bool convert) const
188
- {
189
- return to<double>(*this, convert);
190
- }
191
-
192
- const char*
193
- Value::as_s (bool convert) const
194
- {
195
- return to<const char*>(*this, convert);
196
- }
197
-
198
- Symbol
199
- Value::as_sym (bool convert) const
205
+ bool
206
+ Value::is_nil () const
200
207
  {
201
- return to<Symbol>(*this, convert);
208
+ return NIL_P(v);
202
209
  }
203
210
 
204
211
  % ["call", "operator ()"].each do |op|
@@ -302,6 +309,122 @@ namespace Rucy
302
309
  }
303
310
 
304
311
 
312
+ GlobalValue::GlobalValue ()
313
+ {
314
+ init(false);
315
+ }
316
+
317
+ GlobalValue::GlobalValue (bool b, bool gc_)
318
+ : Super(b)
319
+ {
320
+ init(gc_);
321
+ }
322
+
323
+ GlobalValue::GlobalValue (int i, bool gc_)
324
+ : Super(i)
325
+ {
326
+ init(gc_);
327
+ }
328
+
329
+ GlobalValue::GlobalValue (float f, bool gc_)
330
+ : Super(f)
331
+ {
332
+ init(gc_);
333
+ }
334
+
335
+ GlobalValue::GlobalValue (double d, bool gc_)
336
+ : Super(d)
337
+ {
338
+ init(gc_);
339
+ }
340
+
341
+ GlobalValue::GlobalValue (const char* s, bool tainted, bool gc_)
342
+ : Super(s, tainted)
343
+ {
344
+ init(gc_);
345
+ }
346
+
347
+ GlobalValue::GlobalValue (const char* s, size_t len, bool tainted, bool gc_)
348
+ : Super(s, len, tainted)
349
+ {
350
+ init(gc_);
351
+ }
352
+
353
+ GlobalValue::GlobalValue (size_t size, const Value* values, bool gc_)
354
+ : Super(size, values)
355
+ {
356
+ init(gc_);
357
+ }
358
+
359
+ GlobalValue::GlobalValue (VALUE v, bool gc_)
360
+ : Super(v)
361
+ {
362
+ init(gc_);
363
+ }
364
+
365
+ GlobalValue::GlobalValue (const Value& obj, bool gc_)
366
+ : Super(obj)
367
+ {
368
+ init(gc_);
369
+ }
370
+
371
+ GlobalValue::GlobalValue (const GlobalValue& obj, bool gc_)
372
+ : Super(obj)
373
+ {
374
+ init(gc_);
375
+ }
376
+
377
+ GlobalValue&
378
+ GlobalValue::operator = (const Value& obj)
379
+ {
380
+ Super::operator=(obj);
381
+ update_guard();
382
+ return *this;
383
+ }
384
+
385
+ GlobalValue::~GlobalValue ()
386
+ {
387
+ while (gc_guarded) gc(true);
388
+ }
389
+
390
+ void
391
+ GlobalValue::gc (bool enable)
392
+ {
393
+ gc_disable_count += enable ? -1 : +1;
394
+ update_guard();
395
+ }
396
+
397
+ void
398
+ GlobalValue::init (bool gc_)
399
+ {
400
+ gc_disable_count = 0;
401
+ gc_guarded = false;
402
+ if (!gc_) gc(false);
403
+ }
404
+
405
+ void
406
+ GlobalValue::update_guard ()
407
+ {
408
+ assert(gc_disable_count >= 0);
409
+
410
+ if (IMMEDIATE_P(v))
411
+ {
412
+ if (gc_guarded) rb_gc_unregister_address(&v);
413
+ gc_guarded = false;
414
+ }
415
+ else if (gc_disable_count > 0)
416
+ {
417
+ if (!gc_guarded) rb_gc_register_address(&v);
418
+ gc_guarded = true;
419
+ }
420
+ else
421
+ {
422
+ if (gc_guarded) rb_gc_unregister_address(&v);
423
+ gc_guarded = false;
424
+ }
425
+ }
426
+
427
+
305
428
  Value
306
429
  value (bool b)
307
430
  {
@@ -404,5 +527,18 @@ namespace Rucy
404
527
  return ID2SYM(sym.id());
405
528
  }
406
529
 
530
+ Value
531
+ value (void* ptr)
532
+ {
533
+ if (ptr) argument_error("Rucy::value(void*) can take only (void*) NULL.");
534
+ return Qnil;
535
+ }
536
+
537
+ Value
538
+ nil ()
539
+ {
540
+ return Qnil;
541
+ }
542
+
407
543
 
408
544
  }// Rucy
data/task/doc.rake ADDED
@@ -0,0 +1,50 @@
1
+ # -*- mode: ruby; coding: utf-8 -*-
2
+
3
+
4
+ task :doc => 'doc:build'
5
+
6
+ %w[clean rdoc].each do |t|
7
+ task t.intern => "doc:#{t}"
8
+ end
9
+
10
+
11
+ namespace :doc do
12
+
13
+
14
+ mod = MODULE
15
+ name = env :NAME, MODULE.name.downcase
16
+ extdir = env :EXTDIR, 'ext'
17
+ docdir = env :DOCDIR, 'doc'
18
+ rdoc = env :RDOC, 'rdoc'# 'yardoc'
19
+ rucy2rdoc = env :RUCY2RDOC, 'rucy2rdoc'
20
+
21
+ srcdir = "#{extdir}/#{name}"
22
+ rdocdir = ".doc/#{srcdir}"
23
+
24
+ srcs = FileList["#{srcdir}/**/*.cpp"]
25
+ rdocs = Hash[srcs.map{|path| [path, "#{rdocdir}/#{File.basename path}"]}]
26
+ out = "#{docdir}/index.html"
27
+
28
+
29
+ task :build => out
30
+
31
+ task :clean do
32
+ sh %( rm -rf #{docdir} #{rdocs.values.join ' '} )
33
+ end
34
+
35
+ task :rdoc => rdocs.values
36
+
37
+ file out => :rdoc do
38
+ sh %( #{rdoc} #{rdocs.values.join ' '} )
39
+ end
40
+
41
+ rdocs.each do |(cpp, rdoc)|
42
+ file rdoc => [cpp, rdocdir] do
43
+ sh %( #{rucy2rdoc} #{cpp} > #{rdoc} )
44
+ end
45
+ end
46
+
47
+ directory rdocdir
48
+
49
+
50
+ end# :doc
data/test/helpers.rb ADDED
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require 'bundler/setup'
5
+ require 'test/unit'
6
+ require 'rucy'
7
+ require 'rucy/tester'
@@ -0,0 +1,161 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helpers'
5
+
6
+
7
+ class Temp < Rucy::Tester::Sub
8
+
9
+ def name ()
10
+ "Temp::name"
11
+ end
12
+
13
+ def name_overridable ()
14
+ "Temp::name_overridable"
15
+ end
16
+
17
+ def name_overridable_faster ()
18
+ "Temp::name_overridable_faster"
19
+ end
20
+
21
+ end# Temp
22
+
23
+
24
+ class TestClass < Test::Unit::TestCase
25
+
26
+ include Rucy::Tester
27
+
28
+ def base (*args)
29
+ Base.new *args
30
+ end
31
+
32
+ def sub (*args)
33
+ Sub.new *args
34
+ end
35
+
36
+ def temp (*args)
37
+ Temp.new *args
38
+ end
39
+
40
+ def base_raw (*args)
41
+ Base.new_raw *args
42
+ end
43
+
44
+ def sub_raw (*args)
45
+ Sub.new_raw *args
46
+ end
47
+
48
+ def test_is_kind_of_base ()
49
+ assert_kind_of Base, base
50
+ assert_kind_of Base, base_raw
51
+
52
+ assert_kind_of Base, sub
53
+ assert_kind_of Base, sub_raw
54
+ assert_kind_of Sub, sub
55
+ assert_kind_of Sub, sub_raw
56
+
57
+ assert_kind_of Base, temp
58
+ assert_kind_of Sub, temp
59
+ assert_kind_of Temp, temp
60
+
61
+ assert !base .kind_of?(Sub)
62
+ assert !base_raw .kind_of?(Sub)
63
+ assert !base .kind_of?(Temp)
64
+ assert !base_raw .kind_of?(Temp)
65
+
66
+ assert !sub .kind_of?(Temp)
67
+ assert !sub_raw.kind_of?(Temp)
68
+ end
69
+
70
+ def test_name ()
71
+ assert_equal "Base::name", base .name
72
+ assert_equal "Base::name", base_raw.name
73
+ assert_equal "Sub::name", sub .name
74
+ assert_equal "Sub::name", sub_raw .name
75
+ assert_equal "Temp::name", temp .name
76
+ end
77
+
78
+ def test_name_overridable ()
79
+ assert_equal "Base::name_overridable", base .name_overridable
80
+ assert_equal "Base::name_overridable", base_raw.name_overridable
81
+ assert_equal "Sub::name_overridable", sub .name_overridable
82
+ assert_equal "Sub::name_overridable", sub_raw .name_overridable
83
+ assert_equal "Temp::name_overridable", temp .name_overridable
84
+ end
85
+
86
+ def test_call_name ()
87
+ assert_equal "Base::name", base .call_name
88
+ assert_equal "Base::name", base_raw.call_name
89
+ assert_equal "Sub::name", sub .call_name
90
+ assert_equal "Sub::name", sub_raw .call_name
91
+ assert_equal "Sub::name", temp .call_name # returns "Sub" not "Temp"!
92
+ end
93
+
94
+ def test_call_name_overridable ()
95
+ assert_equal "Base::name_overridable", base .call_name_overridable
96
+ assert_equal "Base::name_overridable", base_raw.call_name_overridable
97
+ assert_equal "Sub::name_overridable", sub .call_name_overridable
98
+ assert_equal "Sub::name_overridable", sub_raw .call_name_overridable
99
+ assert_equal "Temp::name_overridable", temp .call_name_overridable
100
+ end
101
+
102
+ class X < Sub; end
103
+
104
+ def test_is_overridden ()
105
+ m = :name_overridable_faster
106
+ def is_overridden (o) o.is_name_overridable_faster_overridden; end
107
+
108
+ assert_equal true, is_overridden(temp)
109
+
110
+ o = X.new
111
+ assert_equal false, is_overridden(o)
112
+ def o.name_overridable_faster () end
113
+ assert_equal true, is_overridden(o)
114
+
115
+ o = X.new
116
+ assert_equal false, is_overridden(o)
117
+ eval "class X; def #{m}; end; end"
118
+ assert_equal true, is_overridden(o)
119
+ eval "class X; remove_method :#{m}; end"
120
+ assert_equal false, is_overridden(o)
121
+
122
+ o = X.new
123
+ assert_equal false, is_overridden(o)
124
+ X.send(:define_method, m) {}
125
+ assert_equal true, is_overridden(o)
126
+ X.send :remove_method, m
127
+ assert_equal false, is_overridden(o)
128
+ end
129
+
130
+ def test_gc ()
131
+ def gc () 10.times {GC.start} end
132
+ rt = Rucy::Tester
133
+
134
+ gc
135
+ rt.clear_logs
136
+
137
+ o = RubyObj.new
138
+ assert_equal 'RubyObj()', last_log
139
+ gc
140
+ assert_equal 'RubyObj()', last_log
141
+ o = nil
142
+ gc
143
+ assert_equal '~RubyObj()', last_log
144
+
145
+ gc
146
+ rt.clear_logs
147
+
148
+ o = RubyObj.new
149
+ assert_equal 'RubyObj()', last_log
150
+ RubyObj.set_ref o
151
+ gc
152
+ assert_equal 'RubyObj()', last_log
153
+ o = nil
154
+ gc
155
+ assert_equal 'RubyObj()', last_log
156
+ RubyObj.clear_ref
157
+ gc
158
+ assert_equal '~RubyObj()', last_log
159
+ end
160
+
161
+ end# TestClass
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helpers'
5
+
6
+
7
+ class TestException < Test::Unit::TestCase
8
+
9
+ include Rucy::Tester
10
+
11
+ def test_raise_ruby_exception ()
12
+ assert_raise(StandardError) {raise_ruby_exception}
13
+ end
14
+
15
+ def test_raise_in_eval ()
16
+ assert_raise(RuntimeError) {raise_in_eval}
17
+ end
18
+
19
+ def test_throw_std_exception ()
20
+ assert_raise(Rucy::NativeError) {throw_std_exception}
21
+ end
22
+
23
+ def test_throw_std_runtime_error ()
24
+ assert_raise(Rucy::NativeError) {throw_std_runtime_error}
25
+ end
26
+
27
+ def test_throw_custom_exception ()
28
+ assert_raise(Rucy::NativeError) {throw_custom_exception}
29
+ end
30
+
31
+ def test_throw_std_string ()
32
+ assert_raise(Rucy::NativeError) {throw_std_string}
33
+ end
34
+
35
+ def test_throw_cstring ()
36
+ assert_raise(Rucy::NativeError) {throw_cstring}
37
+ end
38
+
39
+ end# TestException
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helpers'
5
+
6
+
7
+ class TestFunction < Test::Unit::TestCase
8
+
9
+ include Rucy::Tester
10
+
11
+ def test_do_nothing_returns_nil ()
12
+ assert_equal nil, do_nothing
13
+ end
14
+
15
+ def test_returns_nil ()
16
+ assert_equal nil, return_nil
17
+ end
18
+
19
+ def test_return_int ()
20
+ assert_kind_of Integer, return_int
21
+ end
22
+
23
+ def test_return_float ()
24
+ assert_kind_of Float, return_float
25
+ end
26
+
27
+ def test_return_string ()
28
+ assert_kind_of String, return_string
29
+ end
30
+
31
+ end# TestFunction
@@ -0,0 +1,30 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helpers'
5
+
6
+
7
+ class TestStruct < Test::Unit::TestCase
8
+
9
+ def setup ()
10
+ @x = Rucy::Tester::Struct.new
11
+ end
12
+
13
+ def test_default_value_is_0 ()
14
+ assert_equal 0, @x.num
15
+ end
16
+
17
+ def test_get_set_num ()
18
+ @x.num = 1
19
+ assert_equal 1, @x.num
20
+ end
21
+
22
+ def test_dup ()
23
+ assert_equal 0, @x.num
24
+ x = @x.dup
25
+ @x.num = 1
26
+ assert_equal 1, @x.num
27
+ assert_equal 0, x.num
28
+ end
29
+
30
+ end# TestStruct
@@ -0,0 +1,18 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helpers'
5
+
6
+
7
+ class TestFunction < Test::Unit::TestCase
8
+
9
+ include Rucy::Tester
10
+
11
+ def test_to_value ()
12
+ assert_equal true, true_to_value
13
+ assert_equal false, false_to_value
14
+ assert_equal nil, null_to_value
15
+ assert_equal nil, nil_value
16
+ end
17
+
18
+ end# TestFunction