cgen 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.gitignore +5 -0
  2. data/History.txt +199 -0
  3. data/README.txt +34 -0
  4. data/examples/bench.rb +14 -0
  5. data/examples/complex.rb +63 -0
  6. data/examples/complex2.rb +48 -0
  7. data/examples/cshadow-example.rb +55 -0
  8. data/examples/cshadow-point.rb +58 -0
  9. data/examples/ctest.rb +34 -0
  10. data/examples/ctest2.rb +32 -0
  11. data/examples/ctest3.rb +179 -0
  12. data/examples/ctest4.rb +18 -0
  13. data/examples/ctest5.rb +27 -0
  14. data/examples/example-ruby-talk-30April2004.rb +65 -0
  15. data/examples/fixed-array.rb +221 -0
  16. data/examples/inherit-example.rb +26 -0
  17. data/examples/inherit-example.txt +80 -0
  18. data/examples/instance-eval.rb +66 -0
  19. data/examples/ivset.rb +55 -0
  20. data/examples/marshal-test.rb +19 -0
  21. data/examples/matrix.rb +91 -0
  22. data/examples/modular-def.rb +87 -0
  23. data/examples/objattr.rb +46 -0
  24. data/examples/opaque-struct-test.rb +36 -0
  25. data/examples/sample.rb +184 -0
  26. data/examples/struct.rb +103 -0
  27. data/examples/test.rb +24 -0
  28. data/examples/yaml.rb +56 -0
  29. data/install.rb +1015 -0
  30. data/lib/cgen/attribute.rb +414 -0
  31. data/lib/cgen/cgen.rb +2041 -0
  32. data/lib/cgen/cshadow.rb +1037 -0
  33. data/lib/cgen/inherit.rb +46 -0
  34. data/rakefile +42 -0
  35. data/tasks/ann.rake +80 -0
  36. data/tasks/bones.rake +20 -0
  37. data/tasks/gem.rake +201 -0
  38. data/tasks/git.rake +40 -0
  39. data/tasks/notes.rake +27 -0
  40. data/tasks/post_load.rake +34 -0
  41. data/tasks/rdoc.rake +51 -0
  42. data/tasks/rubyforge.rake +55 -0
  43. data/tasks/setup.rb +292 -0
  44. data/tasks/spec.rake +54 -0
  45. data/tasks/svn.rake +47 -0
  46. data/tasks/test.rake +40 -0
  47. data/tasks/zentest.rake +36 -0
  48. data/test/test-attribute.rb +430 -0
  49. data/test/test-cgen.rb +127 -0
  50. data/test/test-cshadow.rb +289 -0
  51. data/test/test.rb +17 -0
  52. metadata +123 -0
@@ -0,0 +1,34 @@
1
+ require 'cshadow.rb'
2
+
3
+ class Test
4
+ include CShadow
5
+
6
+ define_class_method :foo do
7
+ body %{
8
+ typedef struct Bar {
9
+ struct Foo *foo;
10
+ } Bar;
11
+ typedef struct Foo {
12
+ int x;
13
+ } Foo;
14
+
15
+ Bar bar;
16
+ char s[20], buf[100];
17
+
18
+ bar.foo->x;
19
+
20
+ {int *x = 0; printf("%d", *x);}
21
+
22
+ sscanf("foo bar", "%s", s);
23
+ while (gets(buf))
24
+ printf("%s\n", s);
25
+ }
26
+ end
27
+ end
28
+
29
+ Dir.mkdir "tmp" rescue SystemCallError
30
+ Dir.chdir "tmp"
31
+
32
+ Test.commit
33
+
34
+ Test.foo
@@ -0,0 +1,32 @@
1
+ require 'cshadow.rb'
2
+ require 'misc/irb-session'
3
+
4
+ class Dummy
5
+ def initialize value
6
+ @value = value
7
+ end
8
+ end
9
+
10
+ class Test2
11
+ include CShadow
12
+
13
+ shadow_attr_accessor :ary => Dummy
14
+ attr_accessor :x
15
+
16
+ def initialize
17
+ self.ary = Dummy.new 1
18
+ self.x = Dummy.new 2
19
+ end
20
+ end
21
+
22
+ Dir.mkdir "tmp" rescue SystemCallError
23
+ Dir.chdir "tmp"
24
+
25
+ Test2.commit
26
+
27
+ t = Test2.new
28
+ GC.start
29
+
30
+ $z = GC.reachability_paths t.x
31
+
32
+ IRB.start_session([])
@@ -0,0 +1,179 @@
1
+ require 'cshadow.rb'
2
+
3
+ class Object
4
+ def insteval_proc pr
5
+ instance_eval &pr
6
+ end
7
+ end
8
+
9
+ class TestSuper
10
+ def foo arg
11
+ p "foo #{arg}"
12
+ end
13
+
14
+ class << self
15
+ def class_meth
16
+ puts "Class method!"
17
+ end
18
+ end
19
+ end
20
+
21
+ class Test < TestSuper
22
+ include CShadow
23
+
24
+ # shadow_library.declare :typedefs => %{
25
+ # typedef struct zap *T1;
26
+ # typedef int *T2;
27
+ # struct zap {
28
+ # double z;
29
+ # };
30
+ # }
31
+
32
+ # shadow_library_include_file.declare :foo => "extern int foo"
33
+ # shadow_library.declare :foo => "int foo"
34
+
35
+ shadow_attr_accessor :ary => Array
36
+
37
+ def initialize
38
+ self.ary = []
39
+ end
40
+ # protected :zap
41
+
42
+ shadow_library.include "<assert.h>"
43
+ shadow_library.include "<math.h>"
44
+
45
+ define_method :bar do
46
+ body %{
47
+ rb_funcall(RBASIC(shadow->self)->klass, #{declare_symbol :class_meth}, 0);
48
+ }
49
+ end
50
+
51
+ define_class_method :foo do
52
+ arguments :from_array
53
+ body %{
54
+ enum zap {zow, zim=3, zug=zow+zim, zwip} zzz;
55
+ typedef struct {
56
+ short s;
57
+ unsigned a : 4;
58
+ enum zap b : 4;
59
+ // enum zap c : 15;
60
+ // unsigned d : 1;
61
+ unsigned e : 5;
62
+ unsigned f : 3;
63
+ } bitfld;
64
+ struct {
65
+ struct {} v0;
66
+ struct {} v1;
67
+ struct {} v2;
68
+ int x;
69
+ } z;
70
+ int zz = 123;
71
+ VALUE pi;
72
+
73
+ inline VALUE fn(VALUE v) {
74
+ printf("The value is %d.\\n", NUM2LONG(v));
75
+ }
76
+
77
+ VALUE fnie(VALUE arg, VALUE my_proc) {
78
+ rb_funcall(my_proc, #{declare_symbol :call}, 0);
79
+ }
80
+
81
+ typedef void (*Flow)(void *); // evaluates one variable
82
+ typedef struct {
83
+ unsigned d_tick : 16; // last discrete tick at which flow computed
84
+ unsigned rk_level : 3; // last rk level at which flow was computed
85
+ unsigned algebraic : 1; // should compute flow when inputs change?
86
+ unsigned nested : 1; // to catch circular evaluation
87
+ Flow flow; // cached flow function of current state
88
+ double value_0; // value during discrete step
89
+ double value_1; // value at steps of Runge-Kutta
90
+ double value_2;
91
+ double value_3;
92
+ } ContVar;
93
+
94
+ typedef struct T_o_ContState_Shadow {
95
+
96
+ /* RedShift_o_Component_o_ContState_Shadow members */
97
+ long self;
98
+ long foo;
99
+
100
+ struct {} begin_vars __attribute__ ((aligned (8)));
101
+
102
+ ContVar x;
103
+ } T_o_ContState_Shadow;
104
+
105
+ T_o_ContState_Shadow shadow;
106
+
107
+ printf("sizeof(z) = %d\\n", sizeof(z));
108
+ printf("sizeof(ContVar) = %d\\n", sizeof(ContVar));
109
+ printf("sizeof(T_o_ContState_Shadow) = %d\\n", sizeof(T_o_ContState_Shadow));
110
+
111
+ printf("&shadow.x - &shadow.begin_vars = %d\\n",
112
+ (void *)&(shadow.x) - (void *)&(shadow.begin_vars));
113
+
114
+ return Qnil;
115
+
116
+ printf("sizeof(z) = %d\n", sizeof(z));
117
+ return Qnil;
118
+
119
+ #if 1
120
+ rb_funcall(Qnil, #{declare_symbol :insteval_proc},
121
+ 1, RARRAY(from_array)->ptr[0]);
122
+ #else
123
+ //# rb_obj_instance_eval(1, &RARRAY(from_array)->ptr[0], Qnil);
124
+ rb_iterate(rb_obj_instance_eval, INT2NUM(15), &fnie, RARRAY(from_array)->ptr[0]);
125
+ #endif
126
+
127
+ return Qnil;
128
+
129
+ // printf("Result = %f\\n", pow(1.0,5));
130
+
131
+ // return Qnil;
132
+
133
+ fn(RARRAY(from_array)->ptr[2]);
134
+ printf("Len = %d\\n", RARRAY(from_array)->len);
135
+
136
+ goto skip;
137
+ assert(1==0);
138
+ skip:
139
+ pi = rb_const_get(#{declare_module :Math}, #{declare_symbol :PI});
140
+
141
+ printf("Math::PI = %f", NUM2DBL(pi));
142
+
143
+ printf("\\n%d, %d, %d, %d.\\n", zow, zim, zug, zwip);
144
+
145
+ printf("\\nSize is: %d\\n", sizeof(bitfld));
146
+
147
+ switch (zz) {
148
+ case 1: 0;
149
+ }
150
+
151
+ while (zz-- > 0) {
152
+ int xx = zz;
153
+ printf("%d\n", xx);
154
+ }
155
+ }
156
+ end
157
+ end
158
+
159
+ Dir.mkdir "tmp" rescue SystemCallError
160
+ Dir.chdir "tmp"
161
+
162
+ Test.commit
163
+
164
+ Test.new.bar
165
+ exit
166
+
167
+ #p Test.new
168
+
169
+ #num = 2**31-1
170
+ #puts "original num = #{num}"
171
+
172
+ class MyArray < Array; end
173
+ ma = MyArray.new << 0 << 1 << 2 << 3
174
+
175
+ result = Test.foo([proc { puts "bar" }])
176
+ #puts "result num = #{num}"
177
+
178
+ #marshalled_num = Marshal.load(Marshal.dump(num))
179
+ #puts "marshalled num = #{marshalled_num}"
@@ -0,0 +1,18 @@
1
+ require 'cgen/cshadow.rb'
2
+
3
+ class Test
4
+ include CShadow
5
+
6
+ define_c_class_method :foo do
7
+ body %{
8
+ printf("Ok!\n");
9
+ }
10
+ end
11
+ end
12
+
13
+ Dir.mkdir "tmp" rescue SystemCallError
14
+ Dir.chdir "tmp"
15
+
16
+ Test.commit
17
+
18
+ Test.foo
@@ -0,0 +1,27 @@
1
+ require 'cgen/cshadow.rb'
2
+
3
+ class Test
4
+ include CShadow
5
+
6
+ shadow_attr_accessor :sym => Symbol
7
+
8
+ define_c_method :foo do
9
+ body %{
10
+ shadow->sym = ID2SYM(rb_intern("some_symbol"));
11
+ }
12
+ end
13
+ free_function.body %{
14
+ printf("Freeing a Test instance.\\n");
15
+ }
16
+ end
17
+
18
+ Dir.mkdir "tmp" rescue SystemCallError
19
+ Dir.chdir "tmp"
20
+
21
+ Test.commit
22
+
23
+ t = Test.new
24
+ t.foo
25
+ p t.sym
26
+ t.sym = :qwerty
27
+ p t.sym
@@ -0,0 +1,65 @@
1
+ require 'cgen/cshadow'
2
+
3
+ class MyClass
4
+ include CShadow
5
+ shadow_attr_accessor :my_c_string => "char *my_string"
6
+ shadow_attr_accessor :my_ruby_string => String
7
+ shadow_attr_accessor :my_ruby_object => Object
8
+
9
+ def initialize
10
+ # Must use 'self.varname = value', or else ruby will assign to
11
+ # local var
12
+ self.my_c_string = "default string"
13
+ # stored as null-terminated char *
14
+
15
+ self.my_ruby_string = "default string"
16
+ # stored as ruby VALUE string, after checking type is String
17
+
18
+ self.my_ruby_object = "default string"
19
+ # stored as ruby VALUE string, no type checking
20
+ end
21
+
22
+ def inspect
23
+ "<#{self.class}: %p, %p, %p>" %
24
+ [my_c_string, my_ruby_string, my_ruby_object]
25
+ end
26
+
27
+ # easy way to add a method written in C
28
+ define_c_method :foo do
29
+
30
+ c_array_args { # interface to rb_scan_args
31
+ required :x
32
+ optional :y
33
+ rest :stuff
34
+ block :block
35
+ typecheck :x => Numeric
36
+ default :y => "INT2NUM(NUM2INT(x) + 1)"
37
+ }
38
+
39
+ declare :result => "VALUE result"
40
+
41
+ body %{
42
+ result = rb_funcall(block, #{declare_symbol :call}, 4,
43
+ shadow->my_ruby_string,
44
+ x, y, stuff);
45
+ }
46
+ # note use of shadow var to access shadow attrs
47
+
48
+ returns "result"
49
+ end
50
+ end
51
+
52
+ MyClass.commit # write C lib, compile, load
53
+
54
+ my_obj = MyClass.new
55
+ p my_obj
56
+ # ==> <MyClass: "default string", "default string", "default string">
57
+
58
+ block = proc do |str, x, y, stuff|
59
+ "%s, %p, %p, %p" % [str, x, y, stuff]
60
+ end
61
+
62
+ p my_obj.foo(1, &block)
63
+ # ==> "default string, 1, 2, []"
64
+ p my_obj.foo(5, 0, "stuff", "more stuff", &block)
65
+ # ==> "default string, 5, 0, [\"stuff\", \"more stuff\"]"
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "cgen/cshadow"
4
+
5
+ =begin
6
+
7
+ This file contains an assortment of classes of shadow objects that are useful in building up complex data structures.
8
+
9
+ ==class (({FixedArray}))
10
+
11
+ (({FixedArray})) is a factory class for generating fixed-size arrays of C variables or Ruby objects. There are several reasons for implementing (({FixedArray})) as a standalone object instead of as an attribute. First, defining [] and []= for one array attribute might conflict with another definition of those methods in the same object. Second, it can include Enumerable and add additional methods in subclasses. Third, the factory approach can handle different Ruby and C types more easily, with length and item_type stored as Ruby class attributes. Finally, an array attribute cannot easily return itself as a value to Ruby code. It is better if the array ((*is*)) the object.
12
+
13
+ For efficiency and easy access from C code, an attribute that refers to a (({FixedArray})) can be a (({ShadowAttribute})) rather than an (({ObjectAttribute})). (See ((<attribute.rb>)).)
14
+
15
+ If the (({item_type})) is a class which includes (({CShadow})), then the array itself uses (({ShadowAttribute}))s for efficiency. Ruby code doesn't need to be aware of this, but C code does: the entries are not of type (({VALUE})) but of type determined by calling (({#shadow_struct_name})).
16
+
17
+ Each different (({length})) and (({item_type})) results in a new anonymous subclass of (({FixedArray})), defined in its own library (because of the commit problem).
18
+
19
+ =end
20
+
21
+ if true # if this ever is useful, put it in attribute.rb
22
+
23
+ # Fixed length array, embedded within shadow struct.
24
+ # For use, see examples/fixed-array.rb.
25
+ #
26
+ # Currently, this attr type accepts declarations of
27
+ # the form
28
+ # shadow_attr :var => "<type> <name>[<len>]"
29
+ # and
30
+ # shadow_attr :var => "<type> * <name>[<len>]"
31
+ # with any arrangement of spaces around the "*",
32
+ # where <type> is a standard C type (int, double,
33
+ # char) or a type defined by typedef.
34
+ #
35
+ # Support for VALUE and shadow struct types is less
36
+ # useful, but may later be added for completeness.
37
+ #
38
+ # The host object must define reader/writer methods.
39
+ #
40
+ class FixedArrayAttribute < CShadow::CNativeAttribute
41
+ @pattern = /\A(\w+\s*\*?)\s*(\w+)\[(\d+)\]\z/
42
+
43
+ attr_reader :length
44
+
45
+ def initialize(*args)
46
+ super
47
+ @length = @match[3].to_i
48
+
49
+ case @ctype
50
+ when /\AVALUE /
51
+ raise NotImplementedError
52
+ when /#{CShadow::SHADOW_SUFFIX}\s*\*/
53
+ raise NotImplementedError
54
+ when /\*/
55
+ @free = %{
56
+ {
57
+ int i;
58
+ for (i = 0; i < #{@length}; i++)
59
+ free(shadow->#{@cvar}[i])
60
+ }
61
+ }
62
+ else
63
+ # Not a pointer. Nothing to do.
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ class FixedArray
72
+ include Enumerable
73
+
74
+ # length and item_type are hard-coded in the subclass definitions.
75
+ def length; type.length; end
76
+ def item_type; type.item_type; end
77
+
78
+ @subs = {}
79
+
80
+ class << self
81
+ def length; @length; end
82
+ def item_type; @item_type; end
83
+
84
+ def to_s ### necessary?
85
+ name
86
+ end
87
+
88
+ def new length, item_type = Object
89
+ if self == FixedArray
90
+ c = @subs[[length, item_type]] ||= make_subclass(length, item_type)
91
+ c.new
92
+ else
93
+ super() ### superclass.new ... ???
94
+ end
95
+ end
96
+
97
+ def make_subclass length, item_type
98
+ c = Class.new(FixedArray)
99
+
100
+ def c.name
101
+ "FixedArray_#{@length}_#{@item_type}"
102
+ end
103
+
104
+ c.class_eval %q{ ### why doesn't block work?
105
+ @length = length
106
+ @item_type = item_type
107
+
108
+ include CShadow
109
+ shadow_library "foo_#@length_#@item_type"
110
+
111
+ unless length > 0
112
+ raise ArgumentError, "\nLength must be positive."
113
+ end
114
+
115
+ case item_type
116
+ when Class
117
+ raise NotImplementedError ## for now. These cases aren't so useful.
118
+ if item_type.included_modules.include? CShadow
119
+ shadow_attr :array =>
120
+ "#{item_type.shadow_struct_name} *array[#{length}]"
121
+ else
122
+ shadow_attr :array => "VALUE array[#{length}]"
123
+ end
124
+ when String
125
+ unless item_type =~ /\A\w+\s*\*?\z/
126
+ raise TypeError, "\n"
127
+ end
128
+ shadow_attr :array => "#{item_type} array[#{length}]"
129
+ end
130
+
131
+ define_method(:[]) {
132
+ arguments :index
133
+ declare :i => "int i"
134
+ body %{
135
+ i = NUM2INT(index);
136
+ if (i < 0 || i >= sizeof(shadow->array))
137
+ rb_raise(#{declare_class IndexError},
138
+ "Index %d out of range [0, %d]",
139
+ i, sizeof(shadow->array) - 1);
140
+ }
141
+ case item_type
142
+ when "int"; returns "INT2FIX(shadow->array[i])"
143
+ when "double"; returns "rb_float_new(shadow->array[i])"
144
+ else raise NotImplementedError
145
+ end
146
+ }
147
+
148
+ define_method(:[]=) {
149
+ arguments :index, :value
150
+ declare :i => "int i"
151
+ body %{
152
+ i = NUM2INT(index);
153
+ if (i < 0 || i >= sizeof(shadow->array))
154
+ rb_raise(#{declare_class IndexError},
155
+ "Index %d out of range [0, %d]",
156
+ i, sizeof(shadow->array) - 1);
157
+ }
158
+ case item_type
159
+ when "int"; body "shadow->array[i] = NUM2INT(value)"
160
+ when "double"; body "shadow->array[i] = NUM2DBL(value)"
161
+ else raise NotImplementedError
162
+ end
163
+ returns "value"
164
+ }
165
+ }
166
+
167
+ begin
168
+ Dir.mkdir "FixedArray"
169
+ rescue SystemCallError
170
+ end
171
+ Dir.chdir "FixedArray"
172
+
173
+ c.commit
174
+
175
+ Dir.chdir ".."
176
+
177
+ return c
178
+ end
179
+ private :make_subclass
180
+ end
181
+
182
+ # conversion to array and back
183
+
184
+ def each
185
+
186
+ end
187
+ end
188
+
189
+ def FixedArray length, item_type = Object
190
+ FixedArray.new length, item_type
191
+ end
192
+
193
+
194
+ if $0 == __FILE__
195
+
196
+ require "cgen/cshadow"
197
+
198
+ require 'runit/testcase'
199
+ require 'runit/cui/testrunner'
200
+ require 'runit/testsuite'
201
+
202
+ begin
203
+ Dir.mkdir "tmp"
204
+ rescue SystemCallError
205
+ end
206
+ Dir.chdir "tmp"
207
+
208
+ class FixedArrayTest < RUNIT::TestCase
209
+
210
+ Fai = FixedArray 10, "int"
211
+ Fad = FixedArray 10, "double"
212
+
213
+ def test__initial
214
+ assert_equal(0, Fai[0])
215
+ assert_equal(0, Fad[0])
216
+ end
217
+ end
218
+
219
+ RUNIT::CUI::TestRunner.run(FixedArrayTest.suite)
220
+
221
+ end